@firecms/core 3.1.0 → 3.2.0-canary.44dc65b
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/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
- package/dist/components/ErrorBoundary.d.ts +3 -1
- 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/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/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 +12898 -2265
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +12877 -2264
- package/dist/index.umd.js.map +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/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 +7 -0
- package/dist/types/storage.d.ts +1 -0
- package/dist/types/translations.d.ts +646 -0
- package/dist/util/useStorageUploadController.d.ts +10 -1
- package/package.json +45 -9
- 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/popup_field/PopupFormField.tsx +3 -2
- package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
- package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +16 -43
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +26 -18
- 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/VirtualTableHeader.tsx +12 -10
- 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 +14 -10
- 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 +6 -5
- package/src/core/FireCMS.tsx +33 -6
- 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 +16 -3
- package/src/form/EntityFormActions.tsx +19 -12
- package/src/form/PropertyFieldBinding.tsx +3 -2
- 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 +33 -19
- package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +4 -3
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildNavigationController.tsx +45 -18
- package/src/hooks/useCollapsedGroups.ts +7 -6
- package/src/hooks/useTranslation.ts +31 -0
- package/src/i18n/FireCMSi18nProvider.tsx +160 -0
- package/src/index.ts +4 -0
- 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/components/UrlComponentPreview.tsx +4 -2
- package/src/preview/components/UserPreview.tsx +3 -1
- 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 +8 -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/useStorageUploadController.tsx +23 -29
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.2.0-canary.44dc65b",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -53,22 +53,46 @@
|
|
|
53
53
|
"@dnd-kit/core": "^6.3.1",
|
|
54
54
|
"@dnd-kit/modifiers": "^9.0.0",
|
|
55
55
|
"@dnd-kit/sortable": "^10.0.0",
|
|
56
|
-
"@firecms/
|
|
57
|
-
"@firecms/
|
|
58
|
-
"@
|
|
56
|
+
"@firecms/formex": "3.2.0-canary.44dc65b",
|
|
57
|
+
"@firecms/ui": "3.2.0-canary.44dc65b",
|
|
58
|
+
"@floating-ui/dom": "^1.7.4",
|
|
59
59
|
"@radix-ui/react-portal": "^1.1.10",
|
|
60
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
60
61
|
"clsx": "^2.1.1",
|
|
61
62
|
"compressorjs": "^1.2.1",
|
|
62
63
|
"date-fns": "^3.6.0",
|
|
63
64
|
"fuse.js": "^7.1.0",
|
|
64
65
|
"history": "^5.3.0",
|
|
66
|
+
"i18next": "^23.16.4",
|
|
65
67
|
"json-logic-js": "^2.0.5",
|
|
66
68
|
"markdown-it": "^14.1.0",
|
|
69
|
+
"markdown-it-ins": "^4.0.0",
|
|
70
|
+
"markdown-it-mark": "^4.0.0",
|
|
71
|
+
"markdown-it-task-lists": "^2.1.1",
|
|
67
72
|
"notistack": "^3.0.2",
|
|
68
73
|
"object-hash": "^3.0.0",
|
|
69
74
|
"prism-react-renderer": "^2.4.1",
|
|
75
|
+
"prosemirror-commands": "^1.6.0",
|
|
76
|
+
"prosemirror-dropcursor": "^1.8.1",
|
|
77
|
+
"prosemirror-example-setup": "^1.2.3",
|
|
78
|
+
"prosemirror-gapcursor": "^1.3.2",
|
|
79
|
+
"prosemirror-history": "^1.4.1",
|
|
80
|
+
"prosemirror-inputrules": "^1.5.1",
|
|
81
|
+
"prosemirror-keymap": "^1.2.2",
|
|
82
|
+
"prosemirror-markdown": "^1.13.0",
|
|
83
|
+
"prosemirror-model": "^1.22.3",
|
|
84
|
+
"prosemirror-schema-basic": "^1.2.3",
|
|
85
|
+
"prosemirror-schema-list": "^1.4.1",
|
|
86
|
+
"prosemirror-state": "^1.4.3",
|
|
87
|
+
"prosemirror-tables": "^1.8.5",
|
|
88
|
+
"prosemirror-transform": "^1.10.0",
|
|
89
|
+
"prosemirror-view": "^1.33.8",
|
|
70
90
|
"react-dropzone": "^14.3.8",
|
|
71
91
|
"react-fast-compare": "^3.2.2",
|
|
92
|
+
"react-i18next": "^14.1.3",
|
|
93
|
+
"react-image-crop": "^11.0.10",
|
|
94
|
+
"react-markdown": "^9.1.0",
|
|
95
|
+
"react-moveable": "^0.56.0",
|
|
72
96
|
"react-transition-group": "^4.4.5",
|
|
73
97
|
"react-use-measure": "^2.1.7",
|
|
74
98
|
"react-window": "^1.8.11",
|
|
@@ -95,6 +119,7 @@
|
|
|
95
119
|
"@vitejs/plugin-react": "^4.7.0",
|
|
96
120
|
"babel-plugin-react-compiler": "^19.0.0-beta-af1b7da-20250417",
|
|
97
121
|
"cross-env": "^7.0.3",
|
|
122
|
+
"eslint-plugin-i18next": "^6.1.3",
|
|
98
123
|
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
|
99
124
|
"jest": "^29.7.0",
|
|
100
125
|
"jest-environment-jsdom": "^30.2.0",
|
|
@@ -111,15 +136,27 @@
|
|
|
111
136
|
"dist",
|
|
112
137
|
"src"
|
|
113
138
|
],
|
|
114
|
-
"gitHead": "
|
|
139
|
+
"gitHead": "af4cd57871ac430b4ffac0295c40b9cd3cee24ff",
|
|
115
140
|
"publishConfig": {
|
|
116
141
|
"access": "public"
|
|
117
142
|
},
|
|
118
143
|
"eslintConfig": {
|
|
119
144
|
"extends": [
|
|
120
145
|
"react-app",
|
|
121
|
-
"react-app/jest"
|
|
122
|
-
|
|
146
|
+
"react-app/jest",
|
|
147
|
+
"plugin:i18next/recommended"
|
|
148
|
+
],
|
|
149
|
+
"plugins": [
|
|
150
|
+
"i18next"
|
|
151
|
+
],
|
|
152
|
+
"rules": {
|
|
153
|
+
"i18next/no-literal-string": [
|
|
154
|
+
"warn",
|
|
155
|
+
{
|
|
156
|
+
"markupOnly": true
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
123
160
|
},
|
|
124
161
|
"jest": {
|
|
125
162
|
"transform": {
|
|
@@ -136,8 +173,7 @@
|
|
|
136
173
|
],
|
|
137
174
|
"testEnvironment": "node",
|
|
138
175
|
"moduleNameMapper": {
|
|
139
|
-
"\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
|
|
140
|
-
"^@firecms/editor$": "<rootDir>/test/__mocks__/editorMock.js"
|
|
176
|
+
"\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
|
|
141
177
|
}
|
|
142
178
|
}
|
|
143
179
|
}
|
package/src/app/Scaffold.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import equal from "react-fast-compare"
|
|
|
4
4
|
import { useLargeLayout } from "../hooks";
|
|
5
5
|
import { ErrorBoundary } from "../components";
|
|
6
6
|
import { AppContext } from "./useApp";
|
|
7
|
+
import { useTranslation } from "../hooks/useTranslation";
|
|
7
8
|
|
|
8
9
|
export const DRAWER_WIDTH = 280;
|
|
9
10
|
|
|
@@ -163,6 +164,7 @@ function DrawerWrapper(props: {
|
|
|
163
164
|
onMouseLeave: () => void
|
|
164
165
|
}) {
|
|
165
166
|
|
|
167
|
+
const { t } = useTranslation();
|
|
166
168
|
const width = !props.displayed ? 0 : (props.open ? DRAWER_WIDTH : 72);
|
|
167
169
|
const innerDrawer = <div
|
|
168
170
|
className={"relative h-full no-scrollbar overflow-y-auto overflow-x-hidden"}
|
|
@@ -173,7 +175,7 @@ function DrawerWrapper(props: {
|
|
|
173
175
|
>
|
|
174
176
|
|
|
175
177
|
{!props.open && props.displayed && (
|
|
176
|
-
<Tooltip title="
|
|
178
|
+
<Tooltip title={t("open_menu")}
|
|
177
179
|
side="right"
|
|
178
180
|
sideOffset={12}
|
|
179
181
|
asChild={true}>
|
|
@@ -181,7 +183,7 @@ function DrawerWrapper(props: {
|
|
|
181
183
|
className="ml-2 fixed top-1 left-2 sm:top-2 sm:left-2 !bg-surface-50 dark:!bg-surface-900 rounded-full w-fit z-20">
|
|
182
184
|
<IconButton
|
|
183
185
|
color="inherit"
|
|
184
|
-
aria-label="
|
|
186
|
+
aria-label={t("open_menu")}
|
|
185
187
|
onClick={() => props.setDrawerOpen(true)}
|
|
186
188
|
size="large"
|
|
187
189
|
>
|
|
@@ -195,7 +197,7 @@ function DrawerWrapper(props: {
|
|
|
195
197
|
className={`z-20 absolute right-0 top-4 ${props.open ? "opacity-100" : "opacity-0 invisible"
|
|
196
198
|
} transition-opacity duration-200 ease-in-out`}>
|
|
197
199
|
<IconButton
|
|
198
|
-
aria-label="
|
|
200
|
+
aria-label={t("close_drawer")}
|
|
199
201
|
onClick={() => props.setDrawerOpen(false)}
|
|
200
202
|
>
|
|
201
203
|
<ChevronLeftIcon />
|
|
@@ -215,7 +217,7 @@ function DrawerWrapper(props: {
|
|
|
215
217
|
return <>
|
|
216
218
|
<IconButton
|
|
217
219
|
color="inherit"
|
|
218
|
-
aria-label="
|
|
220
|
+
aria-label={t("open_menu")}
|
|
219
221
|
onClick={() => props.setDrawerOpen(true)}
|
|
220
222
|
size="large"
|
|
221
223
|
className="absolute sm:top-2 sm:left-4 top-1 left-2"
|
|
@@ -226,7 +228,7 @@ function DrawerWrapper(props: {
|
|
|
226
228
|
transparent={true}
|
|
227
229
|
open={props.open}
|
|
228
230
|
onOpenChange={props.setDrawerOpen}
|
|
229
|
-
title={"
|
|
231
|
+
title={t("navigation_drawer")}
|
|
230
232
|
overlayClassName={"bg-white bg-opacity-80 bg-white/80"}
|
|
231
233
|
>
|
|
232
234
|
{innerDrawer}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { AutoAwesomeIcon } from "@firecms/ui";
|
|
3
|
+
import { useTranslation } from "../hooks";
|
|
3
4
|
|
|
4
5
|
export interface AIIconProps {
|
|
5
6
|
size?: "smallest" | "small" | "medium" | "large";
|
|
@@ -30,10 +31,11 @@ export function AIIcon({ size = "small", className }: AIIconProps) {
|
|
|
30
31
|
* Shows a pulsing gradient dot.
|
|
31
32
|
*/
|
|
32
33
|
export function AIModifiedIndicator({ className }: { className?: string }) {
|
|
34
|
+
const { t } = useTranslation();
|
|
33
35
|
return (
|
|
34
36
|
<div
|
|
35
37
|
className={`w-2 h-2 rounded-full bg-gradient-to-r from-primary to-secondary animate-pulse ${className ?? ""}`}
|
|
36
|
-
title="
|
|
38
|
+
title={t("ai_modified")}
|
|
37
39
|
/>
|
|
38
40
|
);
|
|
39
41
|
}
|
|
@@ -13,6 +13,7 @@ import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
|
13
13
|
import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
14
14
|
import { CSS } from "@dnd-kit/utilities";
|
|
15
15
|
import { getHashValue } from "../util";
|
|
16
|
+
import { useTranslation } from "../hooks";
|
|
16
17
|
import {
|
|
17
18
|
AddIcon,
|
|
18
19
|
Button,
|
|
@@ -235,6 +236,7 @@ export function ArrayItemOptions({
|
|
|
235
236
|
canAddElements?: boolean;
|
|
236
237
|
addInIndex?: (index: number) => void;
|
|
237
238
|
}) {
|
|
239
|
+
const { t } = useTranslation();
|
|
238
240
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
239
241
|
const iconRef = useRef<HTMLDivElement>(null);
|
|
240
242
|
useOutsideAlerter(iconRef, () => {
|
|
@@ -296,7 +298,7 @@ export function ArrayItemOptions({
|
|
|
296
298
|
}}
|
|
297
299
|
>
|
|
298
300
|
<RemoveIcon size={"small"}/>
|
|
299
|
-
|
|
301
|
+
{t("remove")}
|
|
300
302
|
</MenuItem>
|
|
301
303
|
<MenuItem
|
|
302
304
|
dense
|
|
@@ -306,7 +308,7 @@ export function ArrayItemOptions({
|
|
|
306
308
|
}}
|
|
307
309
|
>
|
|
308
310
|
<ContentCopyIcon size={"small"}/>
|
|
309
|
-
|
|
311
|
+
{t("copy")}
|
|
310
312
|
</MenuItem>
|
|
311
313
|
{addInIndex && (
|
|
312
314
|
<MenuItem
|
|
@@ -317,7 +319,7 @@ export function ArrayItemOptions({
|
|
|
317
319
|
}}
|
|
318
320
|
>
|
|
319
321
|
<KeyboardArrowUpIcon size={"small"}/>
|
|
320
|
-
|
|
322
|
+
{t("add_on_top")}
|
|
321
323
|
</MenuItem>
|
|
322
324
|
)}
|
|
323
325
|
{addInIndex && (
|
|
@@ -329,7 +331,7 @@ export function ArrayItemOptions({
|
|
|
329
331
|
}}
|
|
330
332
|
>
|
|
331
333
|
<KeyboardArrowDownIcon size={"small"}/>
|
|
332
|
-
|
|
334
|
+
{t("add_below")}
|
|
333
335
|
</MenuItem>
|
|
334
336
|
)}
|
|
335
337
|
</Menu>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FilterListOffIcon, Button, Tooltip } from "@firecms/ui";
|
|
2
2
|
import { EntityTableController } from "../types";
|
|
3
|
+
import { useTranslation } from "../hooks";
|
|
3
4
|
|
|
4
5
|
export function ClearFilterSortButton({
|
|
5
6
|
tableController,
|
|
@@ -8,6 +9,8 @@ export function ClearFilterSortButton({
|
|
|
8
9
|
enabled: boolean;
|
|
9
10
|
tableController: EntityTableController
|
|
10
11
|
}) {
|
|
12
|
+
const { t } = useTranslation();
|
|
13
|
+
|
|
11
14
|
if (!enabled) {
|
|
12
15
|
return null;
|
|
13
16
|
}
|
|
@@ -18,11 +21,11 @@ export function ClearFilterSortButton({
|
|
|
18
21
|
if ((filterIsSet || sortIsSet) && (tableController.clearFilter || tableController.setSortBy)) {
|
|
19
22
|
let label;
|
|
20
23
|
if (filterIsSet && sortIsSet) {
|
|
21
|
-
label = "
|
|
24
|
+
label = t("clear_filter_sort");
|
|
22
25
|
} else if (filterIsSet) {
|
|
23
|
-
label = "
|
|
26
|
+
label = t("clear_filter");
|
|
24
27
|
} else {
|
|
25
|
-
label = "
|
|
28
|
+
label = t("clear_sort");
|
|
26
29
|
}
|
|
27
30
|
return (
|
|
28
31
|
<Tooltip title={label}>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
3
|
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, LoadingButton } from "@firecms/ui";
|
|
4
|
+
import { useTranslation } from "../hooks/useTranslation";
|
|
4
5
|
|
|
5
6
|
export function ConfirmationDialog({
|
|
6
7
|
open,
|
|
@@ -17,6 +18,7 @@ export function ConfirmationDialog({
|
|
|
17
18
|
title: React.ReactNode,
|
|
18
19
|
body?: React.ReactNode,
|
|
19
20
|
}) {
|
|
21
|
+
const { t } = useTranslation();
|
|
20
22
|
return (
|
|
21
23
|
<Dialog
|
|
22
24
|
open={open}
|
|
@@ -31,14 +33,14 @@ export function ConfirmationDialog({
|
|
|
31
33
|
<Button
|
|
32
34
|
variant={"text"}
|
|
33
35
|
onClick={onCancel}
|
|
34
|
-
autoFocus>
|
|
36
|
+
autoFocus>{t("cancel")}</Button>
|
|
35
37
|
|
|
36
38
|
<LoadingButton
|
|
37
39
|
type="submit"
|
|
38
40
|
loading={loading}
|
|
39
41
|
onClick={onAccept}
|
|
40
42
|
autoFocus>
|
|
41
|
-
|
|
43
|
+
{t("ok")}
|
|
42
44
|
</LoadingButton>
|
|
43
45
|
</DialogActions>
|
|
44
46
|
</Dialog>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "../hooks";
|
|
12
12
|
import { resolveCollection } from "../util";
|
|
13
13
|
import { EntityView } from "./EntityView";
|
|
14
|
+
import { useTranslation } from "../hooks/useTranslation";
|
|
14
15
|
|
|
15
16
|
export interface DeleteEntityDialogProps<M extends Record<string, any>> {
|
|
16
17
|
entityOrEntitiesToDelete?: Entity<M> | Entity<M>[],
|
|
@@ -39,6 +40,8 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
|
|
|
39
40
|
const dataSource = useDataSource(collection);
|
|
40
41
|
const customizationController = useCustomizationController();
|
|
41
42
|
const snackbarController = useSnackbarController();
|
|
43
|
+
const { t } = useTranslation();
|
|
44
|
+
|
|
42
45
|
const [loading, setLoading] = useState(false);
|
|
43
46
|
|
|
44
47
|
const context = useFireCMSContext();
|
|
@@ -66,7 +69,7 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
|
|
|
66
69
|
const onDeleteFailure = useCallback((entity: Entity<any>, e: Error) => {
|
|
67
70
|
snackbarController.open({
|
|
68
71
|
type: "error",
|
|
69
|
-
message: "
|
|
72
|
+
message: t("error_deleting", { message: e?.message })
|
|
70
73
|
});
|
|
71
74
|
|
|
72
75
|
console.error("Error deleting entity");
|
|
@@ -76,7 +79,7 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
|
|
|
76
79
|
const onPreDeleteHookError = useCallback((entity: Entity<any>, e: Error) => {
|
|
77
80
|
snackbarController.open({
|
|
78
81
|
type: "error",
|
|
79
|
-
message: "
|
|
82
|
+
message: t("error_before_delete", { message: e?.message })
|
|
80
83
|
});
|
|
81
84
|
console.error(e);
|
|
82
85
|
}, [resolvedCollection.name]);
|
|
@@ -153,7 +156,7 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
|
|
|
153
156
|
|
|
154
157
|
let content: React.ReactNode;
|
|
155
158
|
if (entityOrEntities && multipleEntities) {
|
|
156
|
-
content = <>
|
|
159
|
+
content = <>{t("multiple_entities")}</>;
|
|
157
160
|
} else {
|
|
158
161
|
const entity = entityOrEntities as Entity<M> | undefined;
|
|
159
162
|
content = entity
|
|
@@ -165,8 +168,8 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
|
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
const dialogTitle = multipleEntities
|
|
168
|
-
? <><b>{resolvedCollection.name}</b>:
|
|
169
|
-
:
|
|
171
|
+
? <><b>{resolvedCollection.name}</b>: {t("confirm_multiple_delete")}</>
|
|
172
|
+
: t("delete_entity_confirm_title", { entityName: resolvedCollection.singularName ?? resolvedCollection.name });
|
|
170
173
|
|
|
171
174
|
return (
|
|
172
175
|
<Dialog
|
|
@@ -188,14 +191,14 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
|
|
|
188
191
|
<Button onClick={handleCancel}
|
|
189
192
|
disabled={loading}
|
|
190
193
|
variant="text">
|
|
191
|
-
|
|
194
|
+
{t("cancel")}
|
|
192
195
|
</Button>
|
|
193
196
|
<Button
|
|
194
197
|
autoFocus
|
|
195
198
|
disabled={loading}
|
|
196
199
|
onClick={handleOk}
|
|
197
200
|
variant="filled">
|
|
198
|
-
|
|
201
|
+
{t("ok")}
|
|
199
202
|
</Button>
|
|
200
203
|
</DialogActions>
|
|
201
204
|
|
|
@@ -10,6 +10,7 @@ import { useCustomizationController, useNavigationController, useReferenceDialog
|
|
|
10
10
|
import { ErrorView } from "../../ErrorView";
|
|
11
11
|
import { cls, EditIcon } from "@firecms/ui";
|
|
12
12
|
import { EntityPreviewContainer } from "../../EntityPreview";
|
|
13
|
+
import { useTranslation } from "../../../hooks";
|
|
13
14
|
|
|
14
15
|
type TableReferenceFieldProps = {
|
|
15
16
|
name: string;
|
|
@@ -62,6 +63,8 @@ export const TableReferenceFieldInternal = React.memo(
|
|
|
62
63
|
includeEntityLink
|
|
63
64
|
} = props;
|
|
64
65
|
|
|
66
|
+
const { t } = useTranslation();
|
|
67
|
+
|
|
65
68
|
const onSingleEntitySelected = useCallback((entity: Entity<any>) => {
|
|
66
69
|
updateValue(entity ? getReferenceFrom(entity) : null);
|
|
67
70
|
}, [updateValue]);
|
|
@@ -111,7 +114,7 @@ export const TableReferenceFieldInternal = React.memo(
|
|
|
111
114
|
return <EntityPreviewContainer
|
|
112
115
|
onClick={disabled ? undefined : handleOpen}
|
|
113
116
|
size={getPreviewSizeFrom(size)}>
|
|
114
|
-
<ErrorView title="
|
|
117
|
+
<ErrorView title={t("value_is_not_reference")} error={t("click_to_edit")}/>
|
|
115
118
|
</EntityPreviewContainer>;
|
|
116
119
|
};
|
|
117
120
|
|
|
@@ -136,11 +139,11 @@ export const TableReferenceFieldInternal = React.memo(
|
|
|
136
139
|
}
|
|
137
140
|
</>;
|
|
138
141
|
else
|
|
139
|
-
return <ErrorView error={"
|
|
142
|
+
return <ErrorView error={t("data_is_not_array_of_references")}/>;
|
|
140
143
|
};
|
|
141
144
|
|
|
142
145
|
if (!collection)
|
|
143
|
-
return <ErrorView error={"
|
|
146
|
+
return <ErrorView error={t("collection_does_not_exist")}/>;
|
|
144
147
|
|
|
145
148
|
return (
|
|
146
149
|
<div className="w-full group">
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
defaultBorderMixin,
|
|
7
7
|
SearchBar
|
|
8
8
|
} from "@firecms/ui";
|
|
9
|
-
import { useLargeLayout } from "../../../hooks";
|
|
9
|
+
import { useLargeLayout, useTranslation } from "../../../hooks";
|
|
10
10
|
|
|
11
11
|
interface CollectionTableToolbarProps {
|
|
12
12
|
loading: boolean;
|
|
@@ -33,6 +33,7 @@ export function CollectionTableToolbar({
|
|
|
33
33
|
viewModeToggle
|
|
34
34
|
}: CollectionTableToolbarProps) {
|
|
35
35
|
|
|
36
|
+
const { t } = useTranslation();
|
|
36
37
|
const searchInputRef = React.useRef<HTMLInputElement>(null);
|
|
37
38
|
const largeLayout = useLargeLayout();
|
|
38
39
|
|
|
@@ -78,6 +79,7 @@ export function CollectionTableToolbar({
|
|
|
78
79
|
disabled={Boolean(onTextSearchClick)}
|
|
79
80
|
onClick={onTextSearchClick}
|
|
80
81
|
onTextSearch={onTextSearchClick ? undefined : onTextSearch}
|
|
82
|
+
placeholder={t("search")}
|
|
81
83
|
expandable={true} />}
|
|
82
84
|
|
|
83
85
|
{actions}
|
|
@@ -20,7 +20,7 @@ import { useWindowSize } from "./useWindowSize";
|
|
|
20
20
|
import { getPropertyInPath, isReadOnly, resolveCollection } from "../../../../util";
|
|
21
21
|
import { Button, CloseIcon, DialogActions, IconButton, Typography } from "@firecms/ui";
|
|
22
22
|
import { PropertyFieldBinding, yupToFormErrors } from "../../../../form";
|
|
23
|
-
import { useAuthController, useCustomizationController, useDataSource, useFireCMSContext } from "../../../../hooks";
|
|
23
|
+
import { useAuthController, useCustomizationController, useDataSource, useFireCMSContext, useTranslation } from "../../../../hooks";
|
|
24
24
|
import { OnCellValueChangeParams } from "../../../common";
|
|
25
25
|
|
|
26
26
|
interface PopupFormFieldProps<M extends Record<string, any>> {
|
|
@@ -108,6 +108,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
108
108
|
const fireCMSContext = useFireCMSContext();
|
|
109
109
|
const authController = useAuthController();
|
|
110
110
|
const customizationController = useCustomizationController();
|
|
111
|
+
const { t } = useTranslation();
|
|
111
112
|
|
|
112
113
|
const [savingError, setSavingError] = React.useState<any>();
|
|
113
114
|
const [popupLocation, setPopupLocation] = useState<{
|
|
@@ -345,7 +346,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
345
346
|
type="submit"
|
|
346
347
|
disabled={disabled}
|
|
347
348
|
>
|
|
348
|
-
|
|
349
|
+
{t("save")}
|
|
349
350
|
</Button>
|
|
350
351
|
</DialogActions>
|
|
351
352
|
|
|
@@ -4,6 +4,7 @@ import { useSortable } from "@dnd-kit/sortable";
|
|
|
4
4
|
import { CSS } from "@dnd-kit/utilities";
|
|
5
5
|
import { CircularProgress, cls } from "@firecms/ui";
|
|
6
6
|
import { BoardItem, BoardItemViewProps } from "./board_types";
|
|
7
|
+
import { useTranslation } from "../../hooks";
|
|
7
8
|
|
|
8
9
|
interface BoardSortableListProps<M extends Record<string, any>> {
|
|
9
10
|
columnId: string;
|
|
@@ -26,6 +27,7 @@ export function BoardSortableList<M extends Record<string, any>>({
|
|
|
26
27
|
hasMore = false,
|
|
27
28
|
onLoadMore,
|
|
28
29
|
}: BoardSortableListProps<M>) {
|
|
30
|
+
const { t } = useTranslation();
|
|
29
31
|
const {
|
|
30
32
|
setNodeRef,
|
|
31
33
|
} = useDroppable({
|
|
@@ -97,7 +99,7 @@ export function BoardSortableList<M extends Record<string, any>>({
|
|
|
97
99
|
{items.length === 0 && !loading ? (
|
|
98
100
|
<div className="flex-1 flex items-center justify-center">
|
|
99
101
|
<span className="text-xs text-surface-400 dark:text-surface-500">
|
|
100
|
-
|
|
102
|
+
{t("no_items")}
|
|
101
103
|
</span>
|
|
102
104
|
</div>
|
|
103
105
|
) : (
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Typography, IconButton, RefreshIcon, Button, Tooltip } from "@firecms/ui";
|
|
3
|
+
import { useTranslation } from "../../hooks";
|
|
4
|
+
|
|
5
|
+
export function CollectionDataErrorBanner({ error, onRetry }: { error?: Error, onRetry?: () => void }) {
|
|
6
|
+
const { t } = useTranslation();
|
|
7
|
+
if (!error) return null;
|
|
8
|
+
|
|
9
|
+
const errorMessage = error.message || "";
|
|
10
|
+
// Only extract standard Firestore index errors using the standard matching pattern
|
|
11
|
+
const indexUrl = errorMessage.match(/https:\/\/console\.firebase\.google\.com[^\s]+/)?.[0];
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className="flex w-full items-center gap-4 px-4 py-3 bg-red-50 dark:bg-red-900/20 border-b border-red-200 dark:border-red-800">
|
|
15
|
+
<Typography variant="body2" className="text-red-700 dark:text-red-300 flex-1 break-words">
|
|
16
|
+
<strong>{t("error")}:</strong>{" "}
|
|
17
|
+
{indexUrl
|
|
18
|
+
? t("error_firestore_index")
|
|
19
|
+
: errorMessage}
|
|
20
|
+
</Typography>
|
|
21
|
+
{onRetry && (
|
|
22
|
+
<Tooltip title={t("refresh_data")}>
|
|
23
|
+
<IconButton
|
|
24
|
+
size="small"
|
|
25
|
+
onClick={onRetry}
|
|
26
|
+
>
|
|
27
|
+
<RefreshIcon size="small" />
|
|
28
|
+
</IconButton>
|
|
29
|
+
</Tooltip>
|
|
30
|
+
)}
|
|
31
|
+
{indexUrl && (
|
|
32
|
+
<Button
|
|
33
|
+
size="small"
|
|
34
|
+
variant="outlined"
|
|
35
|
+
color="error"
|
|
36
|
+
onClick={() => window.open(indexUrl, "_blank")}
|
|
37
|
+
>
|
|
38
|
+
{t("create_index")}
|
|
39
|
+
</Button>
|
|
40
|
+
)}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|