@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.
Files changed (60) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +15 -0
  3. package/package.json +55 -0
  4. package/src/components/pages/Locales.d.ts +35 -0
  5. package/src/components/pages/Locales.js +188 -0
  6. package/src/components/pages/Locales.tsx +254 -0
  7. package/src/components/pages/Templates/Create.d.ts +36 -0
  8. package/src/components/pages/Templates/Create.js +98 -0
  9. package/src/components/pages/Templates/Create.tsx +139 -0
  10. package/src/components/pages/Templates/Template/Content/Create/Email.d.ts +39 -0
  11. package/src/components/pages/Templates/Template/Content/Create/Email.js +51 -0
  12. package/src/components/pages/Templates/Template/Content/Create/Email.tsx +96 -0
  13. package/src/components/pages/Templates/Template/Content/Create/SMS.d.ts +37 -0
  14. package/src/components/pages/Templates/Template/Content/Create/SMS.js +42 -0
  15. package/src/components/pages/Templates/Template/Content/Create/SMS.tsx +68 -0
  16. package/src/components/pages/Templates/Template/Content/Create/index.d.ts +42 -0
  17. package/src/components/pages/Templates/Template/Content/Create/index.js +177 -0
  18. package/src/components/pages/Templates/Template/Content/Create/index.tsx +257 -0
  19. package/src/components/pages/Templates/Template/Content/Preview/Email.d.ts +37 -0
  20. package/src/components/pages/Templates/Template/Content/Preview/Email.js +51 -0
  21. package/src/components/pages/Templates/Template/Content/Preview/Email.tsx +78 -0
  22. package/src/components/pages/Templates/Template/Content/Preview/SMS.d.ts +32 -0
  23. package/src/components/pages/Templates/Template/Content/Preview/SMS.js +38 -0
  24. package/src/components/pages/Templates/Template/Content/Preview/SMS.tsx +59 -0
  25. package/src/components/pages/Templates/Template/Content/Preview/index.d.ts +42 -0
  26. package/src/components/pages/Templates/Template/Content/Preview/index.js +63 -0
  27. package/src/components/pages/Templates/Template/Content/Preview/index.tsx +107 -0
  28. package/src/components/pages/Templates/Template/Content/Update/Email.d.ts +39 -0
  29. package/src/components/pages/Templates/Template/Content/Update/Email.js +51 -0
  30. package/src/components/pages/Templates/Template/Content/Update/Email.tsx +96 -0
  31. package/src/components/pages/Templates/Template/Content/Update/SMS.d.ts +37 -0
  32. package/src/components/pages/Templates/Template/Content/Update/SMS.js +42 -0
  33. package/src/components/pages/Templates/Template/Content/Update/SMS.tsx +68 -0
  34. package/src/components/pages/Templates/Template/Content/Update/index.d.ts +42 -0
  35. package/src/components/pages/Templates/Template/Content/Update/index.js +117 -0
  36. package/src/components/pages/Templates/Template/Content/Update/index.tsx +162 -0
  37. package/src/components/pages/Templates/Template/Content/View/Email.d.ts +43 -0
  38. package/src/components/pages/Templates/Template/Content/View/Email.js +57 -0
  39. package/src/components/pages/Templates/Template/Content/View/Email.tsx +80 -0
  40. package/src/components/pages/Templates/Template/Content/View/SMS.d.ts +41 -0
  41. package/src/components/pages/Templates/Template/Content/View/SMS.js +46 -0
  42. package/src/components/pages/Templates/Template/Content/View/SMS.tsx +64 -0
  43. package/src/components/pages/Templates/Template/Content/View/index.d.ts +39 -0
  44. package/src/components/pages/Templates/Template/Content/View/index.js +50 -0
  45. package/src/components/pages/Templates/Template/Content/View/index.tsx +78 -0
  46. package/src/components/pages/Templates/Template/Variables.d.ts +34 -0
  47. package/src/components/pages/Templates/Template/Variables.js +91 -0
  48. package/src/components/pages/Templates/Template/Variables.tsx +138 -0
  49. package/src/components/pages/Templates/Template/index.d.ts +90 -0
  50. package/src/components/pages/Templates/Template/index.js +207 -0
  51. package/src/components/pages/Templates/Template/index.tsx +337 -0
  52. package/src/components/pages/Templates/index.d.ts +35 -0
  53. package/src/components/pages/Templates/index.js +112 -0
  54. package/src/components/pages/Templates/index.tsx +165 -0
  55. package/src/index.d.ts +5 -0
  56. package/src/index.js +5 -0
  57. package/src/index.ts +8 -0
  58. package/src/locales.d.ts +72 -0
  59. package/src/locales.js +160 -0
  60. 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
+ };