@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.
Files changed (57) hide show
  1. package/lib/components/pages/Locales.d.ts +1 -3
  2. package/lib/components/pages/Locales.js +32 -23
  3. package/lib/components/pages/Templates/Create.d.ts +1 -1
  4. package/lib/components/pages/Templates/Create.js +11 -14
  5. package/lib/components/pages/Templates/Template/Content/Create/Email.d.ts +1 -1
  6. package/lib/components/pages/Templates/Template/Content/Create/Email.js +6 -10
  7. package/lib/components/pages/Templates/Template/Content/Create/SMS.d.ts +1 -1
  8. package/lib/components/pages/Templates/Template/Content/Create/SMS.js +4 -6
  9. package/lib/components/pages/Templates/Template/Content/Create/index.d.ts +1 -3
  10. package/lib/components/pages/Templates/Template/Content/Create/index.js +14 -20
  11. package/lib/components/pages/Templates/Template/Content/Preview/Email.d.ts +1 -3
  12. package/lib/components/pages/Templates/Template/Content/Preview/Email.js +6 -7
  13. package/lib/components/pages/Templates/Template/Content/Preview/SMS.d.ts +1 -3
  14. package/lib/components/pages/Templates/Template/Content/Preview/SMS.js +3 -4
  15. package/lib/components/pages/Templates/Template/Content/Preview/index.d.ts +1 -3
  16. package/lib/components/pages/Templates/Template/Content/Preview/index.js +3 -6
  17. package/lib/components/pages/Templates/Template/Content/Update/Email.d.ts +1 -1
  18. package/lib/components/pages/Templates/Template/Content/Update/Email.js +6 -11
  19. package/lib/components/pages/Templates/Template/Content/Update/SMS.d.ts +1 -1
  20. package/lib/components/pages/Templates/Template/Content/Update/SMS.js +4 -6
  21. package/lib/components/pages/Templates/Template/Content/Update/index.d.ts +1 -3
  22. package/lib/components/pages/Templates/Template/Content/Update/index.js +17 -23
  23. package/lib/components/pages/Templates/Template/Content/View/Email.d.ts +1 -3
  24. package/lib/components/pages/Templates/Template/Content/View/Email.js +6 -7
  25. package/lib/components/pages/Templates/Template/Content/View/SMS.d.ts +1 -3
  26. package/lib/components/pages/Templates/Template/Content/View/SMS.js +3 -4
  27. package/lib/components/pages/Templates/Template/Content/View/index.d.ts +1 -3
  28. package/lib/components/pages/Templates/Template/Content/View/index.js +5 -6
  29. package/lib/components/pages/Templates/Template/Variables.d.ts +1 -1
  30. package/lib/components/pages/Templates/Template/Variables.js +6 -7
  31. package/lib/components/pages/Templates/Template/index.d.ts +1 -3
  32. package/lib/components/pages/Templates/Template/index.js +27 -45
  33. package/lib/components/pages/Templates/index.d.ts +1 -3
  34. package/lib/components/pages/Templates/index.js +9 -21
  35. package/lib/shared.d.ts +12 -0
  36. package/lib/shared.js +25 -0
  37. package/package.json +7 -8
  38. package/src/components/pages/Locales.tsx +40 -27
  39. package/src/components/pages/Templates/Create.tsx +12 -15
  40. package/src/components/pages/Templates/Template/Content/Create/Email.tsx +15 -19
  41. package/src/components/pages/Templates/Template/Content/Create/SMS.tsx +7 -9
  42. package/src/components/pages/Templates/Template/Content/Create/index.tsx +15 -23
  43. package/src/components/pages/Templates/Template/Content/Preview/Email.tsx +7 -9
  44. package/src/components/pages/Templates/Template/Content/Preview/SMS.tsx +3 -9
  45. package/src/components/pages/Templates/Template/Content/Preview/index.tsx +2 -9
  46. package/src/components/pages/Templates/Template/Content/Update/Email.tsx +15 -18
  47. package/src/components/pages/Templates/Template/Content/Update/SMS.tsx +7 -9
  48. package/src/components/pages/Templates/Template/Content/Update/index.tsx +19 -29
  49. package/src/components/pages/Templates/Template/Content/View/Email.tsx +6 -8
  50. package/src/components/pages/Templates/Template/Content/View/SMS.tsx +3 -5
  51. package/src/components/pages/Templates/Template/Content/View/index.tsx +9 -12
  52. package/src/components/pages/Templates/Template/Variables.tsx +6 -7
  53. package/src/components/pages/Templates/Template/index.tsx +37 -59
  54. package/src/components/pages/Templates/index.tsx +19 -31
  55. package/src/shared.ts +29 -0
  56. package/ouroboros-mouth-mui-1.3.2.tgz +0 -0
  57. package/src/types/xhr2.d.ts +0 -3
