{ "version": 3, "sources": ["../../board/board_history.tsx"], "sourcesContent": ["import * as React from \"react\"\nimport {classNames} from \"@cling/lib.web.utils\"\nimport {observer} from \"mobx-react\"\nimport {BoardContext} from \"../board_context\"\nimport {board_resource} from \"@cling/lib.web.resources\"\nimport {Button, Icon, IconButton, ListItem, SearchableList, Snackbar} from \"@cling/lib.web.mdc\"\nimport {\n AccountUID,\n Board,\n BoardChangelogEntry,\n BoardPatchOpType,\n BoardUID,\n Card,\n CardChangelogEntry,\n CardPatchOpType,\n CLING_BOT,\n CommentChangelogEntry,\n CommentPatchOpType,\n} from \"@cling/lib.shared.model\"\nimport {observable, runInAction, makeObservable} from \"mobx\"\nimport {i18n} from \"@cling/lib.web.i18n\"\nimport {PrincipalInfo} from \"../account/principal_info\"\nimport {current_user, ui_actions, ui_state} from \"../state/index\"\nimport {RelDate} from \"../misc/rel_date\"\nimport {can_call_faas} from \"@cling/lib.web.auth\"\nimport {running_on_mobile_device, running_on_phone} from \"@cling/lib.web.utils\"\nimport {cancel_event} from \"@cling/lib.web.utils\"\nimport {not_null} from \"@cling/lib.shared.utils\"\nimport {useCardPermission, useCurrentBoardPermission} from \"../state/permission_hooks\"\nimport {HighlightBadge} from \"../account/highlight_badge\"\nimport {Chip, ChipSet} from \"@cling/lib.web.mdc/chip\"\nimport {CardSynopsisOneLiner} from \"../card/card_synopsis\"\nimport {LoadingIndicator} from \"@cling/lib.web.lazy_load/loading_indicator\"\nimport {GlobalBackdrop} from \"../misc/global_backdrop\"\n\nclass BoardHistoryState {\n private _open = false\n\n constructor() {\n makeObservable<BoardHistoryState, \"_open\">(this, {\n _open: observable,\n })\n }\n\n get is_open() {\n return this._open\n }\n\n open = () => {\n if (!ui_state.current_board.board || this._open) {\n return\n }\n if (!can_call_faas()) {\n Snackbar.show_message(i18n.version_history_is_not_available_are_you_offline)\n }\n runInAction(() => {\n this._open = true\n })\n }\n\n toggle = () => {\n if (this._open) {\n this.close()\n } else {\n this.open()\n }\n }\n\n close = () => {\n runInAction(() => {\n this._open = false\n ui_state.app_bar_enabled = true\n })\n ui_actions.highlight_card(undefined)\n if (!ui_state.current_board_uid) {\n return\n }\n ui_state.set_current_board_uid(ui_state.current_board_uid, \"latest\")\n }\n}\n\nexport const board_history_state = new BoardHistoryState()\n\ntype ChangelogData = {\n account_uid: AccountUID\n patch_op_type: number\n board_uid?: BoardUID\n date: Date\n}\n\nconst important_change_op_types = [\n CardPatchOpType.AddCard,\n CommentPatchOpType.AddComment,\n CardPatchOpType.SetCardFileBlob,\n CardPatchOpType.SetCardFileFileName,\n CardPatchOpType.SetCardFileTitle,\n CardPatchOpType.SetCardLinkTitle,\n CardPatchOpType.SetCardLinkURL,\n CardPatchOpType.SetCardNoteSafeHtml,\n CardPatchOpType.SetCardNoteTitle,\n CardPatchOpType.SetTaskAssignee,\n CardPatchOpType.SetTaskStatus,\n CardPatchOpType.SetTaskDate,\n CardPatchOpType.PasteCard,\n] as number[]\n\nexport const BoardHistoryList = observer(\n ({\n search_visible,\n show_my_changes,\n show_important_only,\n onChange,\n }: {\n search_visible?: boolean\n show_my_changes: boolean\n show_important_only: boolean\n onChange?: () => void\n }) => {\n const list_ref = React.useRef<SearchableList>(null)\n const {\n current_board: {display_version},\n current_board_uid,\n } = React.useContext(BoardContext)\n const [changes, set_changes] = React.useState<\n {\n board_version: number\n card?: Card\n patch_op_type: CardPatchOpType | CommentPatchOpType | BoardPatchOpType\n account_uid: AccountUID\n date: Date\n desc: React.ReactElement\n }[]\n >([])\n const [show_spinner_for, set_show_spinner_for] = React.useState<number | undefined>()\n const [show_num, set_show_num] = React.useState(100)\n const show_more = React.useCallback(() => {\n set_show_num(Math.min(show_num + 100, changes.length))\n }, [show_num, changes])\n const show_version = React.useCallback(\n (index_str: string) => {\n if (index_str === \"latest\") {\n ui_actions.highlight_card(undefined)\n ui_state.set_current_board_uid(not_null(current_board_uid), \"latest\")\n return\n }\n const change = changes[parseInt(index_str)]\n ui_actions.hide_all_comments()\n set_show_spinner_for(change.board_version)\n ui_actions.fully_expand_all()\n ui_state.set_current_board_uid(\n not_null(current_board_uid),\n change.board_version,\n () => {\n set_show_spinner_for(undefined)\n ui_actions.highlight_card(change.card?.uid)\n if (change.patch_op_type === CommentPatchOpType.AddComment && change.card) {\n // Note: We must use `ui_state.current_board.board` here, because `board`\n // is not up-to-date yet.\n const card = not_null(\n ui_state.current_board.board?.card(change.card.uid),\n )\n ui_actions.open_comments(card)\n }\n onChange?.()\n },\n )\n },\n [current_board_uid, changes, onChange],\n )\n React.useEffect(() => {\n // Go to \"latest version\" whenever `show_my_changes` or `show_important_only` changes.\n ui_actions.highlight_card(undefined)\n ui_state.set_current_board_uid(not_null(current_board_uid), \"latest\")\n }, [current_board_uid, show_my_changes, show_important_only])\n const latest_board = current_board_uid ? board_resource.read(current_board_uid) : undefined\n const {can_view_whole_history, could_view_whole_history} = useCurrentBoardPermission()\n React.useEffect(() => {\n if (!latest_board) {\n set_changes([])\n return\n }\n set_changes(\n calculate_changes({\n can_view_whole_history,\n show_important_only,\n show_my_changes,\n latest_board,\n }),\n )\n // `latest_board?.last_change` is important, because we want to re-calculate the\n // list of changes even if the board changes locally only.\n }, [\n show_my_changes,\n show_important_only,\n latest_board,\n latest_board?.last_change,\n can_view_whole_history,\n ])\n React.useEffect(() => {\n if (search_visible) {\n list_ref.current?.focus_search_field()\n }\n }, [search_visible])\n const {can_edit_card, can_add_comment} = useCardPermission(latest_board?.root)\n const modifications_allowed_in_latest_version = can_edit_card || can_add_comment\n const is_plan_free_limit_reached =\n !can_view_whole_history &&\n show_num >= changes.length &&\n changes[changes.length - 1]?.board_version !== 1\n const are_there_versions_before_20210401 =\n !is_plan_free_limit_reached &&\n show_num >= changes.length &&\n changes[changes.length - 1]?.board_version !== 1 &&\n (latest_board?.first_change?.date.getTime() ?? 0) < new Date(\"2021-04-01\").getTime()\n const show_cling_pro_teaser = React.useCallback(\n () =>\n ui_actions.open_pro_feature_teaser_dialog({\n description: i18n.to_view_versions_older_than_7_days,\n }),\n [],\n )\n if (!current_board_uid) {\n return null\n }\n return (\n <SearchableList\n search_visible={!!search_visible}\n onSelected={show_version}\n search_label={i18n.search}\n className=\"board-history__list\"\n ref={list_ref}\n data-test-id=\"BoardHistory_list\"\n >\n <ListItem\n key=\"latest\"\n value=\"latest\"\n selected={display_version === \"latest\"}\n data-test-id=\"BoardHistory_version_latest\"\n >\n <div className=\"board-history__avatar\">\n <Icon\n icon={modifications_allowed_in_latest_version ? \"edit\" : \"history\"}\n outlined\n />\n </div>\n <div className=\"board-history__entry\">\n <div className=\"board-history__entry-header\">\n {modifications_allowed_in_latest_version &&\n i18n.modifications_are_allowed}\n </div>\n <div\n className=\"board-history__entry-description\"\n data-test-id=\"BoardHistory_entry_desc\"\n >\n {i18n.live}\n </div>\n </div>\n </ListItem>\n {changes\n .filter((_, i) => i < show_num)\n .map((x, i) => (\n <ListItem\n key={x.board_version}\n value={`${i}`}\n selected={x.board_version === display_version}\n data-test-id={`BoardHistory_version_${x.board_version}`}\n >\n <div className=\"board-history__avatar\">\n {show_spinner_for === x.board_version && (\n <div className=\"board-history__avatar-loading\">\n <LoadingIndicator delay={500} alpha={1} />\n </div>\n )}\n <PrincipalInfo\n className={classNames(\"board-history__avatar-pi\", {\n \"board-history__avatar-pi--loading\":\n show_spinner_for === x.board_version,\n })}\n display=\"avatar\"\n uid={x.account_uid}\n data-test-ignore\n />\n {x.date.getTime() >\n (ui_state.board_last_seen(current_board_uid)?.getTime() ??\n 0) && (\n <div className=\"board-history__avatar-badge mdcx-badge mdcx-badge--secondary mdcx-badge--small\" />\n )}\n </div>\n <div className=\"board-history__entry\">\n <div className=\"board-history__entry-header\">\n <RelDate date={x.date} />{\" \"}\n <PrincipalInfo\n data-test-ignore\n display=\"full_name_no_teams\"\n uid={x.account_uid}\n />\n </div>\n {!!x.card && (\n <div\n className=\"board-history__entry-synopsis\"\n data-test-id=\"BoardHistory_entry_synopsis\"\n >\n <CardSynopsisOneLiner card={x.card} />\n </div>\n )}\n <div\n className=\"board-history__entry-description\"\n data-test-id=\"BoardHistory_entry_desc\"\n >\n {x.desc}\n </div>\n </div>\n </ListItem>\n ))}\n {show_num < changes.length && (\n <div className=\"width--full\" data-ignore-in-search>\n <Button onClick={show_more} className=\"width--full\">\n {i18n.show_older_versions}\n </Button>\n </div>\n )}\n {are_there_versions_before_20210401 && (\n <div className=\"width--full font-caption mdc-list-item\" data-ignore-in-search>\n <div className=\"mt--1\">\n {i18n.due_to_technical_reasons_you_cannot_view_changes_made_before}\n </div>\n </div>\n )}\n {is_plan_free_limit_reached && could_view_whole_history && (\n <div\n className=\"width--full font-caption mdc-list-item\"\n data-ignore-in-search\n onClick={show_cling_pro_teaser}\n >\n <div className=\"mt--1\">\n {i18n.to_view_versions_older_than_7_days} <HighlightBadge type=\"pro\" />\n </div>\n </div>\n )}\n {/* Just a spacer (for NewElmFAB) */}\n <div className=\"board-history__list-bottom-spacer\" data-ignore-in-search />\n </SearchableList>\n )\n },\n)\n\nconst BoardHistory = observer(({is_open, on_close}: {is_open: boolean; on_close: () => void}) => {\n const [search_visible, set_search_visible] = React.useState(false)\n const {\n current_board: {board},\n } = React.useContext(BoardContext)\n const [show_my_changes, set_show_my_changes] = React.useState<boolean>(\n board?.acl.all.length === 1,\n )\n const [show_important_only, set_show_important_only] = React.useState<boolean>(true)\n const toggle_show_my_changes = React.useCallback(\n () => set_show_my_changes(!show_my_changes),\n [show_my_changes],\n )\n const toggle_show_important_only = React.useCallback(\n () => set_show_important_only(!show_important_only),\n [show_important_only],\n )\n const on_toggle_search = React.useCallback(\n () => set_search_visible(!search_visible),\n [search_visible],\n )\n const [collapsed, set_collapsed] = React.useState(false)\n const toggle_collapsed = React.useCallback(() => {\n set_collapsed(!collapsed)\n if (!running_on_phone()) {\n return\n }\n runInAction(() => {\n if (collapsed) {\n ui_state.app_bar_shown = true\n ui_state.app_bar_enabled = false\n } else {\n ui_state.app_bar_enabled = true\n }\n })\n }, [collapsed])\n const on_change_mobile = React.useCallback(() => {\n toggle_collapsed()\n }, [toggle_collapsed])\n React.useEffect(() => {\n if (is_open && running_on_phone()) {\n runInAction(() => {\n ui_state.app_bar_shown = true\n ui_state.app_bar_enabled = false\n })\n }\n if (!is_open) {\n set_collapsed(false)\n set_search_visible(false)\n }\n }, [is_open])\n const open_help = React.useCallback(\n () => ui_actions.open_website_page(\"detail/version-history\"),\n [],\n )\n if (!board) {\n return null\n }\n return (\n <div\n className={classNames(\"board-history\", {\n \"board-history-desktop\": !running_on_phone(),\n \"board-history-mobile\": running_on_phone(),\n \"board-history--open\": is_open,\n \"board-history--collapsed\": is_open && collapsed,\n \"board-history--app-bar-shown\":\n ui_state.app_bar_shown && running_on_mobile_device(),\n })}\n onClick={cancel_event}\n >\n <GlobalBackdrop />\n <div className=\"board-history__header\">\n {running_on_phone() && (\n <IconButton\n icon={collapsed ? \"expand_less\" : \"expand_more\"}\n onClick={toggle_collapsed}\n outlined\n data-test-id=\"BoardHistory_toggle_collapsed\"\n data-test-state={collapsed ? \"collapsed\" : \"expanded\"}\n />\n )}\n <div\n className=\"board-history__header-title\"\n onClick={running_on_phone() ? toggle_collapsed : undefined}\n >\n {i18n.version_history}\n </div>\n {!collapsed && (\n <IconButton\n icon={search_visible ? \"search_off\" : \"search\"}\n onClick={on_toggle_search}\n outlined\n small={!running_on_phone()}\n tooltip={i18n.search}\n />\n )}\n <IconButton\n onClick={open_help}\n small={!running_on_phone()}\n icon=\"help\"\n outlined\n tooltip={i18n.help}\n />\n <IconButton\n icon=\"close\"\n small={!running_on_phone()}\n outlined\n onClick={on_close}\n data-test-id=\"BoardHistory_close\"\n tooltip={i18n.close}\n />\n </div>\n {is_open && (\n <>\n <ChipSet className=\"p--1\" onClick={cancel_event}>\n <Chip primary={show_my_changes} onClick={toggle_show_my_changes}>\n {i18n.my_changes}\n </Chip>\n <Chip\n primary={show_important_only}\n onClick={toggle_show_important_only}\n data-test-id=\"BoardHistory_important_only\"\n >\n {i18n.important_only}\n </Chip>\n </ChipSet>\n <BoardHistoryList\n key=\"board_history_list\"\n search_visible={search_visible}\n onChange={running_on_phone() ? on_change_mobile : undefined}\n show_my_changes={show_my_changes}\n show_important_only={show_important_only}\n />\n </>\n )}\n </div>\n )\n})\n\nexport const ObservingBoardHistory = observer(() => {\n return (\n <BoardHistory is_open={board_history_state.is_open} on_close={board_history_state.close} />\n )\n})\n\nexport function calculate_changes({\n show_my_changes,\n show_important_only,\n can_view_whole_history,\n latest_board,\n}: {\n show_my_changes: boolean\n show_important_only: boolean\n can_view_whole_history: boolean\n latest_board: Board\n}) {\n const changes_map = new Map<\n number,\n [\n CardChangelogEntry | CommentChangelogEntry | BoardChangelogEntry,\n Card | undefined,\n boolean /* `card_was_on_board` */,\n boolean /* `contains_important_change */,\n ]\n >()\n const set_change = (\n changelog_entry: CardChangelogEntry | CommentChangelogEntry | BoardChangelogEntry,\n card: Card | undefined,\n card_was_on_board: boolean,\n ) => {\n // If there are multiple operations in a single patch, we have to deterministically\n // determine, which one we want to display.\n const precedence = [\n // SetCardNoteSafeHtml is on top because we will add link-cards whenever the\n // user enters an URL in a text-card IN THE SAME PATCH. We want to show this as\n // \"Note text changed\".\n CardPatchOpType.SetCardNoteSafeHtml,\n CardPatchOpType.AddCard,\n CommentPatchOpType.AddComment,\n BoardPatchOpType.AddSystemBoard,\n BoardPatchOpType.AddPeopleBoard,\n BoardPatchOpType.AddBoard,\n CardPatchOpType.PasteCard,\n CardPatchOpType.SetCardFileBlob,\n ]\n const current = changes_map.get(changelog_entry.board_version)\n if (current) {\n let cur_precedence = precedence.indexOf(current[0].patch_op_type)\n if (cur_precedence === -1) {\n cur_precedence = Number.MAX_SAFE_INTEGER\n }\n let new_precedence = precedence.indexOf(changelog_entry.patch_op_type)\n if (new_precedence === -1) {\n new_precedence = Number.MAX_SAFE_INTEGER\n }\n if (new_precedence > cur_precedence) {\n if (important_change_op_types.includes(changelog_entry.patch_op_type)) {\n current[3] = true\n }\n return\n }\n }\n changes_map.set(changelog_entry.board_version, [\n changelog_entry,\n card,\n card_was_on_board,\n important_change_op_types.includes(changelog_entry.patch_op_type) || !!current?.[3],\n ])\n }\n const changelog_is_clean_after = new Date(\"2021-04-01T00:00:00Z\").getTime()\n const seven_days_ago = Date.now() - 7 * 24 * 60 * 60_000\n const changelog_filter = (x: ChangelogData) =>\n x.account_uid !== CLING_BOT &&\n (show_my_changes || x.account_uid !== current_user.account.uid) &&\n x.patch_op_type !== CardPatchOpType.CardChangelogMigration &&\n !x.board_uid &&\n // We cannot use changelog-data from before 2021-04-01 because it may contain\n // metadata generated on other boards with higher board-version-numbers\n // See ef25b6e39755d44348d93396c9cad875c0aec829 for the fix to that.\n // We should re-create all metadata eventually.\n x.date.getTime() > changelog_is_clean_after &&\n (can_view_whole_history || x.date.getTime() > seven_days_ago)\n // Note: BoardPatchOpType.CardChangelogMigration\n // equals CardPatchOpType.CardChangelogMigration\n latest_board.changelog.filter(changelog_filter).forEach((x) => set_change(x, undefined, false))\n for (const card of latest_board.regular_cards) {\n let card_was_on_board = false\n card.changelog\n .filter(changelog_filter)\n // Make a copy because `collapse_card_changes` might alter entries.\n .map((x) => new CardChangelogEntry({...x}))\n .filter(collapse_card_changes())\n .forEach((x) => {\n set_change(x, card, card_was_on_board)\n card_was_on_board = card_was_on_board || !x.board_uid\n })\n for (const comment of card.comments.filter((x) => !x.removed)) {\n comment.changelog.filter(changelog_filter).forEach((x) => set_change(x, card, false))\n }\n }\n const result = []\n for (let i = latest_board.version; i > 0; i--) {\n const change = changes_map.get(i)\n if (change) {\n const [x, card, was_on_board_before, has_important_change] = change\n if (show_important_only && !has_important_change) {\n continue\n }\n result.push({\n board_version: x.board_version,\n card,\n account_uid: x.account_uid,\n patch_op_type: x.patch_op_type,\n date: x.date,\n desc: i18n.changelog_entry(x, was_on_board_before),\n })\n }\n }\n return result\n}\n\n/**\n * We want to collapse certain changes like consecutive operations on the same card by the same\n * user.\n * Note: Changelog entries are mutated!\n */\nfunction collapse_card_changes() {\n let last_card_change: CardChangelogEntry | undefined\n return (x: CardChangelogEntry): boolean => {\n if (\n !last_card_change ||\n last_card_change.date.getTime() < x.date.getTime() - 60_000 ||\n last_card_change.account_uid !== x.account_uid ||\n last_card_change.board_version + 1 !== x.board_version\n ) {\n last_card_change = x\n return true\n }\n if (last_card_change.patch_op_type === x.patch_op_type) {\n last_card_change.board_version = x.board_version\n return false\n }\n if (last_card_change.patch_op_type === CardPatchOpType.AddCard) {\n last_card_change.board_version = x.board_version\n return false\n }\n last_card_change = x\n return true\n }\n}\n\nexport default ObservingBoardHistory\n"], "mappings": "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", "names": ["init_compat_module", "_BoardHistoryState", "__publicField", "__name", "ui_state", "can_call_faas", "Snackbar", "i18n", "runInAction", "ui_actions", "makeObservable", "observable", "BoardHistoryState", "board_history_state", "important_change_op_types", "BoardHistoryList", "observer", "search_visible", "show_my_changes", "show_important_only", "onChange", "list_ref", "A", "display_version", "current_board_uid", "x", "BoardContext", "changes", "set_changes", "d", "show_spinner_for", "set_show_spinner_for", "show_num", "set_show_num", "show_more", "q", "show_version", "index_str", "not_null", "change", "card", "y", "latest_board", "board_resource", "can_view_whole_history", "could_view_whole_history", "useCurrentBoardPermission", "calculate_changes", "can_edit_card", "can_add_comment", "useCardPermission", "modifications_allowed_in_latest_version", "is_plan_free_limit_reached", "are_there_versions_before_20210401", "show_cling_pro_teaser", "_", "SearchableList", "ListItem", "Icon", "i", "LoadingIndicator", "PrincipalInfo", "classNames", "RelDate", "CardSynopsisOneLiner", "Button", "HighlightBadge", "BoardHistory", "is_open", "on_close", "set_search_visible", "board", "set_show_my_changes", "set_show_important_only", "toggle_show_my_changes", "toggle_show_important_only", "on_toggle_search", "collapsed", "set_collapsed", "toggle_collapsed", "running_on_phone", "on_change_mobile", "open_help", "running_on_mobile_device", "cancel_event", "GlobalBackdrop", "IconButton", "k", "ChipSet", "Chip", "ObservingBoardHistory", "changes_map", "set_change", "changelog_entry", "card_was_on_board", "precedence", "current", "cur_precedence", "new_precedence", "changelog_is_clean_after", "seven_days_ago", "changelog_filter", "CLING_BOT", "current_user", "CardChangelogEntry", "collapse_card_changes", "comment", "result", "was_on_board_before", "has_important_change", "last_card_change", "board_history_default"] }