@ouroboros/mouth-mui 1.3.2 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/pages/Locales.d.ts +1 -3
- package/lib/components/pages/Locales.js +32 -23
- package/lib/components/pages/Templates/Create.d.ts +1 -1
- package/lib/components/pages/Templates/Create.js +11 -14
- package/lib/components/pages/Templates/Template/Content/Create/Email.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Create/Email.js +6 -10
- package/lib/components/pages/Templates/Template/Content/Create/SMS.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Create/SMS.js +4 -6
- package/lib/components/pages/Templates/Template/Content/Create/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Create/index.js +14 -20
- package/lib/components/pages/Templates/Template/Content/Preview/Email.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Preview/Email.js +6 -7
- package/lib/components/pages/Templates/Template/Content/Preview/SMS.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Preview/SMS.js +3 -4
- package/lib/components/pages/Templates/Template/Content/Preview/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Preview/index.js +3 -6
- package/lib/components/pages/Templates/Template/Content/Update/Email.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Update/Email.js +6 -11
- package/lib/components/pages/Templates/Template/Content/Update/SMS.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Update/SMS.js +4 -6
- package/lib/components/pages/Templates/Template/Content/Update/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Update/index.js +17 -23
- package/lib/components/pages/Templates/Template/Content/View/Email.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/View/Email.js +6 -7
- package/lib/components/pages/Templates/Template/Content/View/SMS.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/View/SMS.js +3 -4
- package/lib/components/pages/Templates/Template/Content/View/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/View/index.js +5 -6
- package/lib/components/pages/Templates/Template/Variables.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Variables.js +6 -7
- package/lib/components/pages/Templates/Template/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/index.js +27 -45
- package/lib/components/pages/Templates/index.d.ts +1 -3
- package/lib/components/pages/Templates/index.js +9 -21
- package/lib/shared.d.ts +12 -0
- package/lib/shared.js +25 -0
- package/package.json +7 -8
- package/src/components/pages/Locales.tsx +40 -27
- package/src/components/pages/Templates/Create.tsx +12 -15
- package/src/components/pages/Templates/Template/Content/Create/Email.tsx +15 -19
- package/src/components/pages/Templates/Template/Content/Create/SMS.tsx +7 -9
- package/src/components/pages/Templates/Template/Content/Create/index.tsx +15 -23
- package/src/components/pages/Templates/Template/Content/Preview/Email.tsx +7 -9
- package/src/components/pages/Templates/Template/Content/Preview/SMS.tsx +3 -9
- package/src/components/pages/Templates/Template/Content/Preview/index.tsx +2 -9
- package/src/components/pages/Templates/Template/Content/Update/Email.tsx +15 -18
- package/src/components/pages/Templates/Template/Content/Update/SMS.tsx +7 -9
- package/src/components/pages/Templates/Template/Content/Update/index.tsx +19 -29
- package/src/components/pages/Templates/Template/Content/View/Email.tsx +6 -8
- package/src/components/pages/Templates/Template/Content/View/SMS.tsx +3 -5
- package/src/components/pages/Templates/Template/Content/View/index.tsx +9 -12
- package/src/components/pages/Templates/Template/Variables.tsx +6 -7
- package/src/components/pages/Templates/Template/index.tsx +37 -59
- package/src/components/pages/Templates/index.tsx +19 -31
- package/src/shared.ts +29 -0
- package/ouroboros-mouth-mui-1.3.2.tgz +0 -0
- package/src/types/xhr2.d.ts +0 -3
|
@@ -6,19 +6,14 @@
|
|
|
6
6
|
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
7
|
* @created 2023-01-23
|
|
8
8
|
*/
|
|
9
|
-
// Ouroboros modules
|
|
10
|
-
import { Node } from '@ouroboros/define';
|
|
11
9
|
import { DefineNode } from '@ouroboros/define-mui';
|
|
12
|
-
import TemplateEmail from '@ouroboros/mouth/definitions/template_email.json';
|
|
13
10
|
// NPM modules
|
|
14
11
|
import PropTypes from 'prop-types';
|
|
15
12
|
import React from 'react';
|
|
16
13
|
// Material UI
|
|
17
14
|
import Grid from '@mui/material/Grid';
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
const oTextNode = new Node(TemplateEmail.text);
|
|
21
|
-
const oHtmlNode = new Node(TemplateEmail.html);
|
|
15
|
+
// Import the shared types
|
|
16
|
+
import { EmailTree } from '../../../../../../shared';
|
|
22
17
|
/**
|
|
23
18
|
* Email
|
|
24
19
|
*
|
|
@@ -29,15 +24,15 @@ const oHtmlNode = new Node(TemplateEmail.html);
|
|
|
29
24
|
* @param Object props Properties passed to the component
|
|
30
25
|
* @returns React.Component
|
|
31
26
|
*/
|
|
32
|
-
export default function Email(
|
|
27
|
+
export default function Email({ errors, onChanged, value }) {
|
|
33
28
|
// Render
|
|
34
29
|
return (React.createElement(Grid, { container: true, className: "content_update_email", spacing: 1 },
|
|
35
30
|
React.createElement(Grid, { item: true, xs: 12, className: "field" },
|
|
36
|
-
React.createElement(DefineNode, { error:
|
|
31
|
+
React.createElement(DefineNode, { error: errors.subject || false, label: "placeholder", name: "subject", node: EmailTree.get('subject'), onChange: val => onChanged('subject', val), type: "update", value: value.subject })),
|
|
37
32
|
React.createElement(Grid, { item: true, xs: 12, lg: 6, className: "field" },
|
|
38
|
-
React.createElement(DefineNode, { error:
|
|
33
|
+
React.createElement(DefineNode, { error: errors.text || false, label: "placeholder", name: "text", node: EmailTree.get('text'), onChange: val => onChanged('text', val), type: "update", value: value.text })),
|
|
39
34
|
React.createElement(Grid, { item: true, xs: 12, lg: 6, className: "field" },
|
|
40
|
-
React.createElement(DefineNode, { error:
|
|
35
|
+
React.createElement(DefineNode, { error: errors.html || false, label: "placeholder", name: "html", node: EmailTree.get('html'), onChange: val => onChanged('html', val), type: "update", value: value.html }))));
|
|
41
36
|
}
|
|
42
37
|
// Valid props
|
|
43
38
|
Email.propTypes = {
|
|
@@ -24,7 +24,7 @@ export type SMSProps = {
|
|
|
24
24
|
* @param Object props Properties passed to the component
|
|
25
25
|
* @returns React.Component
|
|
26
26
|
*/
|
|
27
|
-
declare function SMS(
|
|
27
|
+
declare function SMS({ errors, onChanged, value }: SMSProps): React.JSX.Element;
|
|
28
28
|
declare namespace SMS {
|
|
29
29
|
var propTypes: {
|
|
30
30
|
errors: PropTypes.Validator<object>;
|
|
@@ -7,16 +7,14 @@
|
|
|
7
7
|
* @created 2023-01-23
|
|
8
8
|
*/
|
|
9
9
|
// Ouroboros modules
|
|
10
|
-
import { Node } from '@ouroboros/define';
|
|
11
10
|
import { DefineNode } from '@ouroboros/define-mui';
|
|
12
|
-
import TemplateSMS from '@ouroboros/mouth/definitions/template_sms.json';
|
|
13
11
|
// NPM modules
|
|
14
12
|
import PropTypes from 'prop-types';
|
|
15
13
|
import React from 'react';
|
|
16
14
|
// Material UI
|
|
17
15
|
import Box from '@mui/material/Box';
|
|
18
|
-
//
|
|
19
|
-
|
|
16
|
+
// Import the shared types
|
|
17
|
+
import { SmsTree } from '../../../../../../shared';
|
|
20
18
|
/**
|
|
21
19
|
* SMS
|
|
22
20
|
*
|
|
@@ -27,10 +25,10 @@ const oContentNode = new Node(TemplateSMS.content);
|
|
|
27
25
|
* @param Object props Properties passed to the component
|
|
28
26
|
* @returns React.Component
|
|
29
27
|
*/
|
|
30
|
-
export default function SMS(
|
|
28
|
+
export default function SMS({ errors, onChanged, value }) {
|
|
31
29
|
// Render
|
|
32
30
|
return (React.createElement(Box, { className: "content_update_sms field" },
|
|
33
|
-
React.createElement(DefineNode, { error:
|
|
31
|
+
React.createElement(DefineNode, { error: errors.content || false, label: "placeholder", name: "content", node: SmsTree.get('content'), onChange: val => onChanged('content', val), type: "update", value: value.content })));
|
|
34
32
|
}
|
|
35
33
|
// Valid props
|
|
36
34
|
SMS.propTypes = {
|
|
@@ -12,7 +12,6 @@ import { responseErrorStruct } from '@ouroboros/body';
|
|
|
12
12
|
import { contentStruct } from '../..';
|
|
13
13
|
export type updateStruct = Omit<contentStruct, 'type'>;
|
|
14
14
|
export type UpdateProps = {
|
|
15
|
-
mobile: boolean;
|
|
16
15
|
onError: (error: responseErrorStruct) => void;
|
|
17
16
|
onUpdated: (content: contentStruct) => void;
|
|
18
17
|
value: contentStruct;
|
|
@@ -27,10 +26,9 @@ export type UpdateProps = {
|
|
|
27
26
|
* @param Object props Properties passed to the component
|
|
28
27
|
* @returns React.Component
|
|
29
28
|
*/
|
|
30
|
-
declare function Update(
|
|
29
|
+
declare function Update({ onError, onUpdated, value }: UpdateProps): React.JSX.Element;
|
|
31
30
|
declare namespace Update {
|
|
32
31
|
var propTypes: {
|
|
33
|
-
mobile: PropTypes.Validator<boolean>;
|
|
34
32
|
onError: PropTypes.Validator<(...args: any[]) => any>;
|
|
35
33
|
onUpdated: PropTypes.Validator<(...args: any[]) => any>;
|
|
36
34
|
value: PropTypes.Requireable<PropTypes.InferProps<{
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* @created 2023-01-22
|
|
8
8
|
*/
|
|
9
9
|
// Ouroboros modules
|
|
10
|
-
import clone from '@ouroboros/clone';
|
|
11
10
|
import { errorTree } from '@ouroboros/define-mui';
|
|
12
11
|
import mouth, { errors } from '@ouroboros/mouth';
|
|
13
12
|
import { owithout } from '@ouroboros/tools';
|
|
@@ -31,16 +30,16 @@ import SMS from './SMS';
|
|
|
31
30
|
* @param Object props Properties passed to the component
|
|
32
31
|
* @returns React.Component
|
|
33
32
|
*/
|
|
34
|
-
export default function Update(
|
|
33
|
+
export default function Update({ onError, onUpdated, value }) {
|
|
35
34
|
// State
|
|
36
35
|
const [fieldErrors, fieldErrorsSet] = useState({});
|
|
37
36
|
const [preview, previewSet] = useState(false);
|
|
38
|
-
const [record, recordSet] = useState(owithout(
|
|
37
|
+
const [record, recordSet] = useState(owithout(value, 'type'));
|
|
39
38
|
// Called to create the new content record
|
|
40
39
|
function update() {
|
|
41
40
|
// Send the record data to the server
|
|
42
|
-
mouth.update(`template/${
|
|
43
|
-
|
|
41
|
+
mouth.update(`template/${value.type}`, record).then(() => {
|
|
42
|
+
onUpdated({ type: value.type, ...record });
|
|
44
43
|
}, (error) => {
|
|
45
44
|
if (error.code === errors.body.DATA_FIELDS) {
|
|
46
45
|
fieldErrorsSet(errorTree(error.msg));
|
|
@@ -63,51 +62,46 @@ export default function Update(props) {
|
|
|
63
62
|
lLines.push('The following variables are invalid: ' + oLines.variables.join(', '));
|
|
64
63
|
}
|
|
65
64
|
// Show the errors
|
|
66
|
-
if (
|
|
67
|
-
|
|
65
|
+
if (onError) {
|
|
66
|
+
onError({ code: 0, msg: lLines.join('\n') });
|
|
68
67
|
}
|
|
69
68
|
}
|
|
70
69
|
else {
|
|
71
|
-
|
|
70
|
+
onError(error);
|
|
72
71
|
}
|
|
73
72
|
});
|
|
74
73
|
}
|
|
75
74
|
// Called when any fields in the record are changed
|
|
76
|
-
function recordChanged(field,
|
|
75
|
+
function recordChanged(field, val) {
|
|
77
76
|
// Clear error
|
|
78
77
|
if (field in fieldErrors) {
|
|
79
78
|
delete fieldErrors.field;
|
|
80
79
|
}
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
// Update the field
|
|
84
|
-
oRecord[field] = value;
|
|
85
|
-
// Store the new record
|
|
86
|
-
recordSet(oRecord);
|
|
80
|
+
// Set the new record
|
|
81
|
+
recordSet(o => { return { ...o, [field]: val }; });
|
|
87
82
|
}
|
|
88
83
|
// Render
|
|
89
84
|
return (React.createElement(Box, { className: "content_update" },
|
|
90
|
-
(
|
|
91
|
-
React.createElement(Email, { errors: fieldErrors, key:
|
|
92
|
-
React.createElement(SMS, { errors: fieldErrors, key:
|
|
85
|
+
(value.type === 'email' &&
|
|
86
|
+
React.createElement(Email, { errors: fieldErrors, key: value._id, onChanged: recordChanged, value: record })) || (value.type === 'sms' &&
|
|
87
|
+
React.createElement(SMS, { errors: fieldErrors, key: value._id, onChanged: recordChanged, value: record })),
|
|
93
88
|
React.createElement(Box, { className: "actions" },
|
|
94
|
-
React.createElement(Button, { color: "secondary", onClick: () => recordSet(owithout(
|
|
89
|
+
React.createElement(Button, { color: "secondary", onClick: () => recordSet(owithout(value, 'type')), variant: "contained" }, "Cancel"),
|
|
95
90
|
React.createElement(Button, { color: "info", onClick: () => previewSet(true), variant: "contained" }, "Preview"),
|
|
96
91
|
React.createElement(Button, { color: "primary", onClick: update, variant: "contained" }, "Save Content"),
|
|
97
92
|
preview &&
|
|
98
|
-
React.createElement(Preview, {
|
|
93
|
+
React.createElement(Preview, { onClose: () => previewSet(false), onError: (error) => {
|
|
99
94
|
if (error.code === errors.body.DATA_FIELDS) {
|
|
100
95
|
fieldErrorsSet(errorTree(error.msg));
|
|
101
96
|
}
|
|
102
97
|
else {
|
|
103
|
-
|
|
98
|
+
onError(error);
|
|
104
99
|
}
|
|
105
100
|
previewSet(false);
|
|
106
|
-
}, value: { ...record, type:
|
|
101
|
+
}, value: { ...record, type: value.type } }))));
|
|
107
102
|
}
|
|
108
103
|
// Valid props
|
|
109
104
|
Update.propTypes = {
|
|
110
|
-
mobile: PropTypes.bool.isRequired,
|
|
111
105
|
onError: PropTypes.func.isRequired,
|
|
112
106
|
onUpdated: PropTypes.func.isRequired,
|
|
113
107
|
value: PropTypes.shape({
|
|
@@ -10,7 +10,6 @@ import PropTypes from 'prop-types';
|
|
|
10
10
|
import React from 'react';
|
|
11
11
|
import { contentStruct } from '../../';
|
|
12
12
|
export type EmailProps = {
|
|
13
|
-
mobile: boolean;
|
|
14
13
|
value: contentStruct;
|
|
15
14
|
};
|
|
16
15
|
/**
|
|
@@ -23,10 +22,9 @@ export type EmailProps = {
|
|
|
23
22
|
* @param Object props Properties passed to the component
|
|
24
23
|
* @returns React.Component
|
|
25
24
|
*/
|
|
26
|
-
declare function Email(
|
|
25
|
+
declare function Email({ value }: EmailProps): React.JSX.Element;
|
|
27
26
|
declare namespace Email {
|
|
28
27
|
var propTypes: {
|
|
29
|
-
mobile: PropTypes.Validator<boolean>;
|
|
30
28
|
value: PropTypes.Requireable<Required<PropTypes.InferProps<{
|
|
31
29
|
_id: PropTypes.Validator<string>;
|
|
32
30
|
_created: PropTypes.Requireable<number>;
|
|
@@ -22,27 +22,26 @@ import Typography from '@mui/material/Typography';
|
|
|
22
22
|
* @param Object props Properties passed to the component
|
|
23
23
|
* @returns React.Component
|
|
24
24
|
*/
|
|
25
|
-
export default function Email(
|
|
25
|
+
export default function Email({ value }) {
|
|
26
26
|
// Render
|
|
27
27
|
return (React.createElement(Grid, { container: true, spacing: 2 },
|
|
28
28
|
React.createElement(Grid, { item: true, xs: 12, md: 4, lg: 2, xl: 1 },
|
|
29
29
|
React.createElement(Typography, null,
|
|
30
30
|
React.createElement("strong", null, "Subject"))),
|
|
31
|
-
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 },
|
|
31
|
+
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 }, value.subject),
|
|
32
32
|
React.createElement(Grid, { item: true, xs: 12, md: 4, lg: 2, xl: 1 },
|
|
33
33
|
React.createElement(Typography, null,
|
|
34
34
|
React.createElement("strong", null, "Text"))),
|
|
35
|
-
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 },
|
|
36
|
-
React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } },
|
|
35
|
+
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 }, value.text &&
|
|
36
|
+
React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } }, value.text)),
|
|
37
37
|
React.createElement(Grid, { item: true, xs: 12, md: 4, lg: 2, xl: 1 },
|
|
38
38
|
React.createElement(Typography, null,
|
|
39
39
|
React.createElement("strong", null, "HTML"))),
|
|
40
|
-
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 },
|
|
41
|
-
React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } },
|
|
40
|
+
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 }, value.html &&
|
|
41
|
+
React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } }, value.html))));
|
|
42
42
|
}
|
|
43
43
|
// Valid props
|
|
44
44
|
Email.propTypes = {
|
|
45
|
-
mobile: PropTypes.bool.isRequired,
|
|
46
45
|
value: PropTypes.exact({
|
|
47
46
|
_id: PropTypes.string.isRequired,
|
|
48
47
|
_created: PropTypes.number,
|
|
@@ -10,7 +10,6 @@ import PropTypes from 'prop-types';
|
|
|
10
10
|
import React from 'react';
|
|
11
11
|
import { contentStruct } from '../../';
|
|
12
12
|
export type SMSProps = {
|
|
13
|
-
mobile: boolean;
|
|
14
13
|
value: contentStruct;
|
|
15
14
|
};
|
|
16
15
|
/**
|
|
@@ -23,10 +22,9 @@ export type SMSProps = {
|
|
|
23
22
|
* @param Object props Properties passed to the component
|
|
24
23
|
* @returns React.Component
|
|
25
24
|
*/
|
|
26
|
-
declare function SMS(
|
|
25
|
+
declare function SMS({ value }: SMSProps): React.JSX.Element;
|
|
27
26
|
declare namespace SMS {
|
|
28
27
|
var propTypes: {
|
|
29
|
-
mobile: PropTypes.Validator<boolean>;
|
|
30
28
|
value: PropTypes.Requireable<Required<PropTypes.InferProps<{
|
|
31
29
|
_id: PropTypes.Validator<string>;
|
|
32
30
|
_created: PropTypes.Requireable<number>;
|
|
@@ -22,18 +22,17 @@ import Typography from '@mui/material/Typography';
|
|
|
22
22
|
* @param Object props Properties passed to the component
|
|
23
23
|
* @returns React.Component
|
|
24
24
|
*/
|
|
25
|
-
export default function SMS(
|
|
25
|
+
export default function SMS({ value }) {
|
|
26
26
|
// Render
|
|
27
27
|
return (React.createElement(Grid, { container: true, spacing: 2 },
|
|
28
28
|
React.createElement(Grid, { item: true, xs: 12, md: 4, lg: 2, xl: 1 },
|
|
29
29
|
React.createElement(Typography, null,
|
|
30
30
|
React.createElement("strong", null, "Content"))),
|
|
31
|
-
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 },
|
|
32
|
-
React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } },
|
|
31
|
+
React.createElement(Grid, { item: true, xs: 12, md: 8, lg: 10, xl: 11 }, value.content &&
|
|
32
|
+
React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } }, value.content))));
|
|
33
33
|
}
|
|
34
34
|
// Valid props
|
|
35
35
|
SMS.propTypes = {
|
|
36
|
-
mobile: PropTypes.bool.isRequired,
|
|
37
36
|
value: PropTypes.exact({
|
|
38
37
|
_id: PropTypes.string.isRequired,
|
|
39
38
|
_created: PropTypes.number,
|
|
@@ -11,7 +11,6 @@ import React from 'react';
|
|
|
11
11
|
import { responseErrorStruct } from '@ouroboros/body';
|
|
12
12
|
import { contentStruct } from '../..';
|
|
13
13
|
export type ViewProps = {
|
|
14
|
-
mobile: boolean;
|
|
15
14
|
onError: (error: responseErrorStruct) => void;
|
|
16
15
|
value: contentStruct;
|
|
17
16
|
};
|
|
@@ -25,10 +24,9 @@ export type ViewProps = {
|
|
|
25
24
|
* @param Object props Properties passed to the component
|
|
26
25
|
* @returns React.Component
|
|
27
26
|
*/
|
|
28
|
-
declare function View(
|
|
27
|
+
declare function View({ onError, value }: ViewProps): React.JSX.Element;
|
|
29
28
|
declare namespace View {
|
|
30
29
|
var propTypes: {
|
|
31
|
-
mobile: PropTypes.Validator<boolean>;
|
|
32
30
|
onError: PropTypes.Validator<(...args: any[]) => any>;
|
|
33
31
|
value: PropTypes.Requireable<PropTypes.InferProps<{
|
|
34
32
|
_id: PropTypes.Validator<string>;
|
|
@@ -26,22 +26,21 @@ import SMS from './SMS';
|
|
|
26
26
|
* @param Object props Properties passed to the component
|
|
27
27
|
* @returns React.Component
|
|
28
28
|
*/
|
|
29
|
-
export default function View(
|
|
29
|
+
export default function View({ onError, value }) {
|
|
30
30
|
// State
|
|
31
31
|
const [preview, previewSet] = useState(false);
|
|
32
32
|
// Render
|
|
33
33
|
return (React.createElement(Box, { className: "content_view" },
|
|
34
|
-
(
|
|
35
|
-
React.createElement(Email, {
|
|
36
|
-
React.createElement(SMS, {
|
|
34
|
+
(value.type === 'email' &&
|
|
35
|
+
React.createElement(Email, { key: value._id, value: value })) || (value.type === 'sms' &&
|
|
36
|
+
React.createElement(SMS, { key: value._id, value: value })),
|
|
37
37
|
React.createElement(Box, { className: "actions" },
|
|
38
38
|
React.createElement(Button, { color: "info", onClick: () => previewSet(true), variant: "contained" }, "Preview"),
|
|
39
39
|
preview &&
|
|
40
|
-
React.createElement(Preview, {
|
|
40
|
+
React.createElement(Preview, { onClose: () => previewSet(false), onError: onError, value: value }))));
|
|
41
41
|
}
|
|
42
42
|
// Valid props
|
|
43
43
|
View.propTypes = {
|
|
44
|
-
mobile: PropTypes.bool.isRequired,
|
|
45
44
|
onError: PropTypes.func.isRequired,
|
|
46
45
|
value: PropTypes.shape({
|
|
47
46
|
_id: PropTypes.string.isRequired,
|
|
@@ -22,7 +22,7 @@ export type VariablesProps = {
|
|
|
22
22
|
* @param Object props Properties passed to the component
|
|
23
23
|
* @returns React.Component
|
|
24
24
|
*/
|
|
25
|
-
declare function Variables(
|
|
25
|
+
declare function Variables({ onChange, value }: VariablesProps): React.JSX.Element;
|
|
26
26
|
declare namespace Variables {
|
|
27
27
|
var propTypes: {
|
|
28
28
|
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* @created 2023-01-20
|
|
8
8
|
*/
|
|
9
9
|
// Ouroboros modules
|
|
10
|
-
import clone from '@ouroboros/clone';
|
|
11
10
|
import { Node } from '@ouroboros/define';
|
|
12
11
|
import { DefineNode } from '@ouroboros/define-mui';
|
|
13
12
|
import { omap } from '@ouroboros/tools';
|
|
@@ -35,14 +34,14 @@ const oNameNode = new Node({
|
|
|
35
34
|
* @param Object props Properties passed to the component
|
|
36
35
|
* @returns React.Component
|
|
37
36
|
*/
|
|
38
|
-
export default function Variables(
|
|
37
|
+
export default function Variables({ onChange, value }) {
|
|
39
38
|
// Refs
|
|
40
39
|
const refName = useRef(null);
|
|
41
40
|
const refValue = useRef(null);
|
|
42
41
|
// Called when a new variable is added
|
|
43
42
|
function add() {
|
|
44
43
|
// Clone the current value
|
|
45
|
-
const oValue =
|
|
44
|
+
const oValue = { ...value };
|
|
46
45
|
// If we have references to the inputs
|
|
47
46
|
if (refName.current && refValue.current) {
|
|
48
47
|
// Add the new item to it
|
|
@@ -52,23 +51,23 @@ export default function Variables(props) {
|
|
|
52
51
|
refValue.current.value = '';
|
|
53
52
|
}
|
|
54
53
|
// Let the parent know
|
|
55
|
-
|
|
54
|
+
onChange(oValue);
|
|
56
55
|
}
|
|
57
56
|
// Called when an existing variables needs to be removed
|
|
58
57
|
function remove(name) {
|
|
59
58
|
// Clone the current value
|
|
60
|
-
const oValue =
|
|
59
|
+
const oValue = { ...value };
|
|
61
60
|
// Delete the given key if it exists
|
|
62
61
|
if (name in oValue) {
|
|
63
62
|
delete oValue[name];
|
|
64
63
|
}
|
|
65
64
|
// Let the parent know
|
|
66
|
-
|
|
65
|
+
onChange(oValue);
|
|
67
66
|
}
|
|
68
67
|
// Render
|
|
69
68
|
return (React.createElement(Box, null,
|
|
70
69
|
React.createElement(Grid, { container: true, spacing: 1 },
|
|
71
|
-
omap(
|
|
70
|
+
omap(value, (v, k) => React.createElement(React.Fragment, { key: k },
|
|
72
71
|
React.createElement(Grid, { item: true, xs: 5 }, k),
|
|
73
72
|
React.createElement(Grid, { item: true, xs: 5 }, v),
|
|
74
73
|
React.createElement(Grid, { item: true, xs: 2 },
|
|
@@ -32,7 +32,6 @@ export type templateStruct = {
|
|
|
32
32
|
export type typeOption = 'email' | 'sms';
|
|
33
33
|
export type TemplateProps = {
|
|
34
34
|
locales: Record<string, string>;
|
|
35
|
-
mobile: boolean;
|
|
36
35
|
onChange: (template: templateStruct) => void;
|
|
37
36
|
onError: (error: responseErrorStruct) => void;
|
|
38
37
|
onContent: (type: string) => void;
|
|
@@ -52,13 +51,12 @@ export type TemplateProps = {
|
|
|
52
51
|
* @param Object props Properties passed to the component
|
|
53
52
|
* @returns React.Component
|
|
54
53
|
*/
|
|
55
|
-
declare function Template(
|
|
54
|
+
declare function Template({ locales, onChange, onError, onContent, rights, value }: TemplateProps): React.JSX.Element;
|
|
56
55
|
declare namespace Template {
|
|
57
56
|
var propTypes: {
|
|
58
57
|
locales: PropTypes.Validator<{
|
|
59
58
|
[x: string]: string | null | undefined;
|
|
60
59
|
}>;
|
|
61
|
-
mobile: PropTypes.Validator<boolean>;
|
|
62
60
|
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
63
61
|
onError: PropTypes.Validator<(...args: any[]) => any>;
|
|
64
62
|
onContent: PropTypes.Validator<(...args: any[]) => any>;
|
|
@@ -7,12 +7,11 @@
|
|
|
7
7
|
* @created 2023-01-20
|
|
8
8
|
*/
|
|
9
9
|
// Ouroboros modules
|
|
10
|
-
import clone from '@ouroboros/clone';
|
|
11
10
|
import { Node } from '@ouroboros/define';
|
|
12
11
|
import { DefineNode } from '@ouroboros/define-mui';
|
|
13
12
|
import mouth, { errors } from '@ouroboros/mouth';
|
|
14
|
-
import TemplateDef from '@ouroboros/mouth/
|
|
15
|
-
import {
|
|
13
|
+
import TemplateDef from '@ouroboros/mouth/define/template.json';
|
|
14
|
+
import { arrayFindMerge, omap, ucfirst } from '@ouroboros/tools';
|
|
16
15
|
// NPM modules
|
|
17
16
|
import PropTypes from 'prop-types';
|
|
18
17
|
import React, { useRef, useState } from 'react';
|
|
@@ -43,7 +42,7 @@ const oNameNode = new Node(TemplateDef.name);
|
|
|
43
42
|
* @param Object props Properties passed to the component
|
|
44
43
|
* @returns React.Component
|
|
45
44
|
*/
|
|
46
|
-
export default function Template(
|
|
45
|
+
export default function Template({ locales, onChange, onError, onContent, rights, value }) {
|
|
47
46
|
// State
|
|
48
47
|
const [contents, contentsSet] = useState(false);
|
|
49
48
|
const [tab, tabSet] = useState(0);
|
|
@@ -52,39 +51,23 @@ export default function Template(props) {
|
|
|
52
51
|
// Refs
|
|
53
52
|
const refName = useRef(null);
|
|
54
53
|
// Called when the update record changes
|
|
55
|
-
function change(field,
|
|
54
|
+
function change(field, val) {
|
|
56
55
|
// Set the new record
|
|
57
|
-
editSet(o => {
|
|
58
|
-
const oRecord = clone(o);
|
|
59
|
-
oRecord[field] = value;
|
|
60
|
-
return oRecord;
|
|
61
|
-
});
|
|
56
|
+
editSet(o => { return { ...o, [field]: val }; });
|
|
62
57
|
}
|
|
63
58
|
// Called when a single conent record is created
|
|
64
59
|
function contentCreated(content) {
|
|
65
60
|
// Notify the parent
|
|
66
|
-
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
// Add the new record to the end of the array
|
|
70
|
-
lContents.push(content);
|
|
71
|
-
// Set the new contents
|
|
72
|
-
contentsSet(lContents);
|
|
61
|
+
onContent('create');
|
|
62
|
+
// Add it to the end
|
|
63
|
+
contentsSet(l => [...l, content]);
|
|
73
64
|
}
|
|
74
65
|
// Called when a single content record is updated
|
|
75
66
|
function contentUpdated(content) {
|
|
76
67
|
// Notify the parent
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
// If we got an index
|
|
81
|
-
if (i > -1) {
|
|
82
|
-
// Clone the current contents, merge the current record with the
|
|
83
|
-
// new one, and set the new contents
|
|
84
|
-
const lContents = clone(contents);
|
|
85
|
-
lContents[i] = { ...lContents[i], ...content };
|
|
86
|
-
contentsSet(lContents);
|
|
87
|
-
}
|
|
68
|
+
onContent('update');
|
|
69
|
+
// Work on latest
|
|
70
|
+
contentsSet(l => arrayFindMerge(l, '_id', content._id, content, true));
|
|
88
71
|
}
|
|
89
72
|
// Called to delete the template
|
|
90
73
|
function remove() {
|
|
@@ -97,7 +80,7 @@ export default function Template(props) {
|
|
|
97
80
|
// Hide the form
|
|
98
81
|
editSet(false);
|
|
99
82
|
// Let the parent know
|
|
100
|
-
|
|
83
|
+
onChange(edit);
|
|
101
84
|
}, (error) => {
|
|
102
85
|
if (error.code === errors.body.DB_DUPLICATE) {
|
|
103
86
|
refName.current?.error('Duplicate');
|
|
@@ -115,7 +98,7 @@ export default function Template(props) {
|
|
|
115
98
|
else {
|
|
116
99
|
if (contents === false) {
|
|
117
100
|
mouth.read('template/contents', {
|
|
118
|
-
template:
|
|
101
|
+
template: value._id
|
|
119
102
|
}).then(contentsSet);
|
|
120
103
|
}
|
|
121
104
|
viewSet(true);
|
|
@@ -126,15 +109,15 @@ export default function Template(props) {
|
|
|
126
109
|
React.createElement(Box, { className: "flexColumns" },
|
|
127
110
|
React.createElement(Box, { className: "flexGrow link", onClick: viewToggle },
|
|
128
111
|
React.createElement("h2", null,
|
|
129
|
-
ucfirst(
|
|
112
|
+
ucfirst(value.name.replace(/_/g, ' ')),
|
|
130
113
|
"\u00A0\u00A0",
|
|
131
114
|
React.createElement("i", { className: 'fa-solid fa-angle-' + (view ? 'up' : 'down') }))),
|
|
132
115
|
React.createElement(Box, { className: "flexStatic" },
|
|
133
|
-
|
|
116
|
+
rights.template.update &&
|
|
134
117
|
React.createElement(Tooltip, { title: "Edit the Template" },
|
|
135
|
-
React.createElement(IconButton, { className: "icon", onClick: ev => editSet(edit ? false :
|
|
118
|
+
React.createElement(IconButton, { className: "icon", onClick: ev => editSet(edit ? false : { ...value }) },
|
|
136
119
|
React.createElement("i", { className: 'fa-solid fa-edit ' + (edit ? 'open' : 'closed') }))),
|
|
137
|
-
|
|
120
|
+
rights.template.delete &&
|
|
138
121
|
React.createElement(Tooltip, { title: "Delete the Template" },
|
|
139
122
|
React.createElement(IconButton, { className: "icon", onClick: remove },
|
|
140
123
|
React.createElement("i", { className: "fa-solid fa-trash-alt" }))))),
|
|
@@ -146,11 +129,11 @@ export default function Template(props) {
|
|
|
146
129
|
React.createElement(Grid, { item: true, lg: 6, md: 12, className: "field" },
|
|
147
130
|
React.createElement(Typography, null,
|
|
148
131
|
React.createElement("strong", null, "Name")),
|
|
149
|
-
React.createElement(DefineNode, { label: "none", name: "name", node: oNameNode, onChange:
|
|
132
|
+
React.createElement(DefineNode, { label: "none", name: "name", node: oNameNode, onChange: val => change('name', val), onEnterPressed: update, ref: refName, type: "update", value: edit.name })),
|
|
150
133
|
React.createElement(Grid, { item: true, lg: 6, md: 12 },
|
|
151
134
|
React.createElement(Typography, null,
|
|
152
135
|
React.createElement("strong", null, "Variables")),
|
|
153
|
-
React.createElement(Variables, { onChange:
|
|
136
|
+
React.createElement(Variables, { onChange: val => change('variables', val), value: edit.variables || {} })),
|
|
154
137
|
React.createElement(Grid, { item: true, xs: 12, className: "actions" },
|
|
155
138
|
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => editSet(false) }, "Cancel"),
|
|
156
139
|
React.createElement(Button, { variant: "contained", color: "primary", onClick: update }, "Save")))),
|
|
@@ -160,26 +143,25 @@ export default function Template(props) {
|
|
|
160
143
|
React.createElement(Grid, { container: true, spacing: 1 },
|
|
161
144
|
React.createElement(Grid, { item: true, xs: 12, md: 9, xl: 10 },
|
|
162
145
|
React.createElement(Tabs, { onChange: (ev, val) => tabSet(val), scrollButtons: "auto", variant: "scrollable", value: tab },
|
|
163
|
-
contents && contents.map(o => React.createElement(Tab, { key: o._id, label:
|
|
164
|
-
|
|
146
|
+
contents && contents.map(o => React.createElement(Tab, { key: o._id, label: locales[o.locale] + ' ' + o.type })),
|
|
147
|
+
rights.content.create &&
|
|
165
148
|
React.createElement(Tab, { label: React.createElement("i", { className: "fa-solid fa-plus" }) })),
|
|
166
149
|
React.createElement(Box, { className: "padding" },
|
|
167
150
|
React.createElement("br", null),
|
|
168
151
|
(contents && tab < contents.length &&
|
|
169
|
-
(
|
|
170
|
-
React.createElement(ContentUpdate, { key: contents[tab]._id,
|
|
152
|
+
(rights.content.update ?
|
|
153
|
+
React.createElement(ContentUpdate, { key: contents[tab]._id, onError: onError, onUpdated: contentUpdated, value: contents[tab] })
|
|
171
154
|
:
|
|
172
|
-
React.createElement(ContentView, { key: contents[tab]._id,
|
|
173
|
-
((
|
|
174
|
-
React.createElement(ContentCreate, { locales:
|
|
155
|
+
React.createElement(ContentView, { key: contents[tab]._id, onError: onError, value: contents[tab] }))) ||
|
|
156
|
+
((rights.content.create && contents && tab === contents.length) &&
|
|
157
|
+
React.createElement(ContentCreate, { locales: locales, onCreated: contentCreated, onError: onError, template: value._id })))),
|
|
175
158
|
React.createElement(Grid, { item: true, xs: 12, md: 3, xl: 2 },
|
|
176
159
|
React.createElement("h4", null, "Available Variables"),
|
|
177
|
-
|
|
160
|
+
value && omap(value.variables, (v, k) => React.createElement(Typography, { key: k }, '{' + k + '}')))))));
|
|
178
161
|
}
|
|
179
162
|
// Valid props
|
|
180
163
|
Template.propTypes = {
|
|
181
164
|
locales: PropTypes.objectOf(PropTypes.string).isRequired,
|
|
182
|
-
mobile: PropTypes.bool.isRequired,
|
|
183
165
|
onChange: PropTypes.func.isRequired,
|
|
184
166
|
onError: PropTypes.func.isRequired,
|
|
185
167
|
onContent: PropTypes.func.isRequired,
|
|
@@ -10,7 +10,6 @@ import PropTypes from 'prop-types';
|
|
|
10
10
|
import React from 'react';
|
|
11
11
|
import { responseErrorStruct } from '@ouroboros/body';
|
|
12
12
|
export type TemplatesProps = {
|
|
13
|
-
mobile: boolean;
|
|
14
13
|
onError: (error: responseErrorStruct) => void;
|
|
15
14
|
onSuccess: (type: string) => void;
|
|
16
15
|
};
|
|
@@ -24,10 +23,9 @@ export type TemplatesProps = {
|
|
|
24
23
|
* @param Object props Properties passed to the component
|
|
25
24
|
* @returns React.Component
|
|
26
25
|
*/
|
|
27
|
-
declare function Templates(
|
|
26
|
+
declare function Templates({ onError, onSuccess }: TemplatesProps): React.JSX.Element;
|
|
28
27
|
declare namespace Templates {
|
|
29
28
|
var propTypes: {
|
|
30
|
-
mobile: PropTypes.Validator<boolean>;
|
|
31
29
|
onError: PropTypes.Validator<(...args: any[]) => any>;
|
|
32
30
|
onSuccess: PropTypes.Validator<(...args: any[]) => any>;
|
|
33
31
|
};
|