@rulab/adminjs-components 0.1.0-alpha.8 → 0.1.0-beta.1
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/ColorStatus/ColorStatusEdit.d.ts +2 -2
- package/dist/components/ColorStatus/ColorStatusEdit.js +3 -3
- package/dist/components/ColorStatus/ColorStatusFeature.d.ts +9 -0
- package/dist/components/ColorStatus/ColorStatusFeature.js +23 -0
- package/dist/components/ColorStatus/ColorStatusList.d.ts +1 -1
- package/dist/components/ColorStatus/ColorStatusList.js +4 -2
- package/dist/components/ColorStatus/ColorStatusShow.d.ts +1 -1
- package/dist/components/ColorStatus/ColorStatusShow.js +5 -3
- package/dist/components/ColorStatus/index.d.ts +4 -3
- package/dist/components/ColorStatus/index.js +4 -3
- package/dist/components/ColorStatus/styles.js +2 -1
- package/dist/components/Editor/Editor.d.ts +4 -2
- package/dist/components/Editor/Editor.js +79 -16
- package/dist/components/Editor/EditorFeature.d.ts +10 -0
- package/dist/components/Editor/EditorFeature.js +82 -0
- package/dist/components/Editor/EditorList.d.ts +2 -2
- package/dist/components/Editor/EditorList.js +1 -1
- package/dist/components/Editor/EditorShow.d.ts +2 -2
- package/dist/components/Editor/EditorShow.js +2 -2
- package/dist/components/Editor/index.d.ts +4 -3
- package/dist/components/Editor/index.js +4 -3
- package/dist/components/FeatureTabs/FeatureTabsEdit.d.ts +4 -0
- package/dist/components/FeatureTabs/FeatureTabsEdit.js +105 -0
- package/dist/components/FeatureTabs/FeatureTabsFeature.d.ts +8 -0
- package/dist/components/FeatureTabs/FeatureTabsFeature.js +28 -0
- package/dist/components/FeatureTabs/FeatureTabsShow.d.ts +4 -0
- package/dist/components/FeatureTabs/FeatureTabsShow.js +61 -0
- package/dist/components/FeatureTabs/index.d.ts +4 -0
- package/dist/components/FeatureTabs/index.js +4 -0
- package/dist/components/Preview/PreviewAction.d.ts +4 -0
- package/dist/components/Preview/PreviewAction.js +22 -0
- package/dist/components/Preview/PreviewFeature.d.ts +9 -0
- package/dist/components/Preview/PreviewFeature.js +31 -0
- package/dist/components/Preview/index.d.ts +2 -0
- package/dist/components/Preview/index.js +2 -0
- package/dist/components/Slug/SlugEdit.d.ts +1 -1
- package/dist/components/Slug/SlugEdit.js +9 -3
- package/dist/components/Slug/SlugFeature.d.ts +3 -6
- package/dist/components/Slug/SlugFeature.js +12 -14
- package/dist/components/Slug/SlugOptions.type.d.ts +7 -0
- package/dist/components/StringList/StringList.d.ts +1 -1
- package/dist/components/StringList/StringList.js +4 -4
- package/dist/components/StringList/StringListFeature.d.ts +7 -0
- package/dist/components/StringList/StringListFeature.js +20 -0
- package/dist/components/StringList/StringListShow.d.ts +1 -1
- package/dist/components/StringList/StringListShow.js +2 -2
- package/dist/components/StringList/index.d.ts +3 -2
- package/dist/components/StringList/index.js +3 -2
- package/dist/components/StringList/styles.js +2 -1
- package/dist/components/Tabs/TabsEdit.d.ts +4 -0
- package/dist/components/Tabs/TabsEdit.js +103 -0
- package/dist/components/Tabs/TabsFeature.d.ts +7 -0
- package/dist/components/Tabs/TabsFeature.js +26 -0
- package/dist/components/Tabs/TabsShow.d.ts +4 -0
- package/dist/components/Tabs/TabsShow.js +61 -0
- package/dist/components/Tabs/index.d.ts +3 -0
- package/dist/components/Tabs/index.js +3 -0
- package/dist/components/index.d.ts +15 -7
- package/dist/components/index.js +15 -10
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types/upload-provider.d.ts +13 -0
- package/dist/utils/bundle-component.d.ts +1 -1
- package/dist/utils/bundle-component.js +5 -8
- package/dist/utils/component-loader.d.ts +3 -0
- package/dist/utils/component-loader.js +10 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +12 -11
- package/src/components/ColorStatus/ColorStatusEdit.d.ts +0 -5
- package/src/components/ColorStatus/ColorStatusEdit.js +0 -58
- package/src/components/ColorStatus/ColorStatusEdit.tsx +0 -94
- package/src/components/ColorStatus/ColorStatusList.d.ts +0 -4
- package/src/components/ColorStatus/ColorStatusList.js +0 -7
- package/src/components/ColorStatus/ColorStatusList.tsx +0 -20
- package/src/components/ColorStatus/ColorStatusShow.d.ts +0 -4
- package/src/components/ColorStatus/ColorStatusShow.js +0 -9
- package/src/components/ColorStatus/ColorStatusShow.tsx +0 -23
- package/src/components/ColorStatus/index.d.ts +0 -3
- package/src/components/ColorStatus/index.js +0 -3
- package/src/components/ColorStatus/index.ts +0 -3
- package/src/components/ColorStatus/styles.d.ts +0 -5
- package/src/components/ColorStatus/styles.js +0 -25
- package/src/components/ColorStatus/styles.ts +0 -30
- package/src/components/ColorStatus/types.d.ts +0 -5
- package/src/components/ColorStatus/types.ts +0 -5
- package/src/components/Editor/Editor.d.ts +0 -8
- package/src/components/Editor/Editor.js +0 -36
- package/src/components/Editor/Editor.jsx +0 -49
- package/src/components/Editor/EditorList.d.ts +0 -6
- package/src/components/Editor/EditorList.js +0 -11
- package/src/components/Editor/EditorList.jsx +0 -22
- package/src/components/Editor/EditorShow.d.ts +0 -6
- package/src/components/Editor/EditorShow.js +0 -13
- package/src/components/Editor/EditorShow.jsx +0 -24
- package/src/components/Editor/config.d.ts +0 -29
- package/src/components/Editor/config.js +0 -34
- package/src/components/Editor/config.ts +0 -35
- package/src/components/Editor/index.d.ts +0 -3
- package/src/components/Editor/index.js +0 -3
- package/src/components/Editor/index.ts +0 -3
- package/src/components/Editor/styles.d.ts +0 -6
- package/src/components/Editor/styles.js +0 -145
- package/src/components/Editor/styles.ts +0 -151
- package/src/components/Slug/SlugEdit.d.ts +0 -5
- package/src/components/Slug/SlugEdit.js +0 -27
- package/src/components/Slug/SlugEdit.tsx +0 -68
- package/src/components/Slug/SlugFeature.d.ts +0 -7
- package/src/components/Slug/SlugFeature.js +0 -21
- package/src/components/Slug/SlugFeature.ts +0 -30
- package/src/components/Slug/index.d.ts +0 -1
- package/src/components/Slug/index.js +0 -1
- package/src/components/Slug/index.ts +0 -1
- package/src/components/Slug/styles.d.ts +0 -4
- package/src/components/Slug/styles.js +0 -20
- package/src/components/Slug/styles.ts +0 -24
- package/src/components/StringList/SortableList/SortableList.d.ts +0 -18
- package/src/components/StringList/SortableList/SortableList.js +0 -37
- package/src/components/StringList/SortableList/SortableList.tsx +0 -98
- package/src/components/StringList/SortableList/components/SortableItem/DragHandle.d.ts +0 -7
- package/src/components/StringList/SortableList/components/SortableItem/DragHandle.js +0 -8
- package/src/components/StringList/SortableList/components/SortableItem/DragHandle.tsx +0 -20
- package/src/components/StringList/SortableList/components/SortableItem/SortableItem.d.ts +0 -8
- package/src/components/StringList/SortableList/components/SortableItem/SortableItem.js +0 -28
- package/src/components/StringList/SortableList/components/SortableItem/SortableItem.tsx +0 -59
- package/src/components/StringList/SortableList/components/SortableItem/styles.d.ts +0 -2
- package/src/components/StringList/SortableList/components/SortableItem/styles.js +0 -20
- package/src/components/StringList/SortableList/components/SortableItem/styles.ts +0 -22
- package/src/components/StringList/SortableList/components/SortableItem/types.d.ts +0 -6
- package/src/components/StringList/SortableList/components/SortableItem/types.ts +0 -7
- package/src/components/StringList/SortableList/components/index.d.ts +0 -2
- package/src/components/StringList/SortableList/components/index.js +0 -2
- package/src/components/StringList/SortableList/components/index.ts +0 -2
- package/src/components/StringList/SortableList/index.d.ts +0 -1
- package/src/components/StringList/SortableList/index.js +0 -1
- package/src/components/StringList/SortableList/index.ts +0 -1
- package/src/components/StringList/SortableList/styles.d.ts +0 -1
- package/src/components/StringList/SortableList/styles.js +0 -8
- package/src/components/StringList/SortableList/styles.ts +0 -9
- package/src/components/StringList/StringList.d.ts +0 -8
- package/src/components/StringList/StringList.js +0 -60
- package/src/components/StringList/StringList.tsx +0 -136
- package/src/components/StringList/StringListShow.d.ts +0 -7
- package/src/components/StringList/StringListShow.js +0 -14
- package/src/components/StringList/StringListShow.tsx +0 -37
- package/src/components/StringList/constants.d.ts +0 -1
- package/src/components/StringList/constants.js +0 -1
- package/src/components/StringList/constants.ts +0 -1
- package/src/components/StringList/index.d.ts +0 -2
- package/src/components/StringList/index.js +0 -2
- package/src/components/StringList/index.ts +0 -2
- package/src/components/StringList/styles.d.ts +0 -8
- package/src/components/StringList/styles.js +0 -33
- package/src/components/StringList/styles.ts +0 -41
- package/src/components/index.d.ts +0 -7
- package/src/components/index.js +0 -10
- package/src/components/index.ts +0 -10
- /package/{src/components/ColorStatus/types.js → dist/components/Slug/SlugOptions.type.js} +0 -0
- /package/{src/components/StringList/SortableList/components/SortableItem/types.js → dist/types/upload-provider.js} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { DrawerContent, Tab, Tabs } from "@adminjs/design-system";
|
|
2
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
3
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { ActionHeader, BasePropertyComponent, LayoutElementRenderer, } from "adminjs";
|
|
5
|
+
const StyledTabsContent = styled.div `
|
|
6
|
+
padding-top: ${({ theme }) => theme.space.xl};
|
|
7
|
+
`;
|
|
8
|
+
const DEFAULT_COMMON_LABEL = "Common";
|
|
9
|
+
const buildTabId = (label) => `tab-${label.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-_]/g, "")}`;
|
|
10
|
+
const groupProperties = (properties, commonLabel) => {
|
|
11
|
+
const commonProps = [];
|
|
12
|
+
const tabs = new Map();
|
|
13
|
+
properties.forEach((property) => {
|
|
14
|
+
const tab = property?.props?.tab ?? property?.custom?.tab;
|
|
15
|
+
if (tab) {
|
|
16
|
+
if (!tabs.has(tab)) {
|
|
17
|
+
tabs.set(tab, []);
|
|
18
|
+
}
|
|
19
|
+
tabs.get(tab)?.push(property);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
commonProps.push(property);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const entries = [
|
|
26
|
+
{ id: "common", label: commonLabel, properties: commonProps },
|
|
27
|
+
];
|
|
28
|
+
tabs.forEach((props, label) => {
|
|
29
|
+
entries.push({
|
|
30
|
+
id: buildTabId(label),
|
|
31
|
+
label,
|
|
32
|
+
properties: props,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return entries;
|
|
36
|
+
};
|
|
37
|
+
export const FeatureTabsShow = (props) => {
|
|
38
|
+
const { resource, record, action } = props;
|
|
39
|
+
const commonLabel = resource?.options?.properties?.__featureTabsCommonLabel?.custom?.value ??
|
|
40
|
+
DEFAULT_COMMON_LABEL;
|
|
41
|
+
const tabs = useMemo(() => groupProperties(resource.showProperties, commonLabel), [resource.showProperties, commonLabel]);
|
|
42
|
+
const [currentTab, setCurrentTab] = useState(() => {
|
|
43
|
+
const commonHasProps = Boolean(tabs[0]?.properties?.length);
|
|
44
|
+
return commonHasProps ? "common" : tabs[1]?.id ?? "common";
|
|
45
|
+
});
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const validTab = tabs.find((tab) => tab.id === currentTab);
|
|
48
|
+
if (!validTab) {
|
|
49
|
+
const commonHasProps = Boolean(tabs[0]?.properties?.length);
|
|
50
|
+
setCurrentTab(commonHasProps ? "common" : tabs[1]?.id ?? "common");
|
|
51
|
+
}
|
|
52
|
+
}, [tabs, currentTab]);
|
|
53
|
+
return (React.createElement(DrawerContent, null,
|
|
54
|
+
action?.showInDrawer ? React.createElement(ActionHeader, { ...props }) : null,
|
|
55
|
+
action.layout ? (action.layout.map((layoutElement, i) => (React.createElement(LayoutElementRenderer
|
|
56
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
57
|
+
, {
|
|
58
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
59
|
+
key: i, layoutElement: layoutElement, ...props, where: "show" })))) : (React.createElement(Tabs, { currentTab: currentTab, onChange: setCurrentTab, contentComponent: StyledTabsContent }, tabs.map((tab) => (React.createElement(Tab, { key: tab.id, id: tab.id, label: tab.label }, tab.properties.map((property) => (React.createElement(BasePropertyComponent, { key: property.propertyPath, where: "show", property: property, resource: resource, record: record }))))))))));
|
|
60
|
+
};
|
|
61
|
+
export default FeatureTabsShow;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Box, Button, Text } from "@adminjs/design-system";
|
|
2
|
+
import React, { useMemo } from "react";
|
|
3
|
+
const resolveTemplate = (template, params) => template.replace(/\$([A-Za-z0-9_]+)/g, (_, key) => {
|
|
4
|
+
const value = params?.[key];
|
|
5
|
+
return value === undefined || value === null ? "" : String(value);
|
|
6
|
+
});
|
|
7
|
+
export const PreviewAction = ({ record, resource }) => {
|
|
8
|
+
const template = resource?.properties?.__previewUrlTemplate?.custom?.value ?? "";
|
|
9
|
+
const params = record?.params ?? {};
|
|
10
|
+
const url = useMemo(() => resolveTemplate(template, params), [template, params]);
|
|
11
|
+
if (!url) {
|
|
12
|
+
return (React.createElement(Box, null,
|
|
13
|
+
React.createElement(Text, null, "Preview URL is not configured.")));
|
|
14
|
+
}
|
|
15
|
+
return (React.createElement(Box, { height: "100%", display: "flex", flexDirection: "column" },
|
|
16
|
+
React.createElement(Box, { mb: "lg", display: "flex", alignItems: "center" },
|
|
17
|
+
React.createElement(Box, { mr: "md" },
|
|
18
|
+
React.createElement(Button, { as: "a", variant: "outlined", onClick: () => window.history.back() }, "< Back")),
|
|
19
|
+
React.createElement(Button, { as: "a", variant: "outlined", href: url, target: "_blank", rel: "noopener" }, "Open in new tab")),
|
|
20
|
+
React.createElement(Box, { as: "iframe", src: url, title: "Preview", width: "100%", height: "calc(100vh - 300px)", style: { border: "1px solid #e5e7eb", borderRadius: "8px" } })));
|
|
21
|
+
};
|
|
22
|
+
export default PreviewAction;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComponentLoader, FeatureType } from "adminjs";
|
|
2
|
+
type PreviewOptions = {
|
|
3
|
+
componentLoader?: ComponentLoader;
|
|
4
|
+
url: string;
|
|
5
|
+
actionName?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const createPreviewFeature: (config: PreviewOptions) => FeatureType;
|
|
8
|
+
export declare const PreviewFeature: (config: PreviewOptions) => FeatureType;
|
|
9
|
+
export default createPreviewFeature;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { buildFeature } from "adminjs";
|
|
2
|
+
import { bundleComponent } from "../../utils/bundle-component.js";
|
|
3
|
+
const COMPONENT_NAME = "Preview";
|
|
4
|
+
const createPreviewFeature = (config) => {
|
|
5
|
+
const { componentLoader, url, actionName = "preview" } = config;
|
|
6
|
+
const actionComponent = bundleComponent(componentLoader, COMPONENT_NAME, "PreviewAction.js");
|
|
7
|
+
return buildFeature({
|
|
8
|
+
actions: {
|
|
9
|
+
[actionName]: {
|
|
10
|
+
actionType: "record",
|
|
11
|
+
icon: "Eye",
|
|
12
|
+
label: "Preview",
|
|
13
|
+
showInDrawer: false,
|
|
14
|
+
component: actionComponent,
|
|
15
|
+
handler: async (request, response, context) => ({
|
|
16
|
+
record: context.record?.toJSON(context.currentAdmin),
|
|
17
|
+
}),
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
properties: {
|
|
21
|
+
__previewUrlTemplate: {
|
|
22
|
+
isVisible: false,
|
|
23
|
+
custom: {
|
|
24
|
+
value: url,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
export const PreviewFeature = createPreviewFeature;
|
|
31
|
+
export default createPreviewFeature;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import { flat } from "adminjs";
|
|
1
2
|
import React, { useEffect, useState, } from "react";
|
|
2
3
|
import { ThemeProvider } from "styled-components";
|
|
3
4
|
import { theme } from "@adminjs/design-system";
|
|
4
5
|
import { slugifyTitle } from "../../utils/index.js";
|
|
5
6
|
import { StyledCustomInput, StyledGenerateButton, StyledInputWrapper, StyledLabel, } from "./styles.js";
|
|
6
|
-
const SlugEdit = ({ property, record, resource, onChange, }) => {
|
|
7
|
-
|
|
7
|
+
export const SlugEdit = ({ property, record, resource, onChange, }) => {
|
|
8
|
+
console.log("✅ SlugEdit loaded", { property });
|
|
9
|
+
const { params } = record;
|
|
10
|
+
const { custom } = property;
|
|
11
|
+
const source = flat.get(params, custom.source);
|
|
12
|
+
const key = flat.get(params, custom.key);
|
|
13
|
+
const [inputValue, setInputValue] = useState(key);
|
|
8
14
|
useEffect(() => {
|
|
9
15
|
onChange(property.path, inputValue);
|
|
10
16
|
}, [inputValue]);
|
|
11
17
|
return (React.createElement(ThemeProvider, { theme: theme },
|
|
12
|
-
React.createElement(StyledLabel, { htmlFor: "customSlug" }, property.path),
|
|
18
|
+
React.createElement(StyledLabel, { htmlFor: "customSlug" }, property.label ?? property.path),
|
|
13
19
|
React.createElement(StyledInputWrapper, null,
|
|
14
20
|
React.createElement(StyledCustomInput, { id: property.path, name: property.path, value: inputValue, onChange: handleInput }),
|
|
15
21
|
React.createElement(StyledGenerateButton, { variant: "outlined", onClick: generateSlug }, "Generate Slug"))));
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
key: string;
|
|
5
|
-
};
|
|
6
|
-
declare const SlugFeature: (config: SlugOptions) => FeatureType;
|
|
1
|
+
import { FeatureType } from "adminjs";
|
|
2
|
+
import SlugOptions from "./SlugOptions.type.js";
|
|
3
|
+
export declare const SlugFeature: (config: SlugOptions) => FeatureType;
|
|
7
4
|
export default SlugFeature;
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { buildFeature } from "adminjs";
|
|
2
2
|
import { bundleComponent } from "../../utils/bundle-component.js";
|
|
3
3
|
const COMPONENT_NAME = 'Slug';
|
|
4
|
-
const SlugFeature = (config) => {
|
|
5
|
-
const { componentLoader, key } = config;
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
edit: editComponent,
|
|
14
|
-
},
|
|
4
|
+
export const SlugFeature = (config) => {
|
|
5
|
+
const { componentLoader, source, key } = config;
|
|
6
|
+
const editComponent = bundleComponent(componentLoader, COMPONENT_NAME, 'SlugEdit.js');
|
|
7
|
+
return buildFeature({
|
|
8
|
+
properties: {
|
|
9
|
+
[key]: {
|
|
10
|
+
isVisible: { filter: true, show: true, edit: true, list: true },
|
|
11
|
+
components: {
|
|
12
|
+
edit: editComponent,
|
|
15
13
|
},
|
|
14
|
+
custom: { source, key }
|
|
16
15
|
},
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
return slugFeature();
|
|
16
|
+
},
|
|
17
|
+
});
|
|
20
18
|
};
|
|
21
19
|
export default SlugFeature;
|
|
@@ -4,5 +4,5 @@ type StringListTypes = Omit<EditPropertyProps, "where" | "resource">;
|
|
|
4
4
|
interface StringListShowPropsType extends StringListTypes {
|
|
5
5
|
stringListSeparator?: string;
|
|
6
6
|
}
|
|
7
|
-
declare const StringList: FC<StringListShowPropsType>;
|
|
7
|
+
export declare const StringList: FC<StringListShowPropsType>;
|
|
8
8
|
export default StringList;
|
|
@@ -4,7 +4,7 @@ import { ThemeProvider } from "styled-components";
|
|
|
4
4
|
import { StyledCustomInput, StyledInputWrapper, StyledLabel, StyledListWrapper, StyledWrapper, } from "./styles.js";
|
|
5
5
|
import { SortableList } from "./SortableList/SortableList.js";
|
|
6
6
|
import { separator } from "./constants.js";
|
|
7
|
-
const StringList = ({ record, onChange, property, stringListSeparator = separator, }) => {
|
|
7
|
+
export const StringList = ({ record, onChange, property, stringListSeparator = separator, }) => {
|
|
8
8
|
const stringListValue = record.params?.[property.path] ?? property.props.value ?? "";
|
|
9
9
|
const initialList = stringListValue
|
|
10
10
|
? prepareDataForList(stringListValue)
|
|
@@ -16,12 +16,12 @@ const StringList = ({ record, onChange, property, stringListSeparator = separato
|
|
|
16
16
|
onChange(property.path, serializedData);
|
|
17
17
|
}, [serializedData]);
|
|
18
18
|
return (React.createElement(ThemeProvider, { theme: theme },
|
|
19
|
-
React.createElement(StyledLabel, { htmlFor: "custom" }, property.path),
|
|
19
|
+
React.createElement(StyledLabel, { htmlFor: "custom" }, property.label ?? property.path),
|
|
20
20
|
React.createElement(StyledWrapper, null,
|
|
21
|
-
React.createElement(StyledListWrapper,
|
|
21
|
+
React.createElement(StyledListWrapper, { "$hasItems": list.length > 0 },
|
|
22
22
|
React.createElement(SortableList, { items: list, onChange: setList, renderItem: (item) => (React.createElement(SortableList.Item, { id: item.id, onDelete: handleDeleteButton }, item.value)) })),
|
|
23
23
|
React.createElement(StyledInputWrapper, null,
|
|
24
|
-
React.createElement(Input, { id: "stringList", name: property.path, value: serializedData, hidden: true }),
|
|
24
|
+
React.createElement(Input, { id: "stringList", name: property.path, value: serializedData, hidden: true, readOnly: true }),
|
|
25
25
|
React.createElement(StyledCustomInput, { id: "custom", name: "customInput", value: inputValue, onChange: handleInput, onKeyPress: handleEnterPress }),
|
|
26
26
|
React.createElement(Button, { variant: "outlined", onClick: handleAddButton }, "Add")))));
|
|
27
27
|
function handleInput(e) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { buildFeature } from "adminjs";
|
|
2
|
+
import { bundleComponent } from "../../utils/bundle-component.js";
|
|
3
|
+
const COMPONENT_NAME = "StringList";
|
|
4
|
+
export const StringListFeature = (config) => {
|
|
5
|
+
const { componentLoader, key } = config;
|
|
6
|
+
const editComponent = bundleComponent(componentLoader, COMPONENT_NAME, "StringList.js");
|
|
7
|
+
const showComponent = bundleComponent(componentLoader, COMPONENT_NAME, "StringListShow.js");
|
|
8
|
+
return buildFeature({
|
|
9
|
+
properties: {
|
|
10
|
+
[key]: {
|
|
11
|
+
isVisible: { filter: true, show: true, edit: true, list: true },
|
|
12
|
+
components: {
|
|
13
|
+
edit: editComponent,
|
|
14
|
+
show: showComponent,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
export default StringListFeature;
|
|
@@ -3,5 +3,5 @@ import { ShowPropertyProps } from "adminjs";
|
|
|
3
3
|
interface StringListShowPropsType extends ShowPropertyProps {
|
|
4
4
|
stringListSeparator?: string;
|
|
5
5
|
}
|
|
6
|
-
declare const StringListShow: FC<StringListShowPropsType>;
|
|
6
|
+
export declare const StringListShow: FC<StringListShowPropsType>;
|
|
7
7
|
export default StringListShow;
|
|
@@ -3,10 +3,10 @@ import { ThemeProvider } from "styled-components";
|
|
|
3
3
|
import { theme } from "@adminjs/design-system";
|
|
4
4
|
import { StyledShowLabel, StyledShowWrapper, StyledListItem } from "./styles.js";
|
|
5
5
|
import { separator } from "./constants.js";
|
|
6
|
-
const StringListShow = ({ property, record, stringListSeparator = separator, }) => {
|
|
6
|
+
export const StringListShow = ({ property, record, stringListSeparator = separator, }) => {
|
|
7
7
|
return (React.createElement(ThemeProvider, { theme: theme },
|
|
8
8
|
React.createElement(StyledShowWrapper, null,
|
|
9
|
-
React.createElement(StyledShowLabel, null, property.path),
|
|
9
|
+
React.createElement(StyledShowLabel, null, property.label ?? property.path),
|
|
10
10
|
record.params.facts && (React.createElement("ul", null, record.params.facts
|
|
11
11
|
.split(stringListSeparator)
|
|
12
12
|
.map((item, index) => (React.createElement(StyledListItem, { key: index }, `- ${item}`))))))));
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export { StringList } from "./StringList.js";
|
|
2
|
+
export { StringListShow } from "./StringListShow.js";
|
|
3
|
+
export { StringListFeature } from "./StringListFeature.js";
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export { StringList } from "./StringList.js";
|
|
2
|
+
export { StringListShow } from "./StringListShow.js";
|
|
3
|
+
export { StringListFeature } from "./StringListFeature.js";
|
|
@@ -13,7 +13,8 @@ export const StyledInputWrapper = styled(Box) `
|
|
|
13
13
|
display: flex;
|
|
14
14
|
`;
|
|
15
15
|
export const StyledListWrapper = styled(Box) `
|
|
16
|
-
margin-bottom: 15px;
|
|
16
|
+
margin-bottom: ${({ $hasItems }) => ($hasItems ? "15px" : "4px")};
|
|
17
|
+
min-height: 0;
|
|
17
18
|
`;
|
|
18
19
|
export const StyledLabel = styled.div `
|
|
19
20
|
font-size: 12px;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Box, Button, DrawerContent, DrawerFooter, Icon, Tab, Tabs } from "@adminjs/design-system";
|
|
2
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
3
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { BasePropertyComponent, LayoutElementRenderer, useRecord, useTranslation, ActionHeader, } from "adminjs";
|
|
5
|
+
const StyledTabButton = styled.button `
|
|
6
|
+
background: none;
|
|
7
|
+
border: none;
|
|
8
|
+
padding: ${({ theme }) => `${theme.space.sm} ${theme.space.xl}`};
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
border-bottom: 2px solid ${({ theme }) => theme.colors.border};
|
|
11
|
+
color: ${({ theme }) => theme.colors.grey60};
|
|
12
|
+
user-select: none;
|
|
13
|
+
${({ theme }) => ({
|
|
14
|
+
fontFamily: theme.font,
|
|
15
|
+
fontSize: theme.fontSizes.md,
|
|
16
|
+
lineHeight: theme.lineHeights.lg,
|
|
17
|
+
})};
|
|
18
|
+
${({ active, theme }) => active
|
|
19
|
+
? `
|
|
20
|
+
border-color: ${theme.colors.primary100};
|
|
21
|
+
color: ${theme.colors.primary100};
|
|
22
|
+
`
|
|
23
|
+
: ""}
|
|
24
|
+
`;
|
|
25
|
+
const StyledTabsContent = styled.div `
|
|
26
|
+
padding-top: ${({ theme }) => theme.space.xl};
|
|
27
|
+
`;
|
|
28
|
+
const TabButton = ({ onClick, active, tabId, role, children }) => (React.createElement(StyledTabButton, { type: "button", onClick: onClick, "data-tab-id": tabId, role: role, active: active }, children));
|
|
29
|
+
const DEFAULT_COMMON_LABEL = "Common";
|
|
30
|
+
const buildTabId = (label) => `tab-${label.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-_]/g, "")}`;
|
|
31
|
+
const groupProperties = (properties, commonLabel) => {
|
|
32
|
+
const commonProps = [];
|
|
33
|
+
const tabs = new Map();
|
|
34
|
+
properties.forEach((property) => {
|
|
35
|
+
const tab = property?.props?.tab ?? property?.custom?.tab;
|
|
36
|
+
if (tab) {
|
|
37
|
+
if (!tabs.has(tab)) {
|
|
38
|
+
tabs.set(tab, []);
|
|
39
|
+
}
|
|
40
|
+
tabs.get(tab)?.push(property);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
commonProps.push(property);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const entries = [
|
|
47
|
+
{ id: "common", label: commonLabel, properties: commonProps },
|
|
48
|
+
];
|
|
49
|
+
tabs.forEach((props, label) => {
|
|
50
|
+
entries.push({
|
|
51
|
+
id: buildTabId(label),
|
|
52
|
+
label,
|
|
53
|
+
properties: props,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
return entries;
|
|
57
|
+
};
|
|
58
|
+
export const TabsEdit = (props) => {
|
|
59
|
+
const { record: initialRecord, resource, action } = props;
|
|
60
|
+
const { record, handleChange, submit: handleSubmit, loading, setRecord, } = useRecord(initialRecord, resource.id);
|
|
61
|
+
const { translateButton } = useTranslation();
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (initialRecord) {
|
|
64
|
+
setRecord(initialRecord);
|
|
65
|
+
}
|
|
66
|
+
}, [initialRecord]);
|
|
67
|
+
const submit = (event) => {
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
handleSubmit().then((response) => {
|
|
70
|
+
if (response.data.redirectUrl) {
|
|
71
|
+
window.location.assign(response.data.redirectUrl);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return false;
|
|
75
|
+
};
|
|
76
|
+
const commonLabel = resource?.options?.properties?.__tabsCommonLabel?.custom?.value ??
|
|
77
|
+
DEFAULT_COMMON_LABEL;
|
|
78
|
+
const tabs = useMemo(() => groupProperties(resource.editProperties, commonLabel), [resource.editProperties, commonLabel]);
|
|
79
|
+
const [currentTab, setCurrentTab] = useState(() => {
|
|
80
|
+
const commonHasProps = Boolean(tabs[0]?.properties?.length);
|
|
81
|
+
return commonHasProps ? "common" : tabs[1]?.id ?? "common";
|
|
82
|
+
});
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
const validTab = tabs.find((tab) => tab.id === currentTab);
|
|
85
|
+
if (!validTab) {
|
|
86
|
+
const commonHasProps = Boolean(tabs[0]?.properties?.length);
|
|
87
|
+
setCurrentTab(commonHasProps ? "common" : tabs[1]?.id ?? "common");
|
|
88
|
+
}
|
|
89
|
+
}, [tabs, currentTab]);
|
|
90
|
+
return (React.createElement(Box, { as: "form", onSubmit: submit, flex: true, flexDirection: "column" },
|
|
91
|
+
React.createElement(DrawerContent, null,
|
|
92
|
+
action?.showInDrawer ? React.createElement(ActionHeader, { ...props }) : null,
|
|
93
|
+
action.layout ? (action.layout.map((layoutElement, i) => (React.createElement(LayoutElementRenderer
|
|
94
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
95
|
+
, {
|
|
96
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
97
|
+
key: i, layoutElement: layoutElement, ...props, where: "edit", onChange: handleChange, record: record })))) : (React.createElement(Tabs, { currentTab: currentTab, onChange: setCurrentTab, buttonComponent: TabButton, contentComponent: StyledTabsContent }, tabs.map((tab) => (React.createElement(Tab, { key: tab.id, id: tab.id, label: tab.label }, tab.properties.map((property) => (React.createElement(BasePropertyComponent, { key: property.propertyPath, where: "edit", onChange: handleChange, property: property, resource: resource, record: record }))))))))),
|
|
98
|
+
React.createElement(DrawerFooter, null,
|
|
99
|
+
React.createElement(Button, { variant: "contained", type: "submit", "data-testid": "button-save", disabled: loading },
|
|
100
|
+
loading ? React.createElement(Icon, { icon: "Loader", spin: true }) : null,
|
|
101
|
+
translateButton("save", resource.id)))));
|
|
102
|
+
};
|
|
103
|
+
export default TabsEdit;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { buildFeature } from "adminjs";
|
|
2
|
+
import { bundleComponent } from "../../utils/bundle-component.js";
|
|
3
|
+
const COMPONENT_NAME = "Tabs";
|
|
4
|
+
export const TabsFeature = (config) => {
|
|
5
|
+
const { componentLoader, commonTabLabel } = config;
|
|
6
|
+
const editComponent = bundleComponent(componentLoader, COMPONENT_NAME, "TabsEdit.js");
|
|
7
|
+
const showComponent = bundleComponent(componentLoader, COMPONENT_NAME, "TabsShow.js");
|
|
8
|
+
return buildFeature({
|
|
9
|
+
actions: {
|
|
10
|
+
edit: {
|
|
11
|
+
component: editComponent,
|
|
12
|
+
},
|
|
13
|
+
show: {
|
|
14
|
+
component: showComponent,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
properties: {
|
|
18
|
+
__tabsCommonLabel: {
|
|
19
|
+
isVisible: false,
|
|
20
|
+
custom: {
|
|
21
|
+
value: commonTabLabel,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { DrawerContent, Tab, Tabs } from "@adminjs/design-system";
|
|
2
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
3
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { ActionHeader, BasePropertyComponent, LayoutElementRenderer, } from "adminjs";
|
|
5
|
+
const StyledTabsContent = styled.div `
|
|
6
|
+
padding-top: ${({ theme }) => theme.space.xl};
|
|
7
|
+
`;
|
|
8
|
+
const DEFAULT_COMMON_LABEL = "Common";
|
|
9
|
+
const buildTabId = (label) => `tab-${label.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-_]/g, "")}`;
|
|
10
|
+
const groupProperties = (properties, commonLabel) => {
|
|
11
|
+
const commonProps = [];
|
|
12
|
+
const tabs = new Map();
|
|
13
|
+
properties.forEach((property) => {
|
|
14
|
+
const tab = property?.props?.tab ?? property?.custom?.tab;
|
|
15
|
+
if (tab) {
|
|
16
|
+
if (!tabs.has(tab)) {
|
|
17
|
+
tabs.set(tab, []);
|
|
18
|
+
}
|
|
19
|
+
tabs.get(tab)?.push(property);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
commonProps.push(property);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const entries = [
|
|
26
|
+
{ id: "common", label: commonLabel, properties: commonProps },
|
|
27
|
+
];
|
|
28
|
+
tabs.forEach((props, label) => {
|
|
29
|
+
entries.push({
|
|
30
|
+
id: buildTabId(label),
|
|
31
|
+
label,
|
|
32
|
+
properties: props,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return entries;
|
|
36
|
+
};
|
|
37
|
+
export const TabsShow = (props) => {
|
|
38
|
+
const { resource, record, action } = props;
|
|
39
|
+
const commonLabel = resource?.options?.properties?.__tabsCommonLabel?.custom?.value ??
|
|
40
|
+
DEFAULT_COMMON_LABEL;
|
|
41
|
+
const tabs = useMemo(() => groupProperties(resource.showProperties, commonLabel), [resource.showProperties, commonLabel]);
|
|
42
|
+
const [currentTab, setCurrentTab] = useState(() => {
|
|
43
|
+
const commonHasProps = Boolean(tabs[0]?.properties?.length);
|
|
44
|
+
return commonHasProps ? "common" : tabs[1]?.id ?? "common";
|
|
45
|
+
});
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const validTab = tabs.find((tab) => tab.id === currentTab);
|
|
48
|
+
if (!validTab) {
|
|
49
|
+
const commonHasProps = Boolean(tabs[0]?.properties?.length);
|
|
50
|
+
setCurrentTab(commonHasProps ? "common" : tabs[1]?.id ?? "common");
|
|
51
|
+
}
|
|
52
|
+
}, [tabs, currentTab]);
|
|
53
|
+
return (React.createElement(DrawerContent, null,
|
|
54
|
+
action?.showInDrawer ? React.createElement(ActionHeader, { ...props }) : null,
|
|
55
|
+
action.layout ? (action.layout.map((layoutElement, i) => (React.createElement(LayoutElementRenderer
|
|
56
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
57
|
+
, {
|
|
58
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
59
|
+
key: i, layoutElement: layoutElement, ...props, where: "show" })))) : (React.createElement(Tabs, { currentTab: currentTab, onChange: setCurrentTab, contentComponent: StyledTabsContent }, tabs.map((tab) => (React.createElement(Tab, { key: tab.id, id: tab.id, label: tab.label }, tab.properties.map((property) => (React.createElement(BasePropertyComponent, { key: property.propertyPath, where: "show", property: property, resource: resource, record: record }))))))))));
|
|
60
|
+
};
|
|
61
|
+
export default TabsShow;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
1
|
+
export { ColorStatusEdit } from "./ColorStatus/ColorStatusEdit.js";
|
|
2
|
+
export { ColorStatusShow } from "./ColorStatus/ColorStatusShow.js";
|
|
3
|
+
export { ColorStatusList } from "./ColorStatus/ColorStatusList.js";
|
|
4
|
+
export { ColorStatusFeature } from "./ColorStatus/ColorStatusFeature.js";
|
|
5
|
+
export { SlugEdit } from "./Slug/SlugEdit.js";
|
|
6
|
+
export { Editor } from "./Editor/Editor.js";
|
|
7
|
+
export { EditorList } from "./Editor/EditorList.js";
|
|
8
|
+
export { EditorShow } from "./Editor/EditorShow.js";
|
|
9
|
+
export { EditorFeature } from "./Editor/EditorFeature.js";
|
|
10
|
+
export { StringList } from "./StringList/StringList.js";
|
|
11
|
+
export { StringListShow } from "./StringList/StringListShow.js";
|
|
12
|
+
export { StringListFeature } from "./StringList/StringListFeature.js";
|
|
13
|
+
export { SlugFeature } from "./Slug/SlugFeature.js";
|
|
14
|
+
export { TabsFeature } from "./Tabs/TabsFeature.js";
|
|
15
|
+
export { PreviewFeature } from "./Preview/PreviewFeature.js";
|
package/dist/components/index.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
1
|
+
export { ColorStatusEdit } from "./ColorStatus/ColorStatusEdit.js";
|
|
2
|
+
export { ColorStatusShow } from "./ColorStatus/ColorStatusShow.js";
|
|
3
|
+
export { ColorStatusList } from "./ColorStatus/ColorStatusList.js";
|
|
4
|
+
export { ColorStatusFeature } from "./ColorStatus/ColorStatusFeature.js";
|
|
5
|
+
export { SlugEdit } from "./Slug/SlugEdit.js";
|
|
6
|
+
export { Editor } from "./Editor/Editor.js";
|
|
7
|
+
export { EditorList } from "./Editor/EditorList.js";
|
|
8
|
+
export { EditorShow } from "./Editor/EditorShow.js";
|
|
9
|
+
export { EditorFeature } from "./Editor/EditorFeature.js";
|
|
10
|
+
export { StringList } from "./StringList/StringList.js";
|
|
11
|
+
export { StringListShow } from "./StringList/StringListShow.js";
|
|
12
|
+
export { StringListFeature } from "./StringList/StringListFeature.js";
|
|
13
|
+
export { SlugFeature } from "./Slug/SlugFeature.js";
|
|
14
|
+
export { TabsFeature } from "./Tabs/TabsFeature.js";
|
|
15
|
+
export { PreviewFeature } from "./Preview/PreviewFeature.js";
|