@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.
Files changed (159) hide show
  1. package/dist/components/ColorStatus/ColorStatusEdit.d.ts +2 -2
  2. package/dist/components/ColorStatus/ColorStatusEdit.js +3 -3
  3. package/dist/components/ColorStatus/ColorStatusFeature.d.ts +9 -0
  4. package/dist/components/ColorStatus/ColorStatusFeature.js +23 -0
  5. package/dist/components/ColorStatus/ColorStatusList.d.ts +1 -1
  6. package/dist/components/ColorStatus/ColorStatusList.js +4 -2
  7. package/dist/components/ColorStatus/ColorStatusShow.d.ts +1 -1
  8. package/dist/components/ColorStatus/ColorStatusShow.js +5 -3
  9. package/dist/components/ColorStatus/index.d.ts +4 -3
  10. package/dist/components/ColorStatus/index.js +4 -3
  11. package/dist/components/ColorStatus/styles.js +2 -1
  12. package/dist/components/Editor/Editor.d.ts +4 -2
  13. package/dist/components/Editor/Editor.js +79 -16
  14. package/dist/components/Editor/EditorFeature.d.ts +10 -0
  15. package/dist/components/Editor/EditorFeature.js +82 -0
  16. package/dist/components/Editor/EditorList.d.ts +2 -2
  17. package/dist/components/Editor/EditorList.js +1 -1
  18. package/dist/components/Editor/EditorShow.d.ts +2 -2
  19. package/dist/components/Editor/EditorShow.js +2 -2
  20. package/dist/components/Editor/index.d.ts +4 -3
  21. package/dist/components/Editor/index.js +4 -3
  22. package/dist/components/FeatureTabs/FeatureTabsEdit.d.ts +4 -0
  23. package/dist/components/FeatureTabs/FeatureTabsEdit.js +105 -0
  24. package/dist/components/FeatureTabs/FeatureTabsFeature.d.ts +8 -0
  25. package/dist/components/FeatureTabs/FeatureTabsFeature.js +28 -0
  26. package/dist/components/FeatureTabs/FeatureTabsShow.d.ts +4 -0
  27. package/dist/components/FeatureTabs/FeatureTabsShow.js +61 -0
  28. package/dist/components/FeatureTabs/index.d.ts +4 -0
  29. package/dist/components/FeatureTabs/index.js +4 -0
  30. package/dist/components/Preview/PreviewAction.d.ts +4 -0
  31. package/dist/components/Preview/PreviewAction.js +22 -0
  32. package/dist/components/Preview/PreviewFeature.d.ts +9 -0
  33. package/dist/components/Preview/PreviewFeature.js +31 -0
  34. package/dist/components/Preview/index.d.ts +2 -0
  35. package/dist/components/Preview/index.js +2 -0
  36. package/dist/components/Slug/SlugEdit.d.ts +1 -1
  37. package/dist/components/Slug/SlugEdit.js +9 -3
  38. package/dist/components/Slug/SlugFeature.d.ts +3 -6
  39. package/dist/components/Slug/SlugFeature.js +12 -14
  40. package/dist/components/Slug/SlugOptions.type.d.ts +7 -0
  41. package/dist/components/StringList/StringList.d.ts +1 -1
  42. package/dist/components/StringList/StringList.js +4 -4
  43. package/dist/components/StringList/StringListFeature.d.ts +7 -0
  44. package/dist/components/StringList/StringListFeature.js +20 -0
  45. package/dist/components/StringList/StringListShow.d.ts +1 -1
  46. package/dist/components/StringList/StringListShow.js +2 -2
  47. package/dist/components/StringList/index.d.ts +3 -2
  48. package/dist/components/StringList/index.js +3 -2
  49. package/dist/components/StringList/styles.js +2 -1
  50. package/dist/components/Tabs/TabsEdit.d.ts +4 -0
  51. package/dist/components/Tabs/TabsEdit.js +103 -0
  52. package/dist/components/Tabs/TabsFeature.d.ts +7 -0
  53. package/dist/components/Tabs/TabsFeature.js +26 -0
  54. package/dist/components/Tabs/TabsShow.d.ts +4 -0
  55. package/dist/components/Tabs/TabsShow.js +61 -0
  56. package/dist/components/Tabs/index.d.ts +3 -0
  57. package/dist/components/Tabs/index.js +3 -0
  58. package/dist/components/index.d.ts +15 -7
  59. package/dist/components/index.js +15 -10
  60. package/dist/index.d.ts +1 -0
  61. package/dist/index.js +1 -0
  62. package/dist/types/upload-provider.d.ts +13 -0
  63. package/dist/utils/bundle-component.d.ts +1 -1
  64. package/dist/utils/bundle-component.js +5 -8
  65. package/dist/utils/component-loader.d.ts +3 -0
  66. package/dist/utils/component-loader.js +10 -0
  67. package/dist/utils/index.d.ts +1 -0
  68. package/dist/utils/index.js +1 -0
  69. package/package.json +12 -11
  70. package/src/components/ColorStatus/ColorStatusEdit.d.ts +0 -5
  71. package/src/components/ColorStatus/ColorStatusEdit.js +0 -58
  72. package/src/components/ColorStatus/ColorStatusEdit.tsx +0 -94
  73. package/src/components/ColorStatus/ColorStatusList.d.ts +0 -4
  74. package/src/components/ColorStatus/ColorStatusList.js +0 -7
  75. package/src/components/ColorStatus/ColorStatusList.tsx +0 -20
  76. package/src/components/ColorStatus/ColorStatusShow.d.ts +0 -4
  77. package/src/components/ColorStatus/ColorStatusShow.js +0 -9
  78. package/src/components/ColorStatus/ColorStatusShow.tsx +0 -23
  79. package/src/components/ColorStatus/index.d.ts +0 -3
  80. package/src/components/ColorStatus/index.js +0 -3
  81. package/src/components/ColorStatus/index.ts +0 -3
  82. package/src/components/ColorStatus/styles.d.ts +0 -5
  83. package/src/components/ColorStatus/styles.js +0 -25
  84. package/src/components/ColorStatus/styles.ts +0 -30
  85. package/src/components/ColorStatus/types.d.ts +0 -5
  86. package/src/components/ColorStatus/types.ts +0 -5
  87. package/src/components/Editor/Editor.d.ts +0 -8
  88. package/src/components/Editor/Editor.js +0 -36
  89. package/src/components/Editor/Editor.jsx +0 -49
  90. package/src/components/Editor/EditorList.d.ts +0 -6
  91. package/src/components/Editor/EditorList.js +0 -11
  92. package/src/components/Editor/EditorList.jsx +0 -22
  93. package/src/components/Editor/EditorShow.d.ts +0 -6
  94. package/src/components/Editor/EditorShow.js +0 -13
  95. package/src/components/Editor/EditorShow.jsx +0 -24
  96. package/src/components/Editor/config.d.ts +0 -29
  97. package/src/components/Editor/config.js +0 -34
  98. package/src/components/Editor/config.ts +0 -35
  99. package/src/components/Editor/index.d.ts +0 -3
  100. package/src/components/Editor/index.js +0 -3
  101. package/src/components/Editor/index.ts +0 -3
  102. package/src/components/Editor/styles.d.ts +0 -6
  103. package/src/components/Editor/styles.js +0 -145
  104. package/src/components/Editor/styles.ts +0 -151
  105. package/src/components/Slug/SlugEdit.d.ts +0 -5
  106. package/src/components/Slug/SlugEdit.js +0 -27
  107. package/src/components/Slug/SlugEdit.tsx +0 -68
  108. package/src/components/Slug/SlugFeature.d.ts +0 -7
  109. package/src/components/Slug/SlugFeature.js +0 -21
  110. package/src/components/Slug/SlugFeature.ts +0 -30
  111. package/src/components/Slug/index.d.ts +0 -1
  112. package/src/components/Slug/index.js +0 -1
  113. package/src/components/Slug/index.ts +0 -1
  114. package/src/components/Slug/styles.d.ts +0 -4
  115. package/src/components/Slug/styles.js +0 -20
  116. package/src/components/Slug/styles.ts +0 -24
  117. package/src/components/StringList/SortableList/SortableList.d.ts +0 -18
  118. package/src/components/StringList/SortableList/SortableList.js +0 -37
  119. package/src/components/StringList/SortableList/SortableList.tsx +0 -98
  120. package/src/components/StringList/SortableList/components/SortableItem/DragHandle.d.ts +0 -7
  121. package/src/components/StringList/SortableList/components/SortableItem/DragHandle.js +0 -8
  122. package/src/components/StringList/SortableList/components/SortableItem/DragHandle.tsx +0 -20
  123. package/src/components/StringList/SortableList/components/SortableItem/SortableItem.d.ts +0 -8
  124. package/src/components/StringList/SortableList/components/SortableItem/SortableItem.js +0 -28
  125. package/src/components/StringList/SortableList/components/SortableItem/SortableItem.tsx +0 -59
  126. package/src/components/StringList/SortableList/components/SortableItem/styles.d.ts +0 -2
  127. package/src/components/StringList/SortableList/components/SortableItem/styles.js +0 -20
  128. package/src/components/StringList/SortableList/components/SortableItem/styles.ts +0 -22
  129. package/src/components/StringList/SortableList/components/SortableItem/types.d.ts +0 -6
  130. package/src/components/StringList/SortableList/components/SortableItem/types.ts +0 -7
  131. package/src/components/StringList/SortableList/components/index.d.ts +0 -2
  132. package/src/components/StringList/SortableList/components/index.js +0 -2
  133. package/src/components/StringList/SortableList/components/index.ts +0 -2
  134. package/src/components/StringList/SortableList/index.d.ts +0 -1
  135. package/src/components/StringList/SortableList/index.js +0 -1
  136. package/src/components/StringList/SortableList/index.ts +0 -1
  137. package/src/components/StringList/SortableList/styles.d.ts +0 -1
  138. package/src/components/StringList/SortableList/styles.js +0 -8
  139. package/src/components/StringList/SortableList/styles.ts +0 -9
  140. package/src/components/StringList/StringList.d.ts +0 -8
  141. package/src/components/StringList/StringList.js +0 -60
  142. package/src/components/StringList/StringList.tsx +0 -136
  143. package/src/components/StringList/StringListShow.d.ts +0 -7
  144. package/src/components/StringList/StringListShow.js +0 -14
  145. package/src/components/StringList/StringListShow.tsx +0 -37
  146. package/src/components/StringList/constants.d.ts +0 -1
  147. package/src/components/StringList/constants.js +0 -1
  148. package/src/components/StringList/constants.ts +0 -1
  149. package/src/components/StringList/index.d.ts +0 -2
  150. package/src/components/StringList/index.js +0 -2
  151. package/src/components/StringList/index.ts +0 -2
  152. package/src/components/StringList/styles.d.ts +0 -8
  153. package/src/components/StringList/styles.js +0 -33
  154. package/src/components/StringList/styles.ts +0 -41
  155. package/src/components/index.d.ts +0 -7
  156. package/src/components/index.js +0 -10
  157. package/src/components/index.ts +0 -10
  158. /package/{src/components/ColorStatus/types.js → dist/components/Slug/SlugOptions.type.js} +0 -0
  159. /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,4 @@
