/
display-fields-modal.tsx
76 lines (66 loc) · 2.22 KB
/
display-fields-modal.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { useCallback, useState } from "react";
import { Button } from "@/components/button";
import { Modal } from "@/components/modal";
import { useUpdateSearchParams } from "@/hooks/use-update-search-params";
import { SEARCH_PARAM_NAMES } from "@/search-param-names";
import { DEFAULT_DISPLAY_FIELDS } from "./constants";
import { DisplayFieldsForm } from "./display-fields-form";
import { stringifyDisplayFieldConfigs } from "./stringify-display-field-config";
import { DisplayFieldConfig, IdentifiedDisplayFieldConfig } from "./types";
type DisplayFieldsModalProps = {
fields: DisplayFieldConfig[];
onClose: () => void;
}
const DEFAULT_DISPLAY_FIELDS_STRING = stringifyDisplayFieldConfigs(DEFAULT_DISPLAY_FIELDS);
export function DisplayFieldsModal({
fields: initialFields,
onClose,
}: DisplayFieldsModalProps) {
const [fields, setFields] = useState<IdentifiedDisplayFieldConfig[]>(() => initialFields.map((field) => ({
...field,
id: crypto.randomUUID(),
})));
const updateSearchParams = useUpdateSearchParams();
const handleOk = useCallback(() => {
const s = stringifyDisplayFieldConfigs(fields);
updateSearchParams({
[SEARCH_PARAM_NAMES.SEARCH.FIELDS]: (!s || s === DEFAULT_DISPLAY_FIELDS_STRING) ? undefined : s,
});
onClose();
}, [fields, onClose, updateSearchParams]);
const handleReset = () => {
setFields(DEFAULT_DISPLAY_FIELDS.map((field) => ({
...field,
id: crypto.randomUUID(),
})));
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {
// Commend+Enter or Ctrl+Enter to submit
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
e.stopPropagation();
handleOk();
}
if (e.key === "Escape") {
e.preventDefault();
e.stopPropagation();
onClose();
}
};
return (
<Modal
title="表示する列を変更"
onClose={onClose}
onKeyDown={handleKeyDown}
size="lg"
footer={(
<div className="flex gap-3">
<Button onClick={handleOk}>確定</Button>
<Button variant="secondary" onClick={handleReset}>リセット</Button>
</div>
)}
>
<DisplayFieldsForm fields={fields} onChange={setFields} />
</Modal>
);
}