@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
@@ -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
- // Record Nodes
19
- const oSubjectNode = new Node(TemplateEmail.subject);
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(props) {
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: props.errors.subject || false, label: "placeholder", name: "subject", node: oSubjectNode, onChange: val => props.onChanged('subject', val), type: "update", value: props.value.subject })),
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: props.errors.text || false, label: "placeholder", name: "text", node: oTextNode, onChange: val => props.onChanged('text', val), type: "update", value: props.value.text })),
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: props.errors.html || false, label: "placeholder", name: "html", node: oHtmlNode, onChange: val => props.onChanged('html', val), type: "update", value: props.value.html }))));
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(props: SMSProps): React.JSX.Element;
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
- // Record Nodes
19
- const oContentNode = new Node(TemplateSMS.content);
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(props) {
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: props.errors.content || false, label: "placeholder", name: "content", node: oContentNode, onChange: val => props.onChanged('content', val), type: "update", value: props.value.content })));
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(props: UpdateProps): React.JSX.Element;
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(props) {
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(props.value, 'type'));
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/${props.value.type}`, record).then(() => {
43
- props.onUpdated({ type: props.value.type, ...record });
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 (props.onError) {
67
- props.onError({ code: 0, msg: lLines.join('\n') });
65
+ if (onError) {
66
+ onError({ code: 0, msg: lLines.join('\n') });
68
67
  }
69
68
  }
70
69
  else {
71
- props.onError(error);
70
+ onError(error);
72
71
  }
73
72
  });
74
73
  }
75
74
  // Called when any fields in the record are changed
76
- function recordChanged(field, value) {
75
+ function recordChanged(field, val) {
77
76
  // Clear error
78
77
  if (field in fieldErrors) {
79
78
  delete fieldErrors.field;
80
79
  }
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);
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
- (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 })),
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(props.value, 'type')), variant: "contained" }, "Cancel"),
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, { mobile: props.mobile, onClose: () => previewSet(false), onError: (error) => {
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
- props.onError(error);
98
+ onError(error);
104
99
  }
105
100
  previewSet(false);
106
- }, value: { ...record, type: props.value.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(props: EmailProps): React.JSX.Element;
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(props) {
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 }, props.value.subject),
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 }, props.value.text &&
36
- React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } }, props.value.text)),
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 }, props.value.html &&
41
- React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } }, props.value.html))));
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(props: SMSProps): React.JSX.Element;
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(props) {
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 }, props.value.content &&
32
- React.createElement(Typography, { style: { whiteSpace: 'pre-wrap' } }, props.value.content))));
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(props: ViewProps): React.JSX.Element;
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(props) {
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
- (props.value.type === 'email' &&
35
- React.createElement(Email, { ...props, key: props.value._id })) || (props.value.type === 'sms' &&
36
- React.createElement(SMS, { ...props, key: props.value._id })),
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, { mobile: props.mobile, onClose: () => previewSet(false), onError: props.onError, value: props.value }))));
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(props: VariablesProps): React.JSX.Element;
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(props) {
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 = clone(props.value);
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
- props.onChange(oValue);
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 = clone(props.value);
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
- props.onChange(oValue);
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(props.value, (v, k) => React.createElement(React.Fragment, { key: k },
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(props: TemplateProps): React.JSX.Element;
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/definitions/template.json';
15
- import { afindi, omap, ucfirst } from '@ouroboros/tools';
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(props) {
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, value) {
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
- props.onContent('create');
67
- // Clone the current contents
68
- const lContents = clone(contents);
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
- props.onContent('update');
78
- // Find the index of the record
79
- const i = afindi(contents, '_id', content._id);
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
- props.onChange(edit);
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: props.value._id
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(props.value.name.replace(/_/g, ' ')),
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
- props.rights.template.update &&
116
+ rights.template.update &&
134
117
  React.createElement(Tooltip, { title: "Edit the Template" },
135
- React.createElement(IconButton, { className: "icon", onClick: ev => editSet(edit ? false : clone(props.value)) },
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
- props.rights.template.delete &&
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: value => change('name', value), onEnterPressed: update, ref: refName, type: "update", value: edit.name })),
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: value => change('variables', value), value: edit.variables || {} })),
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: props.locales[o.locale] + ' ' + o.type })),
164
- props.rights.content.create &&
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
- (props.rights.content.update ?
170
- React.createElement(ContentUpdate, { key: contents[tab]._id, mobile: props.mobile, onError: props.onError, onUpdated: contentUpdated, value: contents[tab] })
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, mobile: props.mobile, onError: props.onError, value: contents[tab] }))) ||
173
- ((props.rights.content.create && contents && tab === contents.length) &&
174
- React.createElement(ContentCreate, { locales: props.locales, mobile: props.mobile, onCreated: contentCreated, onError: props.onError, template: props.value._id })))),
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
- props.value && omap(props.value.variables, (v, k) => React.createElement(Typography, { key: k }, '{' + k + '}')))))));
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(props: TemplatesProps): React.JSX.Element;
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
  };