@@ -8,9 +8,8 @@
8
8
  */
9
9
  // Ouroboros modules
10
10
  import { useRights } from '@ouroboros/brain-react';
11
- import clone from '@ouroboros/clone';
12
11
  import mouth from '@ouroboros/mouth';
13
- import { afindi } from '@ouroboros/tools';
12
+ import { arrayFindOverwrite } from '@ouroboros/tools';
14
13
  // NPM modules
15
14
  import PropTypes from 'prop-types';
16
15
  import React, { useEffect, useState } from 'react';
@@ -31,7 +30,7 @@ import Template from './Template';
31
30
  * @param Object props Properties passed to the component
32
31
  * @returns React.Component
33
32
  */
34
- export default function Templates(props) {
33
+ export default function Templates({ onError, onSuccess }) {
35
34
  // State
36
35
  const [create, createSet] = useState(false);
37
36
  const [locales, localesSet] = useState({});
@@ -64,29 +63,19 @@ export default function Templates(props) {
64
63
  // Called when a template has been created
65
64
  function templateCreated(template) {
66
65
  // Notify parent
67
- props.onSuccess('template_create');
66
+ onSuccess('template_create');
68
67
  // Hide the create form
69
68
  createSet(false);
70
69
  // Clone the current templates, add the new one to the front, and set
71
70
  // the new templates
72
- const lTemplates = clone(templates);
73
- lTemplates.unshift(template);
74
- templatesSet(lTemplates);
71
+ templatesSet(l => [template, ...l]);
75
72
  }
76
73
  // Called when a template has been updated
77
74
  function templateUpdated(template) {
78
75
  // Notify parent
79
- props.onSuccess('template_update');
80
- // Look for the template
81
- const i = afindi(templates, '_id', template._id);
82
- // If we have it
83
- if (i > -1) {
84
- // Clone the current templates, update the index, and set the new
85
- // templates
86
- const lTemplates = clone(templates);
87
- lTemplates[i] = template;
88
- templatesSet(lTemplates);
89
- }
76
+ onSuccess('template_update');
77
+ // Work on latest
78
+ templatesSet(l => arrayFindOverwrite(l, '_id', template._id, template, true));
90
79
  }
91
80
  // Render
92
81
  return (React.createElement(Box, { id: "mouth_templates", className: "flexGrow padding" },
@@ -98,15 +87,14 @@ export default function Templates(props) {
98
87
  React.createElement(IconButton, null,
99
88
  React.createElement("i", { className: 'fa-solid fa-plus' + (create ? ' open' : '') }))))),
100
89
  create &&
101
- React.createElement(Create, { onCancel: () => createSet(false), onCreated: templateCreated, onError: props.onError }),
102
- templates.map((o) => React.createElement(Template, { key: o._id, locales: locales, mobile: props.mobile, onChange: templateUpdated, onContent: type => props.onSuccess(`content_${type}`), onError: props.onError, rights: {
90
+ React.createElement(Create, { onCancel: () => createSet(false), onCreated: templateCreated, onError: onError }),
91
+ templates.map((o) => React.createElement(Template, { key: o._id, locales: locales, onChange: templateUpdated, onContent: type => onSuccess(`content_${type}`), onError: onError, rights: {
103
92
  content: rightsContent,
104
93
  template: rightsTemplate
105
94
  }, value: o }))));
106
95
  }
107
96
  // Valid props
108
97
  Templates.propTypes = {
109
- mobile: PropTypes.bool.isRequired,
110
98
  onError: PropTypes.func.isRequired,
111
99
  onSuccess: PropTypes.func.isRequired
112
100
  };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared
3
+ *
4
+ * Holds the Trees used by all the components
5
+ *
6
+ * @author Chris Nasr <chris@ouroboroscoding.com>
7
+ * @copyright Ouroboros Coding Inc.
8
+ * @created 2025-03-11
9
+ */
10
+ import { Tree } from '@ouroboros/define';
11
+ export declare const EmailTree: Tree;
12
+ export declare const SmsTree: Tree;
package/lib/shared.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared
3
+ *
4
+ * Holds the Trees used by all the components
5
+ *
6
+ * @author Chris Nasr <chris@ouroboroscoding.com>
7
+ * @copyright Ouroboros Coding Inc.
8
+ * @created 2025-03-11
9
+ */
10
+ // Ouroboros imports
11
+ import { Tree } from '@ouroboros/define';
12
+ // Mouth definition files
13
+ import TemplateEmailDef from '@ouroboros/mouth/define/template_email.json';
14
+ import TemplateSMSDef from '@ouroboros/mouth/define/template_sms.json';
15
+ // Generate the email Tree
16
+ export const EmailTree = new Tree(TemplateEmailDef, {
17
+ __name__: 'record',
18
+ text: { __ui__: { __title__: 'Plain Text', __type__: 'textarea' } },
19
+ html: { __ui__: { __title__: 'Raw HTML', __type__: 'textarea' } }
20
+ });
21
+ // Generate the sms Tree
22
+ export const SmsTree = new Tree(TemplateSMSDef, {
23
+ __name__: 'record',
24
+ content: { __ui__: { __title__: 'Content', __type__: 'textarea' } }
25
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouroboros/mouth-mui",
3
- "version": "1.3.2",
3
+ "version": "2.1.1",
4
4
  "description": "Components for use with the Mouth service",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -34,9 +34,9 @@
34
34
  "typescript": "^4.8.3"
35
35
  },
36
36
  "dependencies": {
37
- "@ouroboros/clone": "^1.1.0",
38
- "@ouroboros/define": "^1.1.2",
39
- "@ouroboros/define-mui": "^1.5.5",
37
+ "@ouroboros/define": "^1.1.3",
38
+ "@ouroboros/define-mui": "^1.5.6",
39
+ "@ouroboros/mouth": "^2.1.1",
40
40
  "@ouroboros/react-radiobuttons-mui": "^1.1.0",
41
41
  "@ouroboros/subscribe": "^1.3.2",
42
42
  "@ouroboros/tools": "^0.7.0",
@@ -46,11 +46,10 @@
46
46
  "@emotion/react": "^11.8.2",
47
47
  "@emotion/styled": "^11.8.1",
48
48
  "@mui/material": "^5.5.1",
49
- "@ouroboros/body": "^1.1.2",
50
- "@ouroboros/brain-react": "^2.2.0",
49
+ "@ouroboros/body": "^1.2.0",
50
+ "@ouroboros/brain-react": "^2.3.1",
51
51
  "@ouroboros/events": "^1.1.0",
52
- "@ouroboros/mouth": "^1.2.0",
53
52
  "react": "^17.0.2 || ^18.0.0",
54
53
  "react-dom": "^17.0.2 || ^18.0.0"
55
54
  }
56
- }
55
+ }
@@ -9,11 +9,10 @@
9
9
 
10
10
  // Ouroboros modules
11
11
  import { useRights } from '@ouroboros/brain-react';
12
- import clone from '@ouroboros/clone';
13
12
  import { Tree } from '@ouroboros/define'
14
13
  import { Form, Results } from '@ouroboros/define-mui';
15
14
  import mouth, { errors } from '@ouroboros/mouth';
16
- import LocaleDef from '@ouroboros/mouth/definitions/locale.json';
15
+ import LocaleDef from '@ouroboros/mouth/define/locale.json';
17
16
  import { afindi, merge } from '@ouroboros/tools';
18
17
 
19
18
  // NPM modules
@@ -30,12 +29,21 @@ import Tooltip from '@mui/material/Tooltip';
30
29
  import locales from '../../locales';
31
30
 
32
31
  // Generate the user Tree
33
- const LocaleTree = new Tree(LocaleDef);
32
+ const LocaleTree = new Tree(LocaleDef, {
33
+ __name__: 'record',
34
+ __ui__: {
35
+ __copyPrimary__: false,
36
+ __create__: [ '_id', 'name' ],
37
+ __results__: [ '_id', 'name' ],
38
+ __update__: [ 'name' ]
39
+ },
40
+
41
+ _id: { __ui__: { __title__: 'ISO-639 - ISO-3166' } }
42
+ });
34
43
 
35
44
  // Types
36
45
  import { responseErrorStruct } from '@ouroboros/body';
37
46
  export type LocalesProps = {
38
- mobile: boolean,
39
47
  onError: (error: responseErrorStruct) => void,
40
48
  onSuccess: (type: string) => void
41
49
  }
@@ -50,11 +58,11 @@ export type LocalesProps = {
50
58
  * @param Object props Properties passed to the component
51
59
  * @returns React.Component
52
60
  */
53
- export default function Locales(props: LocalesProps) {
61
+ export default function Locales({ onError, onSuccess }: LocalesProps) {
54
62
 
55
63
  // State
56
- const [create, createSet] = useState<boolean>(false);
57
- const [records, recordsSet] = useState<any[]>([]);
64
+ const [ create, createSet ] = useState<boolean>(false);
65
+ const [ records, recordsSet ] = useState<any[]>([ ]);
58
66
 
59
67
  // Hooks
60
68
  const rights = useRights('mouth_locale');
@@ -89,15 +97,14 @@ export default function Locales(props: LocalesProps) {
89
97
  if(data) {
90
98
 
91
99
  // Notify the parent
92
- props.onSuccess('create');
100
+ onSuccess('create');
93
101
 
94
102
  // Close the create form
95
103
  createSet(false);
96
104
 
97
- // Clone the records, add the new one to the start, and set the new
98
- // records
99
- const lRecords = clone(records);
100
- lRecords.unshift(locale);
105
+ // Clone the records, add the new one to the start, and set
106
+ // the new records
107
+ const lRecords = [ locale, ...records ];
101
108
  recordsSet(lRecords);
102
109
 
103
110
  // Send the clone to the locales
@@ -113,8 +120,8 @@ export default function Locales(props: LocalesProps) {
113
120
  } else if(error.code === errors.body.DATA_FIELDS) {
114
121
  reject(error.msg);
115
122
  } else {
116
- if(props.onError) {
117
- props.onError(error);
123
+ if(onError) {
124
+ onError(error);
118
125
  } else {
119
126
  throw new Error(JSON.stringify(error));
120
127
  }
@@ -133,7 +140,7 @@ export default function Locales(props: LocalesProps) {
133
140
  if(data) {
134
141
 
135
142
  // Notify the parent
136
- props.onSuccess('delete');
143
+ onSuccess('delete');
137
144
 
138
145
  // Look for the record
139
146
  const i = afindi(records, '_id', key);
@@ -141,8 +148,9 @@ export default function Locales(props: LocalesProps) {
141
148
  // If it exists
142
149
  if(i > -1) {
143
150
 
144
- // Clone the records, delete the index, and set the new records
145
- const lRecords = clone(records);
151
+ // Clone the records, delete the index, and set the new
152
+ // records
153
+ const lRecords = [ ...records ];
146
154
  lRecords.splice(i, 1);
147
155
  recordsSet(lRecords);
148
156
 
@@ -151,8 +159,8 @@ export default function Locales(props: LocalesProps) {
151
159
  }
152
160
  }
153
161
  }, (error: responseErrorStruct) => {
154
- if(props.onError) {
155
- props.onError(error);
162
+ if(onError) {
163
+ onError(error);
156
164
  } else {
157
165
  throw new Error(JSON.stringify(error));
158
166
  }
@@ -175,7 +183,7 @@ export default function Locales(props: LocalesProps) {
175
183
  if(data) {
176
184
 
177
185
  // Notify the parent
178
- props.onSuccess('update');
186
+ onSuccess('update');
179
187
 
180
188
  // Look for the record
181
189
  const i = afindi(records, '_id', key);
@@ -183,8 +191,9 @@ export default function Locales(props: LocalesProps) {
183
191
  // If it exists
184
192
  if(i > -1) {
185
193
 
186
- // Clone the records, update the index, and set the new records
187
- const lRecords = clone(records);
194
+ // Clone the records, update the index, and set the new
195
+ // records
196
+ const lRecords = [ ...records ];
188
197
  merge(lRecords[i], locale);
189
198
  recordsSet(lRecords);
190
199
 
@@ -200,8 +209,8 @@ export default function Locales(props: LocalesProps) {
200
209
  if(error.code === errors.body.DATA_FIELDS) {
201
210
  reject(error.msg);
202
211
  } else {
203
- if(props.onError) {
204
- props.onError(error);
212
+ if(onError) {
213
+ onError(error);
205
214
  } else {
206
215
  throw new Error(JSON.stringify(error));
207
216
  }
@@ -217,9 +226,14 @@ export default function Locales(props: LocalesProps) {
217
226
  <h1 className="flexGrow">Locales</h1>
218
227
  {rights.create &&
219
228
  <Box className="flexStatic">
220
- <Tooltip title="Create new Locale" className="page_action" onClick={() => createSet(b => !b)}>
229
+ <Tooltip
230
+ title="Create new Locale"
231
+ className="page_action"
232
+ onClick={() => createSet(b => !b)}
233
+ >
221
234
  <IconButton>
222
- <i className={'fa-solid fa-plus' + (create ? ' open' : '')} />
235
+ <i className={'fa-solid fa-plus' +
236
+ (create ? ' open' : '')} />
223
237
  </IconButton>
224
238
  </Tooltip>
225
239
  </Box>
@@ -248,7 +262,6 @@ export default function Locales(props: LocalesProps) {
248
262
 
249
263
  // Valid props
250
264
  Locales.propTypes = {
251
- mobile: PropTypes.bool.isRequired,
252
265
  onError: PropTypes.func.isRequired,
253
266
  onSuccess: PropTypes.func.isRequired
254
267
  }
@@ -8,11 +8,10 @@
8
8
  */
9
9
 
10
10
  // Ouroboros modules
11
- import clone from '@ouroboros/clone';
12
11
  import { Node } from '@ouroboros/define';
13
12
  import { DefineNode } from '@ouroboros/define-mui';
14
13
  import mouth, { errors } from '@ouroboros/mouth';
15
- import TemplateDef from '@ouroboros/mouth/definitions/template.json';
14
+ import TemplateDef from '@ouroboros/mouth/define/template.json';
16
15
 
17
16
  // NPM modules
18
17
  import PropTypes from 'prop-types';
@@ -49,10 +48,10 @@ export interface CreateProps {
49
48
  * @param Object props Properties passed to the component
50
49
  * @returns React.Component
51
50
  */
52
- export default function Create(props: CreateProps) {
51
+ export default function Create({ onCancel, onCreated, onError }: CreateProps) {
53
52
 
54
53
  // State
55
- const [record, recordSet] = useState<templateStruct>({
54
+ const [ record, recordSet ] = useState<templateStruct>({
56
55
  name: '',
57
56
  variables: {}
58
57
  });
@@ -61,13 +60,11 @@ export default function Create(props: CreateProps) {
61
60
  const refName = useRef<DefineNode>(null);
62
61
 
63
62
  // Called when record changes
64
- function change(field: string, value: any) {
63
+ function change(field: string, val: any) {
65
64
 
66
65
  // Set the new record
67
66
  recordSet((o: templateStruct) => {
68
- const oRecord = clone(o);
69
- oRecord[field] = value;
70
- return oRecord;
67
+ return { ...o, [field]: val }
71
68
  });
72
69
  }
73
70
 
@@ -81,13 +78,13 @@ export default function Create(props: CreateProps) {
81
78
  record._id = data;
82
79
 
83
80
  // Let the parent know
84
- props.onCreated(clone(record));
81
+ onCreated({ ...record });
85
82
  }, (error: responseErrorStruct) => {
86
83
  if(error.code === errors.body.DB_DUPLICATE) {
87
84
  refName.current?.error('Duplicate');
88
85
  } else {
89
- if(props.onError) {
90
- props.onError(error);
86
+ if(onError) {
87
+ onError(error);
91
88
  } else {
92
89
  throw new Error(JSON.stringify(error));
93
90
  }
@@ -106,7 +103,7 @@ export default function Create(props: CreateProps) {
106
103
  label="none"
107
104
  name="name"
108
105
  node={oNameNode}
109
- onChange={value => change('name', value)}
106
+ onChange={val => change('name', val)}
110
107
  onEnterPressed={create}
111
108
  ref={refName}
112
109
  type="create"
@@ -116,13 +113,13 @@ export default function Create(props: CreateProps) {
116
113
  <Grid item lg={6} md={12}>
117
114
  <Typography><strong>Variables</strong></Typography>
118
115
  <Variables
119
- onChange={value => change('variables', value)}
116
+ onChange={val => change('variables', val)}
120
117
  value={record.variables || {}}
121
118
  />
122
119
  </Grid>
123
120
  <Grid item xs={12} className="actions">
124
- {props.onCancel &&
125
- <Button variant="contained" color="secondary" onClick={props.onCancel}>Cancel</Button>
121
+ {onCancel &&
122
+ <Button variant="contained" color="secondary" onClick={onCancel}>Cancel</Button>
126
123
  }
127
124
  <Button variant="contained" color="primary" onClick={create}>Create Template</Button>
128
125
  </Grid>
@@ -8,9 +8,7 @@
8
8
  */
9
9
 
10
10
  // Ouroboros modules
11
- import { Node } from '@ouroboros/define';
12
11
  import { DefineNode } from '@ouroboros/define-mui';
13
- import TemplateEmail from '@ouroboros/mouth/definitions/template_email.json';
14
12
 
15
13
  // NPM modules
16
14
  import PropTypes from 'prop-types';
@@ -19,10 +17,8 @@ import React from 'react';
19
17
  // Material UI
20
18
  import Grid from '@mui/material/Grid';
21
19
 
22
- // Record Nodes
23
- const oSubjectNode = new Node(TemplateEmail.subject);
24
- const oTextNode = new Node(TemplateEmail.text);
25
- const oHtmlNode = new Node(TemplateEmail.html);
20
+ // Import the shared types
21
+ import { EmailTree } from '../../../../../../shared';
26
22
 
27
23
  // Types
28
24
  import { contentStruct } from '../../';
@@ -42,42 +38,42 @@ export type EmailProps = {
42
38
  * @param Object props Properties passed to the component
43
39
  * @returns React.Component
44
40
  */
45
- export default function Email(props: EmailProps) {
41
+ export default function Email({ errors, onChanged, value }: EmailProps) {
46
42
 
47
43
  // Render
48
44
  return (
49
45
  <Grid container className="content_create_email" spacing={1}>
50
46
  <Grid item xs={12} className="field">
51
47
  <DefineNode
52
- error={props.errors.subject || false}
48
+ error={errors.subject || false}
53
49
  label="placeholder"
54
50
  name="subject"
55
- node={oSubjectNode}
56
- onChange={val => props.onChanged('subject', val)}
51
+ node={EmailTree.get('subject') as any}
52
+ onChange={val => onChanged('subject', val)}
57
53
  type="create"
58
- value={props.value.subject}
54
+ value={value.subject}
59
55
  />
60
56
  </Grid>
61
57
  <Grid item xs={12} lg={6} className="field">
62
58
  <DefineNode
63
- error={props.errors.text || false}
59
+ error={errors.text || false}
64
60
  label="placeholder"
65
61
  name="text"
66
- node={oTextNode}
67
- onChange={val => props.onChanged('text', val)}
62
+ node={EmailTree.get('text') as any}
63
+ onChange={val => onChanged('text', val)}
68
64
  type="create"
69
- value={props.value.text}
65
+ value={value.text}
70
66
  />
71
67
  </Grid>
72
68
  <Grid item xs={12} lg={6} className="field">
73
69
  <DefineNode
74
- error={props.errors.html || false}
70
+ error={errors.html || false}
75
71
  label="placeholder"
76
72
  name="html"
77
- node={oHtmlNode}
78
- onChange={val => props.onChanged('html', val)}
73
+ node={EmailTree.get('html') as any}
74
+ onChange={val => onChanged('html', val)}
79
75
  type="create"
80
- value={props.value.html}
76
+ value={value.html}
81
77
  />
82
78
  </Grid>
83
79
  </Grid>
@@ -8,9 +8,7 @@
8
8
  */
9
9
 
10
10
  // Ouroboros modules
11
- import { Node } from '@ouroboros/define';
12
11
  import { DefineNode } from '@ouroboros/define-mui';
13
- import TemplateSMS from '@ouroboros/mouth/definitions/template_sms.json';
14
12
 
15
13
  // NPM modules
16
14
  import PropTypes from 'prop-types';
@@ -19,8 +17,8 @@ import React from 'react';
19
17
  // Material UI
20
18
  import Box from '@mui/material/Box';
21
19
 
22
- // Record Nodes
23
- const oContentNode = new Node(TemplateSMS.content);
20
+ // Import the shared types
21
+ import { SmsTree } from '../../../../../../shared';
24
22
 
25
23
  // Types
26
24
  import { contentStruct } from '../../';
@@ -40,19 +38,19 @@ export type SMSProps = {
40
38
  * @param Object props Properties passed to the component
41
39
  * @returns React.Component
42
40
  */
43
- export default function SMS(props: SMSProps) {
41
+ export default function SMS({ errors, onChanged, value }: SMSProps) {
44
42
 
45
43
  // Render
46
44
  return (
47
45
  <Box className="content_create_sms field">
48
46
  <DefineNode
49
- error={props.errors.content || false}
47
+ error={errors.content || false}
50
48
  label="placeholder"
51
49
  name="content"
52
- node={oContentNode}
53
- onChange={val => props.onChanged('content', val)}
50
+ node={SmsTree.get('content') as any}
51
+ onChange={val => onChanged('content', val)}
54
52
  type="create"
55
- value={props.value.content}
53
+ value={value.content}
56
54
  />
57
55
  </Box>
58
56
  );
@@ -8,7 +8,6 @@
8
8
  */
9
9
 
10
10
  // Ouroboros modules
11
- import clone from '@ouroboros/clone';
12
11
  import { errorTree } from '@ouroboros/define-mui';
13
12
  import mouth, { errors } from '@ouroboros/mouth';
14
13
  import RadioButtons from '@ouroboros/react-radiobuttons-mui';
@@ -36,7 +35,6 @@ import { contentStruct, typeOption } from '../../';
36
35
  import { responseErrorStruct } from '@ouroboros/body';
37
36
  export type TemplateContentCreateProps = {
38
37
  locales: Record<string, string>,
39
- mobile: boolean,
40
38
  onCreated: (content: contentStruct) => void,
41
39
  onError: (error: responseErrorStruct) => void,
42
40
  template: string
@@ -52,14 +50,16 @@ export type TemplateContentCreateProps = {
52
50
  * @param Object props Properties passed to the component
53
51
  * @returns React.Component
54
52
  */
55
- export default function Create(props: TemplateContentCreateProps) {
53
+ export default function Create(
54
+ { locales, onCreated, onError, template }: TemplateContentCreateProps
55
+ ) {
56
56
 
57
57
  // State
58
58
  const [fieldErrors, fieldErrorsSet] = useState<Record<string, any>>({});
59
59
  const [preview, previewSet] = useState(false);
60
60
  const [record, recordSet] = useState<Omit<contentStruct, 'type'>>({
61
- locale: Object.keys(props.locales)[0],
62
- template: props.template,
61
+ locale: Object.keys(locales)[0],
62
+ template,
63
63
  subject: '',
64
64
  text: '',
65
65
  html: ''
@@ -76,7 +76,7 @@ export default function Create(props: TemplateContentCreateProps) {
76
76
  const oRecord = { ...record, type, _id: data }
77
77
 
78
78
  // Tell the parent about the new record
79
- props.onCreated(oRecord);
79
+ onCreated(oRecord);
80
80
 
81
81
  }, (error: responseErrorStruct) => {
82
82
  if(error.code === errors.body.DATA_FIELDS) {
@@ -101,11 +101,11 @@ export default function Create(props: TemplateContentCreateProps) {
101
101
  }
102
102
 
103
103
  // Show the errors
104
- if(props.onError) {
105
- props.onError({ code: 0, msg: lLines.join('\n') });
104
+ if(onError) {
105
+ onError({ code: 0, msg: lLines.join('\n') });
106
106
  }
107
107
  } else {
108
- props.onError(error);
108
+ onError(error);
109
109
  }
110
110
  });
111
111
  }
@@ -115,26 +115,20 @@ export default function Create(props: TemplateContentCreateProps) {
115
115
 
116
116
  // Clear error
117
117
  if(field in fieldErrors) {
118
- const oErrors = clone(fieldErrors);
118
+ const oErrors = { ...fieldErrors };
119
119
  delete oErrors[field];
120
120
  fieldErrorsSet(oErrors);
121
121
  }
122
122
 
123
- // Clone the record
124
- const oRecord = clone(record);
125
-
126
- // Update the field
127
- oRecord[field] = value;
128
-
129
- // Store the new record
130
- recordSet(oRecord);
123
+ // Set the new record
124
+ recordSet(o => { return { ...o, [field]: value } });
131
125
  }
132
126
 
133
127
  // Called when the type is changed
134
128
  function typeChanged(value: string) {
135
129
 
136
130
  // Clone the current record
137
- const oRecord = clone(record);
131
+ const oRecord = { ...record };
138
132
 
139
133
  // If the new type is email
140
134
  if(value === 'email') {
@@ -200,7 +194,7 @@ export default function Create(props: TemplateContentCreateProps) {
200
194
  onChange={ev => recordChanged('locale', ev.target.value)}
201
195
  value={record.locale}
202
196
  >
203
- {omap(props.locales, (v,k) =>
197
+ {omap(locales, (v,k) =>
204
198
  <option key={k} value={k}>{v}</option>
205
199
  )}
206
200
  </Select>
@@ -229,13 +223,12 @@ export default function Create(props: TemplateContentCreateProps) {
229
223
  <Button color="primary" onClick={create} variant="contained">Add Content</Button>
230
224
  {preview &&
231
225
  <Preview
232
- mobile={props.mobile}
233
226
  onClose={() => previewSet(false)}
234
227
  onError={(error: responseErrorStruct) => {
235
228
  if(error.code === errors.body.DATA_FIELDS) {
236
229
  fieldErrorsSet(errorTree(error.msg));
237
230
  } else {
238
- props.onError(error);
231
+ onError(error);
239
232
  }
240
233
  previewSet(false);
241
234
  }}
@@ -250,7 +243,6 @@ export default function Create(props: TemplateContentCreateProps) {
250
243
  // Valid props
251
244
  Create.propTypes = {
252
245
  locales: PropTypes.objectOf(PropTypes.string).isRequired,
253
- mobile: PropTypes.bool.isRequired,
254
246
  onCreated: PropTypes.func.isRequired,
255
247
  onError: PropTypes.func,
256
248
  template: PropTypes.string.isRequired