1
+ export { FeatureTabsEdit } from "./FeatureTabsEdit.js";
2
+ export { FeatureTabsShow } from "./FeatureTabsShow.js";
3
+ export { FeatureTabs } from "./FeatureTabsFeature.js";
4
+ export { default as FeatureTabsFeature } from "./FeatureTabsFeature.js";
@@ -0,0 +1,4 @@
1
+ export { FeatureTabsEdit } from "./FeatureTabsEdit.js";
2
+ export { FeatureTabsShow } from "./FeatureTabsShow.js";
3
+ export { FeatureTabs } from "./FeatureTabsFeature.js";
4
+ export { default as FeatureTabsFeature } from "./FeatureTabsFeature.js";
@@ -0,0 +1,4 @@
1
+ import { FC } from "react";
2
+ import { ActionProps } from "adminjs";
3
+ export declare const PreviewAction: FC<ActionProps>;
4
+ export default PreviewAction;
@@ -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;
@@ -0,0 +1,2 @@
1
+ export { PreviewAction } from "./PreviewAction.js";
2
+ export { PreviewFeature } from "./PreviewFeature.js";
@@ -0,0 +1,2 @@
1
+ export { PreviewAction } from "./PreviewAction.js";
2
+ export { PreviewFeature } from "./PreviewFeature.js";
@@ -1,5 +1,5 @@
1
1
  import { EditPropertyProps } from "adminjs";
