@firecms/core 3.1.0-canary.9e89e98 → 3.1.0-canary.a3b8228
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/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 +1 -1
- 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/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 +4 -0
- package/dist/index.es.js +13009 -2312
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +12997 -2320
- 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/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/storage.d.ts +1 -0
- package/dist/types/translations.d.ts +646 -0
- package/dist/util/entities.d.ts +1 -1
- 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/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 +54 -17
- 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 +11 -8
- 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 +116 -113
- package/src/components/VirtualTable/VirtualTableHeader.tsx +54 -52
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
- 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 +4 -3
- package/src/core/EntityEditViewFormActions.tsx +24 -17
- package/src/core/EntitySidePanel.tsx +32 -29
- package/src/core/FireCMS.tsx +33 -6
- package/src/core/field_configs.tsx +14 -9
- 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 +85 -63
- package/src/form/EntityFormActions.tsx +19 -12
- package/src/form/PropertyFieldBinding.tsx +6 -5
- 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/ArrayOfReferencesFieldBinding.tsx +4 -4
- package/src/form/field_bindings/BlockFieldBinding.tsx +5 -2
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +23 -18
- package/src/form/field_bindings/MapFieldBinding.tsx +4 -3
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +34 -20
- package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +87 -86
- 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 +4 -0
- package/src/internal/useBuildDataSource.ts +1 -2
- package/src/internal/useBuildSideEntityController.tsx +22 -20
- package/src/locales/de.ts +691 -0
- package/src/locales/en.ts +703 -0
- package/src/locales/es.ts +703 -0
- package/src/locales/fr.ts +691 -0
- package/src/locales/hi.ts +691 -0
- package/src/locales/it.ts +691 -0
- package/src/locales/pt.ts +700 -0
- package/src/preview/PropertyPreview.tsx +1 -0
- package/src/preview/components/UrlComponentPreview.tsx +4 -2
- package/src/preview/components/UserPreview.tsx +3 -1
- package/src/types/analytics.ts +10 -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 +1 -0
- package/src/types/storage.ts +2 -1
- package/src/types/translations.ts +725 -0
- package/src/util/entities.ts +1 -1
- package/src/util/join_collections.ts +10 -8
- 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
|
@@ -20,9 +20,6 @@ import {
|
|
|
20
20
|
DialogActions,
|
|
21
21
|
DialogContent,
|
|
22
22
|
getColorSchemeForSeed,
|
|
23
|
-
IconButton,
|
|
24
|
-
RefreshIcon,
|
|
25
|
-
Tooltip,
|
|
26
23
|
Typography
|
|
27
24
|
} from "@firecms/ui";
|
|
28
25
|
import { getPropertyInPath, resolveCollection, resolveEnumValues } from "../../util";
|
|
@@ -34,9 +31,12 @@ import {
|
|
|
34
31
|
useFireCMSContext,
|
|
35
32
|
useSideEntityController
|
|
36
33
|
} from "../../hooks";
|
|
34
|
+
import { useAnalyticsController } from "../../hooks/useAnalyticsController";
|
|
37
35
|
import { SaveEntityProps } from "../../types/datasource";
|
|
38
36
|
import { setIn } from "@firecms/formex";
|
|
39
37
|
import { useBoardDataController } from "./useBoardDataController";
|
|
38
|
+
import { CollectionDataErrorBanner } from "./CollectionDataErrorBanner";
|
|
39
|
+
import { useTranslation } from "../../hooks/useTranslation";
|
|
40
40
|
|
|
41
41
|
export type EntityCollectionBoardViewProps<M extends Record<string, any> = any> = {
|
|
42
42
|
collection: EntityCollection<M>;
|
|
@@ -74,7 +74,9 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
74
74
|
const context = useFireCMSContext();
|
|
75
75
|
const dataSource = useDataSource(collection);
|
|
76
76
|
const sideEntityController = useSideEntityController();
|
|
77
|
+
const analyticsController = useAnalyticsController();
|
|
77
78
|
const plugins = customizationController.plugins ?? [];
|
|
79
|
+
const { t } = useTranslation();
|
|
78
80
|
|
|
79
81
|
// State for backfill dialog
|
|
80
82
|
const [showBackfillDialog, setShowBackfillDialog] = useState(false);
|
|
@@ -222,6 +224,10 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
222
224
|
}, [plugins]);
|
|
223
225
|
|
|
224
226
|
const handleColumnReorder = useCallback((newColumns: string[]) => {
|
|
227
|
+
analyticsController.onAnalyticsEvent?.("kanban_column_reorder", {
|
|
228
|
+
path: fullPath,
|
|
229
|
+
columnProperty
|
|
230
|
+
});
|
|
225
231
|
setHasUserReordered(true);
|
|
226
232
|
setLocalColumnsOrder(newColumns);
|
|
227
233
|
plugins
|
|
@@ -235,7 +241,7 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
235
241
|
newColumnsOrder: newColumns
|
|
236
242
|
});
|
|
237
243
|
});
|
|
238
|
-
}, [plugins, fullPath, parentCollectionIds, collection, columnProperty]);
|
|
244
|
+
}, [plugins, fullPath, parentCollectionIds, collection, columnProperty, analyticsController]);
|
|
239
245
|
|
|
240
246
|
// Collection-level count queries to detect missing order property
|
|
241
247
|
// Just TWO counts: total and ordered (for the entire collection, not per column)
|
|
@@ -393,6 +399,13 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
393
399
|
const entity = items.find(item => item.id === moveInfo?.itemId)?.entity;
|
|
394
400
|
if (!entity) return;
|
|
395
401
|
|
|
402
|
+
analyticsController.onAnalyticsEvent?.("kanban_card_moved", {
|
|
403
|
+
path: fullPath,
|
|
404
|
+
entityId: entity.id,
|
|
405
|
+
sourceColumn: moveInfo?.sourceColumn,
|
|
406
|
+
targetColumn: moveInfo?.targetColumn
|
|
407
|
+
});
|
|
408
|
+
|
|
396
409
|
const isColumnChange = moveInfo && moveInfo.sourceColumn !== moveInfo.targetColumn;
|
|
397
410
|
|
|
398
411
|
// If no orderProperty and not a column change, nothing to do
|
|
@@ -440,7 +453,7 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
440
453
|
} catch (e) {
|
|
441
454
|
console.error("Error saving entity:", e);
|
|
442
455
|
}
|
|
443
|
-
}, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController]);
|
|
456
|
+
}, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController, analyticsController, fullPath]);
|
|
444
457
|
|
|
445
458
|
// Backfill order values for all entities
|
|
446
459
|
const handleBackfill = useCallback(async () => {
|
|
@@ -449,6 +462,9 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
449
462
|
console.log("No orderProperty, returning");
|
|
450
463
|
return;
|
|
451
464
|
}
|
|
465
|
+
analyticsController.onAnalyticsEvent?.("kanban_backfill_order", {
|
|
466
|
+
path: fullPath
|
|
467
|
+
});
|
|
452
468
|
setBackfillLoading(true);
|
|
453
469
|
|
|
454
470
|
try {
|
|
@@ -514,7 +530,7 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
514
530
|
} finally {
|
|
515
531
|
setBackfillLoading(false);
|
|
516
532
|
}
|
|
517
|
-
}, [orderProperty, fullPath, collection, dataSource, context, boardDataController]);
|
|
533
|
+
}, [orderProperty, fullPath, collection, dataSource, context, boardDataController, analyticsController]);
|
|
518
534
|
|
|
519
535
|
const handleEntityClick = useCallback((entity: Entity<M>) => {
|
|
520
536
|
onEntityClick?.(entity);
|
|
@@ -563,19 +579,16 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
563
579
|
|
|
564
580
|
// Check for loading error
|
|
565
581
|
const hasError = Boolean(dataLoadingError);
|
|
566
|
-
const errorMessage = dataLoadingError?.message || "";
|
|
567
|
-
const indexUrl = errorMessage.match(/https:\/\/console\.firebase\.google\.com[^\s]+/)?.[0];
|
|
568
582
|
|
|
569
583
|
// Error: no enum properties available for Kanban columns
|
|
570
584
|
if (!columnProperty || enumColumns.length === 0) {
|
|
571
585
|
return (
|
|
572
586
|
<div className="flex-1 flex flex-col items-center justify-center p-8 gap-4">
|
|
573
587
|
<Typography variant="h6">
|
|
574
|
-
|
|
588
|
+
{t("kanban_view_not_available")}
|
|
575
589
|
</Typography>
|
|
576
590
|
<Typography variant="body2" color="secondary" className="text-center max-w-md">
|
|
577
|
-
|
|
578
|
-
Please add an enum property to your collection schema to use this view.
|
|
591
|
+
{t("kanban_view_requires_enum")}
|
|
579
592
|
</Typography>
|
|
580
593
|
{KanbanSetupComponent && (
|
|
581
594
|
<KanbanSetupComponent
|
|
@@ -596,7 +609,7 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
596
609
|
return (
|
|
597
610
|
<div className="flex-1 flex items-center justify-center p-8">
|
|
598
611
|
<Typography variant="label" color="secondary">
|
|
599
|
-
|
|
612
|
+
{t("no_enum_values_configured", { property: columnProperty })}
|
|
600
613
|
</Typography>
|
|
601
614
|
</div>
|
|
602
615
|
);
|
|
@@ -606,33 +619,10 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
606
619
|
<div className="flex-1 flex flex-col overflow-hidden">
|
|
607
620
|
{/* Error banner - only show when no data loaded */}
|
|
608
621
|
{hasError && allEntities.length === 0 && (
|
|
609
|
-
<
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
{indexUrl
|
|
614
|
-
? "A Firestore index is required for this query."
|
|
615
|
-
: errorMessage}
|
|
616
|
-
</Typography>
|
|
617
|
-
<Tooltip title="Refresh data">
|
|
618
|
-
<IconButton
|
|
619
|
-
size="small"
|
|
620
|
-
onClick={() => boardDataController.refreshAll()}
|
|
621
|
-
>
|
|
622
|
-
<RefreshIcon size="small" />
|
|
623
|
-
</IconButton>
|
|
624
|
-
</Tooltip>
|
|
625
|
-
{indexUrl && (
|
|
626
|
-
<Button
|
|
627
|
-
size="small"
|
|
628
|
-
variant="outlined"
|
|
629
|
-
color="error"
|
|
630
|
-
onClick={() => window.open(indexUrl, "_blank")}
|
|
631
|
-
>
|
|
632
|
-
Create Index
|
|
633
|
-
</Button>
|
|
634
|
-
)}
|
|
635
|
-
</div>
|
|
622
|
+
<CollectionDataErrorBanner
|
|
623
|
+
error={dataLoadingError}
|
|
624
|
+
onRetry={() => boardDataController.refreshAll()}
|
|
625
|
+
/>
|
|
636
626
|
)}
|
|
637
627
|
|
|
638
628
|
{/* Backfill info bar - non-blocking */}
|
|
@@ -640,14 +630,14 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
640
630
|
<div
|
|
641
631
|
className="flex items-center justify-between gap-4 px-4 py-2 bg-amber-50 dark:bg-amber-900/20 border-b border-amber-200 dark:border-amber-800">
|
|
642
632
|
<Typography variant="body2" color="secondary">
|
|
643
|
-
|
|
633
|
+
{t("items_need_backfill")}
|
|
644
634
|
</Typography>
|
|
645
635
|
<Button
|
|
646
636
|
size="small"
|
|
647
637
|
variant="text"
|
|
648
638
|
onClick={() => setShowBackfillDialog(true)}
|
|
649
639
|
>
|
|
650
|
-
|
|
640
|
+
{t("initialize")}
|
|
651
641
|
</Button>
|
|
652
642
|
</div>
|
|
653
643
|
)}
|
|
@@ -667,6 +657,10 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
667
657
|
columnLoadingState={columnLoadingState}
|
|
668
658
|
onLoadMoreColumn={(column) => boardDataController.loadMoreColumn(column)}
|
|
669
659
|
onAddItemToColumn={(column) => {
|
|
660
|
+
analyticsController.onAnalyticsEvent?.("kanban_new_entity_in_column", {
|
|
661
|
+
path: fullPath,
|
|
662
|
+
column
|
|
663
|
+
});
|
|
670
664
|
sideEntityController.open({
|
|
671
665
|
path: fullPath,
|
|
672
666
|
collection,
|
|
@@ -693,18 +687,17 @@ export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
|
693
687
|
{/* Backfill dialog */}
|
|
694
688
|
<Dialog open={showBackfillDialog} onOpenChange={setShowBackfillDialog}>
|
|
695
689
|
<DialogContent>
|
|
696
|
-
<Typography variant="h6" className="mb-4">
|
|
690
|
+
<Typography variant="h6" className="mb-4">{t("initialize_kanban_order")}</Typography>
|
|
697
691
|
<Typography variant="body2">
|
|
698
|
-
|
|
699
|
-
Items will maintain their current order within each column.
|
|
692
|
+
{t("initialize_kanban_order_desc")}
|
|
700
693
|
</Typography>
|
|
701
694
|
</DialogContent>
|
|
702
695
|
<DialogActions>
|
|
703
696
|
<Button variant="text" onClick={() => setShowBackfillDialog(false)} disabled={backfillLoading}>
|
|
704
|
-
|
|
697
|
+
{t("cancel")}
|
|
705
698
|
</Button>
|
|
706
699
|
<Button onClick={handleBackfill} disabled={backfillLoading}>
|
|
707
|
-
{backfillLoading ? <CircularProgress size="smallest" /> : "
|
|
700
|
+
{backfillLoading ? <CircularProgress size="smallest" /> : t("initialize")}
|
|
708
701
|
</Button>
|
|
709
702
|
</DialogActions>
|
|
710
703
|
</Dialog>
|
|
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef } from "react";
|
|
|
2
2
|
import { CollectionSize, Entity, EntityCollection, EntityTableController, SelectionController } from "../../types";
|
|
3
3
|
import { EntityCard } from "./EntityCard";
|
|
4
4
|
import { CircularProgress, cls, Typography } from "@firecms/ui";
|
|
5
|
-
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
5
|
+
import { useAuthController, useCustomizationController, useTranslation } from "../../hooks";
|
|
6
6
|
|
|
7
7
|
export type EntityCollectionCardViewProps<M extends Record<string, any> = any> = {
|
|
8
8
|
collection: EntityCollection<M>;
|
|
@@ -61,17 +61,18 @@ function getGridColumnsClass(size: CollectionSize): string {
|
|
|
61
61
|
* Alternative to the EntityCollectionTable for visual browsing.
|
|
62
62
|
*/
|
|
63
63
|
export function EntityCollectionCardView<M extends Record<string, any> = any>({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
collection,
|
|
65
|
+
tableController,
|
|
66
|
+
onEntityClick,
|
|
67
|
+
selectionController,
|
|
68
|
+
selectionEnabled = true,
|
|
69
|
+
highlightedEntities,
|
|
70
|
+
emptyComponent,
|
|
71
|
+
onScroll,
|
|
72
|
+
initialScroll,
|
|
73
|
+
size = "m"
|
|
74
|
+
}: EntityCollectionCardViewProps<M>) {
|
|
75
|
+
const { t } = useTranslation();
|
|
75
76
|
const authController = useAuthController();
|
|
76
77
|
const customizationController = useCustomizationController();
|
|
77
78
|
|
|
@@ -178,23 +179,14 @@ export function EntityCollectionCardView<M extends Record<string, any> = any>({
|
|
|
178
179
|
<div className="flex-1 flex items-center justify-center p-8">
|
|
179
180
|
{emptyComponent ?? (
|
|
180
181
|
<Typography variant="label" color="secondary">
|
|
181
|
-
|
|
182
|
+
{t("no_entries_found")}
|
|
182
183
|
</Typography>
|
|
183
184
|
)}
|
|
184
185
|
</div>
|
|
185
186
|
);
|
|
186
187
|
}
|
|
187
188
|
|
|
188
|
-
|
|
189
|
-
if (dataLoadingError) {
|
|
190
|
-
return (
|
|
191
|
-
<div className="flex-1 flex items-center justify-center p-8">
|
|
192
|
-
<Typography className="text-red-500">
|
|
193
|
-
Error loading data: {dataLoadingError.message}
|
|
194
|
-
</Typography>
|
|
195
|
-
</div>
|
|
196
|
-
);
|
|
197
|
-
}
|
|
189
|
+
|
|
198
190
|
|
|
199
191
|
const gridColumnsClass = getGridColumnsClass(size);
|
|
200
192
|
|
|
@@ -230,11 +222,11 @@ export function EntityCollectionCardView<M extends Record<string, any> = any>({
|
|
|
230
222
|
className="flex items-center justify-center py-8"
|
|
231
223
|
>
|
|
232
224
|
{dataLoading && (
|
|
233
|
-
<CircularProgress size="small"/>
|
|
225
|
+
<CircularProgress size="small" />
|
|
234
226
|
)}
|
|
235
227
|
{!dataLoading && noMoreToLoad && data.length > 0 && (
|
|
236
228
|
<Typography variant="caption" color="secondary">
|
|
237
|
-
|
|
229
|
+
{t("all_entries_loaded", { count: data.length.toString() })}
|
|
238
230
|
</Typography>
|
|
239
231
|
)}
|
|
240
232
|
</div>
|
|
@@ -45,13 +45,15 @@ import {
|
|
|
45
45
|
useFireCMSContext,
|
|
46
46
|
useLargeLayout,
|
|
47
47
|
useNavigationController,
|
|
48
|
-
useSideEntityController
|
|
48
|
+
useSideEntityController,
|
|
49
|
+
useTranslation
|
|
49
50
|
} from "../../hooks";
|
|
50
51
|
import { useBreadcrumbsController } from "../../hooks/useBreadcrumbsController";
|
|
51
52
|
import { useUserConfigurationPersistence } from "../../hooks/useUserConfigurationPersistence";
|
|
52
53
|
import { EntityCollectionViewActions } from "./EntityCollectionViewActions";
|
|
53
54
|
import { EntityCollectionCardView } from "./EntityCollectionCardView";
|
|
54
55
|
import { EntityCollectionBoardView } from "./EntityCollectionBoardView";
|
|
56
|
+
import { CollectionDataErrorBanner } from "./CollectionDataErrorBanner";
|
|
55
57
|
import { ViewModeToggle, KanbanPropertyOption } from "./ViewModeToggle";
|
|
56
58
|
import {
|
|
57
59
|
AddIcon,
|
|
@@ -159,6 +161,7 @@ export const EntityCollectionView = React.memo(
|
|
|
159
161
|
) {
|
|
160
162
|
|
|
161
163
|
const context = useFireCMSContext();
|
|
164
|
+
const { t } = useTranslation();
|
|
162
165
|
const navigation = useNavigationController();
|
|
163
166
|
const breadcrumbs = useBreadcrumbsController();
|
|
164
167
|
const fullPath = fullPathProp ?? collectionProp.path;
|
|
@@ -433,12 +436,17 @@ export const EntityCollectionView = React.memo(
|
|
|
433
436
|
|
|
434
437
|
// View mode change: update URL + save to local persistence
|
|
435
438
|
const onViewModeChange = useCallback((mode: ViewMode) => {
|
|
439
|
+
analyticsController.onAnalyticsEvent?.("view_mode_changed", {
|
|
440
|
+
path: fullPath,
|
|
441
|
+
from: viewMode,
|
|
442
|
+
to: mode
|
|
443
|
+
});
|
|
436
444
|
setViewMode(mode);
|
|
437
445
|
// Save to local persistence for next visit
|
|
438
446
|
if (userConfigPersistence) {
|
|
439
447
|
onCollectionModifiedForUser(fullPath, { defaultViewMode: mode } as PartialEntityCollection<M>);
|
|
440
448
|
}
|
|
441
|
-
}, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath]);
|
|
449
|
+
}, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController, viewMode]);
|
|
442
450
|
|
|
443
451
|
const createEnabled = canCreateEntity(collection, authController, fullPath, null);
|
|
444
452
|
|
|
@@ -568,12 +576,16 @@ export const EntityCollectionView = React.memo(
|
|
|
568
576
|
|
|
569
577
|
// Handle kanban property change
|
|
570
578
|
const onKanbanPropertyChange = useCallback((property: string) => {
|
|
579
|
+
analyticsController.onAnalyticsEvent?.("kanban_property_changed", {
|
|
580
|
+
path: fullPath,
|
|
581
|
+
property
|
|
582
|
+
});
|
|
571
583
|
setSelectedKanbanProperty(property);
|
|
572
584
|
// Save to local persistence
|
|
573
585
|
if (userConfigPersistence) {
|
|
574
586
|
onCollectionModifiedForUser(fullPath, { kanbanColumnProperty: property } as any);
|
|
575
587
|
}
|
|
576
|
-
}, [userConfigPersistence, onCollectionModifiedForUser, fullPath]);
|
|
588
|
+
}, [userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController]);
|
|
577
589
|
|
|
578
590
|
const getPropertyFor = useCallback(({
|
|
579
591
|
propertyKey,
|
|
@@ -686,11 +698,13 @@ export const EntityCollectionView = React.memo(
|
|
|
686
698
|
customEntityActions?: EntityAction[]
|
|
687
699
|
}): EntityAction[] => {
|
|
688
700
|
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
|
|
689
|
-
const actions: EntityAction[] = [
|
|
701
|
+
const actions: EntityAction[] = [
|
|
702
|
+
{ ...editEntityAction, name: t("edit") }
|
|
703
|
+
];
|
|
690
704
|
if (createEnabled)
|
|
691
|
-
actions.push(copyEntityAction);
|
|
705
|
+
actions.push({ ...copyEntityAction, name: t("copy") });
|
|
692
706
|
if (deleteEnabled)
|
|
693
|
-
actions.push(deleteEntityAction);
|
|
707
|
+
actions.push({ ...deleteEntityAction, name: t("delete") });
|
|
694
708
|
if (customEntityActions)
|
|
695
709
|
return mergeEntityActions(actions, customEntityActions);
|
|
696
710
|
return actions;
|
|
@@ -836,6 +850,24 @@ export const EntityCollectionView = React.memo(
|
|
|
836
850
|
/>
|
|
837
851
|
);
|
|
838
852
|
|
|
853
|
+
// Compute plugin-provided error view for collection loading errors
|
|
854
|
+
const pluginErrorView = useMemo(() => {
|
|
855
|
+
const error = tableController.dataLoadingError;
|
|
856
|
+
if (!error || !customizationController.plugins) return null;
|
|
857
|
+
for (const plugin of customizationController.plugins) {
|
|
858
|
+
if (plugin.collectionView?.CollectionError) {
|
|
859
|
+
const CollectionError = plugin.collectionView.CollectionError;
|
|
860
|
+
return <CollectionError
|
|
861
|
+
path={fullPath}
|
|
862
|
+
collection={collection}
|
|
863
|
+
parentCollectionIds={parentCollectionIds}
|
|
864
|
+
error={error}
|
|
865
|
+
/>;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return null;
|
|
869
|
+
}, [tableController.dataLoadingError, customizationController.plugins, fullPath, collection, parentCollectionIds]);
|
|
870
|
+
|
|
839
871
|
return (
|
|
840
872
|
<div className={cls("overflow-hidden h-full w-full rounded-md flex flex-col", className)}
|
|
841
873
|
ref={containerRef}>
|
|
@@ -872,6 +904,10 @@ export const EntityCollectionView = React.memo(
|
|
|
872
904
|
/>
|
|
873
905
|
|
|
874
906
|
{/* View content - only the view-specific content changes */}
|
|
907
|
+
{tableController.dataLoadingError && pluginErrorView}
|
|
908
|
+
{tableController.dataLoadingError && !pluginErrorView && (
|
|
909
|
+
<CollectionDataErrorBanner error={tableController.dataLoadingError} />
|
|
910
|
+
)}
|
|
875
911
|
{viewMode === "kanban" && enabledViews.includes("kanban") ? (
|
|
876
912
|
<EntityCollectionBoardView
|
|
877
913
|
key={`kanban-view-${fullPath}-${selectedKanbanProperty}`}
|
|
@@ -887,16 +923,16 @@ export const EntityCollectionView = React.memo(
|
|
|
887
923
|
deletedEntities={deletedEntities}
|
|
888
924
|
emptyComponent={canCreateEntities && tableController.filterValues === undefined && tableController.sortBy === undefined
|
|
889
925
|
? <div className="flex flex-col items-center justify-center">
|
|
890
|
-
<Typography variant={"subtitle2"}>
|
|
926
|
+
<Typography variant={"subtitle2"}>{t("so_empty")}</Typography>
|
|
891
927
|
<Button
|
|
892
928
|
onClick={onNewClick}
|
|
893
929
|
className="mt-4"
|
|
894
930
|
>
|
|
895
931
|
<AddIcon />
|
|
896
|
-
|
|
932
|
+
{t("create_your_first_entry")}
|
|
897
933
|
</Button>
|
|
898
934
|
</div>
|
|
899
|
-
: <Typography variant={"label"}>
|
|
935
|
+
: <Typography variant={"label"}>{t("no_results_filter_sort")}</Typography>
|
|
900
936
|
}
|
|
901
937
|
/>
|
|
902
938
|
) : viewMode === "cards" ? (
|
|
@@ -913,16 +949,16 @@ export const EntityCollectionView = React.memo(
|
|
|
913
949
|
size={cardSize}
|
|
914
950
|
emptyComponent={canCreateEntities && tableController.filterValues === undefined && tableController.sortBy === undefined
|
|
915
951
|
? <div className="flex flex-col items-center justify-center">
|
|
916
|
-
<Typography variant={"subtitle2"}>
|
|
952
|
+
<Typography variant={"subtitle2"}>{t("so_empty")}</Typography>
|
|
917
953
|
<Button
|
|
918
954
|
onClick={onNewClick}
|
|
919
955
|
className="mt-4"
|
|
920
956
|
>
|
|
921
957
|
<AddIcon />
|
|
922
|
-
|
|
958
|
+
{t("create_your_first_entry")}
|
|
923
959
|
</Button>
|
|
924
960
|
</div>
|
|
925
|
-
: <Typography variant={"label"}>
|
|
961
|
+
: <Typography variant={"label"}>{t("no_results_filter_sort")}</Typography>
|
|
926
962
|
}
|
|
927
963
|
/>
|
|
928
964
|
) : (
|
|
@@ -951,16 +987,16 @@ export const EntityCollectionView = React.memo(
|
|
|
951
987
|
textSearchEnabled={textSearchEnabled}
|
|
952
988
|
emptyComponent={canCreateEntities && tableController.filterValues === undefined && tableController.sortBy === undefined
|
|
953
989
|
? <div className="flex flex-col items-center justify-center">
|
|
954
|
-
<Typography variant={"subtitle2"}>
|
|
990
|
+
<Typography variant={"subtitle2"}>{t("so_empty")}</Typography>
|
|
955
991
|
<Button
|
|
956
992
|
onClick={onNewClick}
|
|
957
993
|
className="mt-4"
|
|
958
994
|
>
|
|
959
995
|
<AddIcon />
|
|
960
|
-
|
|
996
|
+
{t("create_your_first_entry")}
|
|
961
997
|
</Button>
|
|
962
998
|
</div>
|
|
963
|
-
: <Typography variant={"label"}>
|
|
999
|
+
: <Typography variant={"label"}>{t("no_results_filter_sort")}</Typography>
|
|
964
1000
|
}
|
|
965
1001
|
hoverRow={hoverRow}
|
|
966
1002
|
inlineEditing={checkInlineEditing()}
|
|
@@ -1131,11 +1167,12 @@ function EntityIdHeaderWidget({
|
|
|
1131
1167
|
const [searchString, setSearchString] = React.useState("");
|
|
1132
1168
|
const [recentIds, setRecentIds] = React.useState<string[]>(getRecentIds(collection.id));
|
|
1133
1169
|
const sideEntityController = useSideEntityController();
|
|
1170
|
+
const { t } = useTranslation();
|
|
1134
1171
|
|
|
1135
1172
|
const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
|
|
1136
1173
|
|
|
1137
1174
|
return (
|
|
1138
|
-
<Tooltip title={!openPopup ? "
|
|
1175
|
+
<Tooltip title={!openPopup ? t("find_by_id") : undefined} asChild={false}>
|
|
1139
1176
|
<Popover
|
|
1140
1177
|
open={openPopup}
|
|
1141
1178
|
onOpenChange={setOpenPopup}
|
|
@@ -1171,7 +1208,7 @@ function EntityIdHeaderWidget({
|
|
|
1171
1208
|
<div className="flex p-2 w-full gap-2">
|
|
1172
1209
|
<input
|
|
1173
1210
|
autoFocus={openPopup}
|
|
1174
|
-
placeholder={"
|
|
1211
|
+
placeholder={t("find_entity_by_id")}
|
|
1175
1212
|
// size={"small"}
|
|
1176
1213
|
onChange={(e) => {
|
|
1177
1214
|
setSearchString(e.target.value);
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "@firecms/ui";
|
|
18
18
|
import { toArray } from "../../util/arrays";
|
|
19
19
|
import { ErrorBoundary } from "../ErrorBoundary";
|
|
20
|
+
import { useTranslation } from "../../hooks/useTranslation";
|
|
20
21
|
|
|
21
22
|
export type EntityCollectionViewActionsProps<M extends Record<string, any>> = {
|
|
22
23
|
collection: EntityCollection<M>;
|
|
@@ -45,9 +46,9 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
45
46
|
}: EntityCollectionViewActionsProps<M>) {
|
|
46
47
|
|
|
47
48
|
const context = useFireCMSContext();
|
|
48
|
-
|
|
49
49
|
const customizationController = useCustomizationController();
|
|
50
50
|
const plugins = customizationController.plugins ?? [];
|
|
51
|
+
const { t } = useTranslation();
|
|
51
52
|
|
|
52
53
|
const authController = useAuthController();
|
|
53
54
|
|
|
@@ -63,7 +64,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
63
64
|
startIcon={<AddIcon size={"small"} />}
|
|
64
65
|
variant="filled"
|
|
65
66
|
color="primary">
|
|
66
|
-
|
|
67
|
+
{t("add")} {collection.singularName ?? collection.name}
|
|
67
68
|
</Button>
|
|
68
69
|
: <Button
|
|
69
70
|
id={`add_entity_${path}`}
|
|
@@ -98,7 +99,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
98
99
|
</IconButton>;
|
|
99
100
|
multipleDeleteButton =
|
|
100
101
|
<Tooltip
|
|
101
|
-
title={multipleDeleteEnabled ? "
|
|
102
|
+
title={multipleDeleteEnabled ? t("delete_selected") : t("cannot_delete_selected")}>
|
|
102
103
|
{button}
|
|
103
104
|
</Tooltip>
|
|
104
105
|
}
|
|
@@ -12,6 +12,7 @@ import { ErrorBoundary } from "../ErrorBoundary";
|
|
|
12
12
|
import { ClearFilterSortButton } from "../ClearFilterSortButton";
|
|
13
13
|
import { FiltersDialog } from "./FiltersDialog";
|
|
14
14
|
import { Badge, Button, cls, FilterListIcon, IconButton, Tooltip } from "@firecms/ui";
|
|
15
|
+
import { useTranslation } from "../../hooks/useTranslation";
|
|
15
16
|
|
|
16
17
|
export type EntityCollectionViewStartActionsProps<M extends Record<string, any>> = {
|
|
17
18
|
collection: EntityCollection<M>;
|
|
@@ -42,6 +43,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
42
43
|
const customizationController = useCustomizationController();
|
|
43
44
|
const plugins = customizationController.plugins ?? [];
|
|
44
45
|
const largeLayout = useLargeLayout();
|
|
46
|
+
const { t } = useTranslation();
|
|
45
47
|
|
|
46
48
|
// Filters dialog state
|
|
47
49
|
const [filtersDialogOpen, setFiltersDialogOpen] = useState(false);
|
|
@@ -66,7 +68,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
66
68
|
|
|
67
69
|
// Filters button
|
|
68
70
|
const filtersButton = resolvedProperties && tableController.setFilterValues && (
|
|
69
|
-
<Tooltip title="
|
|
71
|
+
<Tooltip title={t("filters")}
|
|
70
72
|
key={"filters_tooltip"}>
|
|
71
73
|
<Badge
|
|
72
74
|
color="primary"
|
|
@@ -80,7 +82,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
80
82
|
startIcon={<FilterListIcon size="small" />}
|
|
81
83
|
className={cls(activeFilterCount > 0 && "text-primary")}
|
|
82
84
|
>
|
|
83
|
-
|
|
85
|
+
{t("filters")}{activeFilterCount > 0 ? ` (${activeFilterCount})` : ""}
|
|
84
86
|
</Button>
|
|
85
87
|
) : (
|
|
86
88
|
<IconButton
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
FilterListIcon,
|
|
16
16
|
Typography
|
|
17
17
|
} from "@firecms/ui";
|
|
18
|
+
import { useTranslation } from "../../hooks/useTranslation";
|
|
18
19
|
import { StringNumberFilterField } from "../SelectableTable/filters/StringNumberFilterField";
|
|
19
20
|
import { BooleanFilterField } from "../SelectableTable/filters/BooleanFilterField";
|
|
20
21
|
import { DateTimeFilterField } from "../SelectableTable/filters/DateTimeFilterField";
|
|
@@ -43,6 +44,8 @@ export function FiltersDialog({
|
|
|
43
44
|
setFilterValues,
|
|
44
45
|
forceFilter
|
|
45
46
|
}: FiltersDialogProps) {
|
|
47
|
+
const { t } = useTranslation();
|
|
48
|
+
|
|
46
49
|
// Local state for filters being edited
|
|
47
50
|
const [localFilters, setLocalFilters] = useState<FilterValues<any>>(filterValues ?? {});
|
|
48
51
|
|
|
@@ -173,7 +176,7 @@ export function FiltersDialog({
|
|
|
173
176
|
containerClassName={isAnyFieldHidden ? "hidden" : undefined}
|
|
174
177
|
>
|
|
175
178
|
<DialogTitle className="flex items-center gap-2">
|
|
176
|
-
<Typography variant="h6">
|
|
179
|
+
<Typography variant="h6">{t("filters")}</Typography>
|
|
177
180
|
{activeFilterCount > 0 && (
|
|
178
181
|
<span className="ml-2 px-2 py-0.5 text-xs rounded-full bg-primary text-white">
|
|
179
182
|
{activeFilterCount}
|
|
@@ -184,7 +187,7 @@ export function FiltersDialog({
|
|
|
184
187
|
<DialogContent >
|
|
185
188
|
{filterableProperties.length === 0 ? (
|
|
186
189
|
<Typography color="secondary" className="py-8 text-center">
|
|
187
|
-
|
|
190
|
+
{t("no_filterable_properties")}
|
|
188
191
|
</Typography>
|
|
189
192
|
) : (
|
|
190
193
|
<table className="w-full border-collapse">
|
|
@@ -228,20 +231,20 @@ export function FiltersDialog({
|
|
|
228
231
|
onClick={handleClearAll}
|
|
229
232
|
disabled={activeFilterCount === 0}
|
|
230
233
|
>
|
|
231
|
-
|
|
234
|
+
{t("clear")}
|
|
232
235
|
</Button>
|
|
233
236
|
<div className="flex-grow" />
|
|
234
237
|
<Button
|
|
235
238
|
variant="text"
|
|
236
239
|
onClick={() => onOpenChange(false)}
|
|
237
240
|
>
|
|
238
|
-
|
|
241
|
+
{t("cancel")}
|
|
239
242
|
</Button>
|
|
240
243
|
<Button
|
|
241
244
|
variant="filled"
|
|
242
245
|
onClick={handleApply}
|
|
243
246
|
>
|
|
244
|
-
|
|
247
|
+
{t("apply_filters")}
|
|
245
248
|
</Button>
|
|
246
249
|
</DialogActions>
|
|
247
250
|
</Dialog>
|