@firecms/core 3.0.0-canary.187 → 3.0.0-canary.188
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/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/index.es.js +186 -154
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +185 -153
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -5
- package/src/core/EntityForm.tsx +8 -4
- package/src/form/components/StorageUploadProgress.tsx +1 -1
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +8 -5
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +5 -3
- package/src/preview/components/UrlComponentPreview.tsx +17 -18
- package/src/util/entity_cache.ts +0 -1
- package/src/util/useStorageUploadController.tsx +39 -21
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.188",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
54
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
55
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
53
|
+
"@firecms/editor": "^3.0.0-canary.188",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.188",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.188",
|
|
56
56
|
"@hello-pangea/dnd": "^17.0.0",
|
|
57
57
|
"@radix-ui/react-portal": "^1.1.3",
|
|
58
58
|
"clsx": "^2.1.1",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"dist",
|
|
105
105
|
"src"
|
|
106
106
|
],
|
|
107
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "12b6a7c4cb3e88d900d169f4903cc8fbfb7c08ba",
|
|
108
108
|
"publishConfig": {
|
|
109
109
|
"access": "public"
|
|
110
110
|
},
|
package/src/core/EntityForm.tsx
CHANGED
|
@@ -891,10 +891,14 @@ function buildBottomActions<M extends object>({
|
|
|
891
891
|
{status === "copy" && "Create copy"}
|
|
892
892
|
{status === "new" && "Create"}
|
|
893
893
|
</Button>
|
|
894
|
-
{canClose && <LoadingButton variant="filled"
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
894
|
+
{canClose && <LoadingButton variant="filled"
|
|
895
|
+
color="primary"
|
|
896
|
+
type="submit"
|
|
897
|
+
loading={isSubmitting}
|
|
898
|
+
disabled={disabled}
|
|
899
|
+
onClick={() => {
|
|
900
|
+
setPendingClose?.(true);
|
|
901
|
+
}}>
|
|
898
902
|
{status === "existing" && "Save and close"}
|
|
899
903
|
{status === "copy" && "Create copy and close"}
|
|
900
904
|
{status === "new" && "Create and close"}
|
|
@@ -92,7 +92,7 @@ export function StorageUploadProgress({
|
|
|
92
92
|
`min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
|
|
93
93
|
|
|
94
94
|
{loading &&
|
|
95
|
-
<Skeleton className="w-full h-full"/>}
|
|
95
|
+
<Skeleton className="m-4 w-full h-full"/>}
|
|
96
96
|
|
|
97
97
|
{error && <ErrorView title={"Error uploading file"}
|
|
98
98
|
error={error}/>}
|
|
@@ -3,13 +3,14 @@ import {
|
|
|
3
3
|
FieldHelperText,
|
|
4
4
|
FieldProps,
|
|
5
5
|
getIconForProperty,
|
|
6
|
-
LabelWithIconAndTooltip,
|
|
6
|
+
LabelWithIconAndTooltip,
|
|
7
|
+
PropertyOrBuilder,
|
|
7
8
|
randomString,
|
|
8
9
|
ResolvedArrayProperty,
|
|
9
10
|
ResolvedStringProperty,
|
|
10
11
|
useStorageSource
|
|
11
12
|
} from "../../index";
|
|
12
|
-
import { cls, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
|
|
13
|
+
import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
|
|
13
14
|
import { FireCMSEditor, FireCMSEditorProps } from "@firecms/editor";
|
|
14
15
|
import { resolveProperty, resolveStorageFilenameString, resolveStoragePathString } from "../../util";
|
|
15
16
|
|
|
@@ -27,11 +28,13 @@ export function MarkdownEditorFieldBinding({
|
|
|
27
28
|
showError,
|
|
28
29
|
error,
|
|
29
30
|
minimalistView,
|
|
31
|
+
disabled: disabledProp,
|
|
30
32
|
isSubmitting,
|
|
31
33
|
context,
|
|
32
34
|
customProps,
|
|
33
35
|
}: FieldProps<string, MarkdownEditorFieldProps>) {
|
|
34
36
|
|
|
37
|
+
const disabled = disabledProp || isSubmitting;
|
|
35
38
|
const highlight = customProps?.highlight;
|
|
36
39
|
const editorProps = customProps?.editorProps;
|
|
37
40
|
const storageSource = useStorageSource();
|
|
@@ -54,11 +57,9 @@ export function MarkdownEditorFieldBinding({
|
|
|
54
57
|
if (internalValue.current !== value) {
|
|
55
58
|
internalValue.current = value;
|
|
56
59
|
setFieldVersion(fieldVersion + 1);
|
|
57
|
-
// fieldVersion.current = fieldVersion.current + 1;
|
|
58
60
|
}
|
|
59
61
|
}, [value]);
|
|
60
62
|
|
|
61
|
-
|
|
62
63
|
const resolvedProperty = resolveProperty({
|
|
63
64
|
propertyOrBuilder: property as PropertyOrBuilder,
|
|
64
65
|
values: entityValues
|
|
@@ -107,6 +108,7 @@ export function MarkdownEditorFieldBinding({
|
|
|
107
108
|
onMarkdownContentChange={onContentChange}
|
|
108
109
|
version={context.formex.version + fieldVersion}
|
|
109
110
|
highlight={highlight}
|
|
111
|
+
disabled={disabled}
|
|
110
112
|
handleImageUpload={async (file: File) => {
|
|
111
113
|
const storagePath = storagePathBuilder(file);
|
|
112
114
|
const fileName = await fileNameBuilder(file);
|
|
@@ -136,7 +138,8 @@ export function MarkdownEditorFieldBinding({
|
|
|
136
138
|
required={property.validation?.required}
|
|
137
139
|
title={property.name}
|
|
138
140
|
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
139
|
-
<div
|
|
141
|
+
<div
|
|
142
|
+
className={cls("rounded-md", fieldBackgroundMixin, disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin)}>
|
|
140
143
|
{editor}
|
|
141
144
|
</div>
|
|
142
145
|
<FieldHelperText includeDescription={includeDescription}
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
29
29
|
|
|
30
30
|
const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
|
|
31
|
-
const disabledClasses =
|
|
31
|
+
const disabledClasses = fieldBackgroundDisabledMixin;
|
|
32
32
|
const nonActiveDropClasses = fieldBackgroundHoverMixin
|
|
33
33
|
const activeDropClasses = "pt-0 border-2 border-solid"
|
|
34
34
|
const acceptDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500"
|
|
@@ -206,6 +206,7 @@ function FileDropComponent({
|
|
|
206
206
|
className={cls(
|
|
207
207
|
fieldBackgroundMixin,
|
|
208
208
|
disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
|
|
209
|
+
disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "",
|
|
209
210
|
dropZoneClasses,
|
|
210
211
|
multipleFilesSupported && internalValue.length ? "" : "flex",
|
|
211
212
|
{
|
|
@@ -248,7 +249,7 @@ function FileDropComponent({
|
|
|
248
249
|
metadata={metadata}
|
|
249
250
|
storagePath={storagePathBuilder(entry.file)}
|
|
250
251
|
onFileUploadComplete={onFileUploadComplete}
|
|
251
|
-
imageSize={size === "
|
|
252
|
+
imageSize={size === "large" ? 220 : 118}
|
|
252
253
|
simple={false}
|
|
253
254
|
/>
|
|
254
255
|
);
|
|
@@ -285,7 +286,8 @@ function FileDropComponent({
|
|
|
285
286
|
<div
|
|
286
287
|
className="flex-grow min-h-[38px] box-border m-2 text-center">
|
|
287
288
|
<Typography align={"center"}
|
|
288
|
-
variant={"label"}
|
|
289
|
+
variant={"label"}
|
|
290
|
+
className={disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : ""}>
|
|
289
291
|
{helpText}
|
|
290
292
|
</Typography>
|
|
291
293
|
</div>
|
|
@@ -55,24 +55,23 @@ export function UrlComponentPreview({
|
|
|
55
55
|
return <VideoPreview size={size} src={url} interactive={interactive}/>;
|
|
56
56
|
} else {
|
|
57
57
|
return (
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
</a>
|
|
58
|
+
<Tooltip title={hint}>
|
|
59
|
+
<a
|
|
60
|
+
href={url}
|
|
61
|
+
rel="noopener noreferrer"
|
|
62
|
+
target="_blank"
|
|
63
|
+
onClick={(e) => e.stopPropagation()}
|
|
64
|
+
className="flex flex-col items-center justify-center"
|
|
65
|
+
style={{
|
|
66
|
+
width: getThumbnailMeasure(size),
|
|
67
|
+
height: getThumbnailMeasure(size)
|
|
68
|
+
}}>
|
|
69
|
+
<DescriptionIcon className="text-surface-700 dark:text-surface-300"/>
|
|
70
|
+
{hint && <Typography
|
|
71
|
+
className="max-w-full truncate rtl text-left"
|
|
72
|
+
variant={"caption"}>{hint}</Typography>}
|
|
73
|
+
</a>
|
|
74
|
+
</Tooltip>
|
|
76
75
|
);
|
|
77
76
|
}
|
|
78
77
|
}
|
package/src/util/entity_cache.ts
CHANGED
|
@@ -101,7 +101,6 @@ export function saveEntityToCache(path: string, data: object): void {
|
|
|
101
101
|
if (isLocalStorageAvailable) {
|
|
102
102
|
try {
|
|
103
103
|
const key = LOCAL_STORAGE_PREFIX + path;
|
|
104
|
-
console.log("Saving entity to cache", key, data);
|
|
105
104
|
const entityString = JSON.stringify(data, customReplacer);
|
|
106
105
|
localStorage.setItem(key, entityString);
|
|
107
106
|
} catch (error) {
|
|
@@ -34,6 +34,7 @@ export interface StorageFieldItem {
|
|
|
34
34
|
size: PreviewSize
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
|
|
37
38
|
export function useStorageUploadController<M extends object>({
|
|
38
39
|
entityId,
|
|
39
40
|
entityValues,
|
|
@@ -45,17 +46,17 @@ export function useStorageUploadController<M extends object>({
|
|
|
45
46
|
disabled,
|
|
46
47
|
onChange
|
|
47
48
|
}:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
{
|
|
50
|
+
entityId: string,
|
|
51
|
+
entityValues: EntityValues<M>,
|
|
52
|
+
value: string | string[] | null;
|
|
53
|
+
path?: string,
|
|
54
|
+
propertyKey: string,
|
|
55
|
+
property: StringProperty | ArrayProperty<string[]> | ResolvedStringProperty | ResolvedArrayProperty<string[]>,
|
|
56
|
+
storageSource: StorageSource,
|
|
57
|
+
disabled: boolean,
|
|
58
|
+
onChange: (value: string | string[] | null) => void
|
|
59
|
+
}) {
|
|
59
60
|
|
|
60
61
|
const storage: StorageConfig | undefined = property.dataType === "string"
|
|
61
62
|
? property.storage
|
|
@@ -75,16 +76,7 @@ export function useStorageUploadController<M extends object>({
|
|
|
75
76
|
const compression: ImageCompression | undefined = storage?.imageCompression;
|
|
76
77
|
|
|
77
78
|
const internalInitialValue: StorageFieldItem[] =
|
|
78
|
-
(multipleFilesSupported
|
|
79
|
-
? (value ?? []) as string[]
|
|
80
|
-
: value ? [value as string] : []).map(entry => (
|
|
81
|
-
{
|
|
82
|
-
id: getRandomId(),
|
|
83
|
-
storagePathOrDownloadUrl: entry,
|
|
84
|
-
metadata,
|
|
85
|
-
size
|
|
86
|
-
}
|
|
87
|
-
));
|
|
79
|
+
getInternalInitialValue(multipleFilesSupported, value, metadata, size);
|
|
88
80
|
|
|
89
81
|
const [initialValue, setInitialValue] = useState<string | string[] | null>(value);
|
|
90
82
|
const [internalValue, setInternalValue] = useState<StorageFieldItem[]>(internalInitialValue);
|
|
@@ -226,6 +218,32 @@ export function useStorageUploadController<M extends object>({
|
|
|
226
218
|
}
|
|
227
219
|
}
|
|
228
220
|
|
|
221
|
+
function getInternalInitialValue(multipleFilesSupported: boolean,
|
|
222
|
+
value: string | string[] | null,
|
|
223
|
+
metadata: Record<string, any> | undefined,
|
|
224
|
+
size: PreviewSize): StorageFieldItem[] {
|
|
225
|
+
let strings: string[] = [];
|
|
226
|
+
if (multipleFilesSupported) {
|
|
227
|
+
if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
|
|
228
|
+
strings = (value ?? []) as string[];
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
if (typeof value === "string") {
|
|
232
|
+
strings = value ? [value as string] : [];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return strings
|
|
237
|
+
.map(entry => (
|
|
238
|
+
{
|
|
239
|
+
id: getRandomId(),
|
|
240
|
+
storagePathOrDownloadUrl: entry,
|
|
241
|
+
metadata,
|
|
242
|
+
size
|
|
243
|
+
}
|
|
244
|
+
));
|
|
245
|
+
}
|
|
246
|
+
|
|
229
247
|
function removeDuplicates(items: StorageFieldItem[]) {
|
|
230
248
|
return items.filter(
|
|
231
249
|
(item, i) => {
|