@ouroboros/mouth-mui 1.0.0
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/LICENSE +8 -0
- package/README.md +15 -0
- package/package.json +55 -0
- package/src/components/pages/Locales.d.ts +35 -0
- package/src/components/pages/Locales.js +188 -0
- package/src/components/pages/Locales.tsx +254 -0
- package/src/components/pages/Templates/Create.d.ts +36 -0
- package/src/components/pages/Templates/Create.js +98 -0
- package/src/components/pages/Templates/Create.tsx +139 -0
- package/src/components/pages/Templates/Template/Content/Create/Email.d.ts +39 -0
- package/src/components/pages/Templates/Template/Content/Create/Email.js +51 -0
- package/src/components/pages/Templates/Template/Content/Create/Email.tsx +96 -0
- package/src/components/pages/Templates/Template/Content/Create/SMS.d.ts +37 -0
- package/src/components/pages/Templates/Template/Content/Create/SMS.js +42 -0
- package/src/components/pages/Templates/Template/Content/Create/SMS.tsx +68 -0
- package/src/components/pages/Templates/Template/Content/Create/index.d.ts +42 -0
- package/src/components/pages/Templates/Template/Content/Create/index.js +177 -0
- package/src/components/pages/Templates/Template/Content/Create/index.tsx +257 -0
- package/src/components/pages/Templates/Template/Content/Preview/Email.d.ts +37 -0
- package/src/components/pages/Templates/Template/Content/Preview/Email.js +51 -0
- package/src/components/pages/Templates/Template/Content/Preview/Email.tsx +78 -0
- package/src/components/pages/Templates/Template/Content/Preview/SMS.d.ts +32 -0
- package/src/components/pages/Templates/Template/Content/Preview/SMS.js +38 -0
- package/src/components/pages/Templates/Template/Content/Preview/SMS.tsx +59 -0
- package/src/components/pages/Templates/Template/Content/Preview/index.d.ts +42 -0
- package/src/components/pages/Templates/Template/Content/Preview/index.js +63 -0
- package/src/components/pages/Templates/Template/Content/Preview/index.tsx +107 -0
- package/src/components/pages/Templates/Template/Content/Update/Email.d.ts +39 -0
- package/src/components/pages/Templates/Template/Content/Update/Email.js +51 -0
- package/src/components/pages/Templates/Template/Content/Update/Email.tsx +96 -0
- package/src/components/pages/Templates/Template/Content/Update/SMS.d.ts +37 -0
- package/src/components/pages/Templates/Template/Content/Update/SMS.js +42 -0
- package/src/components/pages/Templates/Template/Content/Update/SMS.tsx +68 -0
- package/src/components/pages/Templates/Template/Content/Update/index.d.ts +42 -0
- package/src/components/pages/Templates/Template/Content/Update/index.js +117 -0
- package/src/components/pages/Templates/Template/Content/Update/index.tsx +162 -0
- package/src/components/pages/Templates/Template/Content/View/Email.d.ts +43 -0
- package/src/components/pages/Templates/Template/Content/View/Email.js +57 -0
- package/src/components/pages/Templates/Template/Content/View/Email.tsx +80 -0
- package/src/components/pages/Templates/Template/Content/View/SMS.d.ts +41 -0
- package/src/components/pages/Templates/Template/Content/View/SMS.js +46 -0
- package/src/components/pages/Templates/Template/Content/View/SMS.tsx +64 -0
- package/src/components/pages/Templates/Template/Content/View/index.d.ts +39 -0
- package/src/components/pages/Templates/Template/Content/View/index.js +50 -0
- package/src/components/pages/Templates/Template/Content/View/index.tsx +78 -0
- package/src/components/pages/Templates/Template/Variables.d.ts +34 -0
- package/src/components/pages/Templates/Template/Variables.js +91 -0
- package/src/components/pages/Templates/Template/Variables.tsx +138 -0
- package/src/components/pages/Templates/Template/index.d.ts +90 -0
- package/src/components/pages/Templates/Template/index.js +207 -0
- package/src/components/pages/Templates/Template/index.tsx +337 -0
- package/src/components/pages/Templates/index.d.ts +35 -0
- package/src/components/pages/Templates/index.js +112 -0
- package/src/components/pages/Templates/index.tsx +165 -0
- package/src/index.d.ts +5 -0
- package/src/index.js +5 -0
- package/src/index.ts +8 -0
- package/src/locales.d.ts +72 -0
- package/src/locales.js +160 -0
- package/src/locales.ts +200 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Preview
|
|
3
|
+
*
|
|
4
|
+
* Preview component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Ouroboos modules
|
|
11
|
+
import { errorTree } from '@ouroboros/define-mui';
|
|
12
|
+
import mouth, { errors } from '@ouroboros/mouth';
|
|
13
|
+
|
|
14
|
+
// NPM modules
|
|
15
|
+
import PropTypes from 'prop-types';
|
|
16
|
+
import React, { useEffect, useState } from 'react';
|
|
17
|
+
|
|
18
|
+
// Material UI
|
|
19
|
+
import DialogTitle from '@mui/material/DialogTitle';
|
|
20
|
+
import DialogContent from '@mui/material/DialogContent';
|
|
21
|
+
import Dialog from '@mui/material/Dialog';
|
|
22
|
+
import Typography from '@mui/material/Typography';
|
|
23
|
+
|
|
24
|
+
// Local components
|
|
25
|
+
import Email from './Email';
|
|
26
|
+
import SMS from './SMS';
|
|
27
|
+
|
|
28
|
+
// Types
|
|
29
|
+
import { contentStruct } from '../..';
|
|
30
|
+
import { responseErrorStruct } from '@ouroboros/body';
|
|
31
|
+
export type PreviewProps = {
|
|
32
|
+
mobile: boolean,
|
|
33
|
+
onClose: () => void,
|
|
34
|
+
onError: (error: responseErrorStruct) => void,
|
|
35
|
+
value: contentStruct
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Preview
|
|
40
|
+
*
|
|
41
|
+
* Handles viewing template content
|
|
42
|
+
*
|
|
43
|
+
* @name Preview
|
|
44
|
+
* @access public
|
|
45
|
+
* @param Object props Properties passed to the component
|
|
46
|
+
* @returns React.Component
|
|
47
|
+
*/
|
|
48
|
+
export default function Preview(props: PreviewProps) {
|
|
49
|
+
|
|
50
|
+
// Props
|
|
51
|
+
const { mobile, onClose, onError, value } = props;
|
|
52
|
+
|
|
53
|
+
// State
|
|
54
|
+
const [preview, previewSet] = useState<contentStruct | string | false>(false);
|
|
55
|
+
|
|
56
|
+
// Value effect
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
mouth.create(
|
|
59
|
+
`template/${value.type}/generate`,
|
|
60
|
+
value
|
|
61
|
+
).then(previewSet, onError);
|
|
62
|
+
}, [value, onError]);
|
|
63
|
+
|
|
64
|
+
// Render
|
|
65
|
+
return (
|
|
66
|
+
<Dialog
|
|
67
|
+
fullWidth={true}
|
|
68
|
+
maxWidth="lg"
|
|
69
|
+
onClose={onClose}
|
|
70
|
+
open={true}
|
|
71
|
+
aria-labelledby="template-content-preview-title"
|
|
72
|
+
>
|
|
73
|
+
<DialogTitle id="template-content-preview-title">Template Preview for {value.locale}-{value.type}</DialogTitle>
|
|
74
|
+
<DialogContent dividers className="content_preview">
|
|
75
|
+
{preview === false ?
|
|
76
|
+
<Typography>Loading...</Typography>
|
|
77
|
+
: (
|
|
78
|
+
value.type === 'email' &&
|
|
79
|
+
<Email
|
|
80
|
+
key={value.template + '_' + value.locale + '_email'}
|
|
81
|
+
mobile={mobile}
|
|
82
|
+
value={preview as contentStruct}
|
|
83
|
+
/>
|
|
84
|
+
) || (
|
|
85
|
+
value.type === 'sms' &&
|
|
86
|
+
<SMS
|
|
87
|
+
key={value.template + '_' + value.locale + '_sms'}
|
|
88
|
+
mobile={mobile}
|
|
89
|
+
value={preview as string}
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
</DialogContent>
|
|
93
|
+
</Dialog>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Valid props
|
|
98
|
+
Preview.propTypes = {
|
|
99
|
+
mobile: PropTypes.bool.isRequired,
|
|
100
|
+
onClose: PropTypes.func.isRequired,
|
|
101
|
+
onError: PropTypes.func.isRequired,
|
|
102
|
+
value: PropTypes.shape({
|
|
103
|
+
locale: PropTypes.string.isRequired,
|
|
104
|
+
template: PropTypes.string,
|
|
105
|
+
type: PropTypes.oneOf(['email', 'sms']).isRequired
|
|
106
|
+
})
|
|
107
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update Email
|
|
3
|
+
*
|
|
4
|
+
* Email component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
/// <reference types="react" />
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
import { contentStruct } from '../../';
|
|
12
|
+
export type EmailProps = {
|
|
13
|
+
errors: Record<string, any>;
|
|
14
|
+
onChanged: (field: string, value: string) => void;
|
|
15
|
+
value: Omit<contentStruct, 'type'>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Email
|
|
19
|
+
*
|
|
20
|
+
* Handles creating new template content
|
|
21
|
+
*
|
|
22
|
+
* @name Email
|
|
23
|
+
* @access public
|
|
24
|
+
* @param Object props Properties passed to the component
|
|
25
|
+
* @returns React.Component
|
|
26
|
+
*/
|
|
27
|
+
declare function Email(props: EmailProps): JSX.Element;
|
|
28
|
+
declare namespace Email {
|
|
29
|
+
var propTypes: {
|
|
30
|
+
errors: PropTypes.Validator<object>;
|
|
31
|
+
onChanged: PropTypes.Validator<(...args: any[]) => any>;
|
|
32
|
+
value: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
33
|
+
subject: PropTypes.Validator<string>;
|
|
34
|
+
text: PropTypes.Validator<string>;
|
|
35
|
+
html: PropTypes.Validator<string>;
|
|
36
|
+
}>>>;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export default Email;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update Email
|
|
3
|
+
*
|
|
4
|
+
* Email component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
// Ouroboros modules
|
|
10
|
+
import { Node } from '@ouroboros/define';
|
|
11
|
+
import { DefineNode } from '@ouroboros/define-mui';
|
|
12
|
+
import TemplateEmail from '@ouroboros/mouth/definitions/template_email.json';
|
|
13
|
+
// NPM modules
|
|
14
|
+
import PropTypes from 'prop-types';
|
|
15
|
+
import React from 'react';
|
|
16
|
+
// Material UI
|
|
17
|
+
import Grid from '@mui/material/Grid';
|
|
18
|
+
// Record Nodes
|
|
19
|
+
const oSubjectNode = new Node(TemplateEmail.subject);
|
|
20
|
+
const oTextNode = new Node(TemplateEmail.text);
|
|
21
|
+
const oHtmlNode = new Node(TemplateEmail.html);
|
|
22
|
+
/**
|
|
23
|
+
* Email
|
|
24
|
+
*
|
|
25
|
+
* Handles creating new template content
|
|
26
|
+
*
|
|
27
|
+
* @name Email
|
|
28
|
+
* @access public
|
|
29
|
+
* @param Object props Properties passed to the component
|
|
30
|
+
* @returns React.Component
|
|
31
|
+
*/
|
|
32
|
+
export default function Email(props) {
|
|
33
|
+
// Render
|
|
34
|
+
return (React.createElement(Grid, { container: true, className: "content_update_email", spacing: 1 },
|
|
35
|
+
React.createElement(Grid, { item: true, xs: 12, className: "field" },
|
|
36
|
+
React.createElement(DefineNode, { error: props.errors.subject || false, label: "placeholder", name: "subject", node: oSubjectNode, onChange: val => props.onChanged('subject', val), type: "update", value: props.value.subject })),
|
|
37
|
+
React.createElement(Grid, { item: true, xs: 12, lg: 6, className: "field" },
|
|
38
|
+
React.createElement(DefineNode, { error: props.errors.text || false, label: "placeholder", name: "text", node: oTextNode, onChange: val => props.onChanged('text', val), type: "update", value: props.value.text })),
|
|
39
|
+
React.createElement(Grid, { item: true, xs: 12, lg: 6, className: "field" },
|
|
40
|
+
React.createElement(DefineNode, { error: props.errors.html || false, label: "placeholder", name: "html", node: oHtmlNode, onChange: val => props.onChanged('html', val), type: "update", value: props.value.html }))));
|
|
41
|
+
}
|
|
42
|
+
// Valid props
|
|
43
|
+
Email.propTypes = {
|
|
44
|
+
errors: PropTypes.object.isRequired,
|
|
45
|
+
onChanged: PropTypes.func.isRequired,
|
|
46
|
+
value: PropTypes.shape({
|
|
47
|
+
subject: PropTypes.string.isRequired,
|
|
48
|
+
text: PropTypes.string.isRequired,
|
|
49
|
+
html: PropTypes.string.isRequired
|
|
50
|
+
}).isRequired
|
|
51
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update Email
|
|
3
|
+
*
|
|
4
|
+
* Email component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Ouroboros modules
|
|
11
|
+
import { Node } from '@ouroboros/define';
|
|
12
|
+
import { DefineNode } from '@ouroboros/define-mui';
|
|
13
|
+
import TemplateEmail from '@ouroboros/mouth/definitions/template_email.json';
|
|
14
|
+
|
|
15
|
+
// NPM modules
|
|
16
|
+
import PropTypes from 'prop-types';
|
|
17
|
+
import React from 'react';
|
|
18
|
+
|
|
19
|
+
// Material UI
|
|
20
|
+
import Grid from '@mui/material/Grid';
|
|
21
|
+
|
|
22
|
+
// Record Nodes
|
|
23
|
+
const oSubjectNode = new Node(TemplateEmail.subject);
|
|
24
|
+
const oTextNode = new Node(TemplateEmail.text);
|
|
25
|
+
const oHtmlNode = new Node(TemplateEmail.html);
|
|
26
|
+
|
|
27
|
+
// Types
|
|
28
|
+
import { contentStruct } from '../../';
|
|
29
|
+
export type EmailProps = {
|
|
30
|
+
errors: Record<string, any>,
|
|
31
|
+
onChanged: (field: string, value: string) => void,
|
|
32
|
+
value: Omit<contentStruct, 'type'>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Email
|
|
37
|
+
*
|
|
38
|
+
* Handles creating new template content
|
|
39
|
+
*
|
|
40
|
+
* @name Email
|
|
41
|
+
* @access public
|
|
42
|
+
* @param Object props Properties passed to the component
|
|
43
|
+
* @returns React.Component
|
|
44
|
+
*/
|
|
45
|
+
export default function Email(props: EmailProps) {
|
|
46
|
+
|
|
47
|
+
// Render
|
|
48
|
+
return (
|
|
49
|
+
<Grid container className="content_update_email" spacing={1}>
|
|
50
|
+
<Grid item xs={12} className="field">
|
|
51
|
+
<DefineNode
|
|
52
|
+
error={props.errors.subject || false}
|
|
53
|
+
label="placeholder"
|
|
54
|
+
name="subject"
|
|
55
|
+
node={oSubjectNode}
|
|
56
|
+
onChange={val => props.onChanged('subject', val)}
|
|
57
|
+
type="update"
|
|
58
|
+
value={props.value.subject}
|
|
59
|
+
/>
|
|
60
|
+
</Grid>
|
|
61
|
+
<Grid item xs={12} lg={6} className="field">
|
|
62
|
+
<DefineNode
|
|
63
|
+
error={props.errors.text || false}
|
|
64
|
+
label="placeholder"
|
|
65
|
+
name="text"
|
|
66
|
+
node={oTextNode}
|
|
67
|
+
onChange={val => props.onChanged('text', val)}
|
|
68
|
+
type="update"
|
|
69
|
+
value={props.value.text}
|
|
70
|
+
/>
|
|
71
|
+
</Grid>
|
|
72
|
+
<Grid item xs={12} lg={6} className="field">
|
|
73
|
+
<DefineNode
|
|
74
|
+
error={props.errors.html || false}
|
|
75
|
+
label="placeholder"
|
|
76
|
+
name="html"
|
|
77
|
+
node={oHtmlNode}
|
|
78
|
+
onChange={val => props.onChanged('html', val)}
|
|
79
|
+
type="update"
|
|
80
|
+
value={props.value.html}
|
|
81
|
+
/>
|
|
82
|
+
</Grid>
|
|
83
|
+
</Grid>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Valid props
|
|
88
|
+
Email.propTypes = {
|
|
89
|
+
errors: PropTypes.object.isRequired,
|
|
90
|
+
onChanged: PropTypes.func.isRequired,
|
|
91
|
+
value: PropTypes.shape({
|
|
92
|
+
subject: PropTypes.string.isRequired,
|
|
93
|
+
text: PropTypes.string.isRequired,
|
|
94
|
+
html: PropTypes.string.isRequired
|
|
95
|
+
}).isRequired
|
|
96
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update SMS
|
|
3
|
+
*
|
|
4
|
+
* SMS component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
/// <reference types="react" />
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
import { contentStruct } from '../../';
|
|
12
|
+
export type SMSProps = {
|
|
13
|
+
errors: Record<string, any>;
|
|
14
|
+
onChanged: (field: string, value: string) => void;
|
|
15
|
+
value: Omit<contentStruct, 'type'>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* SMS
|
|
19
|
+
*
|
|
20
|
+
* Handles creating new template content
|
|
21
|
+
*
|
|
22
|
+
* @name SMS
|
|
23
|
+
* @access public
|
|
24
|
+
* @param Object props Properties passed to the component
|
|
25
|
+
* @returns React.Component
|
|
26
|
+
*/
|
|
27
|
+
declare function SMS(props: SMSProps): JSX.Element;
|
|
28
|
+
declare namespace SMS {
|
|
29
|
+
var propTypes: {
|
|
30
|
+
errors: PropTypes.Validator<object>;
|
|
31
|
+
onChanged: PropTypes.Validator<(...args: any[]) => any>;
|
|
32
|
+
value: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
33
|
+
content: PropTypes.Validator<string>;
|
|
34
|
+
}>>>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export default SMS;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update SMS
|
|
3
|
+
*
|
|
4
|
+
* SMS component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
// Ouroboros modules
|
|
10
|
+
import { Node } from '@ouroboros/define';
|
|
11
|
+
import { DefineNode } from '@ouroboros/define-mui';
|
|
12
|
+
import TemplateSMS from '@ouroboros/mouth/definitions/template_sms.json';
|
|
13
|
+
// NPM modules
|
|
14
|
+
import PropTypes from 'prop-types';
|
|
15
|
+
import React from 'react';
|
|
16
|
+
// Material UI
|
|
17
|
+
import Box from '@mui/material/Box';
|
|
18
|
+
// Record Nodes
|
|
19
|
+
const oContentNode = new Node(TemplateSMS.content);
|
|
20
|
+
/**
|
|
21
|
+
* SMS
|
|
22
|
+
*
|
|
23
|
+
* Handles creating new template content
|
|
24
|
+
*
|
|
25
|
+
* @name SMS
|
|
26
|
+
* @access public
|
|
27
|
+
* @param Object props Properties passed to the component
|
|
28
|
+
* @returns React.Component
|
|
29
|
+
*/
|
|
30
|
+
export default function SMS(props) {
|
|
31
|
+
// Render
|
|
32
|
+
return (React.createElement(Box, { className: "content_update_sms field" },
|
|
33
|
+
React.createElement(DefineNode, { error: props.errors.content || false, label: "placeholder", name: "content", node: oContentNode, onChange: val => props.onChanged('content', val), type: "update", value: props.value.content })));
|
|
34
|
+
}
|
|
35
|
+
// Valid props
|
|
36
|
+
SMS.propTypes = {
|
|
37
|
+
errors: PropTypes.object.isRequired,
|
|
38
|
+
onChanged: PropTypes.func.isRequired,
|
|
39
|
+
value: PropTypes.shape({
|
|
40
|
+
content: PropTypes.string.isRequired
|
|
41
|
+
}).isRequired
|
|
42
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update SMS
|
|
3
|
+
*
|
|
4
|
+
* SMS component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-23
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Ouroboros modules
|
|
11
|
+
import { Node } from '@ouroboros/define';
|
|
12
|
+
import { DefineNode } from '@ouroboros/define-mui';
|
|
13
|
+
import TemplateSMS from '@ouroboros/mouth/definitions/template_sms.json';
|
|
14
|
+
|
|
15
|
+
// NPM modules
|
|
16
|
+
import PropTypes from 'prop-types';
|
|
17
|
+
import React from 'react';
|
|
18
|
+
|
|
19
|
+
// Material UI
|
|
20
|
+
import Box from '@mui/material/Box';
|
|
21
|
+
|
|
22
|
+
// Record Nodes
|
|
23
|
+
const oContentNode = new Node(TemplateSMS.content);
|
|
24
|
+
|
|
25
|
+
// Types
|
|
26
|
+
import { contentStruct } from '../../';
|
|
27
|
+
export type SMSProps = {
|
|
28
|
+
errors: Record<string, any>,
|
|
29
|
+
onChanged: (field: string, value: string) => void,
|
|
30
|
+
value: Omit<contentStruct, 'type'>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* SMS
|
|
35
|
+
*
|
|
36
|
+
* Handles creating new template content
|
|
37
|
+
*
|
|
38
|
+
* @name SMS
|
|
39
|
+
* @access public
|
|
40
|
+
* @param Object props Properties passed to the component
|
|
41
|
+
* @returns React.Component
|
|
42
|
+
*/
|
|
43
|
+
export default function SMS(props: SMSProps) {
|
|
44
|
+
|
|
45
|
+
// Render
|
|
46
|
+
return (
|
|
47
|
+
<Box className="content_update_sms field">
|
|
48
|
+
<DefineNode
|
|
49
|
+
error={props.errors.content || false}
|
|
50
|
+
label="placeholder"
|
|
51
|
+
name="content"
|
|
52
|
+
node={oContentNode}
|
|
53
|
+
onChange={val => props.onChanged('content', val)}
|
|
54
|
+
type="update"
|
|
55
|
+
value={props.value.content}
|
|
56
|
+
/>
|
|
57
|
+
</Box>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Valid props
|
|
62
|
+
SMS.propTypes = {
|
|
63
|
+
errors: PropTypes.object.isRequired,
|
|
64
|
+
onChanged: PropTypes.func.isRequired,
|
|
65
|
+
value: PropTypes.shape({
|
|
66
|
+
content: PropTypes.string.isRequired
|
|
67
|
+
}).isRequired
|
|
68
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update
|
|
3
|
+
*
|
|
4
|
+
* Update component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-22
|
|
8
|
+
*/
|
|
9
|
+
/// <reference types="react" />
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
import { responseErrorStruct } from '@ouroboros/body';
|
|
12
|
+
import { contentStruct } from '../..';
|
|
13
|
+
export type updateStruct = Omit<contentStruct, 'type'>;
|
|
14
|
+
export type UpdateProps = {
|
|
15
|
+
mobile: boolean;
|
|
16
|
+
onError: (error: responseErrorStruct) => void;
|
|
17
|
+
onUpdated: (content: contentStruct) => void;
|
|
18
|
+
value: contentStruct;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Update
|
|
22
|
+
*
|
|
23
|
+
* Handles updating template content
|
|
24
|
+
*
|
|
25
|
+
* @name Update
|
|
26
|
+
* @access public
|
|
27
|
+
* @param Object props Properties passed to the component
|
|
28
|
+
* @returns React.Component
|
|
29
|
+
*/
|
|
30
|
+
declare function Update(props: UpdateProps): JSX.Element;
|
|
31
|
+
declare namespace Update {
|
|
32
|
+
var propTypes: {
|
|
33
|
+
mobile: PropTypes.Validator<boolean>;
|
|
34
|
+
onError: PropTypes.Validator<(...args: any[]) => any>;
|
|
35
|
+
onUpdated: PropTypes.Validator<(...args: any[]) => any>;
|
|
36
|
+
value: PropTypes.Requireable<PropTypes.InferProps<{
|
|
37
|
+
_id: PropTypes.Validator<string>;
|
|
38
|
+
type: PropTypes.Validator<string>;
|
|
39
|
+
}>>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export default Update;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communications Templates Template Content Update
|
|
3
|
+
*
|
|
4
|
+
* Update component
|
|
5
|
+
*
|
|
6
|
+
* @author Chris Nasr <chris@ouroboroscoding.com>
|
|
7
|
+
* @created 2023-01-22
|
|
8
|
+
*/
|
|
9
|
+
// Ouroboros modules
|
|
10
|
+
import clone from '@ouroboros/clone';
|
|
11
|
+
import { errorTree } from '@ouroboros/define-mui';
|
|
12
|
+
import mouth, { errors } from '@ouroboros/mouth';
|
|
13
|
+
import { owithout } from '@ouroboros/tools';
|
|
14
|
+
// NPM modules
|
|
15
|
+
import PropTypes from 'prop-types';
|
|
16
|
+
import React, { useState } from 'react';
|
|
17
|
+
// Material UI
|
|
18
|
+
import Box from '@mui/material/Box';
|
|
19
|
+
import Button from '@mui/material/Button';
|
|
20
|
+
// Local components
|
|
21
|
+
import Email from './Email';
|
|
22
|
+
import Preview from '../Preview';
|
|
23
|
+
import SMS from './SMS';
|
|
24
|
+
/**
|
|
25
|
+
* Update
|
|
26
|
+
*
|
|
27
|
+
* Handles updating template content
|
|
28
|
+
*
|
|
29
|
+
* @name Update
|
|
30
|
+
* @access public
|
|
31
|
+
* @param Object props Properties passed to the component
|
|
32
|
+
* @returns React.Component
|
|
33
|
+
*/
|
|
34
|
+
export default function Update(props) {
|
|
35
|
+
// State
|
|
36
|
+
const [fieldErrors, fieldErrorsSet] = useState({});
|
|
37
|
+
const [preview, previewSet] = useState(false);
|
|
38
|
+
const [record, recordSet] = useState(owithout(props.value, 'type'));
|
|
39
|
+
// Called to create the new content record
|
|
40
|
+
function update() {
|
|
41
|
+
// Send the record data to the server
|
|
42
|
+
mouth.update(`template/${props.value.type}`, record).then(data => {
|
|
43
|
+
props.onUpdated({ type: props.value.type, ...record });
|
|
44
|
+
}, (error) => {
|
|
45
|
+
if (error.code === errors.body.DATA_FIELDS) {
|
|
46
|
+
fieldErrorsSet(errorTree(error.msg));
|
|
47
|
+
}
|
|
48
|
+
else if (error.code === errors.TEMPLATE_CONTENT_ERROR) {
|
|
49
|
+
const oLines = { templates: [], variables: [] };
|
|
50
|
+
for (const l of error.msg) {
|
|
51
|
+
if (l[0] === 'template') {
|
|
52
|
+
oLines.templates.push(l[1]);
|
|
53
|
+
}
|
|
54
|
+
else if (l[0] === 'variable') {
|
|
55
|
+
oLines.variables.push(l[1]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const lLines = [];
|
|
59
|
+
if (oLines.templates.length) {
|
|
60
|
+
lLines.push('The following templates are invalid: ' + oLines.templates.join(', '));
|
|
61
|
+
}
|
|
62
|
+
if (oLines.variables.length) {
|
|
63
|
+
lLines.push('The following variables are invalid: ' + oLines.variables.join(', '));
|
|
64
|
+
}
|
|
65
|
+
// Show the errors
|
|
66
|
+
if (props.onError) {
|
|
67
|
+
props.onError({ code: 0, msg: lLines.join('\n') });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
props.onError(error);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// Called when any fields in the record are changed
|
|
76
|
+
function recordChanged(field, value) {
|
|
77
|
+
// Clear error
|
|
78
|
+
if (field in fieldErrors) {
|
|
79
|
+
delete fieldErrors.field;
|
|
80
|
+
}
|
|
81
|
+
// Clone the record
|
|
82
|
+
const oRecord = clone(record);
|
|
83
|
+
// Update the field
|
|
84
|
+
oRecord[field] = value;
|
|
85
|
+
// Store the new record
|
|
86
|
+
recordSet(oRecord);
|
|
87
|
+
}
|
|
88
|
+
// Render
|
|
89
|
+
return (React.createElement(Box, { className: "content_update" },
|
|
90
|
+
(props.value.type === 'email' &&
|
|
91
|
+
React.createElement(Email, { errors: fieldErrors, key: props.value._id, onChanged: recordChanged, value: record })) || (props.value.type === 'sms' &&
|
|
92
|
+
React.createElement(SMS, { errors: fieldErrors, key: props.value._id, onChanged: recordChanged, value: record })),
|
|
93
|
+
React.createElement(Box, { className: "actions" },
|
|
94
|
+
React.createElement(Button, { color: "secondary", onClick: () => recordSet(owithout(props.value, 'type')), variant: "contained" }, "Cancel"),
|
|
95
|
+
React.createElement(Button, { color: "info", onClick: () => previewSet(true), variant: "contained" }, "Preview"),
|
|
96
|
+
React.createElement(Button, { color: "primary", onClick: update, variant: "contained" }, "Save Content"),
|
|
97
|
+
preview &&
|
|
98
|
+
React.createElement(Preview, { mobile: props.mobile, onClose: () => previewSet(false), onError: (error) => {
|
|
99
|
+
if (error.code === errors.body.DATA_FIELDS) {
|
|
100
|
+
fieldErrorsSet(errorTree(error.msg));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
props.onError(error);
|
|
104
|
+
}
|
|
105
|
+
previewSet(false);
|
|
106
|
+
}, value: { ...record, type: props.value.type } }))));
|
|
107
|
+
}
|
|
108
|
+
// Valid props
|
|
109
|
+
Update.propTypes = {
|
|
110
|
+
mobile: PropTypes.bool.isRequired,
|
|
111
|
+
onError: PropTypes.func.isRequired,
|
|
112
|
+
onUpdated: PropTypes.func.isRequired,
|
|
113
|
+
value: PropTypes.shape({
|
|
114
|
+
_id: PropTypes.string.isRequired,
|
|
115
|
+
type: PropTypes.oneOf(['email', 'sms']).isRequired
|
|
116
|
+
})
|
|
117
|
+
};
|