@firecms/core 3.0.0-canary.126 → 3.0.0-canary.128
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/README.md +1 -1
- package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
- package/dist/components/EntityCollectionView/utils.d.ts +3 -0
- package/dist/components/EntityPreview.d.ts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/hooks/useProjectLog.d.ts +7 -1
- package/dist/index.es.js +123 -60
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +123 -60
- package/dist/index.umd.js.map +1 -1
- package/dist/types/firecms.d.ts +4 -0
- package/package.json +5 -5
- package/src/components/ArrayContainer.tsx +1 -1
- package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +1 -1
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +66 -39
- package/src/components/EntityCollectionView/utils.ts +19 -0
- package/src/components/EntityPreview.tsx +1 -1
- package/src/components/common/default_entity_actions.tsx +4 -0
- package/src/components/index.tsx +1 -1
- package/src/core/FireCMS.tsx +15 -6
- package/src/hooks/useProjectLog.tsx +16 -5
- package/src/types/firecms.tsx +5 -0
- package/src/util/make_properties_editable.ts +13 -5
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<h1 align="center">FireCMS</h1>
|
|
12
|
-
<h3 align="center">Awesome Firebase/
|
|
12
|
+
<h3 align="center">Awesome Firebase/MongoDB-based headless CMS</h3>
|
|
13
13
|
<p align="center"><a href="https://demo.firecms.co">Live demo</a></p>
|
|
14
14
|
|
|
15
15
|
<br />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function ConfirmationDialog({ open, onAccept, onCancel, title, loading, body }: {
|
|
3
3
|
open: boolean;
|
|
4
4
|
onAccept: () => void;
|
|
5
5
|
onCancel: () => void;
|
|
@@ -18,7 +18,7 @@ export * from "./EntityCollectionTable";
|
|
|
18
18
|
export * from "./NotFoundPage";
|
|
19
19
|
export * from "./VirtualTable";
|
|
20
20
|
export * from "./ErrorBoundary";
|
|
21
|
-
export * from "./
|
|
21
|
+
export * from "./ConfirmationDialog";
|
|
22
22
|
export * from "./FireCMSLogo";
|
|
23
23
|
export * from "../core/DefaultAppBar";
|
|
24
24
|
export * from "./ArrayContainer";
|
|
@@ -5,4 +5,10 @@ export type AccessResponse = {
|
|
|
5
5
|
blocked?: boolean;
|
|
6
6
|
message?: string;
|
|
7
7
|
};
|
|
8
|
-
export
|
|
8
|
+
export interface UseProjectLogParams {
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
authController: AuthController;
|
|
11
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
12
|
+
plugins?: FireCMSPlugin<any, any, any>[];
|
|
13
|
+
}
|
|
14
|
+
export declare function useProjectLog({ authController, dataSourceDelegate, plugins, apiKey }: UseProjectLogParams): AccessResponse | null;
|
package/dist/index.es.js
CHANGED
|
@@ -2960,9 +2960,11 @@ function getArrayValuesCount(array) {
|
|
|
2960
2960
|
function makePropertiesEditable(properties) {
|
|
2961
2961
|
Object.keys(properties).forEach((key) => {
|
|
2962
2962
|
const property = properties[key];
|
|
2963
|
-
property
|
|
2964
|
-
|
|
2965
|
-
|
|
2963
|
+
if (property) {
|
|
2964
|
+
property.editable = true;
|
|
2965
|
+
if (property.dataType === "map" && property.properties) {
|
|
2966
|
+
makePropertiesEditable(property.properties);
|
|
2967
|
+
}
|
|
2966
2968
|
}
|
|
2967
2969
|
});
|
|
2968
2970
|
return properties;
|
|
@@ -2970,13 +2972,19 @@ function makePropertiesEditable(properties) {
|
|
|
2970
2972
|
function makePropertiesNonEditable(properties) {
|
|
2971
2973
|
return Object.entries(properties).reduce((acc, [key, property]) => {
|
|
2972
2974
|
if (!isPropertyBuilder(property) && property.dataType === "map" && property.properties) {
|
|
2973
|
-
const updated = {
|
|
2975
|
+
const updated = {
|
|
2976
|
+
...property,
|
|
2977
|
+
properties: makePropertiesNonEditable(property.properties)
|
|
2978
|
+
};
|
|
2974
2979
|
acc[key] = updated;
|
|
2975
2980
|
}
|
|
2976
2981
|
if (isPropertyBuilder(property)) {
|
|
2977
2982
|
acc[key] = property;
|
|
2978
2983
|
} else {
|
|
2979
|
-
acc[key] = {
|
|
2984
|
+
acc[key] = {
|
|
2985
|
+
...property,
|
|
2986
|
+
editable: false
|
|
2987
|
+
};
|
|
2980
2988
|
}
|
|
2981
2989
|
return acc;
|
|
2982
2990
|
}, {});
|
|
@@ -10782,6 +10790,23 @@ function DeleteEntityDialog({
|
|
|
10782
10790
|
}
|
|
10783
10791
|
);
|
|
10784
10792
|
}
|
|
10793
|
+
function addRecentId(collectionId, id) {
|
|
10794
|
+
const recentIds = getRecentIds(collectionId);
|
|
10795
|
+
const newRecentIds = [id, ...recentIds.filter((i) => i !== id)];
|
|
10796
|
+
if (newRecentIds.length > 5) {
|
|
10797
|
+
newRecentIds.pop();
|
|
10798
|
+
}
|
|
10799
|
+
saveSearchedIdsLocally(collectionId, newRecentIds);
|
|
10800
|
+
return newRecentIds;
|
|
10801
|
+
}
|
|
10802
|
+
function saveSearchedIdsLocally(collectionId, ids) {
|
|
10803
|
+
localStorage.setItem("recent_id_searches::" + collectionId, JSON.stringify(ids));
|
|
10804
|
+
}
|
|
10805
|
+
function getRecentIds(collectionId) {
|
|
10806
|
+
const stored = localStorage.getItem("recent_id_searches::" + collectionId);
|
|
10807
|
+
if (!stored) return [];
|
|
10808
|
+
return JSON.parse(stored);
|
|
10809
|
+
}
|
|
10785
10810
|
const editEntityAction = {
|
|
10786
10811
|
icon: /* @__PURE__ */ jsx(KeyboardTabIcon, {}),
|
|
10787
10812
|
name: "Edit",
|
|
@@ -10799,6 +10824,9 @@ const editEntityAction = {
|
|
|
10799
10824
|
path: entity.path,
|
|
10800
10825
|
entityId: entity.id
|
|
10801
10826
|
});
|
|
10827
|
+
if (collection) {
|
|
10828
|
+
addRecentId(collection.id, entity.id);
|
|
10829
|
+
}
|
|
10802
10830
|
const path = collection?.collectionGroup ? entity.path : fullPath ?? entity.path;
|
|
10803
10831
|
context.sideEntityController.open({
|
|
10804
10832
|
entityId: entity.id,
|
|
@@ -12837,6 +12865,7 @@ function EntityIdHeaderWidget({
|
|
|
12837
12865
|
}) {
|
|
12838
12866
|
const [openPopup, setOpenPopup] = React__default.useState(false);
|
|
12839
12867
|
const [searchString, setSearchString] = React__default.useState("");
|
|
12868
|
+
const [recentIds, setRecentIds] = React__default.useState(getRecentIds(collection.id));
|
|
12840
12869
|
const sideEntityController = useSideEntityController();
|
|
12841
12870
|
return /* @__PURE__ */ jsx(Tooltip, { title: !openPopup ? "Find by ID" : void 0, asChild: false, children: /* @__PURE__ */ jsx(
|
|
12842
12871
|
Popover,
|
|
@@ -12847,47 +12876,69 @@ function EntityIdHeaderWidget({
|
|
|
12847
12876
|
align: "start",
|
|
12848
12877
|
alignOffset: -117,
|
|
12849
12878
|
trigger: /* @__PURE__ */ jsx(IconButton, { size: "small", children: /* @__PURE__ */ jsx(SearchIcon, { size: "small" }) }),
|
|
12850
|
-
children: /* @__PURE__ */
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
e
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12879
|
+
children: /* @__PURE__ */ jsxs("div", { className: cls("my-2 rounded-lg bg-gray-50 dark:bg-gray-950 text-gray-900 dark:text-white"), children: [
|
|
12880
|
+
/* @__PURE__ */ jsx(
|
|
12881
|
+
"form",
|
|
12882
|
+
{
|
|
12883
|
+
noValidate: true,
|
|
12884
|
+
onSubmit: (e) => {
|
|
12885
|
+
e.preventDefault();
|
|
12886
|
+
if (!searchString) return;
|
|
12887
|
+
setOpenPopup(false);
|
|
12888
|
+
setRecentIds(addRecentId(collection.id, searchString.trim()));
|
|
12889
|
+
return sideEntityController.open({
|
|
12890
|
+
entityId: searchString.trim(),
|
|
12891
|
+
path,
|
|
12892
|
+
collection,
|
|
12893
|
+
updateUrl: true
|
|
12894
|
+
});
|
|
12895
|
+
},
|
|
12896
|
+
className: "w-96 max-w-full",
|
|
12897
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex p-2 w-full gap-2", children: [
|
|
12898
|
+
/* @__PURE__ */ jsx(
|
|
12899
|
+
"input",
|
|
12900
|
+
{
|
|
12901
|
+
autoFocus: openPopup,
|
|
12902
|
+
placeholder: "Find entity by ID",
|
|
12903
|
+
onChange: (e) => {
|
|
12904
|
+
setSearchString(e.target.value);
|
|
12905
|
+
},
|
|
12906
|
+
value: searchString,
|
|
12907
|
+
className: "rounded-lg bg-white dark:bg-gray-800 flex-grow bg-transparent outline-none p-2 " + focusedDisabled
|
|
12908
|
+
}
|
|
12909
|
+
),
|
|
12910
|
+
/* @__PURE__ */ jsx(
|
|
12911
|
+
Button,
|
|
12912
|
+
{
|
|
12913
|
+
variant: "text",
|
|
12914
|
+
disabled: !searchString.trim(),
|
|
12915
|
+
type: "submit",
|
|
12916
|
+
children: /* @__PURE__ */ jsx(KeyboardTabIcon, {})
|
|
12917
|
+
}
|
|
12918
|
+
)
|
|
12919
|
+
] })
|
|
12920
|
+
}
|
|
12921
|
+
),
|
|
12922
|
+
recentIds && recentIds.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 p-2", children: recentIds.map((id) => /* @__PURE__ */ jsx(
|
|
12923
|
+
ReferencePreview,
|
|
12924
|
+
{
|
|
12925
|
+
reference: new EntityReference(id, path),
|
|
12926
|
+
hover: true,
|
|
12927
|
+
onClick: () => {
|
|
12928
|
+
setOpenPopup(false);
|
|
12929
|
+
sideEntityController.open({
|
|
12930
|
+
entityId: id,
|
|
12931
|
+
path,
|
|
12932
|
+
collection,
|
|
12933
|
+
updateUrl: true
|
|
12934
|
+
});
|
|
12935
|
+
},
|
|
12936
|
+
includeEntityLink: false,
|
|
12937
|
+
size: "small"
|
|
12864
12938
|
},
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
"input",
|
|
12869
|
-
{
|
|
12870
|
-
autoFocus: openPopup,
|
|
12871
|
-
placeholder: "Find entity by ID",
|
|
12872
|
-
onChange: (e) => {
|
|
12873
|
-
setSearchString(e.target.value);
|
|
12874
|
-
},
|
|
12875
|
-
value: searchString,
|
|
12876
|
-
className: "flex-grow bg-transparent outline-none p-1 " + focusedDisabled
|
|
12877
|
-
}
|
|
12878
|
-
),
|
|
12879
|
-
/* @__PURE__ */ jsx(
|
|
12880
|
-
Button,
|
|
12881
|
-
{
|
|
12882
|
-
variant: "outlined",
|
|
12883
|
-
disabled: !searchString.trim(),
|
|
12884
|
-
type: "submit",
|
|
12885
|
-
children: "Go"
|
|
12886
|
-
}
|
|
12887
|
-
)
|
|
12888
|
-
] })
|
|
12889
|
-
}
|
|
12890
|
-
)
|
|
12939
|
+
id
|
|
12940
|
+
)) })
|
|
12941
|
+
] })
|
|
12891
12942
|
}
|
|
12892
12943
|
) });
|
|
12893
12944
|
}
|
|
@@ -12982,7 +13033,7 @@ function NotFoundPage() {
|
|
|
12982
13033
|
}
|
|
12983
13034
|
) });
|
|
12984
13035
|
}
|
|
12985
|
-
function
|
|
13036
|
+
function ConfirmationDialog({
|
|
12986
13037
|
open,
|
|
12987
13038
|
onAccept,
|
|
12988
13039
|
onCancel,
|
|
@@ -13517,7 +13568,7 @@ function ArrayItemOptions({
|
|
|
13517
13568
|
return /* @__PURE__ */ jsx(
|
|
13518
13569
|
"div",
|
|
13519
13570
|
{
|
|
13520
|
-
className: `pl-2 pt-1 pb-
|
|
13571
|
+
className: `pl-2 pt-1 pb-1 flex ${direction === "row" ? "flex-row-reverse" : "flex-col"} items-center`,
|
|
13521
13572
|
ref: iconRef,
|
|
13522
13573
|
...provided.dragHandleProps,
|
|
13523
13574
|
children: /* @__PURE__ */ jsxs(
|
|
@@ -19005,7 +19056,7 @@ function useBuildDataSource({
|
|
|
19005
19056
|
};
|
|
19006
19057
|
}
|
|
19007
19058
|
const DEFAULT_SERVER = "https://api-drplyi3b6q-ey.a.run.app";
|
|
19008
|
-
async function makeRequest(authController, dataSourceKey, pluginKeys) {
|
|
19059
|
+
async function makeRequest(authController, dataSourceKey, pluginKeys, apiKey) {
|
|
19009
19060
|
let idToken;
|
|
19010
19061
|
try {
|
|
19011
19062
|
idToken = await authController.getAuthToken();
|
|
@@ -19022,6 +19073,7 @@ async function makeRequest(authController, dataSourceKey, pluginKeys) {
|
|
|
19022
19073
|
Authorization: `Basic ${idToken}`
|
|
19023
19074
|
},
|
|
19024
19075
|
body: JSON.stringify({
|
|
19076
|
+
apiKey,
|
|
19025
19077
|
email: authController.user?.email ?? null,
|
|
19026
19078
|
datasource: dataSourceKey,
|
|
19027
19079
|
plugins: pluginKeys
|
|
@@ -19031,14 +19083,19 @@ async function makeRequest(authController, dataSourceKey, pluginKeys) {
|
|
|
19031
19083
|
return res.json();
|
|
19032
19084
|
});
|
|
19033
19085
|
}
|
|
19034
|
-
function useProjectLog(
|
|
19086
|
+
function useProjectLog({
|
|
19087
|
+
authController,
|
|
19088
|
+
dataSourceDelegate,
|
|
19089
|
+
plugins,
|
|
19090
|
+
apiKey
|
|
19091
|
+
}) {
|
|
19035
19092
|
const [accessResponse, setAccessResponse] = useState(null);
|
|
19036
19093
|
const accessedUserRef = useRef(null);
|
|
19037
19094
|
const dataSourceKey = dataSourceDelegate.key;
|
|
19038
19095
|
const pluginKeys = plugins?.map((plugin) => plugin.key);
|
|
19039
19096
|
useEffect(() => {
|
|
19040
19097
|
if (authController.user && authController.user.uid !== accessedUserRef.current && !authController.initialLoading) {
|
|
19041
|
-
makeRequest(authController, dataSourceKey, pluginKeys).then(setAccessResponse);
|
|
19098
|
+
makeRequest(authController, dataSourceKey, pluginKeys, apiKey).then(setAccessResponse);
|
|
19042
19099
|
accessedUserRef.current = authController.user.uid;
|
|
19043
19100
|
}
|
|
19044
19101
|
}, [authController, dataSourceKey, pluginKeys]);
|
|
@@ -19059,7 +19116,8 @@ function FireCMS(props) {
|
|
|
19059
19116
|
propertyConfigs,
|
|
19060
19117
|
entityViews,
|
|
19061
19118
|
components,
|
|
19062
|
-
navigationController
|
|
19119
|
+
navigationController,
|
|
19120
|
+
apiKey
|
|
19063
19121
|
} = props;
|
|
19064
19122
|
useLocaleConfig(locale);
|
|
19065
19123
|
const dataSource = useBuildDataSource({
|
|
@@ -19083,7 +19141,15 @@ function FireCMS(props) {
|
|
|
19083
19141
|
const analyticsController = useMemo(() => ({
|
|
19084
19142
|
onAnalyticsEvent
|
|
19085
19143
|
}), []);
|
|
19086
|
-
const accessResponse = useProjectLog(
|
|
19144
|
+
const accessResponse = useProjectLog({
|
|
19145
|
+
apiKey,
|
|
19146
|
+
authController,
|
|
19147
|
+
dataSourceDelegate,
|
|
19148
|
+
plugins
|
|
19149
|
+
});
|
|
19150
|
+
if (accessResponse?.message) {
|
|
19151
|
+
console.warn(accessResponse.message);
|
|
19152
|
+
}
|
|
19087
19153
|
if (navigationController.navigationLoadingError) {
|
|
19088
19154
|
return /* @__PURE__ */ jsx(CenteredView, { maxWidth: "md", children: /* @__PURE__ */ jsx(
|
|
19089
19155
|
ErrorView,
|
|
@@ -19103,10 +19169,10 @@ function FireCMS(props) {
|
|
|
19103
19169
|
) });
|
|
19104
19170
|
}
|
|
19105
19171
|
if (accessResponse?.blocked) {
|
|
19106
|
-
return /* @__PURE__ */ jsxs(CenteredView, { maxWidth: "md", fullScreen: true, children: [
|
|
19107
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", children: "
|
|
19172
|
+
return /* @__PURE__ */ jsxs(CenteredView, { maxWidth: "md", fullScreen: true, className: "flex flex-col gap-2", children: [
|
|
19173
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", gutterBottom: true, children: "License needed" }),
|
|
19108
19174
|
/* @__PURE__ */ jsxs(Typography, { children: [
|
|
19109
|
-
"
|
|
19175
|
+
"You need a valid license to use FireCMS PRO. Please reach out at ",
|
|
19110
19176
|
/* @__PURE__ */ jsx(
|
|
19111
19177
|
"a",
|
|
19112
19178
|
{
|
|
@@ -19116,10 +19182,7 @@ function FireCMS(props) {
|
|
|
19116
19182
|
),
|
|
19117
19183
|
" for more information."
|
|
19118
19184
|
] }),
|
|
19119
|
-
accessResponse?.message && /* @__PURE__ */
|
|
19120
|
-
"Response from the server: ",
|
|
19121
|
-
accessResponse?.message
|
|
19122
|
-
] })
|
|
19185
|
+
accessResponse?.message && /* @__PURE__ */ jsx(Typography, { children: accessResponse?.message })
|
|
19123
19186
|
] });
|
|
19124
19187
|
}
|
|
19125
19188
|
return /* @__PURE__ */ jsx(AnalyticsContext.Provider, { value: analyticsController, children: /* @__PURE__ */ jsx(CustomizationControllerContext.Provider, { value: customizationController, children: /* @__PURE__ */ jsx(
|
|
@@ -19752,6 +19815,7 @@ export {
|
|
|
19752
19815
|
BooleanPreview,
|
|
19753
19816
|
COLLECTION_PATH_SEPARATOR,
|
|
19754
19817
|
CircularProgressCenter,
|
|
19818
|
+
ConfirmationDialog,
|
|
19755
19819
|
DEFAULT_FIELD_CONFIGS,
|
|
19756
19820
|
DRAWER_WIDTH,
|
|
19757
19821
|
DatePreview,
|
|
@@ -19759,7 +19823,6 @@ export {
|
|
|
19759
19823
|
DefaultAppBar,
|
|
19760
19824
|
DefaultDrawer,
|
|
19761
19825
|
DefaultHomePage,
|
|
19762
|
-
DeleteConfirmationDialog,
|
|
19763
19826
|
Drawer,
|
|
19764
19827
|
DrawerLogo,
|
|
19765
19828
|
DrawerNavigationItem,
|