2
2
  import { FC } from "react";
3
3
  type CustomSlugTypes = Omit<EditPropertyProps, "where">;
4
- declare const SlugEdit: FC<CustomSlugTypes>;
4
+ export declare const SlugEdit: FC<CustomSlugTypes>;
5
5
  export default SlugEdit;
@@ -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
- const [inputValue, setInputValue] = useState(record.params.slug);
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 { ComponentLoader, FeatureType } from "adminjs";
2
- type SlugOptions = {
3
- componentLoader: ComponentLoader;
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 slugFeature = () => {
7
- const editComponent = bundleComponent(componentLoader, COMPONENT_NAME, 'SlugEdit');
8
- return buildFeature({
9
- properties: {
10
- [key]: {
11
- isVisible: { show: false, edit: true, list: false, filter: false },
12
- components: {
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;
@@ -0,0 +1,7 @@
1
+ import { ComponentLoader } from "adminjs";
2
+ type SlugOptions = {
3
+ componentLoader?: ComponentLoader;
4
+ source: string;
5
+ key: string;
6
+ };
7
+ export default SlugOptions;
@@ -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, null,
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,7 @@
1
+ import { ComponentLoader, FeatureType } from "adminjs";
2
+ type StringListOptions = {
3
+ componentLoader?: ComponentLoader;
4
+ key: string;
5
+ };
6
+ export declare const StringListFeature: (config: StringListOptions) => FeatureType;
7
+ export default StringListFeature;
@@ -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 * from "./StringList.js";
2
- export * from "./StringListShow.js";
1
+ export { StringList } from "./StringList.js";
2
+ export { StringListShow } from "./StringListShow.js";
3
+ export { StringListFeature } from "./StringListFeature.js";
@@ -1,2 +1,3 @@
1
- export * from "./StringList.js";
2
- export * from "./StringListShow.js";
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,4 @@
1
+ import { FC } from "react";
2
+ import { ActionProps } from "adminjs";
3
+ export declare const TabsEdit: FC<ActionProps>;
4
+ export default TabsEdit;
@@ -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,7 @@
1
+ import { ComponentLoader, FeatureType } from "adminjs";
2
+ type TabsOptions = {
3
+ componentLoader?: ComponentLoader;
4
+ commonTabLabel?: string;
5
+ };
6
+ export declare const TabsFeature: (config: TabsOptions) => FeatureType;
7
+ export {};
@@ -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,4 @@
1
+ import { FC } from "react";
2
+ import { ActionProps } from "adminjs";
3
+ export declare const TabsShow: FC<ActionProps>;
4
+ export default TabsShow;
@@ -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;
@@ -0,0 +1,3 @@
1
+ export { TabsEdit } from "./TabsEdit.js";
2
+ export { TabsShow } from "./TabsShow.js";
3
+ export { TabsFeature } from "./TabsFeature.js";
@@ -0,0 +1,3 @@
1
+ export { TabsEdit } from "./TabsEdit.js";
2
+ export { TabsShow } from "./TabsShow.js";
3
+ export { TabsFeature } from "./TabsFeature.js";
@@ -1,7 +1,15 @@
1
- export { default as ColorStatusEdit } from "./ColorStatus/ColorStatusEdit.js";
2
- export { default as ColorStatusShow } from "./ColorStatus/ColorStatusShow.js";
3
- export { default as ColorStatusList } from "./ColorStatus/ColorStatusList.js";
4
- export { default as SlugEdit } from "./Slug/SlugEdit.js";
5
- export { default as StringList } from "./StringList/StringList.js";
6
- export { default as StringListShow } from "./StringList/StringListShow.js";
7
- export { default as SlugFeature } from "./Slug/SlugFeature.js";
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";
@@ -1,10 +1,15 @@
1
- export { default as ColorStatusEdit } from "./ColorStatus/ColorStatusEdit.js";
2
- export { default as ColorStatusShow } from "./ColorStatus/ColorStatusShow.js";
3
- export { default as ColorStatusList } from "./ColorStatus/ColorStatusList.js";
4
- export { default as SlugEdit } from "./Slug/SlugEdit.js";
5
- //export { default as Editor } from "./Editor/Editor.jsx";
6
- //export { default as EditorList } from "./Editor/EditorList.jsx";
7
- //export { default as EditorShow } from "./Editor/EditorShow.jsx";
8
- export { default as StringList } from "./StringList/StringList.js";
9
- export { default as StringListShow } from "./StringList/StringListShow.js";
10
- export { default as SlugFeature } from "./Slug/SlugFeature.js";
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";