@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.501d471
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.
- package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
- package/dist/components/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
- package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +5 -10
- package/dist/components/ErrorBoundary.d.ts +4 -2
- package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
- package/dist/components/LanguageToggle.d.ts +1 -0
- package/dist/components/UnsavedChangesDialog.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +2 -1
- package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -1
- package/dist/components/VirtualTable/types.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/core/DrawerNavigationGroup.d.ts +2 -2
- package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
- package/dist/editor/components/editor-bubble-item.d.ts +8 -0
- package/dist/editor/components/editor-bubble.d.ts +8 -0
- package/dist/editor/components/image-bubble.d.ts +5 -0
- package/dist/editor/components/index.d.ts +16 -0
- package/dist/editor/components/table-bubble.d.ts +5 -0
- package/dist/editor/editor.d.ts +30 -0
- package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
- package/dist/editor/extensions/Image/index.d.ts +6 -0
- package/dist/editor/extensions/Image.d.ts +6 -0
- package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
- package/dist/editor/extensions/clipboard.d.ts +7 -0
- package/dist/editor/extensions/custom-keymap.d.ts +1 -0
- package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
- package/dist/editor/hooks/useProseMirror.d.ts +13 -0
- package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
- package/dist/editor/index.d.ts +2 -0
- package/dist/editor/markdown.d.ts +5 -0
- package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
- package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
- package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
- package/dist/editor/nodeViews/index.d.ts +6 -0
- package/dist/editor/plugins/index.d.ts +2 -0
- package/dist/editor/plugins/inputrules.d.ts +6 -0
- package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
- package/dist/editor/plugins/slashCommandPlugin.d.ts +12 -0
- package/dist/editor/schema.d.ts +2 -0
- package/dist/editor/selectors/ai-selector.d.ts +0 -0
- package/dist/editor/selectors/color-selector.d.ts +10 -0
- package/dist/editor/selectors/link-selector.d.ts +8 -0
- package/dist/editor/selectors/node-selector.d.ts +15 -0
- package/dist/editor/selectors/text-buttons.d.ts +1 -0
- package/dist/editor/types.d.ts +5 -0
- package/dist/editor/useProseMirror.d.ts +16 -0
- package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
- package/dist/editor/utils/remove_classes.d.ts +1 -0
- package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildNavigationController.d.ts +0 -1
- package/dist/hooks/useCollapsedGroups.d.ts +3 -3
- package/dist/hooks/useTranslation.d.ts +17 -0
- package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.es.js +29682 -18363
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +29681 -18382
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useRestoreScroll.d.ts +1 -1
- package/dist/locales/de.d.ts +2 -0
- package/dist/locales/en.d.ts +10 -0
- package/dist/locales/es.d.ts +10 -0
- package/dist/locales/fr.d.ts +2 -0
- package/dist/locales/hi.d.ts +2 -0
- package/dist/locales/it.d.ts +2 -0
- package/dist/locales/pt.d.ts +7 -0
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/collections.d.ts +46 -0
- package/dist/types/customization_controller.d.ts +2 -1
- package/dist/types/firecms.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/navigation.d.ts +2 -2
- package/dist/types/plugins.d.ts +23 -0
- package/dist/types/properties.d.ts +9 -8
- package/dist/types/storage.d.ts +1 -0
- package/dist/types/translations.d.ts +669 -0
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/index.d.ts +1 -0
- package/dist/util/lazy_eager.d.ts +7 -0
- package/dist/util/objects.d.ts +1 -0
- package/dist/util/resolutions.d.ts +2 -2
- package/dist/util/useStorageUploadController.d.ts +10 -1
- package/package.json +49 -13
- package/src/app/Scaffold.tsx +7 -5
- package/src/components/AIIcon.tsx +3 -1
- package/src/components/ArrayContainer.tsx +6 -4
- package/src/components/ClearFilterSortButton.tsx +6 -3
- package/src/components/ConfirmationDialog.tsx +4 -2
- package/src/components/DeleteEntityDialog.tsx +10 -7
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +9 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
- package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
- package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
- package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +39 -46
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +71 -31
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
- package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +37 -37
- package/src/components/EntityJsonPreview.tsx +2 -1
- package/src/components/EntityView.tsx +3 -2
- package/src/components/ErrorBoundary.tsx +27 -15
- package/src/components/HomePage/DefaultHomePage.tsx +19 -13
- package/src/components/HomePage/HomePageDnD.tsx +3 -1
- package/src/components/HomePage/NavigationGroup.tsx +3 -1
- package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
- package/src/components/LanguageToggle.tsx +66 -0
- package/src/components/NotFoundPage.tsx +5 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
- package/src/components/ReferenceWidget.tsx +3 -2
- package/src/components/SearchIconsView.tsx +3 -1
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
- package/src/components/UnsavedChangesDialog.tsx +6 -4
- package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
- package/src/components/VirtualTable/VirtualTable.tsx +121 -116
- package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -56
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +9 -4
- package/src/components/VirtualTable/VirtualTableProps.tsx +7 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
- package/src/components/VirtualTable/types.tsx +1 -0
- package/src/components/common/default_entity_actions.tsx +4 -0
- package/src/components/common/useDataSourceTableController.tsx +12 -4
- package/src/components/index.tsx +1 -0
- package/src/core/DefaultAppBar.tsx +15 -11
- package/src/core/DefaultDrawer.tsx +8 -2
- package/src/core/DrawerNavigationGroup.tsx +5 -3
- package/src/core/EntityEditView.tsx +54 -8
- package/src/core/EntityEditViewFormActions.tsx +24 -17
- package/src/core/EntitySidePanel.tsx +34 -30
- package/src/core/FireCMS.tsx +33 -6
- package/src/core/field_configs.tsx +18 -11
- package/src/editor/components/SlashCommandMenu.tsx +516 -0
- package/src/editor/components/editor-bubble-item.tsx +32 -0
- package/src/editor/components/editor-bubble.tsx +118 -0
- package/src/editor/components/image-bubble.tsx +156 -0
- package/src/editor/components/index.ts +14 -0
- package/src/editor/components/table-bubble.tsx +165 -0
- package/src/editor/editor.tsx +455 -0
- package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
- package/src/editor/extensions/Image/index.ts +133 -0
- package/src/editor/extensions/Image.ts +159 -0
- package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
- package/src/editor/extensions/clipboard.ts +72 -0
- package/src/editor/extensions/custom-keymap.ts +24 -0
- package/src/editor/extensions/drag-and-drop.tsx +480 -0
- package/src/editor/hooks/useProseMirror.ts +124 -0
- package/src/editor/hooks/useProseMirrorContext.ts +15 -0
- package/src/editor/index.ts +2 -0
- package/src/editor/markdown.ts +172 -0
- package/src/editor/nodeViews/ImageComponent.tsx +20 -0
- package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
- package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
- package/src/editor/nodeViews/index.ts +35 -0
- package/src/editor/plugins/index.ts +58 -0
- package/src/editor/plugins/inputrules.ts +82 -0
- package/src/editor/plugins/placeholderPlugin.ts +55 -0
- package/src/editor/plugins/slashCommandPlugin.ts +61 -0
- package/src/editor/schema.ts +240 -0
- package/src/editor/selectors/ai-selector.tsx +111 -0
- package/src/editor/selectors/color-selector.tsx +200 -0
- package/src/editor/selectors/link-selector.tsx +118 -0
- package/src/editor/selectors/node-selector.tsx +157 -0
- package/src/editor/selectors/text-buttons.tsx +86 -0
- package/src/editor/types.ts +6 -0
- package/src/editor/useProseMirror.ts +126 -0
- package/src/editor/utils/prosemirror-utils.ts +108 -0
- package/src/editor/utils/remove_classes.ts +17 -0
- package/src/editor/utils/useDebouncedCallback.ts +25 -0
- package/src/form/EntityForm.tsx +149 -67
- package/src/form/EntityFormActions.tsx +19 -12
- package/src/form/PropertyFieldBinding.tsx +10 -8
- package/src/form/components/ErrorFocus.tsx +3 -3
- package/src/form/components/LocalChangesMenu.tsx +13 -13
- package/src/form/components/StorageItemPreview.tsx +3 -2
- package/src/form/components/StorageUploadProgress.tsx +18 -3
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +18 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +22 -9
- package/src/form/field_bindings/BlockFieldBinding.tsx +26 -9
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +46 -24
- package/src/form/field_bindings/MapFieldBinding.tsx +27 -11
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +74 -37
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +15 -1
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +25 -11
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +25 -11
- package/src/form/field_bindings/RepeatFieldBinding.tsx +21 -6
- package/src/form/field_bindings/SelectFieldBinding.tsx +7 -5
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +110 -92
- package/src/form/field_bindings/SwitchFieldBinding.tsx +31 -14
- package/src/form/field_bindings/TextFieldBinding.tsx +10 -7
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +7 -5
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildNavigationController.tsx +49 -22
- package/src/hooks/useCollapsedGroups.ts +7 -6
- package/src/hooks/useTranslation.ts +31 -0
- package/src/hooks/useValidateAuthenticator.tsx +1 -1
- package/src/i18n/FireCMSi18nProvider.tsx +160 -0
- package/src/index.ts +5 -0
- package/src/internal/useBuildDataSource.ts +1 -2
- package/src/internal/useBuildSideEntityController.tsx +22 -20
- package/src/locales/de.ts +718 -0
- package/src/locales/en.ts +730 -0
- package/src/locales/es.ts +730 -0
- package/src/locales/fr.ts +718 -0
- package/src/locales/hi.ts +718 -0
- package/src/locales/it.ts +718 -0
- package/src/locales/pt.ts +727 -0
- package/src/preview/PropertyPreview.tsx +4 -2
- package/src/preview/components/ReferencePreview.tsx +2 -1
- package/src/preview/components/UrlComponentPreview.tsx +4 -2
- package/src/preview/components/UserPreview.tsx +3 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +49 -27
- package/src/routes/FireCMSRoute.tsx +63 -54
- package/src/types/analytics.ts +10 -0
- package/src/types/collections.ts +49 -0
- package/src/types/customization_controller.tsx +2 -1
- package/src/types/firecms.tsx +2 -1
- package/src/types/index.ts +1 -0
- package/src/types/navigation.ts +2 -2
- package/src/types/plugins.tsx +26 -0
- package/src/types/properties.ts +12 -10
- package/src/types/storage.ts +2 -1
- package/src/types/translations.ts +752 -0
- package/src/util/entities.ts +1 -1
- package/src/util/index.ts +1 -0
- package/src/util/join_collections.ts +10 -8
- package/src/util/lazy_eager.tsx +33 -0
- package/src/util/objects.ts +15 -0
- package/src/util/previews.ts +2 -2
- package/src/util/property_utils.tsx +1 -1
- package/src/util/resolutions.ts +5 -3
- package/src/util/useStorageUploadController.tsx +23 -29
|
@@ -2,6 +2,7 @@ import React, { RefObject, useCallback, useEffect, useState } from "react";
|
|
|
2
2
|
import equal from "react-fast-compare";
|
|
3
3
|
|
|
4
4
|
import { VirtualTableColumn, VirtualTableSort, VirtualTableWhereFilterOp } from "./VirtualTableProps";
|
|
5
|
+
import { useTranslation } from "../../hooks";
|
|
5
6
|
import { ErrorBoundary } from "../ErrorBoundary";
|
|
6
7
|
import {
|
|
7
8
|
ArrowUpwardIcon,
|
|
@@ -34,7 +35,7 @@ export type FilterFormFieldProps<CustomProps> = {
|
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
type VirtualTableHeaderProps<M extends Record<string, any>> = {
|
|
37
|
-
resizeHandleRef: RefObject<HTMLDivElement>;
|
|
38
|
+
resizeHandleRef: RefObject<HTMLDivElement | null>;
|
|
38
39
|
columnIndex: number;
|
|
39
40
|
isResizingIndex: number;
|
|
40
41
|
column: VirtualTableColumn<any>;
|
|
@@ -47,24 +48,26 @@ type VirtualTableHeaderProps<M extends Record<string, any>> = {
|
|
|
47
48
|
AdditionalHeaderWidget?: (props: { onHover: boolean }) => React.ReactNode;
|
|
48
49
|
isDragging?: boolean;
|
|
49
50
|
isDraggable?: boolean;
|
|
51
|
+
headerIconSize?: "small" | "smallest";
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
53
55
|
function VirtualTableHeader<M extends Record<string, any>>({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
resizeHandleRef,
|
|
57
|
+
columnIndex,
|
|
58
|
+
isResizingIndex,
|
|
59
|
+
sort,
|
|
60
|
+
onColumnSort,
|
|
61
|
+
onFilterUpdate,
|
|
62
|
+
filter,
|
|
63
|
+
column,
|
|
64
|
+
onClickResizeColumn,
|
|
65
|
+
createFilterField,
|
|
66
|
+
AdditionalHeaderWidget,
|
|
67
|
+
isDragging,
|
|
68
|
+
isDraggable,
|
|
69
|
+
headerIconSize = "small",
|
|
70
|
+
}: VirtualTableHeaderProps<M>) {
|
|
68
71
|
|
|
69
72
|
const [onHover, setOnHover] = useState(false);
|
|
70
73
|
|
|
@@ -129,24 +132,23 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
|
129
132
|
<>
|
|
130
133
|
|
|
131
134
|
{AdditionalHeaderWidget &&
|
|
132
|
-
<AdditionalHeaderWidget onHover={onHover || openFilter}/>}
|
|
135
|
+
<AdditionalHeaderWidget onHover={onHover || openFilter} />}
|
|
133
136
|
|
|
134
137
|
{column.sortable && (sort || hovered || openFilter) &&
|
|
135
138
|
<Badge color="secondary"
|
|
136
|
-
|
|
139
|
+
invisible={!sort}>
|
|
137
140
|
<IconButton
|
|
138
|
-
size={
|
|
141
|
+
size={headerIconSize}
|
|
139
142
|
className={onHover || openFilter ? "bg-white dark:bg-surface-950" : undefined}
|
|
140
143
|
onClick={() => {
|
|
141
144
|
onColumnSort(column.key as Extract<keyof M, string>);
|
|
142
145
|
}}
|
|
143
146
|
>
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
<ArrowUpwardIcon className={"rotate-180"}/>}
|
|
147
|
+
<ArrowUpwardIcon size={headerIconSize}
|
|
148
|
+
className={cls(
|
|
149
|
+
"transition-transform duration-200",
|
|
150
|
+
sort === "desc" ? "rotate-180" : "rotate-0"
|
|
151
|
+
)} />
|
|
150
152
|
</IconButton>
|
|
151
153
|
</Badge>
|
|
152
154
|
}
|
|
@@ -154,7 +156,7 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
|
154
156
|
|
|
155
157
|
{column.filter && createFilterField && <div>
|
|
156
158
|
<Badge color="secondary"
|
|
157
|
-
|
|
159
|
+
invisible={!filter}>
|
|
158
160
|
|
|
159
161
|
<Popover
|
|
160
162
|
open={openFilter}
|
|
@@ -166,16 +168,16 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
|
166
168
|
className={onHover || openFilter ? "bg-white dark:bg-surface-950" : undefined}
|
|
167
169
|
size={"small"}
|
|
168
170
|
onClick={handleSettingsClick}>
|
|
169
|
-
<FilterListIcon size={"small"}/>
|
|
171
|
+
<FilterListIcon size={"small"} />
|
|
170
172
|
</IconButton>}
|
|
171
173
|
>
|
|
172
174
|
<FilterForm column={column}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
filter={filter}
|
|
176
|
+
onHover={onHover}
|
|
177
|
+
onFilterUpdate={update}
|
|
178
|
+
createFilterField={createFilterField}
|
|
179
|
+
hidden={hidden}
|
|
180
|
+
setHidden={setHidden} />
|
|
179
181
|
|
|
180
182
|
</Popover>
|
|
181
183
|
|
|
@@ -204,14 +206,16 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
|
204
206
|
}, equal) as React.FunctionComponent<VirtualTableHeaderProps<any>>;
|
|
205
207
|
|
|
206
208
|
function FilterForm<M>({
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
209
|
+
column,
|
|
210
|
+
onFilterUpdate,
|
|
211
|
+
filter,
|
|
212
|
+
onHover,
|
|
213
|
+
createFilterField,
|
|
214
|
+
hidden,
|
|
215
|
+
setHidden
|
|
216
|
+
}: FilterFormProps<M>) {
|
|
217
|
+
|
|
218
|
+
const { t } = useTranslation();
|
|
215
219
|
|
|
216
220
|
const id = column.key;
|
|
217
221
|
|
|
@@ -245,12 +249,12 @@ function FilterForm<M>({
|
|
|
245
249
|
if (!filterField) return null;
|
|
246
250
|
return (
|
|
247
251
|
<form noValidate={true}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
onSubmit={(e) => {
|
|
253
|
+
e.stopPropagation();
|
|
254
|
+
e.preventDefault();
|
|
255
|
+
submit();
|
|
256
|
+
}}
|
|
257
|
+
className={"text-surface-900 dark:text-white"}>
|
|
254
258
|
<div
|
|
255
259
|
className={cls(defaultBorderMixin, "py-4 px-6 typography-label border-b")}>
|
|
256
260
|
{column.title ?? id}
|
|
@@ -258,16 +262,15 @@ function FilterForm<M>({
|
|
|
258
262
|
{filterField && <div className="m-4 w-[400px]">
|
|
259
263
|
{filterField}
|
|
260
264
|
</div>}
|
|
261
|
-
<div className="flex justify-end
|
|
262
|
-
<Button
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
type="submit">Filter</Button>
|
|
265
|
+
<div className="flex justify-end p-4 pt-0 gap-2">
|
|
266
|
+
<Button variant={"text"}
|
|
267
|
+
size={"small"}
|
|
268
|
+
aria-label="filter clear"
|
|
269
|
+
onClick={reset}>{t("clear")}</Button>
|
|
270
|
+
|
|
271
|
+
<Button variant={"outlined"}
|
|
272
|
+
size={"small"}
|
|
273
|
+
type="submit">{t("filter")}</Button>
|
|
271
274
|
</div>
|
|
272
275
|
</form>
|
|
273
276
|
);
|
|
@@ -22,11 +22,12 @@ const SortableColumnHeader = ({
|
|
|
22
22
|
onClickResizeColumn,
|
|
23
23
|
createFilterField,
|
|
24
24
|
isDragging,
|
|
25
|
-
isDraggable
|
|
25
|
+
isDraggable,
|
|
26
|
+
headerIconSize
|
|
26
27
|
}: {
|
|
27
28
|
column: VirtualTableColumn;
|
|
28
29
|
columnIndex: number;
|
|
29
|
-
columnRefs: React.RefObject<HTMLDivElement>[];
|
|
30
|
+
columnRefs: React.RefObject<HTMLDivElement | null>[];
|
|
30
31
|
isResizing: number;
|
|
31
32
|
onFilterUpdate: any;
|
|
32
33
|
filter: [VirtualTableWhereFilterOp, any] | undefined;
|
|
@@ -37,6 +38,7 @@ const SortableColumnHeader = ({
|
|
|
37
38
|
createFilterField: any;
|
|
38
39
|
isDragging: boolean;
|
|
39
40
|
isDraggable: boolean;
|
|
41
|
+
headerIconSize?: "small" | "smallest";
|
|
40
42
|
}) => {
|
|
41
43
|
const [isPressing, setIsPressing] = useState(false);
|
|
42
44
|
|
|
@@ -103,7 +105,8 @@ const SortableColumnHeader = ({
|
|
|
103
105
|
createFilterField={createFilterField}
|
|
104
106
|
AdditionalHeaderWidget={column.AdditionalHeaderWidget}
|
|
105
107
|
isDragging={isDragging || isPressing}
|
|
106
|
-
isDraggable={isDraggable}
|
|
108
|
+
isDraggable={isDraggable}
|
|
109
|
+
headerIconSize={headerIconSize} />
|
|
107
110
|
</div>
|
|
108
111
|
);
|
|
109
112
|
};
|
|
@@ -123,7 +126,8 @@ export const VirtualTableHeaderRow = ({
|
|
|
123
126
|
data,
|
|
124
127
|
cellRenderer: CellRenderer,
|
|
125
128
|
rowHeight = 54,
|
|
126
|
-
draggingColumnId
|
|
129
|
+
draggingColumnId,
|
|
130
|
+
headerIconSize,
|
|
127
131
|
}: VirtualTableContextProps<any>) => {
|
|
128
132
|
|
|
129
133
|
const columnRefs = useMemo(() => columns.map(() => createRef<HTMLDivElement>()), [columns.length]);
|
|
@@ -234,6 +238,7 @@ export const VirtualTableHeaderRow = ({
|
|
|
234
238
|
createFilterField={createFilterField}
|
|
235
239
|
isDragging={isDragging}
|
|
236
240
|
isDraggable={isDraggable}
|
|
241
|
+
headerIconSize={headerIconSize}
|
|
237
242
|
/>
|
|
238
243
|
</ErrorBoundary>
|
|
239
244
|
);
|
|
@@ -168,6 +168,12 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
168
168
|
*/
|
|
169
169
|
onColumnsOrderChange?: (columns: VirtualTableColumn[]) => void;
|
|
170
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Size of icons in column headers (sort, filter).
|
|
173
|
+
* @default "small"
|
|
174
|
+
*/
|
|
175
|
+
headerIconSize?: "small" | "smallest";
|
|
176
|
+
|
|
171
177
|
}
|
|
172
178
|
|
|
173
179
|
export type CellRendererParams<T = any> = {
|
|
@@ -206,7 +212,7 @@ export interface VirtualTableColumn<CustomProps = any> {
|
|
|
206
212
|
/**
|
|
207
213
|
* Label displayed in the header
|
|
208
214
|
*/
|
|
209
|
-
title?:
|
|
215
|
+
title?: React.ReactNode;
|
|
210
216
|
|
|
211
217
|
/**
|
|
212
218
|
* This column is frozen to the left
|
|
@@ -79,7 +79,7 @@ export function VirtualTableSelect(props: {
|
|
|
79
79
|
multiple
|
|
80
80
|
? <MultiSelect
|
|
81
81
|
inputRef={ref}
|
|
82
|
-
className="w-full h-full p-0 bg-transparent"
|
|
82
|
+
className="w-full h-full p-0 bg-transparent outline-none"
|
|
83
83
|
position={"item-aligned"}
|
|
84
84
|
disabled={disabled}
|
|
85
85
|
includeClear={false}
|
|
@@ -104,8 +104,8 @@ export function VirtualTableSelect(props: {
|
|
|
104
104
|
inputRef={ref}
|
|
105
105
|
size={"large"}
|
|
106
106
|
fullWidth={true}
|
|
107
|
-
className="w-full h-full p-0 bg-transparent"
|
|
108
|
-
inputClassName="focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none"
|
|
107
|
+
className="w-full h-full p-0 bg-transparent outline-none [&_button]:ring-0 [&_button]:ring-offset-0"
|
|
108
|
+
inputClassName="ring-0 ring-offset-0 focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-offset-0"
|
|
109
109
|
position={"item-aligned"}
|
|
110
110
|
disabled={disabled}
|
|
111
111
|
padding={false}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// Note: entity action 'name' fields (Edit, Copy, Delete) are plain strings defined
|
|
2
|
+
// at module level. They cannot use hooks. Consumers who need to translate these
|
|
3
|
+
// should override the action name by creating their own EntityAction objects or
|
|
4
|
+
// by using the entityActions prop with custom names for their locale.
|
|
1
5
|
import { DeleteIcon, EditIcon, FileCopyIcon } from "@firecms/ui";
|
|
2
6
|
import { EntityAction } from "../../types";
|
|
3
7
|
import { DeleteEntityDialog } from "../DeleteEntityDialog";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { useLocation } from "react-router-dom";
|
|
2
3
|
|
|
3
4
|
import { useDataSource, useFireCMSContext, useNavigationController } from "../../hooks";
|
|
4
5
|
import { useDataOrder } from "../../hooks/data/useDataOrder";
|
|
@@ -94,7 +95,7 @@ export function useDataSourceTableController<M extends Record<string, any> = any
|
|
|
94
95
|
const [searchString, setSearchString] = React.useState<string | undefined>();
|
|
95
96
|
|
|
96
97
|
const checkFilterCombination = useCallback((filterValues: FilterValues<any>,
|
|
97
|
-
|
|
98
|
+
sortBy?: [string, "asc" | "desc"]) => {
|
|
98
99
|
if (!dataSource.isFilterCombinationValid)
|
|
99
100
|
return true;
|
|
100
101
|
return dataSource.isFilterCombinationValid({
|
|
@@ -106,8 +107,8 @@ export function useDataSourceTableController<M extends Record<string, any> = any
|
|
|
106
107
|
}, []);
|
|
107
108
|
|
|
108
109
|
const onScroll = ({
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
scrollOffset
|
|
111
|
+
}: {
|
|
111
112
|
scrollOffset: number
|
|
112
113
|
}) => {
|
|
113
114
|
if (scrollRestoration) {
|
|
@@ -128,10 +129,12 @@ export function useDataSourceTableController<M extends Record<string, any> = any
|
|
|
128
129
|
return initialSort;
|
|
129
130
|
}, [initialSort, forceFilter]);
|
|
130
131
|
|
|
132
|
+
const location = useLocation();
|
|
133
|
+
|
|
131
134
|
const {
|
|
132
135
|
filterValues: initialFilterUrl,
|
|
133
136
|
sortBy: initialSortUrl,
|
|
134
|
-
} = parseFilterAndSort(
|
|
137
|
+
} = parseFilterAndSort(location.search);
|
|
135
138
|
|
|
136
139
|
const [filterValues, setFilterValues] = React.useState<FilterValues<Extract<keyof M, string>> | undefined>(forceFilter ?? (updateUrl ? initialFilterUrl : undefined) ?? initialFilter ?? undefined);
|
|
137
140
|
const [sortBy, setSortBy] = React.useState<[Extract<keyof M, string>, "asc" | "desc"] | undefined>((updateUrl ? initialSortUrl : undefined) ?? initialSortInternal);
|
|
@@ -328,6 +331,11 @@ function encodeFilterAndSort(filterValues?: FilterValues<string>, sortBy?: [stri
|
|
|
328
331
|
} else if (val instanceof EntityReference) {
|
|
329
332
|
encodedValue = encodeRef(val);
|
|
330
333
|
}
|
|
334
|
+
} else if (typeof val === "string") {
|
|
335
|
+
// JSON.stringify wraps the string in quotes (e.g. "4" → '"4"')
|
|
336
|
+
// so that decodeString's JSON.parse restores the string type,
|
|
337
|
+
// not a number. Without this, "4" round-trips as the number 4.
|
|
338
|
+
encodedValue = JSON.stringify(val);
|
|
331
339
|
}
|
|
332
340
|
} catch (e) {
|
|
333
341
|
encodedValue = val;
|
package/src/components/index.tsx
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
3
|
import { Link, useNavigate } from "react-router-dom";
|
|
4
|
-
import { ErrorBoundary, FireCMSLogo } from "../components";
|
|
4
|
+
import { ErrorBoundary, FireCMSLogo, LanguageToggle } from "../components";
|
|
5
5
|
import {
|
|
6
6
|
Avatar,
|
|
7
7
|
BrightnessMediumIcon,
|
|
8
|
+
CheckIcon,
|
|
8
9
|
cls,
|
|
9
10
|
DarkModeIcon,
|
|
10
11
|
IconButton,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
Skeleton,
|
|
16
17
|
Typography
|
|
17
18
|
} from "@firecms/ui";
|
|
18
|
-
import { useAuthController, useLargeLayout, useModeController, useNavigationController } from "../hooks";
|
|
19
|
+
import { useAuthController, useLargeLayout, useModeController, useNavigationController, useTranslation } from "../hooks";
|
|
19
20
|
import { User } from "../types";
|
|
20
21
|
import { useApp } from "../app/useApp";
|
|
21
22
|
import { useBreadcrumbsController } from "../hooks/useBreadcrumbsController";
|
|
@@ -85,6 +86,8 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
85
86
|
mode,
|
|
86
87
|
setMode
|
|
87
88
|
} = useModeController();
|
|
89
|
+
|
|
90
|
+
const { i18n, t } = useTranslation();
|
|
88
91
|
|
|
89
92
|
const navigate = useNavigate();
|
|
90
93
|
|
|
@@ -92,7 +95,7 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
92
95
|
|
|
93
96
|
const user = userProp ?? authController.user;
|
|
94
97
|
|
|
95
|
-
let avatarComponent:
|
|
98
|
+
let avatarComponent: React.ReactElement | null;
|
|
96
99
|
|
|
97
100
|
if (user) {
|
|
98
101
|
const initial = user?.displayName
|
|
@@ -192,18 +195,19 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
192
195
|
<Menu
|
|
193
196
|
trigger={<IconButton
|
|
194
197
|
color="inherit"
|
|
195
|
-
aria-label="Open drawer"
|
|
196
|
-
size="large">
|
|
198
|
+
aria-label="Open drawer">
|
|
197
199
|
{mode === "dark"
|
|
198
|
-
? <DarkModeIcon />
|
|
199
|
-
: <LightModeIcon />}
|
|
200
|
+
? <DarkModeIcon size="small" />
|
|
201
|
+
: <LightModeIcon size="small" />}
|
|
200
202
|
</IconButton>}>
|
|
201
|
-
<MenuItem onClick={() => setMode("dark")}><DarkModeIcon size={"smallest"} />
|
|
202
|
-
<MenuItem onClick={() => setMode("light")}><LightModeIcon size={"smallest"} />
|
|
203
|
+
<MenuItem onClick={() => setMode("dark")}><DarkModeIcon size={"smallest"} /> {t("dark_mode")}</MenuItem>
|
|
204
|
+
<MenuItem onClick={() => setMode("light")}><LightModeIcon size={"smallest"} /> {t("light_mode")}</MenuItem>
|
|
203
205
|
<MenuItem onClick={() => setMode("system")}> <BrightnessMediumIcon
|
|
204
|
-
size={"smallest"} />
|
|
206
|
+
size={"smallest"} />{t("system_mode")}</MenuItem>
|
|
205
207
|
</Menu>}
|
|
206
208
|
|
|
209
|
+
<LanguageToggle />
|
|
210
|
+
|
|
207
211
|
<Menu trigger={avatarComponent}>
|
|
208
212
|
{user && <div className={"px-4 py-2 mb-2"}>
|
|
209
213
|
{user.displayName && <Typography variant={"body1"} color={"secondary"}>
|
|
@@ -222,7 +226,7 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
222
226
|
navigate("/");
|
|
223
227
|
}}>
|
|
224
228
|
<LogoutIcon />
|
|
225
|
-
|
|
229
|
+
{t("log_out")}
|
|
226
230
|
</MenuItem>}
|
|
227
231
|
|
|
228
232
|
</Menu>
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
useCollapsedGroups,
|
|
5
|
+
useLargeLayout,
|
|
6
|
+
useNavigationController,
|
|
7
|
+
useTranslation
|
|
8
|
+
} from "../hooks";
|
|
4
9
|
|
|
5
10
|
import { Link, useNavigate } from "react-router-dom";
|
|
6
11
|
import { CMSAnalyticsEvent, NavigationEntry, NavigationResult } from "../types";
|
|
@@ -34,6 +39,7 @@ export function DefaultDrawer({
|
|
|
34
39
|
|
|
35
40
|
const analyticsController = useAnalyticsController();
|
|
36
41
|
const navigation = useNavigationController();
|
|
42
|
+
const { t } = useTranslation();
|
|
37
43
|
|
|
38
44
|
const tooltipsOpen = drawerHovered && !drawerOpen && !adminMenuOpen;
|
|
39
45
|
const largeLayout = useLargeLayout();
|
|
@@ -122,7 +128,7 @@ export function DefaultDrawer({
|
|
|
122
128
|
}}
|
|
123
129
|
key={entry.id}>
|
|
124
130
|
{<IconForView collectionOrView={entry.view} />}
|
|
125
|
-
{entry.name}
|
|
131
|
+
{t(entry.name as any)}
|
|
126
132
|
</MenuItem>)}
|
|
127
133
|
|
|
128
134
|
</Menu>}
|
|
@@ -3,12 +3,13 @@ import { cls, ExpandMoreIcon, Typography } from "@firecms/ui";
|
|
|
3
3
|
import { NavigationEntry } from "../types";
|
|
4
4
|
import { IconForView } from "../util";
|
|
5
5
|
import { DrawerNavigationItem } from "./DrawerNavigationItem";
|
|
6
|
+
import { useTranslation } from "../hooks/useTranslation";
|
|
6
7
|
|
|
7
8
|
export interface DrawerNavigationGroupProps {
|
|
8
9
|
/**
|
|
9
|
-
* Group name to display in header
|
|
10
|
+
* Group name to display in header. When null, uses the translated default group name.
|
|
10
11
|
*/
|
|
11
|
-
group: string;
|
|
12
|
+
group: string | null;
|
|
12
13
|
/**
|
|
13
14
|
* Navigation entries in this group
|
|
14
15
|
*/
|
|
@@ -58,6 +59,7 @@ export function DrawerNavigationGroup({
|
|
|
58
59
|
headerActions,
|
|
59
60
|
onItemClick
|
|
60
61
|
}: DrawerNavigationGroupProps) {
|
|
62
|
+
const { t } = useTranslation();
|
|
61
63
|
return (
|
|
62
64
|
<div
|
|
63
65
|
className={"bg-surface-50 dark:bg-surface-800/30 my-4 rounded-lg ml-3 mr-1"}
|
|
@@ -81,7 +83,7 @@ export function DrawerNavigationGroup({
|
|
|
81
83
|
color={"secondary"}
|
|
82
84
|
className="font-medium flex-grow line-clamp-1"
|
|
83
85
|
>
|
|
84
|
-
{(group
|
|
86
|
+
{(group && group !== "__default__" ? group : t("views_group")).toUpperCase()}
|
|
85
87
|
</Typography>
|
|
86
88
|
{headerActions && (
|
|
87
89
|
<div onClick={(e) => e.stopPropagation()}>
|
|
@@ -26,12 +26,13 @@ import {
|
|
|
26
26
|
useFireCMSContext,
|
|
27
27
|
useLargeLayout
|
|
28
28
|
} from "../hooks";
|
|
29
|
-
import { CircularProgress, cls, CodeIcon, defaultBorderMixin, Tab, Tabs, Typography } from "@firecms/ui";
|
|
29
|
+
import { CircularProgress, cls, CodeIcon, defaultBorderMixin, Tab, Tabs, Typography, Menu, MenuItem, ExpandMoreIcon } from "@firecms/ui";
|
|
30
30
|
import { getEntityFromMemoryCache } from "../util/entity_cache";
|
|
31
31
|
import { EntityForm, EntityFormProps } from "../form";
|
|
32
32
|
import { EntityEditViewFormActions } from "./EntityEditViewFormActions";
|
|
33
33
|
import { EntityJsonPreview } from "../components/EntityJsonPreview";
|
|
34
34
|
import { createFormexStub } from "../util/createFormexStub";
|
|
35
|
+
import { useTranslation } from "../hooks/useTranslation";
|
|
35
36
|
|
|
36
37
|
export const MAIN_TAB_VALUE = "__main_##Q$SC^#S6";
|
|
37
38
|
export const JSON_TAB_VALUE = "__json";
|
|
@@ -170,6 +171,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
170
171
|
}) {
|
|
171
172
|
|
|
172
173
|
const context = useFireCMSContext();
|
|
174
|
+
const { t } = useTranslation();
|
|
173
175
|
|
|
174
176
|
const [usedEntity, setUsedEntity] = useState<Entity<M> | undefined>(entity);
|
|
175
177
|
|
|
@@ -228,6 +230,10 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
228
230
|
const includeJsonView = collection.includeJsonView === undefined ? true : collection.includeJsonView;
|
|
229
231
|
const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0 || includeJsonView;
|
|
230
232
|
|
|
233
|
+
const groupedViews = useMemo(() => {
|
|
234
|
+
return (collection.viewGroups ?? []).flatMap(g => g.views);
|
|
235
|
+
}, [collection.viewGroups]);
|
|
236
|
+
|
|
231
237
|
const {
|
|
232
238
|
resolvedEntityViews,
|
|
233
239
|
selectedEntityView,
|
|
@@ -342,8 +348,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
342
348
|
openEntityMode={layout} />
|
|
343
349
|
: <div className="flex items-center justify-center w-full h-full p-3">
|
|
344
350
|
<Typography variant={"label"}>
|
|
345
|
-
|
|
346
|
-
adding additional collections
|
|
351
|
+
{t("youd_need_to_save_before_additional_collections")}
|
|
347
352
|
</Typography>
|
|
348
353
|
</div>)
|
|
349
354
|
}
|
|
@@ -418,16 +423,18 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
418
423
|
Builder={selectedSecondaryForm?.Builder}
|
|
419
424
|
/>;
|
|
420
425
|
|
|
421
|
-
const subcollectionTabs = subcollections && subcollections
|
|
426
|
+
const subcollectionTabs = subcollections && subcollections
|
|
427
|
+
.filter(sub => !groupedViews.includes(sub.id ?? sub.path))
|
|
428
|
+
.map((subcollection) =>
|
|
422
429
|
<Tab
|
|
423
430
|
className="text-sm min-w-[120px]"
|
|
424
|
-
value={subcollection.id}
|
|
431
|
+
value={subcollection.id ?? subcollection.path}
|
|
425
432
|
key={`entity_detail_collection_tab_${subcollection.name}`}>
|
|
426
433
|
{subcollection.name}
|
|
427
434
|
</Tab>
|
|
428
435
|
);
|
|
429
436
|
|
|
430
|
-
const customViewTabsStart = resolvedEntityViews.filter(view => view.position === "start")
|
|
437
|
+
const customViewTabsStart = resolvedEntityViews.filter(view => view.position === "start" && !groupedViews.includes(view.key))
|
|
431
438
|
.map((view) =>
|
|
432
439
|
<Tab
|
|
433
440
|
className={!view.tabComponent ? "text-sm min-w-[120px]" : undefined}
|
|
@@ -436,7 +443,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
436
443
|
{view.tabComponent ?? view.name}
|
|
437
444
|
</Tab>
|
|
438
445
|
);
|
|
439
|
-
const customViewTabsEnd = resolvedEntityViews.filter(view => !view.position || view.position === "end")
|
|
446
|
+
const customViewTabsEnd = resolvedEntityViews.filter(view => (!view.position || view.position === "end") && !groupedViews.includes(view.key))
|
|
440
447
|
.map((view) =>
|
|
441
448
|
<Tab
|
|
442
449
|
className={!view.tabComponent ? "text-sm min-w-[120px]" : undefined}
|
|
@@ -446,12 +453,49 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
446
453
|
</Tab>
|
|
447
454
|
);
|
|
448
455
|
|
|
456
|
+
const viewGroupMenus = collection.viewGroups?.map(group => {
|
|
457
|
+
const isActive = group.views.includes(selectedTab);
|
|
458
|
+
return (
|
|
459
|
+
<Menu
|
|
460
|
+
key={`view_group_${group.name}`}
|
|
461
|
+
trigger={
|
|
462
|
+
<button
|
|
463
|
+
type="button"
|
|
464
|
+
className={cls(
|
|
465
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all",
|
|
466
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400 focus-visible:ring-offset-2",
|
|
467
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
468
|
+
isActive ? "bg-white text-surface-900 dark:bg-surface-950 dark:text-surface-50" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800"
|
|
469
|
+
)}
|
|
470
|
+
>
|
|
471
|
+
{group.name}
|
|
472
|
+
<ExpandMoreIcon className="ml-1 -mr-1" size="small" />
|
|
473
|
+
</button>
|
|
474
|
+
}>
|
|
475
|
+
{group.views.map(viewId => {
|
|
476
|
+
const subcollection = subcollections.find(s => (s.id ?? s.path) === viewId);
|
|
477
|
+
const customView = resolvedEntityViews.find(v => v.key === viewId);
|
|
478
|
+
const name = subcollection?.name ?? customView?.name ?? viewId;
|
|
479
|
+
return (
|
|
480
|
+
<MenuItem
|
|
481
|
+
key={`view_group_${group.name}_${viewId}`}
|
|
482
|
+
onClick={() => onSideTabClick(viewId)}
|
|
483
|
+
className={selectedTab === viewId ? "bg-surface-accent-100 dark:bg-surface-accent-900" : ""}
|
|
484
|
+
>
|
|
485
|
+
{name}
|
|
486
|
+
</MenuItem>
|
|
487
|
+
);
|
|
488
|
+
})}
|
|
489
|
+
</Menu>
|
|
490
|
+
);
|
|
491
|
+
});
|
|
492
|
+
|
|
449
493
|
const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews;
|
|
450
494
|
|
|
451
495
|
let result = <div className="relative flex flex-col h-full w-full bg-white dark:bg-surface-900">
|
|
452
496
|
|
|
453
497
|
{shouldShowTopBar && <div
|
|
454
|
-
className={cls("h-14 items-center overflow-
|
|
498
|
+
className={cls("h-14 items-center overflow-hidden w-full border-b pl-2 pr-2 flex gap-2 bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
|
|
455
499
|
|
|
456
500
|
{barActions?.({
|
|
457
501
|
path: fullIdPath ?? path,
|
|
@@ -493,6 +537,8 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
493
537
|
|
|
494
538
|
{customViewTabsEnd}
|
|
495
539
|
|
|
540
|
+
{viewGroupMenus}
|
|
541
|
+
|
|
496
542
|
{subcollectionTabs}
|
|
497
543
|
</Tabs>}
|
|
498
544
|
</div>}
|