mirror of
https://github.com/docmost/docmost.git
synced 2026-05-18 23:44:24 +08:00
WIP
This commit is contained in:
@@ -2,14 +2,12 @@ import {
|
|||||||
ActionIcon,
|
ActionIcon,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Combobox,
|
|
||||||
Group,
|
Group,
|
||||||
InputBase,
|
|
||||||
Paper,
|
Paper,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
|
Select,
|
||||||
Switch,
|
Switch,
|
||||||
Text,
|
Text,
|
||||||
useCombobox,
|
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import {
|
import {
|
||||||
@@ -21,11 +19,7 @@ import {
|
|||||||
} from "@/features/page-history/atoms/history-atoms";
|
} from "@/features/page-history/atoms/history-atoms";
|
||||||
import HistoryView from "@/features/page-history/components/history-view";
|
import HistoryView from "@/features/page-history/components/history-view";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import {
|
import { IconCheck, IconChevronDown, IconChevronUp } from "@tabler/icons-react";
|
||||||
IconChevronDown,
|
|
||||||
IconChevronUp,
|
|
||||||
IconSelector,
|
|
||||||
} from "@tabler/icons-react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
usePageHistoryListQuery,
|
usePageHistoryListQuery,
|
||||||
@@ -54,9 +48,6 @@ interface Props {
|
|||||||
|
|
||||||
export default function HistoryModalMobile({ pageId, pageTitle }: Props) {
|
export default function HistoryModalMobile({ pageId, pageTitle }: Props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const combobox = useCombobox({
|
|
||||||
onDropdownClose: () => combobox.resetSelectedOption(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const [activeHistoryId, setActiveHistoryId] = useAtom(activeHistoryIdAtom);
|
const [activeHistoryId, setActiveHistoryId] = useAtom(activeHistoryIdAtom);
|
||||||
const [, setActiveHistoryPrevId] = useAtom(activeHistoryPrevIdAtom);
|
const [, setActiveHistoryPrevId] = useAtom(activeHistoryPrevIdAtom);
|
||||||
@@ -75,6 +66,16 @@ export default function HistoryModalMobile({ pageId, pageTitle }: Props) {
|
|||||||
[pageHistoryData],
|
[pageHistoryData],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const selectData = useMemo(
|
||||||
|
() =>
|
||||||
|
historyItems.map((item) => ({
|
||||||
|
value: item.id,
|
||||||
|
label: formattedDate(new Date(item.createdAt)),
|
||||||
|
userName: item.lastUpdatedBy?.name,
|
||||||
|
})),
|
||||||
|
[historyItems],
|
||||||
|
);
|
||||||
|
|
||||||
const [mainEditor] = useAtom(pageEditorAtom);
|
const [mainEditor] = useAtom(pageEditorAtom);
|
||||||
const [mainEditorTitle] = useAtom(titleEditorAtom);
|
const [mainEditorTitle] = useAtom(titleEditorAtom);
|
||||||
|
|
||||||
@@ -141,15 +142,15 @@ export default function HistoryModalMobile({ pageId, pageTitle }: Props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectVersion = useCallback(
|
const handleSelectVersion = useCallback(
|
||||||
(id: string) => {
|
(value: string | null) => {
|
||||||
const index = historyItems.findIndex((item) => item.id === id);
|
if (!value) return;
|
||||||
|
const index = historyItems.findIndex((item) => item.id === value);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
setActiveHistoryId(id);
|
setActiveHistoryId(value);
|
||||||
setActiveHistoryPrevId(historyItems[index + 1]?.id ?? "");
|
setActiveHistoryPrevId(historyItems[index + 1]?.id ?? "");
|
||||||
}
|
}
|
||||||
combobox.closeDropdown();
|
|
||||||
},
|
},
|
||||||
[historyItems, combobox],
|
[historyItems],
|
||||||
);
|
);
|
||||||
|
|
||||||
const confirmRestore = () =>
|
const confirmRestore = () =>
|
||||||
@@ -183,24 +184,6 @@ export default function HistoryModalMobile({ pageId, pageTitle }: Props) {
|
|||||||
}
|
}
|
||||||
}, [activeHistoryData, mainEditor, mainEditorTitle, setHistoryModalOpen, t]);
|
}, [activeHistoryData, mainEditor, mainEditorTitle, setHistoryModalOpen, t]);
|
||||||
|
|
||||||
const selectedItem = historyItems.find((item) => item.id === activeHistoryId);
|
|
||||||
|
|
||||||
const options = historyItems.map((item) => (
|
|
||||||
<Combobox.Option
|
|
||||||
value={item.id}
|
|
||||||
key={item.id}
|
|
||||||
className={classes.option}
|
|
||||||
active={item.id === activeHistoryId}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<Text size="sm">{formattedDate(new Date(item.createdAt))}</Text>
|
|
||||||
<Text size="xs" c="dimmed">
|
|
||||||
{item.lastUpdatedBy?.name}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</Combobox.Option>
|
|
||||||
));
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -208,39 +191,26 @@ export default function HistoryModalMobile({ pageId, pageTitle }: Props) {
|
|||||||
return (
|
return (
|
||||||
<Box className={classes.container}>
|
<Box className={classes.container}>
|
||||||
<Box className={classes.selectorWrapper}>
|
<Box className={classes.selectorWrapper}>
|
||||||
<Combobox
|
<Select
|
||||||
store={combobox}
|
data={selectData}
|
||||||
onOptionSubmit={handleSelectVersion}
|
value={activeHistoryId}
|
||||||
withinPortal={false}
|
onChange={handleSelectVersion}
|
||||||
>
|
placeholder={t("Select version")}
|
||||||
<Combobox.Target>
|
checkIconPosition="right"
|
||||||
<InputBase
|
maxDropdownHeight={300}
|
||||||
component="button"
|
renderOption={({ option, checked }) => (
|
||||||
type="button"
|
<Group justify="space-between" wrap="nowrap" w="100%">
|
||||||
pointer
|
<div>
|
||||||
rightSection={<IconSelector size={16} />}
|
<Text size="sm">{option.label}</Text>
|
||||||
rightSectionPointerEvents="none"
|
<Text size="xs" c="dimmed">
|
||||||
onClick={() => combobox.toggleDropdown()}
|
{(option as { userName?: string }).userName}
|
||||||
className={classes.selector}
|
|
||||||
>
|
|
||||||
{selectedItem ? (
|
|
||||||
<Text size="sm">
|
|
||||||
{formattedDate(new Date(selectedItem.createdAt))}
|
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
</div>
|
||||||
<Text size="sm" c="dimmed">
|
{checked && <IconCheck size={16} />}
|
||||||
{t("Select version")}
|
</Group>
|
||||||
</Text>
|
)}
|
||||||
)}
|
comboboxProps={{ withinPortal: false }}
|
||||||
</InputBase>
|
/>
|
||||||
</Combobox.Target>
|
|
||||||
|
|
||||||
<Combobox.Dropdown className={classes.dropdown}>
|
|
||||||
<Combobox.Options>
|
|
||||||
<ScrollArea.Autosize mah={300}>{options}</ScrollArea.Autosize>
|
|
||||||
</Combobox.Options>
|
|
||||||
</Combobox.Dropdown>
|
|
||||||
</Combobox>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
|
|||||||
Reference in New Issue
Block a user