tycho-components 0.21.19 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/configs/Localization.js +12 -0
  2. package/dist/features/DocumentDrawer/Actions/Actions.d.ts +12 -0
  3. package/dist/features/DocumentDrawer/Actions/Actions.js +77 -0
  4. package/dist/features/DocumentDrawer/Actions/index.d.ts +2 -0
  5. package/dist/features/DocumentDrawer/Actions/index.js +2 -0
  6. package/dist/features/DocumentDrawer/Actions/style.scss +6 -0
  7. package/dist/features/DocumentDrawer/AutomaticParser/AutomaticParser.d.ts +8 -0
  8. package/dist/features/DocumentDrawer/AutomaticParser/AutomaticParser.js +96 -0
  9. package/dist/features/DocumentDrawer/AutomaticParser/index.d.ts +2 -0
  10. package/dist/features/DocumentDrawer/AutomaticParser/index.js +2 -0
  11. package/dist/features/DocumentDrawer/AutomaticParser/style.scss +10 -0
  12. package/dist/features/DocumentDrawer/DocumentDrawer.d.ts +14 -0
  13. package/dist/features/DocumentDrawer/DocumentDrawer.js +111 -0
  14. package/dist/features/DocumentDrawer/DocumentEdit/DocumentEdit.d.ts +35 -0
  15. package/dist/features/DocumentDrawer/DocumentEdit/DocumentEdit.js +207 -0
  16. package/dist/features/DocumentDrawer/DocumentEdit/index.d.ts +2 -0
  17. package/dist/features/DocumentDrawer/DocumentEdit/index.js +1 -0
  18. package/dist/features/DocumentDrawer/DocumentExport/DocumentExport.d.ts +7 -0
  19. package/dist/features/DocumentDrawer/DocumentExport/DocumentExport.js +71 -0
  20. package/dist/features/DocumentDrawer/DocumentExport/ExportInvalidSentences.d.ts +7 -0
  21. package/dist/features/DocumentDrawer/DocumentExport/ExportInvalidSentences.js +12 -0
  22. package/dist/features/DocumentDrawer/DocumentExport/index.d.ts +2 -0
  23. package/dist/features/DocumentDrawer/DocumentExport/index.js +2 -0
  24. package/dist/features/DocumentDrawer/DocumentExport/style.scss +31 -0
  25. package/dist/features/DocumentDrawer/DocumentLexicon/DocumentLexicon.d.ts +7 -0
  26. package/dist/features/DocumentDrawer/DocumentLexicon/DocumentLexicon.js +22 -0
  27. package/dist/features/DocumentDrawer/DocumentLexicon/index.d.ts +2 -0
  28. package/dist/features/DocumentDrawer/DocumentLexicon/index.js +2 -0
  29. package/dist/features/DocumentDrawer/DocumentLexicon/style.scss +38 -0
  30. package/dist/features/DocumentDrawer/DocumentRemove/DocumentRemove.d.ts +12 -0
  31. package/dist/features/DocumentDrawer/DocumentRemove/DocumentRemove.js +28 -0
  32. package/dist/features/DocumentDrawer/DocumentRemove/index.d.ts +2 -0
  33. package/dist/features/DocumentDrawer/DocumentRemove/index.js +2 -0
  34. package/dist/features/DocumentDrawer/DocumentRemove/style.scss +0 -0
  35. package/dist/features/DocumentDrawer/Github/Github.d.ts +8 -0
  36. package/dist/features/DocumentDrawer/Github/Github.js +11 -0
  37. package/dist/features/DocumentDrawer/Github/GithubCommit.d.ts +8 -0
  38. package/dist/features/DocumentDrawer/Github/GithubCommit.js +86 -0
  39. package/dist/features/DocumentDrawer/Github/index.d.ts +2 -0
  40. package/dist/features/DocumentDrawer/Github/index.js +2 -0
  41. package/dist/features/DocumentDrawer/Github/style.scss +31 -0
  42. package/dist/features/DocumentDrawer/ImageGallery/GalleryImage.d.ts +8 -0
  43. package/dist/features/DocumentDrawer/ImageGallery/GalleryImage.js +5 -0
  44. package/dist/features/DocumentDrawer/ImageGallery/GalleryRemoval.d.ts +9 -0
  45. package/dist/features/DocumentDrawer/ImageGallery/GalleryRemoval.js +14 -0
  46. package/dist/features/DocumentDrawer/ImageGallery/ImageGallery.d.ts +9 -0
  47. package/dist/features/DocumentDrawer/ImageGallery/ImageGallery.js +45 -0
  48. package/dist/features/DocumentDrawer/ImageGallery/index.d.ts +2 -0
  49. package/dist/features/DocumentDrawer/ImageGallery/index.js +2 -0
  50. package/dist/features/DocumentDrawer/ImageGallery/style.scss +41 -0
  51. package/dist/features/DocumentDrawer/Info/Info.d.ts +10 -0
  52. package/dist/features/DocumentDrawer/Info/Info.js +16 -0
  53. package/dist/features/DocumentDrawer/Info/index.d.ts +2 -0
  54. package/dist/features/DocumentDrawer/Info/index.js +2 -0
  55. package/dist/features/DocumentDrawer/Info/style.scss +24 -0
  56. package/dist/features/DocumentDrawer/Metadata/DocumentMetadata/DocumentMetadata.d.ts +8 -0
  57. package/dist/features/DocumentDrawer/Metadata/DocumentMetadata/DocumentMetadata.js +60 -0
  58. package/dist/features/DocumentDrawer/Metadata/DocumentMetadata/index.d.ts +2 -0
  59. package/dist/features/DocumentDrawer/Metadata/DocumentMetadata/index.js +2 -0
  60. package/dist/features/DocumentDrawer/Metadata/DocumentMetadata/style.scss +7 -0
  61. package/dist/features/DocumentDrawer/Metadata/DocumentMetadataEdit/DocumentMetadataEdit.d.ts +11 -0
  62. package/dist/features/DocumentDrawer/Metadata/DocumentMetadataEdit/DocumentMetadataEdit.js +195 -0
  63. package/dist/features/DocumentDrawer/Metadata/DocumentMetadataEdit/index.d.ts +2 -0
  64. package/dist/features/DocumentDrawer/Metadata/DocumentMetadataEdit/index.js +2 -0
  65. package/dist/features/DocumentDrawer/Metadata/DocumentMetadataEdit/style.scss +58 -0
  66. package/dist/features/DocumentDrawer/PageStatusComponent/PageStatusComponent.d.ts +9 -0
  67. package/dist/features/DocumentDrawer/PageStatusComponent/PageStatusComponent.js +30 -0
  68. package/dist/features/DocumentDrawer/PageStatusComponent/index.d.ts +2 -0
  69. package/dist/features/DocumentDrawer/PageStatusComponent/index.js +2 -0
  70. package/dist/features/DocumentDrawer/PageStatusComponent/style.scss +19 -0
  71. package/dist/features/DocumentDrawer/Pages/BoxRemoval.d.ts +9 -0
  72. package/dist/features/DocumentDrawer/Pages/BoxRemoval.js +14 -0
  73. package/dist/features/DocumentDrawer/Pages/Boxes.d.ts +9 -0
  74. package/dist/features/DocumentDrawer/Pages/Boxes.js +63 -0
  75. package/dist/features/DocumentDrawer/Pages/PageRemoval.d.ts +9 -0
  76. package/dist/features/DocumentDrawer/Pages/PageRemoval.js +15 -0
  77. package/dist/features/DocumentDrawer/Pages/Pages.d.ts +10 -0
  78. package/dist/features/DocumentDrawer/Pages/Pages.js +72 -0
  79. package/dist/features/DocumentDrawer/Pages/style.scss +48 -0
  80. package/dist/features/DocumentDrawer/deps.d.ts +28 -0
  81. package/dist/features/DocumentDrawer/deps.js +20 -0
  82. package/dist/features/DocumentDrawer/functions/FileUtils.d.ts +4 -0
  83. package/dist/features/DocumentDrawer/functions/FileUtils.js +8 -0
  84. package/dist/features/DocumentDrawer/functions/MetadataUtils.d.ts +41 -0
  85. package/dist/features/DocumentDrawer/functions/MetadataUtils.js +192 -0
  86. package/dist/features/DocumentDrawer/index.d.ts +5 -0
  87. package/dist/features/DocumentDrawer/index.js +3 -0
  88. package/dist/features/DocumentDrawer/localization/ActionsTexts.d.ts +77 -0
  89. package/dist/features/DocumentDrawer/localization/ActionsTexts.js +77 -0
  90. package/dist/features/DocumentDrawer/localization/DocumentTexts.d.ts +140 -0
  91. package/dist/features/DocumentDrawer/localization/DocumentTexts.js +140 -0
  92. package/dist/features/DocumentDrawer/localization/ExportTexts.d.ts +59 -0
  93. package/dist/features/DocumentDrawer/localization/ExportTexts.js +59 -0
  94. package/dist/features/DocumentDrawer/localization/GithubTexts.d.ts +35 -0
  95. package/dist/features/DocumentDrawer/localization/GithubTexts.js +35 -0
  96. package/dist/features/DocumentDrawer/localization/PageTexts.d.ts +45 -0
  97. package/dist/features/DocumentDrawer/localization/PageTexts.js +45 -0
  98. package/dist/features/DocumentDrawer/localization/ParserTexts.d.ts +30 -0
  99. package/dist/features/DocumentDrawer/localization/ParserTexts.js +30 -0
  100. package/dist/features/DocumentDrawer/services/AutomaticParserService.d.ts +8 -0
  101. package/dist/features/DocumentDrawer/services/AutomaticParserService.js +9 -0
  102. package/dist/features/DocumentDrawer/services/BoundingBoxService.d.ts +11 -0
  103. package/dist/features/DocumentDrawer/services/BoundingBoxService.js +20 -0
  104. package/dist/features/DocumentDrawer/services/DocumentService.d.ts +13 -0
  105. package/dist/features/DocumentDrawer/services/DocumentService.js +20 -0
  106. package/dist/features/DocumentDrawer/services/ExportService.d.ts +11 -0
  107. package/dist/features/DocumentDrawer/services/ExportService.js +16 -0
  108. package/dist/features/DocumentDrawer/services/GithubService.d.ts +8 -0
  109. package/dist/features/DocumentDrawer/services/GithubService.js +12 -0
  110. package/dist/features/DocumentDrawer/services/ImageService.d.ts +8 -0
  111. package/dist/features/DocumentDrawer/services/ImageService.js +12 -0
  112. package/dist/features/DocumentDrawer/services/LexiconService.d.ts +10 -0
  113. package/dist/features/DocumentDrawer/services/LexiconService.js +9 -0
  114. package/dist/features/DocumentDrawer/services/MetadataService.d.ts +15 -0
  115. package/dist/features/DocumentDrawer/services/MetadataService.js +26 -0
  116. package/dist/features/DocumentDrawer/services/PageService.d.ts +11 -0
  117. package/dist/features/DocumentDrawer/services/PageService.js +16 -0
  118. package/dist/features/DocumentDrawer/services/SentenceService.d.ts +6 -0
  119. package/dist/features/DocumentDrawer/services/SentenceService.js +6 -0
  120. package/dist/features/DocumentDrawer/style.scss +171 -0
  121. package/dist/features/DocumentDrawer/types/BoundingBox.d.ts +8 -0
  122. package/dist/features/DocumentDrawer/types/BoundingBox.js +1 -0
  123. package/dist/features/DocumentDrawer/types/CatalogSearchFilter.d.ts +15 -0
  124. package/dist/features/DocumentDrawer/types/CatalogSearchFilter.js +16 -0
  125. package/dist/features/DocumentDrawer/types/Category.d.ts +16 -0
  126. package/dist/features/DocumentDrawer/types/Category.js +5 -0
  127. package/dist/features/DocumentDrawer/types/DocumentStatus.d.ts +7 -0
  128. package/dist/features/DocumentDrawer/types/DocumentStatus.js +6 -0
  129. package/dist/features/DocumentDrawer/types/DocumentUpdateRequest.d.ts +13 -0
  130. package/dist/features/DocumentDrawer/types/DocumentUpdateRequest.js +1 -0
  131. package/dist/features/DocumentDrawer/types/Export.d.ts +25 -0
  132. package/dist/features/DocumentDrawer/types/Export.js +36 -0
  133. package/dist/features/DocumentDrawer/types/Lexicon.d.ts +6 -0
  134. package/dist/features/DocumentDrawer/types/Lexicon.js +1 -0
  135. package/dist/features/DocumentDrawer/types/LexiconResponse.d.ts +6 -0
  136. package/dist/features/DocumentDrawer/types/LexiconResponse.js +1 -0
  137. package/dist/features/DocumentDrawer/types/Metadata.d.ts +22 -0
  138. package/dist/features/DocumentDrawer/types/Metadata.js +8 -0
  139. package/dist/features/DocumentDrawer/types/Page.d.ts +10 -0
  140. package/dist/features/DocumentDrawer/types/Page.js +1 -0
  141. package/dist/features/DocumentDrawer/types/PageStatus.d.ts +9 -0
  142. package/dist/features/DocumentDrawer/types/PageStatus.js +8 -0
  143. package/dist/features/DocumentDrawer/types/Parser.d.ts +18 -0
  144. package/dist/features/DocumentDrawer/types/Parser.js +21 -0
  145. package/dist/features/DocumentDrawer/types/Query.d.ts +6 -0
  146. package/dist/features/DocumentDrawer/types/Query.js +1 -0
  147. package/dist/features/DocumentDrawer/types/Sentence.d.ts +4 -0
  148. package/dist/features/DocumentDrawer/types/Sentence.js +1 -0
  149. package/dist/features/index.d.ts +4 -0
  150. package/dist/features/index.js +2 -0
  151. package/dist/shell/Header/HeaderApps/HeaderApps.js +2 -1
  152. package/dist/shell/Header/HelpButton/HelpModal.js +2 -1
  153. package/package.json +1 -1
