@rulab/adminjs-components 0.0.3 → 0.0.5
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/bundle.js +8 -0
- package/dist/components/CustomSlug/CustomSlug.jsx +29 -0
- package/dist/components/CustomSlug/index.js +1 -0
- package/dist/components/CustomSlug/styles.js +15 -0
- package/dist/components/Editor/config.js +11 -0
- package/dist/components/Editor/index.js +1 -0
- package/dist/components/Editor/styles.js +64 -0
- package/dist/components/StringList/SortableList/SortableList.jsx +43 -0
- package/dist/components/StringList/SortableList/components/SortableItem/DragHandle.jsx +10 -0
- package/dist/components/StringList/SortableList/components/SortableItem/SortableItem.jsx +32 -0
- package/dist/components/StringList/SortableList/components/SortableItem/styles.js +20 -0
- package/dist/components/StringList/SortableList/components/SortableItem/types.js +1 -0
- package/dist/components/StringList/SortableList/components/index.js +2 -0
- package/dist/components/StringList/SortableList/index.js +1 -0
- package/dist/components/StringList/SortableList/styles.js +8 -0
- package/dist/components/StringList/StringList.jsx +67 -0
- package/dist/components/StringList/index.js +1 -0
- package/dist/components/StringList/styles.js +16 -0
- package/dist/components/index.js +3 -0
- package/dist/editorFeature.js +16 -0
- package/dist/index.cjs +91 -26
- package/dist/index.d.cts +16 -3
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +16 -3
- package/dist/index.js +83 -20
- package/dist/index.mjs +37 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/slugifyImport.js +3 -0
- package/dist/utils/slugifyTitle.js +10 -0
- package/package.json +2 -1
- package/src/components/CustomSlug/CustomSlug.tsx +4 -2
- package/src/components/Editor/Editor.jsx +2 -1
- package/src/components/Editor/EditorShow.jsx +22 -0
- package/src/components/Editor/index.ts +2 -1
- package/src/components/Editor/styles.ts +2 -0
- package/src/components/StringList/StringList.tsx +13 -3
- package/src/components/StringList/StringListShow.tsx +37 -0
- package/src/components/StringList/constants.ts +1 -0
- package/src/components/StringList/index.ts +2 -1
- package/src/components/StringList/styles.ts +17 -0
- package/src/components/index.ts +3 -1
- package/src/utils/parseHtml.ts +12 -0
- package/src/utils/slugifyTitle.ts +1 -1
package/dist/bundle.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import * as url from "url";
|
|
3
|
+
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
4
|
+
const bundleComponent = (loader, componentName) => {
|
|
5
|
+
const componentPath = path.join(__dirname, `./components/${componentName}`);
|
|
6
|
+
return loader.add(componentName, componentPath);
|
|
7
|
+
};
|
|
8
|
+
export default bundleComponent;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { useEffect, useState, } from "react";
|
|
2
|
+
import { ThemeProvider } from "styled-components";
|
|
3
|
+
import { theme, Label } from "@adminjs/design-system";
|
|
4
|
+
import { slugifyTitle } from "../../utils/index.js";
|
|
5
|
+
import { StyledInputWrapper, StyledCustomInput, StyledGenerateButton, } from "./styles.js";
|
|
6
|
+
const CustomSlug = ({ property, record, onChange }) => {
|
|
7
|
+
const [inputValue, setInputValue] = useState(record.params.slug);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
onChange(property.path, inputValue);
|
|
10
|
+
}, [inputValue]);
|
|
11
|
+
return (<ThemeProvider theme={theme}>
|
|
12
|
+
<Label htmlFor="customSlug">Slug</Label>
|
|
13
|
+
<StyledInputWrapper>
|
|
14
|
+
<StyledCustomInput id={property.path} name={property.path} value={inputValue} onChange={handleInput}/>
|
|
15
|
+
<StyledGenerateButton variant="outlined" onClick={generateSlug}>
|
|
16
|
+
Generate Slug
|
|
17
|
+
</StyledGenerateButton>
|
|
18
|
+
</StyledInputWrapper>
|
|
19
|
+
</ThemeProvider>);
|
|
20
|
+
function handleInput(e) {
|
|
21
|
+
setInputValue(e.target.value);
|
|
22
|
+
}
|
|
23
|
+
function generateSlug(e) {
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
const title = record.title;
|
|
26
|
+
setInputValue(slugifyTitle(title));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export default CustomSlug;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./CustomSlug.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { Button, Box, Input } from "@adminjs/design-system";
|
|
5
|
+
export const StyledInputWrapper = styled(Box) `
|
|
6
|
+
display: flex;
|
|
7
|
+
margin-bottom: 40px;
|
|
8
|
+
`;
|
|
9
|
+
export const StyledCustomInput = styled(Input) `
|
|
10
|
+
width: 100%;
|
|
11
|
+
margin-right: 10px;
|
|
12
|
+
`;
|
|
13
|
+
export const StyledGenerateButton = styled(Button) `
|
|
14
|
+
white-space: nowrap;
|
|
15
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./Editor.jsx";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Box } from "@adminjs/design-system";
|
|
2
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
3
|
+
export const Label = styled.div `
|
|
4
|
+
font-size: 12px;
|
|
5
|
+
margin-bottom: 8px;
|
|
6
|
+
`;
|
|
7
|
+
export const EditorWrapper = styled(Box) `
|
|
8
|
+
padding: 12px;
|
|
9
|
+
border: 1px solid rgb(187, 195, 203);
|
|
10
|
+
`;
|
|
11
|
+
export const StyledEditor = styled.div `
|
|
12
|
+
.cdx-block,
|
|
13
|
+
.ce-header {
|
|
14
|
+
padding-left: 58px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.cdx-list {
|
|
18
|
+
padding-left: 85px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.ce-block__content {
|
|
22
|
+
width: 100%;
|
|
23
|
+
max-width: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.ce-toolbar__content {
|
|
27
|
+
max-width: none;
|
|
28
|
+
left: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ce-toolbar__actions {
|
|
32
|
+
left: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
h1.ce-header {
|
|
36
|
+
font-size: 22px;
|
|
37
|
+
font-weight: bold;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h2.ce-header {
|
|
41
|
+
font-size: 20px;
|
|
42
|
+
font-weight: bold;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
h3.ce-header {
|
|
46
|
+
font-size: 18px;
|
|
47
|
+
font-weight: bold;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
h4.ce-header {
|
|
51
|
+
font-size: 16px;
|
|
52
|
+
font-weight: bold;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
h5.ce-header {
|
|
56
|
+
font-size: 15px;
|
|
57
|
+
font-weight: bold;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
h6.ce-header {
|
|
61
|
+
font-size: 14px;
|
|
62
|
+
font-weight: bold;
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { Fragment, useMemo, useState } from 'react';
|
|
2
|
+
import { DndContext, KeyboardSensor, PointerSensor, useSensor, useSensors, DragOverlay, defaultDropAnimationSideEffects, } from '@dnd-kit/core';
|
|
3
|
+
import { SortableContext, arrayMove, sortableKeyboardCoordinates, verticalListSortingStrategy, } from '@dnd-kit/sortable';
|
|
4
|
+
import { SortableItem } from './components/index.js';
|
|
5
|
+
import { StyledListWrapper } from './styles.js';
|
|
6
|
+
const dropAnimationConfig = {
|
|
7
|
+
sideEffects: defaultDropAnimationSideEffects({
|
|
8
|
+
styles: {
|
|
9
|
+
active: {
|
|
10
|
+
opacity: '0.4',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
export function SortableList({ items, onChange, renderItem, }) {
|
|
16
|
+
const [active, setActive] = useState(null);
|
|
17
|
+
const activeItem = useMemo(() => items.find((item) => item.id === active?.id), [active, items]);
|
|
18
|
+
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
|
|
19
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
|
20
|
+
}));
|
|
21
|
+
return (<DndContext sensors={sensors} onDragStart={({ active }) => {
|
|
22
|
+
setActive(active);
|
|
23
|
+
}} onDragEnd={({ active, over }) => {
|
|
24
|
+
if (over && active.id !== over?.id) {
|
|
25
|
+
const activeIndex = items.findIndex(({ id }) => id === active.id);
|
|
26
|
+
const overIndex = items.findIndex(({ id }) => id === over.id);
|
|
27
|
+
onChange(arrayMove(items, activeIndex, overIndex));
|
|
28
|
+
}
|
|
29
|
+
setActive(null);
|
|
30
|
+
}} onDragCancel={() => {
|
|
31
|
+
setActive(null);
|
|
32
|
+
}}>
|
|
33
|
+
<SortableContext items={items} strategy={verticalListSortingStrategy}>
|
|
34
|
+
<StyledListWrapper role="application">
|
|
35
|
+
{items.map((item, index) => (<Fragment key={index}>{renderItem(item)}</Fragment>))}
|
|
36
|
+
</StyledListWrapper>
|
|
37
|
+
</SortableContext>
|
|
38
|
+
<DragOverlay dropAnimation={dropAnimationConfig}>
|
|
39
|
+
{activeItem ? renderItem(activeItem) : null}
|
|
40
|
+
</DragOverlay>
|
|
41
|
+
</DndContext>);
|
|
42
|
+
}
|
|
43
|
+
SortableList.Item = SortableItem;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { DragButton } from './styles.js';
|
|
3
|
+
export const DragHandle = ({ context }) => {
|
|
4
|
+
const { attributes, listeners, ref } = useContext(context);
|
|
5
|
+
return (<DragButton {...attributes} {...listeners} ref={ref}>
|
|
6
|
+
<svg viewBox="0 0 20 20" width="13">
|
|
7
|
+
<path d="M7 2a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 2zm0 6a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 8zm0 6a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 14zm6-8a2 2 0 1 0-.001-4.001A2 2 0 0 0 13 6zm0 2a2 2 0 1 0 .001 4.001A2 2 0 0 0 13 8zm0 6a2 2 0 1 0 .001 4.001A2 2 0 0 0 13 14z"></path>
|
|
8
|
+
</svg>
|
|
9
|
+
</DragButton>);
|
|
10
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React, { createContext, useMemo } from 'react';
|
|
2
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
3
|
+
import { Button, Icon } from '@adminjs/design-system';
|
|
4
|
+
import { DragHandle } from './DragHandle.js';
|
|
5
|
+
import { StyledListItem } from './styles.js';
|
|
6
|
+
const SortableItemContext = createContext({
|
|
7
|
+
attributes: {},
|
|
8
|
+
listeners: undefined,
|
|
9
|
+
ref() { },
|
|
10
|
+
});
|
|
11
|
+
export function SortableItem({ children, id, onDelete, }) {
|
|
12
|
+
const { attributes, isDragging, listeners, setNodeRef, setActivatorNodeRef } = useSortable({ id });
|
|
13
|
+
const context = useMemo(() => ({
|
|
14
|
+
attributes,
|
|
15
|
+
listeners,
|
|
16
|
+
ref: setActivatorNodeRef,
|
|
17
|
+
}), [attributes, listeners, setActivatorNodeRef]);
|
|
18
|
+
const style = {
|
|
19
|
+
opacity: isDragging ? 0.4 : undefined,
|
|
20
|
+
};
|
|
21
|
+
return (<SortableItemContext.Provider value={context}>
|
|
22
|
+
<StyledListItem ref={setNodeRef} style={style}>
|
|
23
|
+
<div>
|
|
24
|
+
<DragHandle context={SortableItemContext}/>
|
|
25
|
+
{children}
|
|
26
|
+
</div>
|
|
27
|
+
<Button variant="outlined" color="danger" size="icon" onClick={(e) => onDelete(e, id)}>
|
|
28
|
+
<Icon icon="X" color="red"/>
|
|
29
|
+
</Button>
|
|
30
|
+
</StyledListItem>
|
|
31
|
+
</SortableItemContext.Provider>);
|
|
32
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { styled } from '@adminjs/design-system/styled-components';
|
|
2
|
+
export const StyledListItem = styled.li `
|
|
3
|
+
display: flex;
|
|
4
|
+
justify-content: space-between;
|
|
5
|
+
align-items: center;
|
|
6
|
+
background-color: #fff;
|
|
7
|
+
padding: 10px 20px 10px 15px;
|
|
8
|
+
box-shadow:
|
|
9
|
+
0 0 0 calc(1px / var(--scale-x, 1)) rgba(63, 63, 68, 0.05),
|
|
10
|
+
0 1px calc(3px / var(--scale-x, 1)) 0 rgba(34, 33, 81, 0.15);
|
|
11
|
+
border-radius: 5px;
|
|
12
|
+
list-style: none;
|
|
13
|
+
`;
|
|
14
|
+
export const DragButton = styled.button `
|
|
15
|
+
padding: 3px;
|
|
16
|
+
margin-right: 15px;
|
|
17
|
+
cursor: move;
|
|
18
|
+
background: none;
|
|
19
|
+
border: none;
|
|
20
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SortableList } from './SortableList.js';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { useState, useEffect, } from "react";
|
|
2
|
+
import { ThemeProvider } from "styled-components";
|
|
3
|
+
import { theme, Button, Input, Label } from "@adminjs/design-system";
|
|
4
|
+
import { StyledWrapper, StyledCustomInput, StyledListWrapper, StyledInputWrapper, } from "./styles.js";
|
|
5
|
+
import { SortableList } from "./SortableList/SortableList.js";
|
|
6
|
+
const StringList = ({ record, onChange, property }) => {
|
|
7
|
+
const stringListValue = record.params?.[property.path] ?? property.props.value ?? "";
|
|
8
|
+
const initialList = stringListValue
|
|
9
|
+
? prepareDataForList(stringListValue)
|
|
10
|
+
: [];
|
|
11
|
+
const [inputValue, setInputValue] = useState("");
|
|
12
|
+
const [list, setList] = useState(initialList);
|
|
13
|
+
const serializedData = prepareDataForDatabase(list);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
onChange(property.path, serializedData);
|
|
16
|
+
}, [serializedData]);
|
|
17
|
+
return (<ThemeProvider theme={theme}>
|
|
18
|
+
<Label htmlFor="custom">String List</Label>
|
|
19
|
+
<StyledWrapper>
|
|
20
|
+
<StyledListWrapper>
|
|
21
|
+
<SortableList items={list} onChange={setList} renderItem={(item) => (<SortableList.Item id={item.id} onDelete={handleDeleteButton}>
|
|
22
|
+
{item.value}
|
|
23
|
+
</SortableList.Item>)}/>
|
|
24
|
+
</StyledListWrapper>
|
|
25
|
+
<StyledInputWrapper>
|
|
26
|
+
<Input id="stringList" name={property.path} value={serializedData} hidden/>
|
|
27
|
+
<StyledCustomInput id="custom" name="customInput" value={inputValue} onChange={handleInput} onKeyPress={handleEnterPress}/>
|
|
28
|
+
<Button variant="outlined" onClick={handleAddButton}>
|
|
29
|
+
Add
|
|
30
|
+
</Button>
|
|
31
|
+
</StyledInputWrapper>
|
|
32
|
+
</StyledWrapper>
|
|
33
|
+
</ThemeProvider>);
|
|
34
|
+
function handleInput(e) {
|
|
35
|
+
setInputValue(e.target.value);
|
|
36
|
+
}
|
|
37
|
+
function handleEnterPress(e) {
|
|
38
|
+
if (e.key === "Enter") {
|
|
39
|
+
handleAddButton(e);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function handleAddButton(e) {
|
|
43
|
+
e.preventDefault();
|
|
44
|
+
if (Boolean(inputValue)) {
|
|
45
|
+
setList([...list, createListObject(inputValue)]);
|
|
46
|
+
setInputValue("");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function handleDeleteButton(e, id) {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
const newData = list.filter((item) => item.id !== id);
|
|
52
|
+
setList(newData);
|
|
53
|
+
}
|
|
54
|
+
function prepareDataForDatabase(list) {
|
|
55
|
+
return list.map(({ value }) => value).join("|");
|
|
56
|
+
}
|
|
57
|
+
function prepareDataForList(str) {
|
|
58
|
+
return str.split("|").map((item) => createListObject(item));
|
|
59
|
+
}
|
|
60
|
+
function createListObject(value) {
|
|
61
|
+
return {
|
|
62
|
+
id: `${Date.now()}-${Math.floor(Math.random() * 1000)}`,
|
|
63
|
+
value: value,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export default StringList;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./StringList.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
2
|
+
import { Box, Input } from "@adminjs/design-system";
|
|
3
|
+
export const StyledWrapper = styled(Box) `
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
`;
|
|
7
|
+
export const StyledCustomInput = styled(Input) `
|
|
8
|
+
width: 100%;
|
|
9
|
+
margin-right: 10px;
|
|
10
|
+
`;
|
|
11
|
+
export const StyledInputWrapper = styled(Box) `
|
|
12
|
+
display: flex;
|
|
13
|
+
`;
|
|
14
|
+
export const StyledListWrapper = styled(Box) `
|
|
15
|
+
margin-bottom: 15px;
|
|
16
|
+
`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { buildFeature, } from "adminjs";
|
|
2
|
+
import bundleComponent from "./bundle.js";
|
|
3
|
+
const editorFeature = (options) => {
|
|
4
|
+
const { componentLoader, name } = options;
|
|
5
|
+
const editComponent = bundleComponent(componentLoader, "Editor");
|
|
6
|
+
return buildFeature({
|
|
7
|
+
properties: {
|
|
8
|
+
[name]: {
|
|
9
|
+
components: {
|
|
10
|
+
edit: editComponent,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
export default editorFeature;
|
package/dist/index.cjs
CHANGED
|
@@ -32,7 +32,9 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
CustomSlug: () => CustomSlug_default,
|
|
34
34
|
Editor: () => Editor_default,
|
|
35
|
-
|
|
35
|
+
EditorShow: () => EditorShow_default,
|
|
36
|
+
StringList: () => StringList_default,
|
|
37
|
+
StringListShow: () => StringListShow_default
|
|
36
38
|
});
|
|
37
39
|
module.exports = __toCommonJS(src_exports);
|
|
38
40
|
|
|
@@ -49,7 +51,7 @@ var slugifyImport_default = import_slugify.default;
|
|
|
49
51
|
var slugifyTitle = (title) => {
|
|
50
52
|
return slugifyImport_default(title, {
|
|
51
53
|
replacement: "-",
|
|
52
|
-
remove:
|
|
54
|
+
remove: /[*+~.()'"!:@]/g,
|
|
53
55
|
lower: true,
|
|
54
56
|
locale: "vi",
|
|
55
57
|
trim: true
|
|
@@ -91,8 +93,10 @@ var CustomSlug = ({ property, record, onChange }) => {
|
|
|
91
93
|
}
|
|
92
94
|
function generateSlug(e) {
|
|
93
95
|
e.preventDefault();
|
|
94
|
-
const title = record.title;
|
|
95
|
-
|
|
96
|
+
const title = record.params.title;
|
|
97
|
+
if (title) {
|
|
98
|
+
setInputValue(slugifyTitle(title));
|
|
99
|
+
}
|
|
96
100
|
}
|
|
97
101
|
};
|
|
98
102
|
var CustomSlug_default = CustomSlug;
|
|
@@ -108,6 +112,7 @@ var import_design_system3 = require("@adminjs/design-system");
|
|
|
108
112
|
var StyledWrapper = (0, import_styled_components3.styled)(import_design_system3.Box)`
|
|
109
113
|
display: flex;
|
|
110
114
|
flex-direction: column;
|
|
115
|
+
margin-bottom: 45px;
|
|
111
116
|
`;
|
|
112
117
|
var StyledCustomInput2 = (0, import_styled_components3.styled)(import_design_system3.Input)`
|
|
113
118
|
width: 100%;
|
|
@@ -119,6 +124,19 @@ var StyledInputWrapper2 = (0, import_styled_components3.styled)(import_design_sy
|
|
|
119
124
|
var StyledListWrapper = (0, import_styled_components3.styled)(import_design_system3.Box)`
|
|
120
125
|
margin-bottom: 15px;
|
|
121
126
|
`;
|
|
127
|
+
var StringListShowLabel = import_styled_components3.styled.div`
|
|
128
|
+
font-size: 12px;
|
|
129
|
+
margin-bottom: 8px;
|
|
130
|
+
text-transform: capitalize;
|
|
131
|
+
line-height: 16px;
|
|
132
|
+
color: rgb(137, 138, 154);
|
|
133
|
+
`;
|
|
134
|
+
var StringListShowWrapper = (0, import_styled_components3.styled)(import_design_system3.Box)`
|
|
135
|
+
margin-bottom: 35px;
|
|
136
|
+
`;
|
|
137
|
+
var ListItem = import_styled_components3.styled.li`
|
|
138
|
+
margin-bottom: 5px;
|
|
139
|
+
`;
|
|
122
140
|
|
|
123
141
|
// src/components/StringList/SortableList/SortableList.tsx
|
|
124
142
|
var import_react4 = __toESM(require("react"), 1);
|
|
@@ -258,8 +276,16 @@ function SortableList({
|
|
|
258
276
|
}
|
|
259
277
|
SortableList.Item = SortableItem;
|
|
260
278
|
|
|
279
|
+
// src/constants.ts
|
|
280
|
+
var separator = "|";
|
|
281
|
+
|
|
261
282
|
// src/components/StringList/StringList.tsx
|
|
262
|
-
var StringList = ({
|
|
283
|
+
var StringList = ({
|
|
284
|
+
record,
|
|
285
|
+
onChange,
|
|
286
|
+
property,
|
|
287
|
+
stringListSeparator = separator
|
|
288
|
+
}) => {
|
|
263
289
|
const stringListValue = record.params?.[property.path] ?? property.props.value ?? "";
|
|
264
290
|
const initialList = stringListValue ? prepareDataForList(stringListValue) : [];
|
|
265
291
|
const [inputValue, setInputValue] = (0, import_react5.useState)("");
|
|
@@ -314,10 +340,10 @@ var StringList = ({ record, onChange, property }) => {
|
|
|
314
340
|
setList(newData);
|
|
315
341
|
}
|
|
316
342
|
function prepareDataForDatabase(list2) {
|
|
317
|
-
return list2.map(({ value }) => value).join(
|
|
343
|
+
return list2.map(({ value }) => value).join(stringListSeparator);
|
|
318
344
|
}
|
|
319
345
|
function prepareDataForList(str) {
|
|
320
|
-
return str.split(
|
|
346
|
+
return str.split(stringListSeparator).map((item) => createListObject(item));
|
|
321
347
|
}
|
|
322
348
|
function createListObject(value) {
|
|
323
349
|
return {
|
|
@@ -328,24 +354,40 @@ var StringList = ({ record, onChange, property }) => {
|
|
|
328
354
|
};
|
|
329
355
|
var StringList_default = StringList;
|
|
330
356
|
|
|
331
|
-
// src/components/
|
|
357
|
+
// src/components/StringList/StringListShow.tsx
|
|
332
358
|
var import_react6 = __toESM(require("react"), 1);
|
|
333
|
-
var
|
|
359
|
+
var import_styled_components7 = require("styled-components");
|
|
360
|
+
var import_design_system6 = require("@adminjs/design-system");
|
|
361
|
+
var StringListShow = ({
|
|
362
|
+
property,
|
|
363
|
+
record,
|
|
364
|
+
stringListSeparator = separator
|
|
365
|
+
}) => {
|
|
366
|
+
console.log(stringListSeparator, "stringListSeparator");
|
|
367
|
+
return /* @__PURE__ */ import_react6.default.createElement(import_styled_components7.ThemeProvider, { theme: import_design_system6.theme }, /* @__PURE__ */ import_react6.default.createElement(StringListShowWrapper, null, /* @__PURE__ */ import_react6.default.createElement(StringListShowLabel, null, property.name), record.params.facts && /* @__PURE__ */ import_react6.default.createElement("ul", null, record.params.facts.split(stringListSeparator).map((item, index) => /* @__PURE__ */ import_react6.default.createElement(ListItem, { key: index }, `- ${item}`)))));
|
|
368
|
+
};
|
|
369
|
+
var StringListShow_default = StringListShow;
|
|
370
|
+
|
|
371
|
+
// src/components/Editor/Editor.jsx
|
|
372
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
373
|
+
var import_styled_components9 = require("styled-components");
|
|
334
374
|
var import_editorjs = __toESM(require("@editorjs/editorjs"), 1);
|
|
335
|
-
var
|
|
375
|
+
var import_design_system8 = require("@adminjs/design-system");
|
|
336
376
|
|
|
337
377
|
// src/components/Editor/styles.ts
|
|
338
|
-
var
|
|
339
|
-
var
|
|
340
|
-
var Label3 =
|
|
378
|
+
var import_design_system7 = require("@adminjs/design-system");
|
|
379
|
+
var import_styled_components8 = require("@adminjs/design-system/styled-components");
|
|
380
|
+
var Label3 = import_styled_components8.styled.div`
|
|
341
381
|
font-size: 12px;
|
|
342
382
|
margin-bottom: 8px;
|
|
383
|
+
color: rgb(137, 138, 154);
|
|
343
384
|
`;
|
|
344
|
-
var EditorWrapper = (0,
|
|
385
|
+
var EditorWrapper = (0, import_styled_components8.styled)(import_design_system7.Box)`
|
|
345
386
|
padding: 12px;
|
|
387
|
+
margin-bottom: 24px;
|
|
346
388
|
border: 1px solid rgb(187, 195, 203);
|
|
347
389
|
`;
|
|
348
|
-
var StyledEditor =
|
|
390
|
+
var StyledEditor = import_styled_components8.styled.div`
|
|
349
391
|
.cdx-block,
|
|
350
392
|
.ce-header {
|
|
351
393
|
padding-left: 58px;
|
|
@@ -415,21 +457,18 @@ var EDITOR_TOOLS = {
|
|
|
415
457
|
|
|
416
458
|
// src/components/Editor/Editor.jsx
|
|
417
459
|
var Editor = ({ property, record, onChangeAdmin, editorId }) => {
|
|
418
|
-
const [jsonData, setJsonData] = (0,
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
);
|
|
423
|
-
const ref = (0, import_react6.useRef)();
|
|
424
|
-
(0, import_react6.useEffect)(() => {
|
|
460
|
+
const [jsonData, setJsonData] = (0, import_react7.useState)();
|
|
461
|
+
const isSavedData = Boolean(record.params[property.path]);
|
|
462
|
+
const ref = (0, import_react7.useRef)();
|
|
463
|
+
(0, import_react7.useEffect)(() => {
|
|
425
464
|
onChangeAdmin(property.path, jsonData);
|
|
426
465
|
}, [jsonData]);
|
|
427
|
-
(0,
|
|
466
|
+
(0, import_react7.useEffect)(() => {
|
|
428
467
|
if (!ref.current) {
|
|
429
468
|
const editor = new import_editorjs.default({
|
|
430
469
|
holder: editorId,
|
|
431
470
|
tools: EDITOR_TOOLS,
|
|
432
|
-
data: JSON.parse(record.params[property.path]),
|
|
471
|
+
data: isSavedData ? JSON.parse(record.params[property.path]) : "",
|
|
433
472
|
async onChange(api, event) {
|
|
434
473
|
const data = await api.saver.save();
|
|
435
474
|
setJsonData(JSON.stringify(data));
|
|
@@ -441,12 +480,38 @@ var Editor = ({ property, record, onChangeAdmin, editorId }) => {
|
|
|
441
480
|
ref?.current?.destroy?.();
|
|
442
481
|
};
|
|
443
482
|
}, []);
|
|
444
|
-
return /* @__PURE__ */
|
|
483
|
+
return /* @__PURE__ */ import_react7.default.createElement(import_styled_components9.ThemeProvider, { theme: import_design_system8.theme }, /* @__PURE__ */ import_react7.default.createElement(Label3, null, "Text"), /* @__PURE__ */ import_react7.default.createElement(EditorWrapper, null, /* @__PURE__ */ import_react7.default.createElement(StyledEditor, { id: editorId })));
|
|
445
484
|
};
|
|
446
485
|
var Editor_default = Editor;
|
|
486
|
+
|
|
487
|
+
// src/components/Editor/EditorShow.jsx
|
|
488
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
489
|
+
var import_styled_components10 = require("styled-components");
|
|
490
|
+
var import_design_system9 = require("@adminjs/design-system");
|
|
491
|
+
|
|
492
|
+
// src/utils/parseHtml.ts
|
|
493
|
+
var import_editorjs_html = __toESM(require("editorjs-html"), 1);
|
|
494
|
+
var parseHtml = (jsonData) => {
|
|
495
|
+
const edjsParser = (0, import_editorjs_html.default)();
|
|
496
|
+
try {
|
|
497
|
+
const data = edjsParser.parse(JSON.parse(String(jsonData)));
|
|
498
|
+
return String(data).replace(/>,</g, "><");
|
|
499
|
+
} catch (e) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// src/components/Editor/EditorShow.jsx
|
|
505
|
+
var EditorShow = ({ property, record }) => {
|
|
506
|
+
const htmlContent = parseHtml(record.params[property.path]);
|
|
507
|
+
return /* @__PURE__ */ import_react8.default.createElement(import_styled_components10.ThemeProvider, { theme: import_design_system9.theme }, /* @__PURE__ */ import_react8.default.createElement(Label3, null, "Content"), htmlContent && /* @__PURE__ */ import_react8.default.createElement("div", { dangerouslySetInnerHTML: { __html: String(htmlContent) } }));
|
|
508
|
+
};
|
|
509
|
+
var EditorShow_default = EditorShow;
|
|
447
510
|
// Annotate the CommonJS export names for ESM import in node:
|
|
448
511
|
0 && (module.exports = {
|
|
449
512
|
CustomSlug,
|
|
450
513
|
Editor,
|
|
451
|
-
|
|
514
|
+
EditorShow,
|
|
515
|
+
StringList,
|
|
516
|
+
StringListShow
|
|
452
517
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
|
-
import { EditPropertyProps } from 'adminjs';
|
|
2
|
+
import { EditPropertyProps, ShowPropertyProps } from 'adminjs';
|
|
3
3
|
|
|
4
4
|
type CustomSlugTypes = Omit<EditPropertyProps, "where" | "resource">;
|
|
5
5
|
declare const CustomSlug: FC<CustomSlugTypes>;
|
|
6
6
|
|
|
7
7
|
type StringListTypes = Omit<EditPropertyProps, "where" | "resource">;
|
|
8
|
-
|
|
8
|
+
interface StringListShowPropsType$1 extends StringListTypes {
|
|
9
|
+
stringListSeparator?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const StringList: FC<StringListShowPropsType$1>;
|
|
12
|
+
|
|
13
|
+
interface StringListShowPropsType extends ShowPropertyProps {
|
|
14
|
+
stringListSeparator?: string;
|
|
15
|
+
}
|
|
16
|
+
declare const StringListShow: FC<StringListShowPropsType>;
|
|
9
17
|
|
|
10
18
|
declare function Editor({ property, record, onChangeAdmin, editorId }: {
|
|
11
19
|
property: any;
|
|
@@ -14,4 +22,9 @@ declare function Editor({ property, record, onChangeAdmin, editorId }: {
|
|
|
14
22
|
editorId: any;
|
|
15
23
|
}): React.JSX.Element;
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
declare function EditorShow({ property, record }: {
|
|
26
|
+
property: any;
|
|
27
|
+
record: any;
|
|
28
|
+
}): React.JSX.Element;
|
|
29
|
+
|
|
30
|
+
export { CustomSlug, Editor, EditorShow, StringList, StringListShow };
|
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
|
-
import { EditPropertyProps } from 'adminjs';
|
|
2
|
+
import { EditPropertyProps, ShowPropertyProps } from 'adminjs';
|
|
3
3
|
|
|
4
4
|
type CustomSlugTypes = Omit<EditPropertyProps, "where" | "resource">;
|
|
5
5
|
declare const CustomSlug: FC<CustomSlugTypes>;
|
|
6
6
|
|
|
7
7
|
type StringListTypes = Omit<EditPropertyProps, "where" | "resource">;
|
|
8
|
-
|
|
8
|
+
interface StringListShowPropsType$1 extends StringListTypes {
|
|
9
|
+
stringListSeparator?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const StringList: FC<StringListShowPropsType$1>;
|
|
12
|
+
|
|
13
|
+
interface StringListShowPropsType extends ShowPropertyProps {
|
|
14
|
+
stringListSeparator?: string;
|
|
15
|
+
}
|
|
16
|
+
declare const StringListShow: FC<StringListShowPropsType>;
|
|
9
17
|
|
|
10
18
|
declare function Editor({ property, record, onChangeAdmin, editorId }: {
|
|
11
19
|
property: any;
|
|
@@ -14,4 +22,9 @@ declare function Editor({ property, record, onChangeAdmin, editorId }: {
|
|
|
14
22
|
editorId: any;
|
|
15
23
|
}): React.JSX.Element;
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
declare function EditorShow({ property, record }: {
|
|
26
|
+
property: any;
|
|
27
|
+
record: any;
|
|
28
|
+
}): React.JSX.Element;
|
|
29
|
+
|
|
30
|
+
export { CustomSlug, Editor, EditorShow, StringList, StringListShow };
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var slugifyImport_default = slugify;
|
|
|
14
14
|
var slugifyTitle = (title) => {
|
|
15
15
|
return slugifyImport_default(title, {
|
|
16
16
|
replacement: "-",
|
|
17
|
-
remove:
|
|
17
|
+
remove: /[*+~.()'"!:@]/g,
|
|
18
18
|
lower: true,
|
|
19
19
|
locale: "vi",
|
|
20
20
|
trim: true
|
|
@@ -56,8 +56,10 @@ var CustomSlug = ({ property, record, onChange }) => {
|
|
|
56
56
|
}
|
|
57
57
|
function generateSlug(e) {
|
|
58
58
|
e.preventDefault();
|
|
59
|
-
const title = record.title;
|
|
60
|
-
|
|
59
|
+
const title = record.params.title;
|
|
60
|
+
if (title) {
|
|
61
|
+
setInputValue(slugifyTitle(title));
|
|
62
|
+
}
|
|
61
63
|
}
|
|
62
64
|
};
|
|
63
65
|
var CustomSlug_default = CustomSlug;
|
|
@@ -76,6 +78,7 @@ import { Box as Box2, Input as Input2 } from "@adminjs/design-system";
|
|
|
76
78
|
var StyledWrapper = styled2(Box2)`
|
|
77
79
|
display: flex;
|
|
78
80
|
flex-direction: column;
|
|
81
|
+
margin-bottom: 45px;
|
|
79
82
|
`;
|
|
80
83
|
var StyledCustomInput2 = styled2(Input2)`
|
|
81
84
|
width: 100%;
|
|
@@ -87,6 +90,19 @@ var StyledInputWrapper2 = styled2(Box2)`
|
|
|
87
90
|
var StyledListWrapper = styled2(Box2)`
|
|
88
91
|
margin-bottom: 15px;
|
|
89
92
|
`;
|
|
93
|
+
var StringListShowLabel = styled2.div`
|
|
94
|
+
font-size: 12px;
|
|
95
|
+
margin-bottom: 8px;
|
|
96
|
+
text-transform: capitalize;
|
|
97
|
+
line-height: 16px;
|
|
98
|
+
color: rgb(137, 138, 154);
|
|
99
|
+
`;
|
|
100
|
+
var StringListShowWrapper = styled2(Box2)`
|
|
101
|
+
margin-bottom: 35px;
|
|
102
|
+
`;
|
|
103
|
+
var ListItem = styled2.li`
|
|
104
|
+
margin-bottom: 5px;
|
|
105
|
+
`;
|
|
90
106
|
|
|
91
107
|
// src/components/StringList/SortableList/SortableList.tsx
|
|
92
108
|
import React4, { Fragment, useMemo as useMemo2, useState as useState2 } from "react";
|
|
@@ -239,8 +255,16 @@ function SortableList({
|
|
|
239
255
|
}
|
|
240
256
|
SortableList.Item = SortableItem;
|
|
241
257
|
|
|
258
|
+
// src/constants.ts
|
|
259
|
+
var separator = "|";
|
|
260
|
+
|
|
242
261
|
// src/components/StringList/StringList.tsx
|
|
243
|
-
var StringList = ({
|
|
262
|
+
var StringList = ({
|
|
263
|
+
record,
|
|
264
|
+
onChange,
|
|
265
|
+
property,
|
|
266
|
+
stringListSeparator = separator
|
|
267
|
+
}) => {
|
|
244
268
|
const stringListValue = record.params?.[property.path] ?? property.props.value ?? "";
|
|
245
269
|
const initialList = stringListValue ? prepareDataForList(stringListValue) : [];
|
|
246
270
|
const [inputValue, setInputValue] = useState3("");
|
|
@@ -295,10 +319,10 @@ var StringList = ({ record, onChange, property }) => {
|
|
|
295
319
|
setList(newData);
|
|
296
320
|
}
|
|
297
321
|
function prepareDataForDatabase(list2) {
|
|
298
|
-
return list2.map(({ value }) => value).join(
|
|
322
|
+
return list2.map(({ value }) => value).join(stringListSeparator);
|
|
299
323
|
}
|
|
300
324
|
function prepareDataForList(str) {
|
|
301
|
-
return str.split(
|
|
325
|
+
return str.split(stringListSeparator).map((item) => createListObject(item));
|
|
302
326
|
}
|
|
303
327
|
function createListObject(value) {
|
|
304
328
|
return {
|
|
@@ -309,11 +333,25 @@ var StringList = ({ record, onChange, property }) => {
|
|
|
309
333
|
};
|
|
310
334
|
var StringList_default = StringList;
|
|
311
335
|
|
|
312
|
-
// src/components/
|
|
313
|
-
import React6
|
|
336
|
+
// src/components/StringList/StringListShow.tsx
|
|
337
|
+
import React6 from "react";
|
|
314
338
|
import { ThemeProvider as ThemeProvider3 } from "styled-components";
|
|
315
|
-
import EditorJS from "@editorjs/editorjs";
|
|
316
339
|
import { theme as theme3 } from "@adminjs/design-system";
|
|
340
|
+
var StringListShow = ({
|
|
341
|
+
property,
|
|
342
|
+
record,
|
|
343
|
+
stringListSeparator = separator
|
|
344
|
+
}) => {
|
|
345
|
+
console.log(stringListSeparator, "stringListSeparator");
|
|
346
|
+
return /* @__PURE__ */ React6.createElement(ThemeProvider3, { theme: theme3 }, /* @__PURE__ */ React6.createElement(StringListShowWrapper, null, /* @__PURE__ */ React6.createElement(StringListShowLabel, null, property.name), record.params.facts && /* @__PURE__ */ React6.createElement("ul", null, record.params.facts.split(stringListSeparator).map((item, index) => /* @__PURE__ */ React6.createElement(ListItem, { key: index }, `- ${item}`)))));
|
|
347
|
+
};
|
|
348
|
+
var StringListShow_default = StringListShow;
|
|
349
|
+
|
|
350
|
+
// src/components/Editor/Editor.jsx
|
|
351
|
+
import React7, { memo as memo2, useState as useState5, useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
352
|
+
import { ThemeProvider as ThemeProvider4 } from "styled-components";
|
|
353
|
+
import EditorJS from "@editorjs/editorjs";
|
|
354
|
+
import { theme as theme4 } from "@adminjs/design-system";
|
|
317
355
|
|
|
318
356
|
// src/components/Editor/styles.ts
|
|
319
357
|
import { Box as Box3 } from "@adminjs/design-system";
|
|
@@ -321,9 +359,11 @@ import { styled as styled5 } from "@adminjs/design-system/styled-components";
|
|
|
321
359
|
var Label3 = styled5.div`
|
|
322
360
|
font-size: 12px;
|
|
323
361
|
margin-bottom: 8px;
|
|
362
|
+
color: rgb(137, 138, 154);
|
|
324
363
|
`;
|
|
325
364
|
var EditorWrapper = styled5(Box3)`
|
|
326
365
|
padding: 12px;
|
|
366
|
+
margin-bottom: 24px;
|
|
327
367
|
border: 1px solid rgb(187, 195, 203);
|
|
328
368
|
`;
|
|
329
369
|
var StyledEditor = styled5.div`
|
|
@@ -396,21 +436,18 @@ var EDITOR_TOOLS = {
|
|
|
396
436
|
|
|
397
437
|
// src/components/Editor/Editor.jsx
|
|
398
438
|
var Editor = ({ property, record, onChangeAdmin, editorId }) => {
|
|
399
|
-
const [jsonData, setJsonData] =
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
);
|
|
404
|
-
const ref = useRef();
|
|
405
|
-
useEffect3(() => {
|
|
439
|
+
const [jsonData, setJsonData] = useState5();
|
|
440
|
+
const isSavedData = Boolean(record.params[property.path]);
|
|
441
|
+
const ref = useRef2();
|
|
442
|
+
useEffect4(() => {
|
|
406
443
|
onChangeAdmin(property.path, jsonData);
|
|
407
444
|
}, [jsonData]);
|
|
408
|
-
|
|
445
|
+
useEffect4(() => {
|
|
409
446
|
if (!ref.current) {
|
|
410
447
|
const editor = new EditorJS({
|
|
411
448
|
holder: editorId,
|
|
412
449
|
tools: EDITOR_TOOLS,
|
|
413
|
-
data: JSON.parse(record.params[property.path]),
|
|
450
|
+
data: isSavedData ? JSON.parse(record.params[property.path]) : "",
|
|
414
451
|
async onChange(api, event) {
|
|
415
452
|
const data = await api.saver.save();
|
|
416
453
|
setJsonData(JSON.stringify(data));
|
|
@@ -422,11 +459,37 @@ var Editor = ({ property, record, onChangeAdmin, editorId }) => {
|
|
|
422
459
|
ref?.current?.destroy?.();
|
|
423
460
|
};
|
|
424
461
|
}, []);
|
|
425
|
-
return /* @__PURE__ */
|
|
462
|
+
return /* @__PURE__ */ React7.createElement(ThemeProvider4, { theme: theme4 }, /* @__PURE__ */ React7.createElement(Label3, null, "Text"), /* @__PURE__ */ React7.createElement(EditorWrapper, null, /* @__PURE__ */ React7.createElement(StyledEditor, { id: editorId })));
|
|
426
463
|
};
|
|
427
464
|
var Editor_default = Editor;
|
|
465
|
+
|
|
466
|
+
// src/components/Editor/EditorShow.jsx
|
|
467
|
+
import React8, { memo as memo3, useState as useState6, useEffect as useEffect5, useRef as useRef3 } from "react";
|
|
468
|
+
import { ThemeProvider as ThemeProvider5 } from "styled-components";
|
|
469
|
+
import { theme as theme5 } from "@adminjs/design-system";
|
|
470
|
+
|
|
471
|
+
// src/utils/parseHtml.ts
|
|
472
|
+
import edjsHTML from "editorjs-html";
|
|
473
|
+
var parseHtml = (jsonData) => {
|
|
474
|
+
const edjsParser = edjsHTML();
|
|
475
|
+
try {
|
|
476
|
+
const data = edjsParser.parse(JSON.parse(String(jsonData)));
|
|
477
|
+
return String(data).replace(/>,</g, "><");
|
|
478
|
+
} catch (e) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/components/Editor/EditorShow.jsx
|
|
484
|
+
var EditorShow = ({ property, record }) => {
|
|
485
|
+
const htmlContent = parseHtml(record.params[property.path]);
|
|
486
|
+
return /* @__PURE__ */ React8.createElement(ThemeProvider5, { theme: theme5 }, /* @__PURE__ */ React8.createElement(Label3, null, "Content"), htmlContent && /* @__PURE__ */ React8.createElement("div", { dangerouslySetInnerHTML: { __html: String(htmlContent) } }));
|
|
487
|
+
};
|
|
488
|
+
var EditorShow_default = EditorShow;
|
|
428
489
|
export {
|
|
429
490
|
CustomSlug_default as CustomSlug,
|
|
430
491
|
Editor_default as Editor,
|
|
431
|
-
|
|
492
|
+
EditorShow_default as EditorShow,
|
|
493
|
+
StringList_default as StringList,
|
|
494
|
+
StringListShow_default as StringListShow
|
|
432
495
|
};
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/features/editorFeature.ts
|
|
2
|
+
import {
|
|
3
|
+
buildFeature
|
|
4
|
+
} from "adminjs";
|
|
5
|
+
|
|
6
|
+
// src/bundle.ts
|
|
7
|
+
import path from "path";
|
|
8
|
+
import * as url from "url";
|
|
9
|
+
var __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
10
|
+
var bundle = (loader, componentName) => {
|
|
11
|
+
const componentPath = path.join(__dirname, `./components/${componentName}`);
|
|
12
|
+
return loader.add(componentName, componentPath);
|
|
13
|
+
};
|
|
14
|
+
var bundle_default = bundle;
|
|
15
|
+
|
|
16
|
+
// src/features/editorFeature.ts
|
|
17
|
+
var editorFeature = (options) => {
|
|
18
|
+
const { componentLoader } = options;
|
|
19
|
+
const editComponent = bundle_default(componentLoader, "Editor");
|
|
20
|
+
return buildFeature({
|
|
21
|
+
properties: {
|
|
22
|
+
editor: {
|
|
23
|
+
components: {
|
|
24
|
+
edit: editComponent
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var editorFeature_default = editorFeature;
|
|
31
|
+
|
|
32
|
+
// src/index.ts
|
|
33
|
+
var src_default = editorFeature_default;
|
|
34
|
+
export {
|
|
35
|
+
src_default as default,
|
|
36
|
+
editorFeature_default as editorFeature
|
|
37
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { slugifyTitle } from "./slugifyTitle.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulab/adminjs-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@editorjs/list": "^1.9.0",
|
|
26
26
|
"@editorjs/paragraph": "^2.11.6",
|
|
27
27
|
"adminjs": "^7.8.1",
|
|
28
|
+
"editorjs-html": "^3.4.3",
|
|
28
29
|
"react": "^18.2.0",
|
|
29
30
|
"slugify": "^1.6.6",
|
|
30
31
|
"styled-components": "^6.1.11"
|
|
@@ -50,8 +50,10 @@ const CustomSlug: FC<CustomSlugTypes> = ({ property, record, onChange }) => {
|
|
|
50
50
|
|
|
51
51
|
function generateSlug(e: SyntheticEvent<HTMLInputElement>) {
|
|
52
52
|
e.preventDefault();
|
|
53
|
-
const title = record.title;
|
|
54
|
-
|
|
53
|
+
const title = record.params.title;
|
|
54
|
+
if (title) {
|
|
55
|
+
setInputValue(slugifyTitle(title));
|
|
56
|
+
}
|
|
55
57
|
}
|
|
56
58
|
};
|
|
57
59
|
|
|
@@ -9,6 +9,7 @@ import { EDITOR_TOOLS } from "./config";
|
|
|
9
9
|
|
|
10
10
|
const Editor = ({ property, record, onChangeAdmin, editorId }) => {
|
|
11
11
|
const [jsonData, setJsonData] = useState();
|
|
12
|
+
const isSavedData = Boolean(record.params[property.path]);
|
|
12
13
|
|
|
13
14
|
const ref = useRef();
|
|
14
15
|
|
|
@@ -21,7 +22,7 @@ const Editor = ({ property, record, onChangeAdmin, editorId }) => {
|
|
|
21
22
|
const editor = new EditorJS({
|
|
22
23
|
holder: editorId,
|
|
23
24
|
tools: EDITOR_TOOLS,
|
|
24
|
-
data: JSON.parse(record.params[property.path]),
|
|
25
|
+
data: isSavedData ? JSON.parse(record.params[property.path]) : "",
|
|
25
26
|
async onChange(api, event) {
|
|
26
27
|
const data = await api.saver.save();
|
|
27
28
|
setJsonData(JSON.stringify(data));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { memo, useState, useEffect, useRef } from "react";
|
|
2
|
+
import { ThemeProvider } from "styled-components";
|
|
3
|
+
import { theme } from "@adminjs/design-system";
|
|
4
|
+
|
|
5
|
+
import { parseHtml } from "../../utils/parseHtml";
|
|
6
|
+
|
|
7
|
+
import { Label } from "./styles";
|
|
8
|
+
|
|
9
|
+
const EditorShow = ({ property, record }) => {
|
|
10
|
+
const htmlContent = parseHtml(record.params[property.path]);
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<ThemeProvider theme={theme}>
|
|
14
|
+
<Label>Content</Label>
|
|
15
|
+
{htmlContent && (
|
|
16
|
+
<div dangerouslySetInnerHTML={{ __html: String(htmlContent) }} />
|
|
17
|
+
)}
|
|
18
|
+
</ThemeProvider>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default EditorShow;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./Editor.jsx";
|
|
2
|
+
export * from "./EditorShow.jsx";
|
|
@@ -4,10 +4,12 @@ import { styled } from "@adminjs/design-system/styled-components";
|
|
|
4
4
|
export const Label = styled.div`
|
|
5
5
|
font-size: 12px;
|
|
6
6
|
margin-bottom: 8px;
|
|
7
|
+
color: rgb(137, 138, 154);
|
|
7
8
|
`;
|
|
8
9
|
|
|
9
10
|
export const EditorWrapper = styled(Box)`
|
|
10
11
|
padding: 12px;
|
|
12
|
+
margin-bottom: 24px;
|
|
11
13
|
border: 1px solid rgb(187, 195, 203);
|
|
12
14
|
`;
|
|
13
15
|
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "./styles.js";
|
|
19
19
|
|
|
20
20
|
import { SortableList } from "./SortableList/SortableList.js";
|
|
21
|
+
import { separator } from "./constants.js";
|
|
21
22
|
|
|
22
23
|
type ListDataTypes = {
|
|
23
24
|
id: string;
|
|
@@ -26,7 +27,16 @@ type ListDataTypes = {
|
|
|
26
27
|
|
|
27
28
|
type StringListTypes = Omit<EditPropertyProps, "where" | "resource">;
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
interface StringListShowPropsType extends StringListTypes {
|
|
31
|
+
stringListSeparator?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const StringList: FC<StringListShowPropsType> = ({
|
|
35
|
+
record,
|
|
36
|
+
onChange,
|
|
37
|
+
property,
|
|
38
|
+
stringListSeparator = separator,
|
|
39
|
+
}) => {
|
|
30
40
|
const stringListValue =
|
|
31
41
|
record.params?.[property.path] ?? property.props.value ?? "";
|
|
32
42
|
|
|
@@ -107,11 +117,11 @@ const StringList: FC<StringListTypes> = ({ record, onChange, property }) => {
|
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
function prepareDataForDatabase(list: ListDataTypes[]) {
|
|
110
|
-
return list.map(({ value }) => value).join(
|
|
120
|
+
return list.map(({ value }) => value).join(stringListSeparator);
|
|
111
121
|
}
|
|
112
122
|
|
|
113
123
|
function prepareDataForList(str: string) {
|
|
114
|
-
return str.split(
|
|
124
|
+
return str.split(stringListSeparator).map((item) => createListObject(item));
|
|
115
125
|
}
|
|
116
126
|
|
|
117
127
|
function createListObject(value: string) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { memo, useState, useEffect, useRef, FC } from "react";
|
|
2
|
+
import { ShowPropertyProps } from "adminjs";
|
|
3
|
+
|
|
4
|
+
import { ThemeProvider } from "styled-components";
|
|
5
|
+
import { theme } from "@adminjs/design-system";
|
|
6
|
+
|
|
7
|
+
import { StringListShowLabel, StringListShowWrapper, ListItem } from "./styles";
|
|
8
|
+
import { separator } from "./constants";
|
|
9
|
+
|
|
10
|
+
interface StringListShowPropsType extends ShowPropertyProps {
|
|
11
|
+
stringListSeparator?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const StringListShow: FC<StringListShowPropsType> = ({
|
|
15
|
+
property,
|
|
16
|
+
record,
|
|
17
|
+
stringListSeparator = separator,
|
|
18
|
+
}) => {
|
|
19
|
+
return (
|
|
20
|
+
<ThemeProvider theme={theme}>
|
|
21
|
+
<StringListShowWrapper>
|
|
22
|
+
<StringListShowLabel>{property.name}</StringListShowLabel>
|
|
23
|
+
{record.params.facts && (
|
|
24
|
+
<ul>
|
|
25
|
+
{record.params.facts
|
|
26
|
+
.split(stringListSeparator)
|
|
27
|
+
.map((item: string, index: number) => (
|
|
28
|
+
<ListItem key={index}>{`- ${item}`}</ListItem>
|
|
29
|
+
))}
|
|
30
|
+
</ul>
|
|
31
|
+
)}
|
|
32
|
+
</StringListShowWrapper>
|
|
33
|
+
</ThemeProvider>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default StringListShow;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const separator = "|";
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./StringList.js";
|
|
2
|
+
export * from "./StringListShow.js";
|
|
@@ -4,6 +4,7 @@ import { Box, Input } from "@adminjs/design-system";
|
|
|
4
4
|
export const StyledWrapper = styled(Box)`
|
|
5
5
|
display: flex;
|
|
6
6
|
flex-direction: column;
|
|
7
|
+
margin-bottom: 45px;
|
|
7
8
|
`;
|
|
8
9
|
|
|
9
10
|
export const StyledCustomInput = styled(Input)`
|
|
@@ -18,3 +19,19 @@ export const StyledInputWrapper = styled(Box)`
|
|
|
18
19
|
export const StyledListWrapper = styled(Box)`
|
|
19
20
|
margin-bottom: 15px;
|
|
20
21
|
`;
|
|
22
|
+
|
|
23
|
+
export const StringListShowLabel = styled.div`
|
|
24
|
+
font-size: 12px;
|
|
25
|
+
margin-bottom: 8px;
|
|
26
|
+
text-transform: capitalize;
|
|
27
|
+
line-height: 16px;
|
|
28
|
+
color: rgb(137, 138, 154);
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
export const StringListShowWrapper = styled(Box)`
|
|
32
|
+
margin-bottom: 35px;
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
export const ListItem = styled.li`
|
|
36
|
+
margin-bottom: 5px;
|
|
37
|
+
`;
|
package/src/components/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { default as CustomSlug } from "./CustomSlug/CustomSlug.js";
|
|
2
2
|
export { default as StringList } from "./StringList/StringList.js";
|
|
3
|
-
export { default as
|
|
3
|
+
export { default as StringListShow } from "./StringList/StringListShow.js";
|
|
4
|
+
export { default as Editor } from "./Editor/Editor.jsx";
|
|
5
|
+
export { default as EditorShow } from "./Editor/EditorShow.jsx";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import edjsHTML from "editorjs-html";
|
|
2
|
+
|
|
3
|
+
export const parseHtml = (jsonData?: string) => {
|
|
4
|
+
const edjsParser = edjsHTML();
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const data = edjsParser.parse(JSON.parse(String(jsonData)));
|
|
8
|
+
return String(data).replace(/>,</g, "><");
|
|
9
|
+
} catch (e) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
};
|