@evoke-platform/ui-components 1.0.0-dev.163 → 1.0.0-dev.164
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/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js +1 -1
- package/package.json +9 -4
- package/dist/published/shared/RichTextEditor/MergeFieldDialog.d.ts +0 -11
- package/dist/published/shared/RichTextEditor/MergeFieldDialog.js +0 -174
- package/dist/published/shared/RichTextEditor/QRDialog.d.ts +0 -13
- package/dist/published/shared/RichTextEditor/QRDialog.js +0 -90
- package/dist/published/shared/RichTextEditor/RichTextEditor.d.ts +0 -20
- package/dist/published/shared/RichTextEditor/RichTextEditor.js +0 -223
- package/dist/published/shared/RichTextEditor/index.d.ts +0 -3
- package/dist/published/shared/RichTextEditor/index.js +0 -3
- package/dist/published/shared/RichTextEditor/utils.d.ts +0 -31
- package/dist/published/shared/RichTextEditor/utils.js +0 -119
- package/dist/published/stories/RichTextEditor.stories.d.ts +0 -5
- package/dist/published/stories/RichTextEditor.stories.js +0 -11
package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Popover } from '@mui/material';
|
2
2
|
import React, { useEffect, useState } from 'react';
|
3
3
|
import InputMask from 'react-input-mask';
|
4
|
-
import { CancelOutlined } from '
|
4
|
+
import { CancelOutlined } from '@mui/icons-material';
|
5
5
|
import { Button, List, ListItem, TextField, Typography } from '../../../core';
|
6
6
|
import { Box } from '../../../layout';
|
7
7
|
const AddressFieldComponent = (props) => {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@evoke-platform/ui-components",
|
3
|
-
"version": "1.0.0-dev.
|
3
|
+
"version": "1.0.0-dev.164",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/published/index.js",
|
6
6
|
"module": "dist/published/index.js",
|
@@ -10,13 +10,18 @@
|
|
10
10
|
"colors.ts",
|
11
11
|
"types.ts"
|
12
12
|
],
|
13
|
+
"exports": {
|
14
|
+
".": "./dist/published/index.js",
|
15
|
+
"./colors": "./dist/published/colors/index.js",
|
16
|
+
"./icons": "./dist/published/icons/index.js",
|
17
|
+
"./types": "./dist/published/types/index.js"
|
18
|
+
},
|
13
19
|
"scripts": {
|
14
20
|
"test": "jest",
|
15
21
|
"copy-files": "copyfiles -u 1 src/styles/*.css dist/published/",
|
16
|
-
"build": "rm -rf
|
17
|
-
"build:esm": "tsc",
|
22
|
+
"build": "rm -rf ./dist && tsc",
|
18
23
|
"build:cjs": "tsc --module CommonJS --outDir dist/cjs",
|
19
|
-
"prepublish": "rm -rf
|
24
|
+
"prepublish": "rm -rf ./dist && tsc && npm run copy-files",
|
20
25
|
"storybook": "start-storybook -p 6006",
|
21
26
|
"build-storybook": "build-storybook",
|
22
27
|
"lint": "prettier --check src/**/*.*",
|
@@ -1,11 +0,0 @@
|
|
1
|
-
/// <reference types="react" />
|
2
|
-
import { EvokeObject } from '../../components/custom/types';
|
3
|
-
declare type MergeFieldDialogProps = {
|
4
|
-
objectId: string;
|
5
|
-
openMergeFieldDialog: boolean;
|
6
|
-
setOpenMergeFieldDialog: (open: boolean) => void;
|
7
|
-
insertMergeField: (mergeField: string, type?: string) => void;
|
8
|
-
fetchObject: (id: string) => Promise<EvokeObject | undefined>;
|
9
|
-
};
|
10
|
-
export default function MergeFieldDialog(props: MergeFieldDialogProps): JSX.Element;
|
11
|
-
export {};
|
@@ -1,174 +0,0 @@
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
-
});
|
9
|
-
};
|
10
|
-
import React, { useEffect, useState } from 'react';
|
11
|
-
import { Box, Button, Dialog, DialogContent, DialogTitle, TreeView, TreeItem, Typography, Divider, styled, Tooltip, Skeleton, } from '../..';
|
12
|
-
import { ChevronRight, ExpandMore } from '../../icons';
|
13
|
-
import { getAddressProperties } from './utils';
|
14
|
-
const StyledSpan = styled('span')({
|
15
|
-
marginLeft: '5px',
|
16
|
-
});
|
17
|
-
const PropertyTreeItem = (props) => {
|
18
|
-
var _a;
|
19
|
-
const { property, handleClick } = props;
|
20
|
-
return (React.createElement(TreeItem, Object.assign({ key: property.expandedId, nodeId: property.expandedId, label: property.name, onClick: () => handleClick(property), sx: { '& .MuiTreeItem-label': { whiteSpace: 'normal' }, width: '100%' } }, (property.type === 'object' || property.type === 'address' || property.type === 'collection'
|
21
|
-
? {
|
22
|
-
endIcon: React.createElement(ChevronRight, null),
|
23
|
-
}
|
24
|
-
: {})), property.children && (React.createElement(React.Fragment, null, (_a = property.children) === null || _a === void 0 ? void 0 : _a.map((childProperty) => {
|
25
|
-
if (childProperty.name === 'Loading...') {
|
26
|
-
return (React.createElement(TreeItem, { key: childProperty.id, nodeId: childProperty.expandedId, label: React.createElement(React.Fragment, null,
|
27
|
-
React.createElement(Skeleton, null),
|
28
|
-
React.createElement(Skeleton, null),
|
29
|
-
React.createElement(Skeleton, null)), sx: { '& .MuiTreeItem-label': { whiteSpace: 'normal' }, width: '100%' } }));
|
30
|
-
}
|
31
|
-
else if (childProperty.name === '<<foreach>> Wrapper') {
|
32
|
-
return (React.createElement(Tooltip, { placement: "top", title: React.createElement("div", null,
|
33
|
-
"This wrapper is required to display each item within this collection. For example...",
|
34
|
-
React.createElement("div", null, `
|
35
|
-
<<foreach [item in myCollection]>>
|
36
|
-
<<[item.firstName]>>, <<[item.lastName]>>
|
37
|
-
<</foreach>>`)), children: React.createElement(TreeItem, { key: childProperty.expandedId, nodeId: `${childProperty.expandedId}-collection`, label: childProperty.name, onClick: () => handleClick(childProperty), sx: {
|
38
|
-
'& .MuiTreeItem-label': { whiteSpace: 'normal' },
|
39
|
-
width: '100%',
|
40
|
-
backgroundColor: '#f5f5f5',
|
41
|
-
} }) }));
|
42
|
-
}
|
43
|
-
else {
|
44
|
-
return React.createElement(PropertyTreeItem, { property: childProperty, handleClick: handleClick });
|
45
|
-
}
|
46
|
-
})))));
|
47
|
-
};
|
48
|
-
export default function MergeFieldDialog(props) {
|
49
|
-
const { objectId, openMergeFieldDialog, setOpenMergeFieldDialog, insertMergeField, fetchObject } = props;
|
50
|
-
const [selectedProperty, setSelectedProperty] = useState();
|
51
|
-
const [propertyTree, setPropertyTree] = useState([]);
|
52
|
-
const getProperties = (objectId) => __awaiter(this, void 0, void 0, function* () {
|
53
|
-
try {
|
54
|
-
const data = yield fetchObject(objectId);
|
55
|
-
if (data === null || data === void 0 ? void 0 : data.properties) {
|
56
|
-
setPropertyTree(data.properties.map((property) => (Object.assign(Object.assign(Object.assign({}, property), { expandedId: property.id, mergeFieldId: `${property.id}` }), ((property.type === 'object' ||
|
57
|
-
property.type === 'address' ||
|
58
|
-
property.type === 'collection') && {
|
59
|
-
children: [
|
60
|
-
{
|
61
|
-
id: `${property.id}-loading`,
|
62
|
-
name: 'Loading...',
|
63
|
-
},
|
64
|
-
],
|
65
|
-
})))));
|
66
|
-
}
|
67
|
-
}
|
68
|
-
catch (error) {
|
69
|
-
console.log('Error:', error);
|
70
|
-
}
|
71
|
-
});
|
72
|
-
useEffect(() => {
|
73
|
-
getProperties(objectId);
|
74
|
-
}, [objectId]);
|
75
|
-
const handleSubmit = () => {
|
76
|
-
if (!selectedProperty)
|
77
|
-
return;
|
78
|
-
insertMergeField(selectedProperty.mergeFieldId, selectedProperty.expandedId);
|
79
|
-
setOpenMergeFieldDialog(false);
|
80
|
-
};
|
81
|
-
const handleClick = (property) => __awaiter(this, void 0, void 0, function* () {
|
82
|
-
if (property.type !== 'object' && property.type !== 'address' && property.type !== 'collection') {
|
83
|
-
setSelectedProperty(property);
|
84
|
-
}
|
85
|
-
else if (property.type === 'collection' && property.mergeFieldId.includes('foreach')) {
|
86
|
-
setSelectedProperty(property);
|
87
|
-
}
|
88
|
-
else {
|
89
|
-
const getChildren = (objectId, collectionNumber) => __awaiter(this, void 0, void 0, function* () {
|
90
|
-
try {
|
91
|
-
const object = yield fetchObject(objectId);
|
92
|
-
if (object === null || object === void 0 ? void 0 : object.properties) {
|
93
|
-
const children = object.properties.map((prop) => {
|
94
|
-
const mergeFieldPrefix = property.type === 'collection' ? `item${collectionNumber}` : `${property.mergeFieldId}`;
|
95
|
-
// conso;
|
96
|
-
return Object.assign(Object.assign(Object.assign({}, prop), { expandedId: `${property.expandedId}.${prop.id}`, mergeFieldId: `${mergeFieldPrefix}?.${prop.id}` }), (prop.type === 'object' || prop.type === 'address' || prop.type === 'collection'
|
97
|
-
? {
|
98
|
-
children: [
|
99
|
-
{
|
100
|
-
id: `${property.expandedId}.${prop.id}-loading`,
|
101
|
-
name: 'Loading...',
|
102
|
-
},
|
103
|
-
],
|
104
|
-
}
|
105
|
-
: {}));
|
106
|
-
});
|
107
|
-
return children;
|
108
|
-
}
|
109
|
-
}
|
110
|
-
catch (error) {
|
111
|
-
console.log('Error:', error);
|
112
|
-
}
|
113
|
-
});
|
114
|
-
const updatePropertyTree = (tree, level) => __awaiter(this, void 0, void 0, function* () {
|
115
|
-
const updatedTree = yield Promise.all(tree.map((node) => __awaiter(this, void 0, void 0, function* () {
|
116
|
-
if (node.expandedId === property.expandedId) {
|
117
|
-
if (property.type === 'address') {
|
118
|
-
return Object.assign(Object.assign({}, node), { children: getAddressProperties(node) });
|
119
|
-
}
|
120
|
-
if (node.children && property.objectId) {
|
121
|
-
const collectionNumber = property.type === 'collection' ? level + 1 : level;
|
122
|
-
const children = yield getChildren(property.objectId, collectionNumber);
|
123
|
-
if (children) {
|
124
|
-
return Object.assign(Object.assign({}, node), { children: [
|
125
|
-
property.type === 'collection' && {
|
126
|
-
id: `${node.expandedId}-collection`,
|
127
|
-
expandedId: `${node.expandedId}`,
|
128
|
-
name: '<<foreach>> Wrapper',
|
129
|
-
mergeFieldId: `foreach [item${collectionNumber} in ${node.mergeFieldId}]`,
|
130
|
-
},
|
131
|
-
...children,
|
132
|
-
] });
|
133
|
-
}
|
134
|
-
}
|
135
|
-
}
|
136
|
-
if (node.children) {
|
137
|
-
node.children = yield updatePropertyTree(node.children, level + 1);
|
138
|
-
}
|
139
|
-
return node;
|
140
|
-
})));
|
141
|
-
return updatedTree;
|
142
|
-
});
|
143
|
-
const updatedPropertyTree = yield updatePropertyTree(propertyTree, 0);
|
144
|
-
setPropertyTree(updatedPropertyTree);
|
145
|
-
}
|
146
|
-
});
|
147
|
-
return (React.createElement(Dialog, { open: openMergeFieldDialog, onClose: () => setOpenMergeFieldDialog(false), hideBackdrop: true, sx: {
|
148
|
-
'& .MuiDialog-paper': {
|
149
|
-
width: '90%',
|
150
|
-
maxWidth: '600px',
|
151
|
-
},
|
152
|
-
borderRadius: '8px',
|
153
|
-
} },
|
154
|
-
React.createElement(DialogTitle, null, "Insert Merge Field"),
|
155
|
-
React.createElement(DialogContent, { sx: { marginTop: '5px' } },
|
156
|
-
selectedProperty ? (React.createElement(Typography, null,
|
157
|
-
React.createElement("strong", null, "Selected Field:"),
|
158
|
-
React.createElement(StyledSpan, null, selectedProperty.expandedId.replace(/\?/g, '')))) : (React.createElement(Typography, null, "Select a field to merge")),
|
159
|
-
React.createElement(Divider, { sx: { marginTop: '10px', marginBottom: '10px' } }),
|
160
|
-
React.createElement(TreeView, { "aria-label": "merge field navigator", defaultCollapseIcon: React.createElement(ExpandMore, null), defaultExpandIcon: React.createElement(ChevronRight, null), sx: {
|
161
|
-
height: 300,
|
162
|
-
width: '100%',
|
163
|
-
flexGrow: 1,
|
164
|
-
overflowY: 'auto',
|
165
|
-
border: '1px solid #999',
|
166
|
-
borderRadius: '4px',
|
167
|
-
} }, propertyTree.map((property) => (React.createElement(PropertyTreeItem, { property: property, handleClick: handleClick })))),
|
168
|
-
React.createElement(Box, { sx: { display: 'flex', justifyContent: 'flex-end', marginTop: '20px' } },
|
169
|
-
React.createElement(Button, { onClick: () => {
|
170
|
-
setSelectedProperty(null);
|
171
|
-
setOpenMergeFieldDialog(false);
|
172
|
-
}, variant: "outlined" }, "Cancel"),
|
173
|
-
React.createElement(Button, { sx: { marginLeft: '10px' }, onClick: () => handleSubmit(), variant: "contained", disabled: !selectedProperty }, "Ok")))));
|
174
|
-
}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
/// <reference types="react" />
|
2
|
-
import { Page } from '../../components/custom/types';
|
3
|
-
declare type QRDialogProps = {
|
4
|
-
openQRdialog: boolean;
|
5
|
-
setOpenQRdialog: (openQRdialog: boolean) => void;
|
6
|
-
insertImage: (qr: string) => void;
|
7
|
-
pages: PageWithAppName[];
|
8
|
-
};
|
9
|
-
declare type PageWithAppName = Page & {
|
10
|
-
appName: string;
|
11
|
-
};
|
12
|
-
export default function QRDialog(props: QRDialogProps): JSX.Element;
|
13
|
-
export {};
|
@@ -1,90 +0,0 @@
|
|
1
|
-
import React, { useState } from 'react';
|
2
|
-
import { Autocomplete, Box, Button, Dialog, DialogContent, DialogTitle, TextField, Typography, } from '../..';
|
3
|
-
import { styled, lighten, darken } from '@mui/system';
|
4
|
-
const GroupItems = styled('ul')({ padding: 0, fontSize: '12px' });
|
5
|
-
const GroupHeader = styled('div')(({ theme }) => ({
|
6
|
-
position: 'sticky',
|
7
|
-
top: '-8px',
|
8
|
-
padding: '4px 10px',
|
9
|
-
fontSize: '12px',
|
10
|
-
color: theme.palette.primary.main,
|
11
|
-
backgroundColor: theme.palette.mode === 'light'
|
12
|
-
? lighten(theme.palette.primary.light, 0.85)
|
13
|
-
: darken(theme.palette.primary.main, 0.8),
|
14
|
-
}));
|
15
|
-
export default function QRDialog(props) {
|
16
|
-
const { openQRdialog, setOpenQRdialog, insertImage, pages } = props;
|
17
|
-
const [QRCode, setQRCode] = useState({ encodedData: '', isPage: false, appId: '' });
|
18
|
-
const handleSubmit = () => {
|
19
|
-
let { encodedData } = QRCode;
|
20
|
-
let qrUrl = `"https://api.qrserver.com/v1/create-qr-code/?data=`;
|
21
|
-
if (!encodedData)
|
22
|
-
return;
|
23
|
-
if (QRCode.isPage) {
|
24
|
-
const baseUrl = process.env.REACT_APP_API_ROOT
|
25
|
-
? process.env.REACT_APP_API_ROOT.replace('/api', '')
|
26
|
-
: window.location.origin;
|
27
|
-
if (encodedData.includes(':instanceId')) {
|
28
|
-
const pathParts = encodedData.split(':instanceId');
|
29
|
-
encodedData = `${pathParts[0]}" + id ${pathParts[1] && `+ "${pathParts[1]}"`}`;
|
30
|
-
}
|
31
|
-
else {
|
32
|
-
encodedData = `${encodedData}"`;
|
33
|
-
}
|
34
|
-
qrUrl += `${baseUrl}/app/${encodedData}`;
|
35
|
-
}
|
36
|
-
else {
|
37
|
-
qrUrl += `" + ${encodedData}`;
|
38
|
-
}
|
39
|
-
const qrTemplateExpressions = `
|
40
|
-
<<var [qrURL = ${qrUrl}]>>
|
41
|
-
<<image [qrURL]>>
|
42
|
-
`;
|
43
|
-
insertImage(qrTemplateExpressions);
|
44
|
-
setQRCode({ encodedData: '', isPage: false, appId: '' });
|
45
|
-
};
|
46
|
-
return (React.createElement(Dialog, { open: openQRdialog, onClose: () => setOpenQRdialog(false), hideBackdrop: true, keepMounted: false },
|
47
|
-
React.createElement(DialogTitle, null, "Insert QR Code"),
|
48
|
-
React.createElement(DialogContent, { sx: { width: '300px' } },
|
49
|
-
React.createElement(Typography, null, "Data To Encode"),
|
50
|
-
React.createElement(Autocomplete, { freeSolo: true, options: pages.map((page) => ({
|
51
|
-
label: page.name,
|
52
|
-
value: `${page.appId}/${page.id}`,
|
53
|
-
sublabel: `/${page.id}`,
|
54
|
-
appId: page.appId,
|
55
|
-
appName: page.appName,
|
56
|
-
})), isOptionEqualToValue: (option, value) => {
|
57
|
-
return option.value === value;
|
58
|
-
}, filterOptions: (options, state) => {
|
59
|
-
const inputValue = state.inputValue.toLowerCase();
|
60
|
-
return options.filter((option) => option.value.toLowerCase().includes(inputValue) ||
|
61
|
-
option.sublabel.toLowerCase().includes(inputValue) ||
|
62
|
-
option.appName.toLowerCase().includes(inputValue));
|
63
|
-
}, getOptionLabel: (selectedValue) => {
|
64
|
-
if (typeof selectedValue === 'string') {
|
65
|
-
const [appId, ...pageId] = selectedValue.split('/');
|
66
|
-
const foundPage = pages.find((page) => page.id === pageId.join('/') && page.appId === appId);
|
67
|
-
return foundPage ? foundPage === null || foundPage === void 0 ? void 0 : foundPage.name : '';
|
68
|
-
}
|
69
|
-
return selectedValue.label;
|
70
|
-
}, groupBy: (option) => option['appName'], renderGroup: (params) => {
|
71
|
-
return (React.createElement("li", { key: params.key },
|
72
|
-
React.createElement(GroupHeader, null, params.group),
|
73
|
-
React.createElement(GroupItems, null, params.children)));
|
74
|
-
}, renderOption: (props, option) => (React.createElement("li", Object.assign({}, props),
|
75
|
-
React.createElement(Box, { sx: { padding: '0px' } },
|
76
|
-
React.createElement(Typography, { sx: { fontSize: '12px', height: '17px' } }, option.label),
|
77
|
-
React.createElement(Typography, { sx: { color: '#586069', fontSize: '12px' } }, option.sublabel)))), onChange: (event, option) => {
|
78
|
-
setQRCode(Object.assign(Object.assign({}, QRCode), { encodedData: (option === null || option === void 0 ? void 0 : option.value) || '', appId: option.appId || '', isPage: true }));
|
79
|
-
}, sortBy: 'NONE',
|
80
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
81
|
-
renderInput: (params) => {
|
82
|
-
var _a;
|
83
|
-
return (React.createElement(TextField, Object.assign({}, params, { size: "small", sx: Object.assign(Object.assign({}, ((_a = params.sx) !== null && _a !== void 0 ? _a : {})), { color: 'blue', fontSize: '14px' }), value: QRCode.encodedData, onChange: (e) => {
|
84
|
-
setQRCode(Object.assign(Object.assign({}, QRCode), { encodedData: e.target.value }));
|
85
|
-
} })));
|
86
|
-
} }),
|
87
|
-
React.createElement(Box, { sx: { display: 'flex', justifyContent: 'flex-end', marginTop: '20px' } },
|
88
|
-
React.createElement(Button, { onClick: () => setOpenQRdialog(false), variant: "outlined" }, "Cancel"),
|
89
|
-
React.createElement(Button, { sx: { marginLeft: '10px' }, onClick: () => handleSubmit(), variant: "contained", disabled: !QRCode.encodedData }, "Ok")))));
|
90
|
-
}
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import 'devexpress-richedit/dist/dx.richedit.css';
|
2
|
-
import 'devextreme-dist/css/dx.light.css';
|
3
|
-
import { Dispatch, SetStateAction } from 'react';
|
4
|
-
import { RichTextTemplate, EvokeObject, Page } from '../../components/custom/types';
|
5
|
-
import '../../styles/custom.css';
|
6
|
-
export declare type RichTextEditorProps = {
|
7
|
-
id: string;
|
8
|
-
richTextTemplate: RichTextTemplate;
|
9
|
-
setRichTextTemplate: Dispatch<SetStateAction<RichTextTemplate>>;
|
10
|
-
height: number | string;
|
11
|
-
object: EvokeObject;
|
12
|
-
timeZone: string;
|
13
|
-
fetchObject: (id: string) => Promise<EvokeObject | undefined>;
|
14
|
-
pages: PageWithAppName[];
|
15
|
-
};
|
16
|
-
declare type PageWithAppName = Page & {
|
17
|
-
appName: string;
|
18
|
-
};
|
19
|
-
declare const RichTextEditor: (props: RichTextEditorProps) => JSX.Element;
|
20
|
-
export default RichTextEditor;
|
@@ -1,223 +0,0 @@
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
-
});
|
9
|
-
};
|
10
|
-
import { Box } from '../../components/layout';
|
11
|
-
import { DocumentFormat, InsertTabCommandId, ViewType, create, createOptions, MailMergeTabItemId, ViewTabItemId, FileTabItemId, RibbonItemType, RibbonMenuItem, RibbonButtonItem, InsertTabItemId, } from 'devexpress-richedit';
|
12
|
-
import 'devexpress-richedit/dist/dx.richedit.css';
|
13
|
-
import 'devextreme-dist/css/dx.light.css';
|
14
|
-
import { debounce } from 'lodash';
|
15
|
-
import React, { useEffect, useRef, useState } from 'react';
|
16
|
-
import '../../styles/custom.css';
|
17
|
-
import QRDialog from './QRDialog';
|
18
|
-
import { convertIconToSvgString, getTemplateFields } from './utils';
|
19
|
-
import { QrCode2Rounded } from '../../icons';
|
20
|
-
import MergeFieldDialog from './MergeFieldDialog';
|
21
|
-
const qrIcon = convertIconToSvgString(React.createElement(QrCode2Rounded, null));
|
22
|
-
const RichTextEditor = (props) => {
|
23
|
-
const { id, richTextTemplate, setRichTextTemplate, timeZone, fetchObject, pages } = props;
|
24
|
-
const editorInstanceRef = useRef(null);
|
25
|
-
const [openQRdialog, setOpenQRdialog] = useState(false);
|
26
|
-
const [openMergeFieldDialog, setOpenMergeFieldDialog] = useState(false);
|
27
|
-
const options = createOptions();
|
28
|
-
useEffect(() => {
|
29
|
-
var _a;
|
30
|
-
if (options) {
|
31
|
-
//ribbon customizations
|
32
|
-
const fileTab = options.ribbon.getTab(0);
|
33
|
-
fileTab === null || fileTab === void 0 ? void 0 : fileTab.removeItem(FileTabItemId.CreateNewDocument); // Remove New
|
34
|
-
fileTab === null || fileTab === void 0 ? void 0 : fileTab.removeItem(FileTabItemId.ExportDocument); // Remove Save
|
35
|
-
fileTab === null || fileTab === void 0 ? void 0 : fileTab.removeItem(FileTabItemId.PrintDocument); // Remove Print
|
36
|
-
const viewTab = options.ribbon.getTab(6);
|
37
|
-
viewTab === null || viewTab === void 0 ? void 0 : viewTab.removeItem(ViewTabItemId.ToggleFullScreen); // Remove Fullscreen
|
38
|
-
//remove and rewrite/rename Simple View to Email Layout
|
39
|
-
viewTab === null || viewTab === void 0 ? void 0 : viewTab.removeItem(ViewTabItemId.SwitchToSimpleView);
|
40
|
-
viewTab === null || viewTab === void 0 ? void 0 : viewTab.insertItem({
|
41
|
-
beginGroup: false,
|
42
|
-
id: ViewTabItemId.SwitchToSimpleView,
|
43
|
-
type: RibbonItemType.Button,
|
44
|
-
text: 'Email Layout',
|
45
|
-
icon: 'dxre-icon-SimpleView',
|
46
|
-
showText: true,
|
47
|
-
toggleMode: true,
|
48
|
-
selected: false,
|
49
|
-
}, 0);
|
50
|
-
const mailMergeTab = options.ribbon.getTab(5);
|
51
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.CreateFieldMenu); // Remove Create Field (i.e. Date, Page, etc.)
|
52
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.ToggleViewMergedData); // Remove Merge Preview
|
53
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.UpdateAllFields); // Remove Update All Fields
|
54
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.ShowAllFieldResults); // Remove Field Results
|
55
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.GoToFirstDataRecord); // Remove Go To First Record
|
56
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.GoToPreviousDataRecord); // Remove Go To Previous Record
|
57
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.GoToNextDataRecord); // Remove Go To Next Record
|
58
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.GoToLastDataRecord); // Remove Go To Last Record
|
59
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.ShowMailMergeDialog); // Remove Mail Merge Dialog
|
60
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.ShowAllFieldCodes); // Remove Field Codes
|
61
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.removeItem(MailMergeTabItemId.ShowInsertMergeFieldDialog); // Remove Out-Of-Box Merge Field Dialog
|
62
|
-
const objectPropertiesButton = new RibbonButtonItem('insertMergeField', 'Object Properties', {
|
63
|
-
showText: true,
|
64
|
-
toggleMode: false,
|
65
|
-
selected: false,
|
66
|
-
icon: 'dxre-icon-InsertDataField',
|
67
|
-
beginGroup: false,
|
68
|
-
});
|
69
|
-
const templateFieldMenu = new RibbonMenuItem('10001', 'Template Fields', [
|
70
|
-
...(getTemplateFields(timeZone) || []),
|
71
|
-
]);
|
72
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.insertItem(objectPropertiesButton, 0);
|
73
|
-
mailMergeTab === null || mailMergeTab === void 0 ? void 0 : mailMergeTab.insertItem(templateFieldMenu, 1);
|
74
|
-
const insertTab = options.ribbon.getTab(2);
|
75
|
-
//Create QR Code Button
|
76
|
-
const QRButton = new RibbonButtonItem('qr', 'QR Code', {
|
77
|
-
showText: true,
|
78
|
-
toggleMode: false,
|
79
|
-
selected: false,
|
80
|
-
icon: qrIcon,
|
81
|
-
beginGroup: false,
|
82
|
-
});
|
83
|
-
const InsertPageCountField = new RibbonButtonItem('NUMPAGES', 'Page Count', {
|
84
|
-
showText: true,
|
85
|
-
toggleMode: false,
|
86
|
-
selected: false,
|
87
|
-
icon: 'dxre-icon-InsertPageCount',
|
88
|
-
beginGroup: false,
|
89
|
-
});
|
90
|
-
const InsertPageNumberField = new RibbonButtonItem('PAGE', 'Page Number', {
|
91
|
-
showText: true,
|
92
|
-
toggleMode: false,
|
93
|
-
selected: false,
|
94
|
-
icon: 'dxre-icon-InsertPageNumber',
|
95
|
-
beginGroup: false,
|
96
|
-
});
|
97
|
-
insertTab === null || insertTab === void 0 ? void 0 : insertTab.insertItem(QRButton, 2);
|
98
|
-
insertTab === null || insertTab === void 0 ? void 0 : insertTab.removeItem(InsertTabItemId.InsertPageCountField);
|
99
|
-
insertTab === null || insertTab === void 0 ? void 0 : insertTab.insertItem(InsertPageCountField, InsertTabItemId.InsertPageCountField);
|
100
|
-
insertTab === null || insertTab === void 0 ? void 0 : insertTab.removeItem(InsertTabItemId.InsertPageNumberField);
|
101
|
-
insertTab === null || insertTab === void 0 ? void 0 : insertTab.insertItem(InsertPageNumberField, InsertTabItemId.InsertPageNumberField);
|
102
|
-
//Event handlers
|
103
|
-
options.events.customCommandExecuted = (s, e) => {
|
104
|
-
if (e.commandName === 'qr') {
|
105
|
-
setOpenQRdialog(true);
|
106
|
-
}
|
107
|
-
if (e.commandName === 'insertMergeField') {
|
108
|
-
setOpenMergeFieldDialog(true);
|
109
|
-
}
|
110
|
-
if (e.commandName === 'NUMPAGES' || e.commandName === 'PAGE') {
|
111
|
-
// insert NUMPAGES or PAGE fields from the Insert Tab
|
112
|
-
insertMergeField(e.commandName, undefined, 'templateField-pages');
|
113
|
-
}
|
114
|
-
const setMergeCommandListeners = (items, commandName) => {
|
115
|
-
items === null || items === void 0 ? void 0 : items.forEach((item) => {
|
116
|
-
if (item.id === commandName) {
|
117
|
-
insertMergeField(item.mergeField, undefined, item.fieldType);
|
118
|
-
}
|
119
|
-
});
|
120
|
-
};
|
121
|
-
setMergeCommandListeners(getTemplateFields(timeZone), e.commandName);
|
122
|
-
};
|
123
|
-
if (options.confirmOnLosingChanges) {
|
124
|
-
options.confirmOnLosingChanges.enabled = false;
|
125
|
-
}
|
126
|
-
options.height = ((_a = props.height) === null || _a === void 0 ? void 0 : _a.toString()) + 'px';
|
127
|
-
if (options.view && richTextTemplate.viewType) {
|
128
|
-
options.view.viewType = richTextTemplate.viewType || 1;
|
129
|
-
}
|
130
|
-
options.events.documentChanged = (doc) => {
|
131
|
-
debouncedChangeHandler(doc);
|
132
|
-
};
|
133
|
-
options.events.documentLoaded = (doc) => {
|
134
|
-
// without the following, the document fields (i.e. page, date, etc.) are not shown
|
135
|
-
doc.document.fields.showAllFieldCodes();
|
136
|
-
};
|
137
|
-
}
|
138
|
-
const element = document.getElementById(id);
|
139
|
-
if (element && !editorInstanceRef.current) {
|
140
|
-
editorInstanceRef.current = create(element, options);
|
141
|
-
if (richTextTemplate.content) {
|
142
|
-
try {
|
143
|
-
editorInstanceRef.current.openDocument(richTextTemplate.content, richTextTemplate.name, DocumentFormat.OpenXml);
|
144
|
-
}
|
145
|
-
catch (e) {
|
146
|
-
console.error('content is not base64 encoded', e);
|
147
|
-
}
|
148
|
-
}
|
149
|
-
//editor customizations
|
150
|
-
editorInstanceRef.current.viewType = ViewType.PrintLayout;
|
151
|
-
editorInstanceRef.current.selection.showCursorAtEndOfLine = true;
|
152
|
-
}
|
153
|
-
}, []);
|
154
|
-
const debouncedChangeHandler = debounce((doc) => __awaiter(void 0, void 0, void 0, function* () {
|
155
|
-
doc.exportToBase64((docAsBase64) => setRichTextTemplate((prevTemplate) => (Object.assign(Object.assign({}, prevTemplate), { isDocx: true, content: docAsBase64 }))), DocumentFormat.OpenXml);
|
156
|
-
}), 500);
|
157
|
-
const insertImage = (imageTag) => {
|
158
|
-
const editorInstance = editorInstanceRef.current;
|
159
|
-
if (editorInstance !== undefined && editorInstance !== null) {
|
160
|
-
//insert new text box
|
161
|
-
editorInstance === null || editorInstance === void 0 ? void 0 : editorInstance.executeCommand(InsertTabCommandId.InsertFloatingTextBox);
|
162
|
-
const textBox = editorInstance === null || editorInstance === void 0 ? void 0 : editorInstance.selection.activeSubDocument;
|
163
|
-
textBox.insertText(editorInstance.selection.active, imageTag);
|
164
|
-
}
|
165
|
-
setOpenQRdialog(false);
|
166
|
-
};
|
167
|
-
const insertMergeField = (mergeFieldId, expandedFieldId, type) => {
|
168
|
-
// only add to additionalDatasources if it is a nested property
|
169
|
-
if (expandedFieldId && expandedFieldId.includes('.')) {
|
170
|
-
setRichTextTemplate((prevTemplate) => {
|
171
|
-
return Object.assign(Object.assign({}, prevTemplate), { additionalDatasources: [
|
172
|
-
...new Set([...(prevTemplate.additionalDatasources || []), expandedFieldId]),
|
173
|
-
] });
|
174
|
-
});
|
175
|
-
}
|
176
|
-
let mergeField;
|
177
|
-
if (type === 'templateField-pages') {
|
178
|
-
mergeField = mergeFieldId;
|
179
|
-
}
|
180
|
-
else if (mergeFieldId.includes('foreach')) {
|
181
|
-
mergeField = `<<${mergeFieldId}>> <</foreach>>`;
|
182
|
-
}
|
183
|
-
else {
|
184
|
-
mergeField = `<<[${mergeFieldId}]>>`;
|
185
|
-
}
|
186
|
-
if (editorInstanceRef.current) {
|
187
|
-
if (type === 'image') {
|
188
|
-
insertImage(mergeField);
|
189
|
-
}
|
190
|
-
else if (type === 'templateField-pages') {
|
191
|
-
if (editorInstanceRef.current.selection.activeSubDocument) {
|
192
|
-
editorInstanceRef.current.selection.activeSubDocument.fields.create(editorInstanceRef.current.selection.active, mergeField);
|
193
|
-
}
|
194
|
-
else {
|
195
|
-
editorInstanceRef.current.document.fields.create(editorInstanceRef.current.selection.active, mergeField);
|
196
|
-
}
|
197
|
-
editorInstanceRef.current.selection.setSelection(editorInstanceRef.current.selection.active + 2);
|
198
|
-
}
|
199
|
-
else {
|
200
|
-
if (editorInstanceRef.current.selection.activeSubDocument) {
|
201
|
-
editorInstanceRef.current.selection.activeSubDocument.insertText(editorInstanceRef.current.selection.active, mergeField);
|
202
|
-
}
|
203
|
-
else {
|
204
|
-
editorInstanceRef.current.document.insertText(editorInstanceRef.current.selection.active, mergeField);
|
205
|
-
}
|
206
|
-
}
|
207
|
-
if (mergeField.includes('<<foreach')) {
|
208
|
-
//put cursor between forEach Tags
|
209
|
-
const position = editorInstanceRef.current.selection.active + mergeField.length - 12;
|
210
|
-
editorInstanceRef.current.selection.setSelection(position);
|
211
|
-
}
|
212
|
-
else {
|
213
|
-
//put cursor after inserted merge field
|
214
|
-
editorInstanceRef.current.selection.setSelection(editorInstanceRef.current.selection.active + mergeField.length);
|
215
|
-
}
|
216
|
-
}
|
217
|
-
};
|
218
|
-
return (React.createElement(Box, { sx: { width: '100%' } },
|
219
|
-
React.createElement("div", { id: id }),
|
220
|
-
React.createElement(QRDialog, { openQRdialog: openQRdialog, setOpenQRdialog: setOpenQRdialog, insertImage: insertImage, pages: pages }),
|
221
|
-
React.createElement(MergeFieldDialog, { objectId: props.object.id, openMergeFieldDialog: openMergeFieldDialog, setOpenMergeFieldDialog: setOpenMergeFieldDialog, insertMergeField: insertMergeField, fetchObject: fetchObject })));
|
222
|
-
};
|
223
|
-
export default RichTextEditor;
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { ObjectProperty } from '../../components/custom/types';
|
2
|
-
import { RibbonSubMenuItem } from 'devexpress-richedit';
|
3
|
-
import React from 'react';
|
4
|
-
export declare function convertIconToSvgString(reactComponent: React.ReactElement): string;
|
5
|
-
export declare type CustomRibbonSubMenuItem = RibbonSubMenuItem & {
|
6
|
-
mergeField: string;
|
7
|
-
fieldType?: string;
|
8
|
-
items?: CustomRibbonSubMenuItem[];
|
9
|
-
convertToButton?: () => void;
|
10
|
-
};
|
11
|
-
export declare type MergeProperty = ObjectProperty & {
|
12
|
-
expandedId: string;
|
13
|
-
mergeFieldId: string;
|
14
|
-
children?: MergeProperty[];
|
15
|
-
};
|
16
|
-
export declare const getAddressProperties: (address: MergeProperty) => ({
|
17
|
-
id: string;
|
18
|
-
expandedId: string;
|
19
|
-
mergeFieldId: string;
|
20
|
-
name: string;
|
21
|
-
type: string;
|
22
|
-
mergeField?: undefined;
|
23
|
-
} | {
|
24
|
-
id: string;
|
25
|
-
expandedId: string;
|
26
|
-
mergeField: string;
|
27
|
-
name: string;
|
28
|
-
type: string;
|
29
|
-
mergeFieldId?: undefined;
|
30
|
-
})[];
|
31
|
-
export declare const getTemplateFields: (timeZone: string) => CustomRibbonSubMenuItem[];
|
@@ -1,119 +0,0 @@
|
|
1
|
-
import ReactDOM from 'react-dom';
|
2
|
-
import { RibbonButtonItem } from 'devexpress-richedit';
|
3
|
-
export function convertIconToSvgString(reactComponent) {
|
4
|
-
const container = document.createElement('div');
|
5
|
-
ReactDOM.render(reactComponent, container);
|
6
|
-
const svgString = container.innerHTML;
|
7
|
-
return svgString;
|
8
|
-
}
|
9
|
-
export const getAddressProperties = (address) => {
|
10
|
-
const { expandedId } = address;
|
11
|
-
return [
|
12
|
-
{
|
13
|
-
id: expandedId + '.line1',
|
14
|
-
expandedId: expandedId + '.line1',
|
15
|
-
mergeFieldId: expandedId + '?.line1',
|
16
|
-
name: address.name + ' Line 1',
|
17
|
-
type: 'addressField',
|
18
|
-
},
|
19
|
-
{
|
20
|
-
id: expandedId + '.line2',
|
21
|
-
expandedId: expandedId + '.line2',
|
22
|
-
mergeFieldId: expandedId + '?.line2',
|
23
|
-
name: address.name + ' Line 2',
|
24
|
-
type: 'addressField',
|
25
|
-
},
|
26
|
-
{
|
27
|
-
id: expandedId + '.city',
|
28
|
-
expandedId: expandedId + '.city',
|
29
|
-
mergeFieldId: expandedId + '?.city',
|
30
|
-
name: address.name + ' City',
|
31
|
-
type: 'addressField',
|
32
|
-
},
|
33
|
-
{
|
34
|
-
id: expandedId + '.state',
|
35
|
-
expandedId: expandedId + '.state',
|
36
|
-
mergeFieldId: expandedId + '?.state',
|
37
|
-
name: address.name + ' State',
|
38
|
-
type: 'addressField',
|
39
|
-
},
|
40
|
-
{
|
41
|
-
id: expandedId + '.zipCode',
|
42
|
-
expandedId: expandedId + '.zipCode',
|
43
|
-
mergeFieldId: expandedId + '?.zipCode',
|
44
|
-
name: address.name + ' Zip',
|
45
|
-
type: 'addressField',
|
46
|
-
},
|
47
|
-
{
|
48
|
-
id: expandedId + '.county',
|
49
|
-
expandedId: expandedId + '.county',
|
50
|
-
mergeField: expandedId + '?.county',
|
51
|
-
name: address.name + ' County',
|
52
|
-
type: 'addressField',
|
53
|
-
},
|
54
|
-
];
|
55
|
-
};
|
56
|
-
export const getTemplateFields = (timeZone) => {
|
57
|
-
return [
|
58
|
-
{
|
59
|
-
beginGroup: false,
|
60
|
-
type: 5,
|
61
|
-
text: 'Date',
|
62
|
-
id: 'dateAtMerge',
|
63
|
-
mergeField: `ZonedDateTime.now(ZoneId.of("${timeZone}")).format(DateTimeFormatter.ofPattern("MMMM d, yyyy"))`,
|
64
|
-
fieldType: 'templateField-date',
|
65
|
-
items: [],
|
66
|
-
convertToButton: () => {
|
67
|
-
return new RibbonButtonItem('10000', 'Empty', {});
|
68
|
-
},
|
69
|
-
},
|
70
|
-
{
|
71
|
-
beginGroup: false,
|
72
|
-
type: 5,
|
73
|
-
text: 'Time',
|
74
|
-
id: 'timeAtMerge',
|
75
|
-
mergeField: `ZonedDateTime.now(ZoneId.of("${timeZone}")).format(DateTimeFormatter.ofPattern("h:mm a"))`,
|
76
|
-
fieldType: 'templateField-time',
|
77
|
-
items: [],
|
78
|
-
convertToButton: () => {
|
79
|
-
return new RibbonButtonItem('10000', 'Empty', {});
|
80
|
-
},
|
81
|
-
},
|
82
|
-
{
|
83
|
-
beginGroup: false,
|
84
|
-
type: 5,
|
85
|
-
text: 'Date Time',
|
86
|
-
id: 'dateTimeAtMerge',
|
87
|
-
mergeField: `ZonedDateTime.now(ZoneId.of("${timeZone}")).format(DateTimeFormatter.ofPattern("MMMM d, yyyy h:mm a"))`,
|
88
|
-
fieldType: 'templateField-date-time',
|
89
|
-
items: [],
|
90
|
-
convertToButton: () => {
|
91
|
-
return new RibbonButtonItem('10000', 'Empty', {});
|
92
|
-
},
|
93
|
-
},
|
94
|
-
{
|
95
|
-
beginGroup: false,
|
96
|
-
type: 5,
|
97
|
-
text: 'Page Number',
|
98
|
-
id: 'pageNumber',
|
99
|
-
mergeField: `PAGE`,
|
100
|
-
fieldType: 'templateField-pages',
|
101
|
-
items: [],
|
102
|
-
convertToButton: () => {
|
103
|
-
return new RibbonButtonItem('10000', 'Empty', {});
|
104
|
-
},
|
105
|
-
},
|
106
|
-
{
|
107
|
-
beginGroup: false,
|
108
|
-
type: 5,
|
109
|
-
text: 'Page Count',
|
110
|
-
id: 'numPages',
|
111
|
-
mergeField: `NUMPAGES`,
|
112
|
-
fieldType: 'templateField-pages',
|
113
|
-
items: [],
|
114
|
-
convertToButton: () => {
|
115
|
-
return new RibbonButtonItem('10000', 'Empty', {});
|
116
|
-
},
|
117
|
-
},
|
118
|
-
];
|
119
|
-
};
|
@@ -1,5 +0,0 @@
|
|
1
|
-
/// <reference types="react" />
|
2
|
-
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
3
|
-
declare const _default: ComponentMeta<(props: import("../shared/RichTextEditor/RichTextEditor").RichTextEditorProps) => JSX.Element>;
|
4
|
-
export default _default;
|
5
|
-
export declare const MyRichTextEditor: ComponentStory<(props: import("../shared/RichTextEditor/RichTextEditor").RichTextEditorProps) => JSX.Element>;
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import RichTextEditor from '../shared/RichTextEditor';
|
3
|
-
export default {
|
4
|
-
title: 'Input/RichTextEditor',
|
5
|
-
component: RichTextEditor,
|
6
|
-
};
|
7
|
-
const Template = (props) => {
|
8
|
-
//TODO: make a story that involves all of the data as either dummy data and mock functions
|
9
|
-
return React.createElement(RichTextEditor, Object.assign({}, props));
|
10
|
-
};
|
11
|
-
export const MyRichTextEditor = Template.bind({});
|