@@ -0,0 +1,8 @@
1
+ import { Document } from '../../deps';
2
+ import './style.scss';
3
+ type Props = {
4
+ document: Document;
5
+ onDocumentChange?: (document: Document) => void;
6
+ };
7
+ export default function DocumentMetadata({ document, onDocumentChange, }: Props): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import metadataService from '../../services/MetadataService';
3
+ import { useEffect, useMemo, useState } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { AppFormInfo, AppPlaceholder, } from '../../deps';
6
+ import './style.scss';
7
+ import { Button } from 'tycho-storybook';
8
+ import DocumentMetadataEdit from '../DocumentMetadataEdit/DocumentMetadataEdit';
9
+ import MetadataUtils from '../../functions/MetadataUtils';
10
+ function getDocumentMetaValue(document, attr) {
11
+ const entry = document.metadata?.find((m) => {
12
+ const values = m;
13
+ return (values.uid === attr || values.symbol === attr || values[attr] != null);
14
+ });
15
+ if (!entry)
16
+ return undefined;
17
+ const values = entry;
18
+ return values.value || values[attr];
19
+ }
20
+ function hasDisplayValue(value) {
21
+ return value != null && String(value).trim() !== '';
22
+ }
23
+ export default function DocumentMetadata({ document, onDocumentChange, }) {
24
+ const { t } = useTranslation('document');
25
+ const { metaAttr, normalizeMetadataType, formatMetadataDateForDisplay } = MetadataUtils;
26
+ const [editOpen, setEditOpen] = useState(false);
27
+ const [metadata, setMetadata] = useState();
28
+ const filteredMetadata = useMemo(() => (metadata ?? []).filter((meta) => hasDisplayValue(getDocumentMetaValue(document, metaAttr(meta)))), [metadata, document]);
29
+ const fields = useMemo(() => filteredMetadata.map((meta) => {
30
+ const attr = metaAttr(meta);
31
+ const type = normalizeMetadataType(meta.type);
32
+ const base = {
33
+ attr,
34
+ name: meta.name,
35
+ type: type === 'DATE' ? 'datepicker' : meta.type?.toLowerCase() || 'text',
36
+ };
37
+ if (type === 'DATE') {
38
+ return {
39
+ ...base,
40
+ display: (raw) => formatMetadataDateForDisplay(raw == null ? '' : String(raw)),
41
+ };
42
+ }
43
+ return base;
44
+ }), [filteredMetadata]);
45
+ const data = useMemo(() => {
46
+ const row = {};
47
+ filteredMetadata.forEach((meta) => {
48
+ const attr = metaAttr(meta);
49
+ const raw = getDocumentMetaValue(document, attr);
50
+ row[attr] = raw;
51
+ });
52
+ return row;
53
+ }, [filteredMetadata, document]);
54
+ useEffect(() => {
55
+ metadataService.list(document).then((response) => {
56
+ setMetadata(response.data);
57
+ });
58
+ }, [document]);
59
+ return (_jsxs("div", { className: "metadata-container", children: [_jsxs("div", { className: "header", children: [_jsx("div", { className: "title", children: t('metadata.label.title') }), _jsx(Button, { size: "small", onClick: () => setEditOpen(true), text: t('document.button.edit'), icon: "edit", mode: "outlined" })] }), _jsxs("div", { className: "body", children: [filteredMetadata.length > 0 && (_jsx(AppFormInfo, { fields: fields, data: data })), metadata && filteredMetadata.length === 0 && (_jsx(AppPlaceholder, { text: t('placeholder.empty.metadata') }))] }), editOpen && metadata && (_jsx(DocumentMetadataEdit, { document: document, metadata: metadata, onClose: () => setEditOpen(false), onSave: (updated) => onDocumentChange?.(updated) }))] }));
60
+ }
@@ -0,0 +1,2 @@
1
+ import DocumentMetadata from './DocumentMetadata';
2
+ export default DocumentMetadata;
@@ -0,0 +1,2 @@
1
+ import DocumentMetadata from './DocumentMetadata';
2
+ export default DocumentMetadata;
@@ -0,0 +1,7 @@
1
+ .metadata-container {
2
+ .body {
3
+ height: 90vh;
4
+ overflow-y: auto;
5
+ padding: 16px;
6
+ }
7
+ }
@@ -0,0 +1,11 @@
1
+ import Metadata from '../../types/Metadata';
2
+ import { Document } from '../../deps';
3
+ import './style.scss';
4
+ type Props = {
5
+ document: Document;
6
+ metadata: Metadata[];
7
+ onClose: () => void;
8
+ onSave: (document: Document) => void;
9
+ };
10
+ export default function DocumentMetadataEdit({ document, metadata, onClose, onSave, }: Props): import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,195 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import MetadataUtils from '../../functions/MetadataUtils';
3
+ import documentService from '../../services/DocumentService';
4
+ import metadataService from '../../services/MetadataService';
5
+ import { useEffect, useMemo, useRef, useState } from 'react';
6
+ import { useForm } from 'react-hook-form';
7
+ import { useTranslation } from 'react-i18next';
8
+ import { AppForm, AppModal, useMessageUtils, } from '../../deps';
9
+ import { Button, IconButton, SelectField } from 'tycho-storybook';
10
+ import './style.scss';
11
+ const PENDING_FIELD = 'val';
12
+ const ADD_SELECT_FIELD = 'attr';
13
+ export default function DocumentMetadataEdit({ document, metadata, onClose, onSave, }) {
14
+ const { t } = useTranslation('document');
15
+ const { dispatchMessage, dispatchError } = useMessageUtils();
16
+ const { metaAttr, normalizeMetadataType, toAppFormField, toAutocompleteFormValue, normalizeMetadataDateValue, resolveRawFromForm, serializeMetadataValue, compareMetadata, buildInitialEntries, } = MetadataUtils;
17
+ const initialAttrsRef = useRef(new Set((document.metadata || []).map((m) => {
18
+ const values = m;
19
+ return values.uid || values.symbol || values[m.attr];
20
+ })));
21
+ const modalContentRef = useRef(null);
22
+ const syncedEntryAttrsRef = useRef('');
23
+ const definitions = useMemo(() => [...metadata].sort(compareMetadata), [metadata]);
24
+ const [entries, setEntries] = useState([]);
25
+ const [loaded, setLoaded] = useState(false);
26
+ const [pendingAttr, setPendingAttr] = useState(null);
27
+ const [saving, setSaving] = useState(false);
28
+ const pendingFieldRef = useRef(null);
29
+ const form = useForm({ defaultValues: {} });
30
+ const addSelectForm = useForm({
31
+ defaultValues: { [ADD_SELECT_FIELD]: '' },
32
+ });
33
+ const pendingForm = useForm({
34
+ defaultValues: { [PENDING_FIELD]: '' },
35
+ });
36
+ const pendingMeta = useMemo(() => pendingAttr
37
+ ? definitions.find((d) => metaAttr(d) === pendingAttr)
38
+ : undefined, [definitions, pendingAttr]);
39
+ const selectedAddAttr = addSelectForm.watch(ADD_SELECT_FIELD);
40
+ const availableToAdd = useMemo(() => definitions
41
+ .filter((d) => !entries.some((e) => e.attr === metaAttr(d)))
42
+ .sort((a, b) => a.name.localeCompare(b.name)), [definitions, entries]);
43
+ const entryLoadOptions = useMemo(() => {
44
+ const base = {};
45
+ for (const m of definitions) {
46
+ if (normalizeMetadataType(m.type) === 'TEXT') {
47
+ const attr = metaAttr(m);
48
+ base[attr] = async (query) => {
49
+ const r = await metadataService.suggestValues(document.corpus, m.uid, query);
50
+ return r.data.map((v) => ({ label: v, value: v }));
51
+ };
52
+ }
53
+ }
54
+ return base;
55
+ }, [definitions, document.corpus]);
56
+ const pendingLoadOptions = useMemo(() => {
57
+ const base = {};
58
+ if (!pendingMeta || normalizeMetadataType(pendingMeta.type) !== 'TEXT')
59
+ return base;
60
+ base[PENDING_FIELD] = async (query) => {
61
+ const r = await metadataService.suggestValues(document.corpus, pendingMeta.uid, query);
62
+ return r.data.map((v) => ({ label: v, value: v }));
63
+ };
64
+ return base;
65
+ }, [pendingMeta, document.corpus]);
66
+ const pendingFields = useMemo(() => {
67
+ if (!pendingMeta)
68
+ return [];
69
+ return [toAppFormField(pendingMeta, PENDING_FIELD, t)];
70
+ }, [pendingMeta, t]);
71
+ const handleRemove = (attr) => {
72
+ setEntries((prev) => prev.filter((e) => e.attr !== attr));
73
+ if (pendingAttr === attr)
74
+ setPendingAttr(null);
75
+ };
76
+ const handleAddPending = () => {
77
+ if (!pendingMeta || pendingAttr == null)
78
+ return;
79
+ const raw = pendingForm.getValues(PENDING_FIELD);
80
+ const val = serializeMetadataValue(pendingMeta, raw);
81
+ setEntries((prev) => [
82
+ ...prev,
83
+ { attr: pendingAttr, meta: pendingMeta, value: val },
84
+ ]);
85
+ setPendingAttr(null);
86
+ addSelectForm.reset({ [ADD_SELECT_FIELD]: '' });
87
+ pendingForm.reset({ [PENDING_FIELD]: '' });
88
+ };
89
+ const buildPayload = (formValues) => {
90
+ const domRoot = modalContentRef.current;
91
+ const payload = {};
92
+ for (const e of entries) {
93
+ const raw = resolveRawFromForm(e.meta, e.attr, formValues, domRoot);
94
+ payload[e.attr] = serializeMetadataValue(e.meta, raw);
95
+ }
96
+ for (const uid of initialAttrsRef.current) {
97
+ if (!(uid in payload)) {
98
+ payload[uid] = '';
99
+ }
100
+ }
101
+ return payload;
102
+ };
103
+ const submitMetadata = async (formValues) => {
104
+ const payload = buildPayload(formValues);
105
+ setSaving(true);
106
+ try {
107
+ await metadataService.update(document.uid, payload);
108
+ dispatchMessage({ key: 'update.success', t });
109
+ const refreshed = await documentService.get(document.uid);
110
+ onSave(refreshed.data);
111
+ onClose();
112
+ }
113
+ catch (err) {
114
+ const msg = t('error.metadata.invalid', {
115
+ value: err.response.data.details[0],
116
+ field: err.response.data.details[1],
117
+ type: err.response.data.details[2],
118
+ });
119
+ dispatchError({ err: msg });
120
+ }
121
+ finally {
122
+ setSaving(false);
123
+ }
124
+ };
125
+ const handleConfirm = () => {
126
+ void form.handleSubmit((values) => submitMetadata(values))();
127
+ };
128
+ useEffect(() => {
129
+ setEntries(buildInitialEntries(definitions, document));
130
+ setLoaded(true);
131
+ syncedEntryAttrsRef.current = '';
132
+ }, [definitions, document]);
133
+ useEffect(() => {
134
+ if (!loaded)
135
+ return;
136
+ const attrKey = entries
137
+ .map((e) => e.attr)
138
+ .sort()
139
+ .join('|');
140
+ if (syncedEntryAttrsRef.current === attrKey)
141
+ return;
142
+ syncedEntryAttrsRef.current = attrKey;
143
+ const prev = form.getValues();
144
+ const dirty = form.formState.dirtyFields;
145
+ const next = {};
146
+ entries.forEach((e) => {
147
+ const existing = prev[e.attr];
148
+ const type = normalizeMetadataType(e.meta.type);
149
+ const isDirty = !!dirty[e.attr];
150
+ if (isDirty && existing !== undefined) {
151
+ next[e.attr] = existing;
152
+ return;
153
+ }
154
+ const stored = e.value ?? '';
155
+ if (type === 'TEXT') {
156
+ if (existing != null && typeof existing === 'object') {
157
+ next[e.attr] = existing;
158
+ }
159
+ else {
160
+ next[e.attr] = toAutocompleteFormValue(existing != null ? String(existing) : stored);
161
+ }
162
+ }
163
+ else if (type === 'DATE') {
164
+ next[e.attr] = normalizeMetadataDateValue(existing != null ? String(existing) : stored);
165
+ }
166
+ else {
167
+ next[e.attr] = existing ?? stored;
168
+ }
169
+ });
170
+ form.reset(next);
171
+ }, [entries, loaded]);
172
+ useEffect(() => {
173
+ if (!pendingMeta)
174
+ return;
175
+ pendingForm.reset({
176
+ [PENDING_FIELD]: normalizeMetadataType(pendingMeta.type) === 'TEXT' ? null : '',
177
+ });
178
+ }, [pendingMeta, pendingForm]);
179
+ useEffect(() => {
180
+ if (!pendingMeta)
181
+ return;
182
+ const timeout = window.setTimeout(() => {
183
+ const el = pendingFieldRef.current?.querySelector('input:not([disabled]), textarea:not([disabled]), select:not([disabled])');
184
+ el?.focus();
185
+ }, 0);
186
+ return () => window.clearTimeout(timeout);
187
+ }, [pendingMeta]);
188
+ useEffect(() => {
189
+ setPendingAttr(selectedAddAttr || null);
190
+ }, [selectedAddAttr]);
191
+ return (_jsx(AppModal, { title: t('metadata.modal.edit.title'), className: "modal-document-metadata", close: onClose, confirm: handleConfirm, disableConfirm: !loaded || saving, disableBackdropClose: true, disableEscapeClose: true, children: _jsxs("div", { className: "document-metadata-edit", ref: modalContentRef, children: [_jsxs("div", { className: "document-metadata-edit-add", children: [_jsx(SelectField, { label: t('metadata.add.select.label'), attr: ADD_SELECT_FIELD, placeholder: t('metadata.add.select.placeholder'), createdForm: addSelectForm, options: availableToAdd.map((def) => ({
192
+ label: def.name,
193
+ value: metaAttr(def),
194
+ })), showEndAdornment: false }), pendingMeta && (_jsxs("div", { className: "document-metadata-edit-pending-field", ref: pendingFieldRef, children: [_jsx(AppForm, { fields: pendingFields, form: pendingForm, runtimeLoadOptions: pendingLoadOptions }), _jsx(Button, { size: "small", mode: "outlined", text: t('metadata.button.add'), onClick: handleAddPending })] }))] }), entries.length > 0 && (_jsxs("div", { className: "document-metadata-edit-list", children: [_jsx("div", { className: "document-metadata-edit-list-label", children: t('metadata.list.label') }), entries.map((e) => (_jsxs("div", { className: "document-metadata-edit-row", "data-metadata-field": e.attr, children: [_jsx("div", { className: "document-metadata-edit-row-field", children: _jsx(AppForm, { fields: [toAppFormField(e.meta, e.attr, t)], form: form, runtimeLoadOptions: entryLoadOptions }) }), _jsx(IconButton, { name: "delete", size: "large", mode: "outlined", color: "danger", title: t('metadata.remove.tooltip'), onClick: () => handleRemove(e.attr) })] }, e.attr)))] }))] }) }));
195
+ }
@@ -0,0 +1,2 @@
1
+ import DocumentMetadataEdit from './DocumentMetadataEdit';
2
+ export default DocumentMetadataEdit;
@@ -0,0 +1,2 @@
1
+ import DocumentMetadataEdit from './DocumentMetadataEdit';
2
+ export default DocumentMetadataEdit;
@@ -0,0 +1,58 @@
1
+ .modal-document-metadata {
2
+ width: min(560px, 92vw);
3
+ margin-top: 8vh;
4
+
5
+ .body {
6
+ height: 70vh;
7
+ overflow-y: auto;
8
+
9
+ .document-metadata-edit {
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: 24px;
13
+
14
+ &-label {
15
+ display: block;
16
+ font-size: 0.875rem;
17
+ margin-bottom: var(--spacing-x-small, 0.25rem);
18
+ }
19
+
20
+ &-select {
21
+ width: 100%;
22
+ max-width: 100%;
23
+ padding: 0.5rem 0.75rem;
24
+ border-radius: var(--radius-100, 4px);
25
+ border: 1px solid var(--border-default, #ccc);
26
+ background: var(--background-default, #fff);
27
+ }
28
+
29
+ &-pending-field {
30
+ margin-top: var(--spacing-small, 0.5rem);
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: var(--spacing-small, 0.5rem);
34
+ }
35
+
36
+ &-list-label {
37
+ font-weight: 600;
38
+ margin-bottom: var(--spacing-x-small, 0.25rem);
39
+ }
40
+
41
+ &-row {
42
+ display: flex;
43
+ align-items: flex-start;
44
+ gap: var(--spacing-small, 0.5rem);
45
+ margin-bottom: var(--spacing-small, 0.5rem);
46
+
47
+ &-field {
48
+ flex: 1;
49
+ min-width: 0;
50
+
51
+ .app-form-container {
52
+ width: 100%;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,9 @@
1
+ import { PageStatus } from '../types/PageStatus';
2
+ import Page from '../types/Page';
3
+ import './style.scss';
4
+ type Props = {
5
+ page: Page;
6
+ onUpdate: (status: PageStatus) => void;
7
+ };
8
+ export default function PageStatusComponent({ page, onUpdate }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { PageStatusNames } from '../types/PageStatus';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { Tag } from 'tycho-storybook';
5
+ import './style.scss';
6
+ const SELECTABLE_STATUSES = [
7
+ 'TRANSCRIPTION',
8
+ 'EDITION',
9
+ 'REVIEW',
10
+ 'COMPLETED',
11
+ ];
12
+ export default function PageStatusComponent({ page, onUpdate }) {
13
+ const { t } = useTranslation('page');
14
+ const currentStatus = page.status ?? 'EDITION';
15
+ const colors = {
16
+ blue: 'blue',
17
+ green: 'green',
18
+ yellow: 'yellow',
19
+ violet: 'violet',
20
+ gray: 'gray',
21
+ };
22
+ const colorByStatus = {
23
+ TRANSCRIPTION: colors.blue,
24
+ EDITION: colors.violet,
25
+ REVIEW: colors.yellow,
26
+ COMPLETED: colors.green,
27
+ };
28
+ const statusColor = colorByStatus[currentStatus];
29
+ return (_jsx(Tag, { color: statusColor, size: "medium", text: t(PageStatusNames[currentStatus]), className: "page-status-tag" }));
30
+ }
@@ -0,0 +1,2 @@
1
+ import PageStatusComponent from './PageStatusComponent';
2
+ export default PageStatusComponent;
@@ -0,0 +1,2 @@
1
+ import PageStatusComponent from './PageStatusComponent';
2
+ export default PageStatusComponent;
@@ -0,0 +1,19 @@
1
+ .page-status-tag {
2
+ cursor: pointer;
3
+ }
4
+
5
+ .popover-status {
6
+ .popover-body {
7
+ padding: 8px;
8
+
9
+ .options {
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: 8px;
13
+
14
+ > .ds-button {
15
+ width: 100%;
16
+ }
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ import BoundingBox from '../types/BoundingBox';
2
+ import './style.scss';
3
+ type Props = {
4
+ box: BoundingBox;
5
+ onClose: () => void;
6
+ onRemove: () => void;
7
+ };
8
+ export default function BoxRemoval({ box, onClose, onRemove }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import BoundingBoxService from '../services/BoundingBoxService';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { AppModalConfirm } from '../deps';
5
+ import './style.scss';
6
+ export default function BoxRemoval({ box, onClose, onRemove }) {
7
+ const { t } = useTranslation('page');
8
+ const handleRemovePage = () => {
9
+ BoundingBoxService.remove(box).then(() => {
10
+ onRemove();
11
+ });
12
+ };
13
+ return (_jsx(AppModalConfirm, { title: t('modal.title.page.remove'), subtitle: t('modal.description.page.remove'), onClose: onClose, onConfirm: handleRemovePage }));
14
+ }
@@ -0,0 +1,9 @@
1
+ import { Document } from '../deps';
2
+ import './style.scss';
3
+ type Props = {
4
+ document: Document;
5
+ setDocument: React.Dispatch<React.SetStateAction<Document | undefined>>;
6
+ setOpenFile: (b: boolean) => void;
7
+ };
8
+ export default function Boxes({ document, setDocument, setOpenFile }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import BoundingBoxService from '../services/BoundingBoxService';
3
+ import { useEffect, useState } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { AppCard, AppPagination, AppPicture, ToolsUtils, useCorpusUtils, useMessageUtils } from '../deps';
6
+ import { Button, IconButton } from 'tycho-storybook';
7
+ import BoxRemoval from './BoxRemoval';
8
+ import './style.scss';
9
+ export default function Boxes({ document, setDocument, setOpenFile }) {
10
+ const { t } = useTranslation('page');
11
+ const { dispatchMessage, dispatchLoading, isLoading } = useMessageUtils();
12
+ const { getCorpus, hasCorpus, hasParameter } = useCorpusUtils();
13
+ const [pages, setPages] = useState();
14
+ const [removeBox, setRemoveBox] = useState(null);
15
+ const [pagination, setPagination] = useState({
16
+ pageIndex: 0,
17
+ pageSize: 10,
18
+ });
19
+ const open = (thisBox) => {
20
+ setOpenFile(false);
21
+ hasCorpus();
22
+ ToolsUtils.redirectPage({
23
+ corpus: getCorpus(),
24
+ tool: document.defaultTool,
25
+ uid: thisBox.uid,
26
+ hasParameter,
27
+ });
28
+ };
29
+ const handleAddPage = () => {
30
+ if (isLoading() || !hasCorpus())
31
+ return;
32
+ dispatchLoading(true);
33
+ BoundingBoxService.create(document.uid, getCorpus()).then(() => {
34
+ loadData();
35
+ });
36
+ };
37
+ const loadData = () => {
38
+ BoundingBoxService.page(document, pagination.pageIndex, pagination.pageSize).then((r) => {
39
+ setPages(r.data);
40
+ dispatchLoading(false);
41
+ });
42
+ };
43
+ const validateRemovePage = (thisBox) => {
44
+ if (pages?.totalElements === 1) {
45
+ dispatchMessage({ key: 'remove.one.page', t });
46
+ return;
47
+ }
48
+ setRemoveBox(thisBox);
49
+ };
50
+ useEffect(() => {
51
+ loadData();
52
+ }, [pagination]);
53
+ return (_jsxs("div", { className: "pages-container", children: [_jsxs("div", { className: "header", children: [_jsx("div", { className: "title", children: t('pages.label.title') }), _jsx(Button, { size: "small", onClick: handleAddPage, text: t('pages.tooltip.add'), icon: "add", mode: "outlined" })] }), _jsx("div", { className: "body", children: pages &&
54
+ pages.content &&
55
+ pages.content.map((thisBox, idx) => (_jsx(AppCard, { onClick: () => open(thisBox), footer: _jsxs(_Fragment, { children: [_jsxs("span", { children: [t('pages.label.card'), " ", thisBox.order] }), _jsx(IconButton, { onClick: (e) => {
56
+ validateRemovePage(thisBox);
57
+ e.stopPropagation();
58
+ }, title: t('pages.tooltip.remove'), name: "delete", mode: "ghost", size: "small" })] }), children: _jsx(AppPicture, { src: thisBox.image?.url || '' }) }, idx.valueOf()))) }), _jsx("div", { className: "footer", children: pages && (_jsx(AppPagination, { totalElements: pages.totalElements, pagination: pagination, setPagination: setPagination, hideItensPage: true })) }), removeBox !== null && (_jsx(BoxRemoval, { box: removeBox, onClose: () => setRemoveBox(null), onRemove: () => {
59
+ setRemoveBox(null);
60
+ setDocument((prevState) => prevState && { ...prevState, pages: (prevState.pages || 1) - 1 });
61
+ loadData();
62
+ } }))] }));
63
+ }
@@ -0,0 +1,9 @@
1
+ import Page from '../types/Page';
2
+ import './style.scss';
3
+ type Props = {
4
+ page: Page;
5
+ onClose: () => void;
6
+ onRemove: () => void;
7
+ };
8
+ export default function PageRemoval({ page, onClose, onRemove }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import PageService from '../services/PageService';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { AppModalConfirm } from '../deps';
5
+ import './style.scss';
6
+ export default function PageRemoval({ page, onClose, onRemove }) {
7
+ const { t } = useTranslation('page');
8
+ const handleRemovePage = () => {
9
+ PageService.remove(page).then(() => {
10
+ onRemove();
11
+ onClose();
12
+ });
13
+ };
14
+ return (_jsx(AppModalConfirm, { title: t('modal.title.page.remove'), subtitle: t('modal.description.page.remove'), onClose: onClose, onConfirm: handleRemovePage }));
15
+ }
@@ -0,0 +1,10 @@
1
+ import { Document } from '../deps';
2
+ import './style.scss';
3
+ type Props = {
4
+ document: Document;
5
+ setDocument: React.Dispatch<React.SetStateAction<Document | undefined>>;
6
+ handleChange: (document: Document) => void;
7
+ setOpenFile: (b: boolean) => void;
8
+ };
9
+ export default function Pages({ document, setDocument, setOpenFile, handleChange, }: Props): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import pageService from '../services/PageService';
3
+ import { useEffect, useState } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { AppCard, AppPagination, AppPicture, ToolsUtils, useCorpusUtils, useMessageUtils, } from '../deps';
6
+ import { Button, IconButton } from 'tycho-storybook';
7
+ import PageRemoval from './PageRemoval';
8
+ import './style.scss';
9
+ import PageStatusComponent from '../PageStatusComponent';
10
+ export default function Pages({ document, setDocument, setOpenFile, handleChange, }) {
11
+ const { t } = useTranslation('page');
12
+ const { dispatchLoading, dispatchMessage } = useMessageUtils();
13
+ const { getCorpus, hasCorpus, hasParameter } = useCorpusUtils();
14
+ const [pages, setPages] = useState();
15
+ const [removePage, setRemovePage] = useState(null);
16
+ const [pagination, setPagination] = useState({
17
+ pageIndex: 0,
18
+ pageSize: 10,
19
+ });
20
+ const open = (thisPage) => {
21
+ setOpenFile(false);
22
+ hasCorpus();
23
+ ToolsUtils.redirectPage({
24
+ corpus: getCorpus(),
25
+ tool: document.defaultTool,
26
+ uid: thisPage.uid,
27
+ hasParameter,
28
+ sameWindow: true,
29
+ });
30
+ };
31
+ const handleAddPage = () => {
32
+ dispatchLoading(true);
33
+ pageService.create(document.uid).then((response) => {
34
+ loadData();
35
+ });
36
+ };
37
+ const loadData = () => {
38
+ pageService
39
+ .page(document, pagination.pageIndex, pagination.pageSize)
40
+ .then((r) => {
41
+ setPages(r.data);
42
+ setDocument((prevState) => prevState && {
43
+ ...prevState,
44
+ pages: r.data.content.length,
45
+ page: removePage === null ? prevState.page : r.data.content[0].uid,
46
+ });
47
+ removePage &&
48
+ handleChange({
49
+ ...document,
50
+ page: r.data.content[0].uid,
51
+ });
52
+ setRemovePage(null);
53
+ dispatchLoading(false);
54
+ });
55
+ };
56
+ const validateRemovePage = (thisPage) => {
57
+ if (pages?.totalElements === 1) {
58
+ dispatchMessage({ key: 'remove.one.page', t });
59
+ return;
60
+ }
61
+ setRemovePage(thisPage);
62
+ };
63
+ useEffect(() => {
64
+ loadData();
65
+ }, [pagination]);
66
+ return (_jsxs("div", { className: "pages-container", children: [_jsxs("div", { className: "header", children: [_jsx("div", { className: "title", children: t('pages.label.title') }), _jsx(Button, { size: "small", onClick: handleAddPage, text: t('pages.tooltip.add'), icon: "add", mode: "outlined" })] }), _jsx("div", { className: "body", children: pages &&
67
+ pages.content &&
68
+ pages.content.map((thisPage, idx) => (_jsxs(AppCard, { onClick: () => open(thisPage), footer: _jsxs(_Fragment, { children: [_jsxs("span", { children: [t('pages.label.card'), " ", thisPage.order] }), _jsx(IconButton, { onClick: (e) => {
69
+ validateRemovePage(thisPage);
70
+ e.stopPropagation();
71
+ }, title: t('pages.tooltip.remove'), name: "delete", mode: "ghost", size: "small" })] }), children: [_jsx(PageStatusComponent, { page: thisPage, onUpdate: (status) => console.log(status) }), _jsx(AppPicture, { src: thisPage.image?.url || '' })] }, idx.valueOf()))) }), _jsx("div", { className: "footer", children: pages && (_jsx(AppPagination, { totalElements: pages.totalElements, pagination: pagination, setPagination: setPagination, hideItensPage: true })) }), removePage !== null && (_jsx(PageRemoval, { page: removePage, onClose: () => setRemovePage(null), onRemove: loadData }))] }));
72
+ }