@ouroboros/mouth-mui 2.1.1 → 2.1.3
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/README.md +80 -10
- package/lib/components/pages/Locales.d.ts +2 -2
- package/lib/components/pages/Locales.js +62 -48
- package/lib/components/pages/Templates/Create.d.ts +2 -2
- package/lib/components/pages/Templates/Create.js +17 -14
- package/lib/components/pages/Templates/Template/Content/Create/index.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Create/index.js +44 -32
- package/lib/components/pages/Templates/Template/Content/Preview/index.d.ts +2 -2
- package/lib/components/pages/Templates/Template/Content/Preview/index.js +15 -2
- package/lib/components/pages/Templates/Template/Content/Update/index.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Update/index.js +36 -26
- package/lib/components/pages/Templates/Template/Content/View/index.d.ts +2 -2
- package/lib/components/pages/Templates/Template/Content/View/index.js +1 -1
- package/lib/components/pages/Templates/Template/index.d.ts +2 -2
- package/lib/components/pages/Templates/Template/index.js +18 -10
- package/lib/components/pages/Templates/index.d.ts +4 -4
- package/lib/components/pages/Templates/index.js +16 -8
- package/lib/locales.js +18 -15
- package/package.json +9 -10
- package/releases.md +21 -0
- package/src/components/pages/Locales.tsx +61 -46
- package/src/components/pages/Templates/Create.tsx +21 -17
- package/src/components/pages/Templates/Template/Content/Create/index.tsx +48 -38
- package/src/components/pages/Templates/Template/Content/Preview/index.tsx +20 -5
- package/src/components/pages/Templates/Template/Content/Update/index.tsx +38 -28
- package/src/components/pages/Templates/Template/Content/View/index.tsx +2 -2
- package/src/components/pages/Templates/Template/index.tsx +20 -13
- package/src/components/pages/Templates/index.tsx +20 -12
- package/src/locales.ts +25 -22
package/README.md
CHANGED
|
@@ -1,15 +1,85 @@
|
|
|
1
1
|
# @ouroboros/mouth-mui
|
|
2
|
+
[](https://www.npmjs.com/package/@ouroboros/mouth-mui) 
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
Material-UI Components for interacting with the
|
|
5
|
+
[mouth2_oc](https://pypi.org/project/mouth2_oc/) service. It uses
|
|
6
|
+
[@ouroboros/mouth](https://npmjs.com/package/@ouroboros/mouth) to handle the
|
|
7
|
+
actual connections.
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
This code comes without documentation as it's not meant to be used by anyone
|
|
9
|
-
outside of Ouroboros Coding Inc. Please see LICENSE for further information.
|
|
9
|
+
See [Releases](https://github.com/ouroboroscoding/mouth-mui/blob/main/releases.md)
|
|
10
|
+
for changes from release to release.
|
|
10
11
|
|
|
11
12
|
## Installation
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
```console
|
|
14
|
+
foo@bar:~$ npm install @ouroboros/mouth-mui
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Using mouth-mui
|
|
18
|
+
If you're using react with material-ui, this library provides components for
|
|
19
|
+
creating and editing locales and templates.
|
|
20
|
+
|
|
21
|
+
### Components
|
|
22
|
+
- [Locales](#locales)
|
|
23
|
+
- [Templates](#templates)
|
|
24
|
+
|
|
25
|
+
### Locales
|
|
26
|
+
`Locales` is used to setup allowable locales on the system, as well as to make
|
|
27
|
+
it easier to look up what locales can be chosen. It handles all C.R.U.D.
|
|
28
|
+
operations.
|
|
29
|
+
|
|
30
|
+
```jsx
|
|
31
|
+
import { Locales } from '@ouroboros/mouth-mui';
|
|
32
|
+
import React from 'react';
|
|
33
|
+
import { addError, addMessage } from 'your_module';
|
|
34
|
+
function MyLocalesPage(props) {
|
|
35
|
+
return <Locales
|
|
36
|
+
onError={addError}
|
|
37
|
+
onSuccess={(type) => {
|
|
38
|
+
/* type includes [
|
|
39
|
+
'create', 'delete', 'update',
|
|
40
|
+
] */
|
|
41
|
+
addMessage(`${type} successful!`)
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
| Prop | Type | Optional | Description |
|
|
48
|
+
| ---- | ---- | -------- | ----------- |
|
|
49
|
+
| onError | <nobr>`error => void`</nobr> | yes | Callback for when an error occurs. `error` is a `responseErrorStruct` from [@ouroboros/body](https://www.npmjs.com/package/@ouroboros/body). |
|
|
50
|
+
| onSuccess | <nobr>`type => void`</nobr> | yes | Callback for when any of the following `type`s happen: 'create', 'delete', and 'update'. |
|
|
51
|
+
|
|
52
|
+
[ [top](#ouroborosmouth-mui) / [components](#components) ]
|
|
53
|
+
|
|
54
|
+
### Templates
|
|
55
|
+
`Templates` is used to setup named templates with individual versions per locale
|
|
56
|
+
and method (content). For example, you could make a template with both email
|
|
57
|
+
content and sms content so that depending on the user's preference you have
|
|
58
|
+
both. Or you could have an email with both English and Spanish content. Or you
|
|
59
|
+
could have all instances and have multiple locales setup for both email and sms.
|
|
60
|
+
The component handles creating and updating for all these variations.
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
import { Templates } from '@ouroboros/mouth-mui';
|
|
64
|
+
import React from 'react';
|
|
65
|
+
import { addError, addMessage } from 'your_module';
|
|
66
|
+
function MyTemplatesPage(props) {
|
|
67
|
+
return <Templates
|
|
68
|
+
onError={addError}
|
|
69
|
+
onSuccess={(type) => {
|
|
70
|
+
/* type includes [
|
|
71
|
+
'template_create', 'template_update',
|
|
72
|
+
'content_create', 'content_update'
|
|
73
|
+
] */
|
|
74
|
+
addMessage(`${type} successful!`)
|
|
75
|
+
}}
|
|
76
|
+
/>
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Prop | Type | Optional | Description |
|
|
81
|
+
| ---- | ---- | -------- | ----------- |
|
|
82
|
+
| onError | <nobr>`error => void`</nobr> | yes | Callback for when an error occurs. `error` is a `responseErrorStruct` from [@ouroboros/body](https://www.npmjs.com/package/@ouroboros/body). |
|
|
83
|
+
| onSuccess | <nobr>`type => void`</nobr> | yes | Callback for when any of the following `type`s happen: 'template_create', 'template_update', 'content_create','content_update'. |
|
|
84
|
+
|
|
85
|
+
[ [top](#ouroborosmouth-mui) / [components](#components) ]
|
|
@@ -26,8 +26,8 @@ export type LocalesProps = {
|
|
|
26
26
|
declare function Locales({ onError, onSuccess }: LocalesProps): React.JSX.Element;
|
|
27
27
|
declare namespace Locales {
|
|
28
28
|
var propTypes: {
|
|
29
|
-
onError: PropTypes.
|
|
30
|
-
onSuccess: PropTypes.
|
|
29
|
+
onError: PropTypes.Requireable<(...args: any[]) => any>;
|
|
30
|
+
onSuccess: PropTypes.Requireable<(...args: any[]) => any>;
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
export default Locales;
|
|
@@ -54,7 +54,7 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
54
54
|
useEffect(() => {
|
|
55
55
|
// If we have read rights
|
|
56
56
|
if (rights.read) {
|
|
57
|
-
mouth.read('locales').then(recordsSet);
|
|
57
|
+
mouth.read('locales').then((res) => recordsSet(res.data));
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
60
|
recordsSet([]);
|
|
@@ -69,11 +69,31 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
69
69
|
// Create a new Promise and return it
|
|
70
70
|
return new Promise((resolve, reject) => {
|
|
71
71
|
// Create the new locale
|
|
72
|
-
mouth.create('locale', locale).then((
|
|
72
|
+
mouth.create('locale', locale).then((res) => {
|
|
73
|
+
// If we failed
|
|
74
|
+
if (res.error) {
|
|
75
|
+
if (res.error.code === errors.body.DB_NO_RECORD) {
|
|
76
|
+
return reject([['_id', 'Already in use']]);
|
|
77
|
+
}
|
|
78
|
+
else if (res.error.code === errors.body.DATA_FIELDS) {
|
|
79
|
+
return reject(res.error.msg);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
if (onError) {
|
|
83
|
+
onError(res.error);
|
|
84
|
+
return reject([]);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw new Error(JSON.stringify(res.error));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
73
91
|
// If we were successful
|
|
74
|
-
if (data) {
|
|
92
|
+
if (res.data) {
|
|
75
93
|
// Notify the parent
|
|
76
|
-
onSuccess
|
|
94
|
+
if (onSuccess) {
|
|
95
|
+
onSuccess('create');
|
|
96
|
+
}
|
|
77
97
|
// Close the create form
|
|
78
98
|
createSet(false);
|
|
79
99
|
// Clone the records, add the new one to the start, and set
|
|
@@ -84,33 +104,29 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
84
104
|
locales.set(lRecords);
|
|
85
105
|
}
|
|
86
106
|
// Resolve with the form
|
|
87
|
-
resolve(data ? true : false);
|
|
88
|
-
}, (error) => {
|
|
89
|
-
if (error.code === errors.body.DB_NO_RECORD) {
|
|
90
|
-
reject([['_id', 'Already in use']]);
|
|
91
|
-
}
|
|
92
|
-
else if (error.code === errors.body.DATA_FIELDS) {
|
|
93
|
-
reject(error.msg);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
if (onError) {
|
|
97
|
-
onError(error);
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
throw new Error(JSON.stringify(error));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
107
|
+
resolve(res.data ? true : false);
|
|
103
108
|
});
|
|
104
109
|
});
|
|
105
110
|
}
|
|
106
111
|
// Called when the delete button on a locale was clicked
|
|
107
112
|
function deleteClick(key) {
|
|
108
113
|
// Delete the existing locale
|
|
109
|
-
mouth.delete('locale', { _id: key }).then((
|
|
114
|
+
mouth.delete('locale', { _id: key }).then((res) => {
|
|
115
|
+
// If we failed
|
|
116
|
+
if (res.error) {
|
|
117
|
+
if (onError) {
|
|
118
|
+
return onError(res.error);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
throw new Error(JSON.stringify(res.error));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
110
124
|
// If it was successful
|
|
111
|
-
if (data) {
|
|
125
|
+
if (res.data) {
|
|
112
126
|
// Notify the parent
|
|
113
|
-
onSuccess
|
|
127
|
+
if (onSuccess) {
|
|
128
|
+
onSuccess('delete');
|
|
129
|
+
}
|
|
114
130
|
// Look for the record
|
|
115
131
|
const i = afindi(records, '_id', key);
|
|
116
132
|
// If it exists
|
|
@@ -124,13 +140,6 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
124
140
|
locales.set(lRecords);
|
|
125
141
|
}
|
|
126
142
|
}
|
|
127
|
-
}, (error) => {
|
|
128
|
-
if (onError) {
|
|
129
|
-
onError(error);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
throw new Error(JSON.stringify(error));
|
|
133
|
-
}
|
|
134
143
|
});
|
|
135
144
|
}
|
|
136
145
|
// Called when an update form is submitted
|
|
@@ -140,11 +149,28 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
140
149
|
// Create a new Promise and return it
|
|
141
150
|
return new Promise((resolve, reject) => {
|
|
142
151
|
// Update the locale on the server
|
|
143
|
-
mouth.update('locale', locale).then((
|
|
152
|
+
mouth.update('locale', locale).then((res) => {
|
|
153
|
+
// If we failed
|
|
154
|
+
if (res.error) {
|
|
155
|
+
if (res.error.code === errors.body.DATA_FIELDS) {
|
|
156
|
+
return reject(res.error.msg);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
if (onError) {
|
|
160
|
+
onError(res.error);
|
|
161
|
+
return reject([]);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
throw new Error(JSON.stringify(res.error));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
144
168
|
// If we were successful
|
|
145
|
-
if (data) {
|
|
169
|
+
if (res.data) {
|
|
146
170
|
// Notify the parent
|
|
147
|
-
onSuccess
|
|
171
|
+
if (onSuccess) {
|
|
172
|
+
onSuccess('update');
|
|
173
|
+
}
|
|
148
174
|
// Look for the record
|
|
149
175
|
const i = afindi(records, '_id', key);
|
|
150
176
|
// If it exists
|
|
@@ -159,19 +185,7 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
159
185
|
}
|
|
160
186
|
}
|
|
161
187
|
// Resolve with the Form
|
|
162
|
-
resolve(data);
|
|
163
|
-
}, (error) => {
|
|
164
|
-
if (error.code === errors.body.DATA_FIELDS) {
|
|
165
|
-
reject(error.msg);
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
if (onError) {
|
|
169
|
-
onError(error);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
throw new Error(JSON.stringify(error));
|
|
173
|
-
}
|
|
174
|
-
}
|
|
188
|
+
resolve(res.data);
|
|
175
189
|
});
|
|
176
190
|
});
|
|
177
191
|
}
|
|
@@ -192,6 +206,6 @@ export default function Locales({ onError, onSuccess }) {
|
|
|
192
206
|
}
|
|
193
207
|
// Valid props
|
|
194
208
|
Locales.propTypes = {
|
|
195
|
-
onError: PropTypes.func
|
|
196
|
-
onSuccess: PropTypes.func
|
|
209
|
+
onError: PropTypes.func,
|
|
210
|
+
onSuccess: PropTypes.func
|
|
197
211
|
};
|
|
@@ -13,7 +13,7 @@ import { templateStruct } from './Template';
|
|
|
13
13
|
export interface CreateProps {
|
|
14
14
|
onCancel?: () => void;
|
|
15
15
|
onCreated: (template: templateStruct) => void;
|
|
16
|
-
onError
|
|
16
|
+
onError?: (error: responseErrorStruct) => void;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Create
|
|
@@ -30,7 +30,7 @@ declare namespace Create {
|
|
|
30
30
|
var propTypes: {
|
|
31
31
|
onCancel: PropTypes.Requireable<(...args: any[]) => any>;
|
|
32
32
|
onCreated: PropTypes.Validator<(...args: any[]) => any>;
|
|
33
|
-
onError: PropTypes.
|
|
33
|
+
onError: PropTypes.Requireable<(...args: any[]) => any>;
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
export default Create;
|
|
@@ -51,23 +51,26 @@ export default function Create({ onCancel, onCreated, onError }) {
|
|
|
51
51
|
// Called to create the template
|
|
52
52
|
function create() {
|
|
53
53
|
// Create the data in the system
|
|
54
|
-
mouth.create('template', record).then((
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}, (error) => {
|
|
60
|
-
if (error.code === errors.body.DB_DUPLICATE) {
|
|
61
|
-
refName.current?.error('Duplicate');
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
if (onError) {
|
|
65
|
-
onError(error);
|
|
54
|
+
mouth.create('template', record).then((res) => {
|
|
55
|
+
// If we failed
|
|
56
|
+
if (res.error) {
|
|
57
|
+
if (res.error.code === errors.body.DB_DUPLICATE) {
|
|
58
|
+
refName.current?.error('Duplicate');
|
|
66
59
|
}
|
|
67
60
|
else {
|
|
68
|
-
|
|
61
|
+
if (onError) {
|
|
62
|
+
onError(res.error);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
throw new Error(JSON.stringify(res.error));
|
|
67
|
+
}
|
|
69
68
|
}
|
|
70
69
|
}
|
|
70
|
+
// Add the ID to the record
|
|
71
|
+
record._id = res.data;
|
|
72
|
+
// Let the parent know
|
|
73
|
+
onCreated({ ...record });
|
|
71
74
|
});
|
|
72
75
|
}
|
|
73
76
|
// Render
|
|
@@ -91,5 +94,5 @@ export default function Create({ onCancel, onCreated, onError }) {
|
|
|
91
94
|
Create.propTypes = {
|
|
92
95
|
onCancel: PropTypes.func,
|
|
93
96
|
onCreated: PropTypes.func.isRequired,
|
|
94
|
-
onError: PropTypes.func
|
|
97
|
+
onError: PropTypes.func,
|
|
95
98
|
};
|
|
@@ -13,7 +13,7 @@ import { responseErrorStruct } from '@ouroboros/body';
|
|
|
13
13
|
export type TemplateContentCreateProps = {
|
|
14
14
|
locales: Record<string, string>;
|
|
15
15
|
onCreated: (content: contentStruct) => void;
|
|
16
|
-
onError
|
|
16
|
+
onError?: (error: responseErrorStruct) => void;
|
|
17
17
|
template: string;
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
@@ -50,43 +50,52 @@ export default function Create({ locales, onCreated, onError, template }) {
|
|
|
50
50
|
// Called to create the new content record
|
|
51
51
|
function create() {
|
|
52
52
|
// Send the record data to the server
|
|
53
|
-
mouth.create(`template/${type}`, record).then((
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
mouth.create(`template/${type}`, record).then((res) => {
|
|
54
|
+
// If we failed
|
|
55
|
+
if (res.error) {
|
|
56
|
+
if (res.error.code === errors.body.DATA_FIELDS) {
|
|
57
|
+
fieldErrorsSet(errorTree(res.error.msg));
|
|
58
|
+
}
|
|
59
|
+
else if (res.error.code === errors.body.DB_DUPLICATE) {
|
|
60
|
+
fieldErrorsSet({ locale: 'Already used' });
|
|
61
|
+
}
|
|
62
|
+
else if (res.error.code === errors.TEMPLATE_CONTENT_ERROR) {
|
|
63
|
+
const oLines = { templates: [], variables: [] };
|
|
64
|
+
for (const l of res.error.msg) {
|
|
65
|
+
if (l[0] === 'template') {
|
|
66
|
+
oLines.templates.push(l[1]);
|
|
67
|
+
}
|
|
68
|
+
else if (l[0] === 'variable') {
|
|
69
|
+
oLines.variables.push(l[1]);
|
|
70
|
+
}
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
const lLines = [];
|
|
73
|
+
if (oLines.templates.length) {
|
|
74
|
+
lLines.push('The following templates are invalid: ' + oLines.templates.join(', '));
|
|
75
|
+
}
|
|
76
|
+
if (oLines.variables.length) {
|
|
77
|
+
lLines.push('The following variables are invalid: ' + oLines.variables.join(', '));
|
|
78
|
+
}
|
|
79
|
+
// Show the errors
|
|
80
|
+
if (onError) {
|
|
81
|
+
onError({ code: 0, msg: lLines.join('\n') });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw new Error(JSON.stringify(res.error));
|
|
73
85
|
}
|
|
74
86
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
lLines.push('The following templates are invalid: ' + oLines.templates.join(', '));
|
|
78
|
-
}
|
|
79
|
-
if (oLines.variables.length) {
|
|
80
|
-
lLines.push('The following variables are invalid: ' + oLines.variables.join(', '));
|
|
87
|
+
else if (onError) {
|
|
88
|
+
onError(res.error);
|
|
81
89
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
onError({ code: 0, msg: lLines.join('\n') });
|
|
90
|
+
else {
|
|
91
|
+
throw new Error(JSON.stringify(res.error));
|
|
85
92
|
}
|
|
93
|
+
return;
|
|
86
94
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
95
|
+
// Add the type and ID
|
|
96
|
+
const oRecord = { ...record, type, _id: res.data };
|
|
97
|
+
// Tell the parent about the new record
|
|
98
|
+
onCreated(oRecord);
|
|
90
99
|
});
|
|
91
100
|
}
|
|
92
101
|
// Called when any fields in the record are changed
|
|
@@ -156,9 +165,12 @@ export default function Create({ locales, onCreated, onError, template }) {
|
|
|
156
165
|
if (error.code === errors.body.DATA_FIELDS) {
|
|
157
166
|
fieldErrorsSet(errorTree(error.msg));
|
|
158
167
|
}
|
|
159
|
-
else {
|
|
168
|
+
else if (onError) {
|
|
160
169
|
onError(error);
|
|
161
170
|
}
|
|
171
|
+
else {
|
|
172
|
+
throw new Error(JSON.stringify(error));
|
|
173
|
+
}
|
|
162
174
|
previewSet(false);
|
|
163
175
|
}, value: { ...record, type } }))));
|
|
164
176
|
}
|
|
@@ -12,7 +12,7 @@ import { contentStruct } from '../..';
|
|
|
12
12
|
import { responseErrorStruct } from '@ouroboros/body';
|
|
13
13
|
export type PreviewProps = {
|
|
14
14
|
onClose: () => void;
|
|
15
|
-
onError
|
|
15
|
+
onError?: (error: responseErrorStruct) => void;
|
|
16
16
|
value: contentStruct;
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
@@ -29,7 +29,7 @@ declare function Preview({ onClose, onError, value }: PreviewProps): React.JSX.E
|
|
|
29
29
|
declare namespace Preview {
|
|
30
30
|
var propTypes: {
|
|
31
31
|
onClose: PropTypes.Validator<(...args: any[]) => any>;
|
|
32
|
-
onError: PropTypes.
|
|
32
|
+
onError: PropTypes.Requireable<(...args: any[]) => any>;
|
|
33
33
|
value: PropTypes.Requireable<PropTypes.InferProps<{
|
|
34
34
|
locale: PropTypes.Validator<string>;
|
|
35
35
|
template: PropTypes.Requireable<string>;
|
|
@@ -33,7 +33,20 @@ export default function Preview({ onClose, onError, value }) {
|
|
|
33
33
|
const [preview, previewSet] = useState(false);
|
|
34
34
|
// Value effect
|
|
35
35
|
useEffect(() => {
|
|
36
|
-
mouth.create(`template/${value.type}/generate`, value).then(
|
|
36
|
+
mouth.create(`template/${value.type}/generate`, value).then((res) => {
|
|
37
|
+
// If we failed
|
|
38
|
+
if (res.error) {
|
|
39
|
+
if (onError) {
|
|
40
|
+
onError(res.error);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
throw new Error(JSON.stringify(res.error));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Set the preview
|
|
48
|
+
previewSet(res.data);
|
|
49
|
+
});
|
|
37
50
|
}, [value, onError]);
|
|
38
51
|
// Render
|
|
39
52
|
return (React.createElement(Dialog, { fullWidth: true, maxWidth: "lg", onClose: onClose, open: true, "aria-labelledby": "template-content-preview-title" },
|
|
@@ -51,7 +64,7 @@ export default function Preview({ onClose, onError, value }) {
|
|
|
51
64
|
// Valid props
|
|
52
65
|
Preview.propTypes = {
|
|
53
66
|
onClose: PropTypes.func.isRequired,
|
|
54
|
-
onError: PropTypes.func
|
|
67
|
+
onError: PropTypes.func,
|
|
55
68
|
value: PropTypes.shape({
|
|
56
69
|
locale: PropTypes.string.isRequired,
|
|
57
70
|
template: PropTypes.string,
|
|
@@ -12,7 +12,7 @@ import { responseErrorStruct } from '@ouroboros/body';
|
|
|
12
12
|
import { contentStruct } from '../..';
|
|
13
13
|
export type updateStruct = Omit<contentStruct, 'type'>;
|
|
14
14
|
export type UpdateProps = {
|
|
15
|
-
onError
|
|
15
|
+
onError?: (error: responseErrorStruct) => void;
|
|
16
16
|
onUpdated: (content: contentStruct) => void;
|
|
17
17
|
value: contentStruct;
|
|
18
18
|
};
|
|
@@ -38,37 +38,44 @@ export default function Update({ onError, onUpdated, value }) {
|
|
|
38
38
|
// Called to create the new content record
|
|
39
39
|
function update() {
|
|
40
40
|
// Send the record data to the server
|
|
41
|
-
mouth.update(`template/${value.type}`, record).then(() => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
mouth.update(`template/${value.type}`, record).then((res) => {
|
|
42
|
+
// If we failed
|
|
43
|
+
if (res.error) {
|
|
44
|
+
if (res.error.code === errors.body.DATA_FIELDS) {
|
|
45
|
+
fieldErrorsSet(errorTree(res.error.msg));
|
|
46
|
+
}
|
|
47
|
+
else if (res.error.code === errors.TEMPLATE_CONTENT_ERROR) {
|
|
48
|
+
const oLines = { templates: [], variables: [] };
|
|
49
|
+
for (const l of res.error.msg) {
|
|
50
|
+
if (l[0] === 'template') {
|
|
51
|
+
oLines.templates.push(l[1]);
|
|
52
|
+
}
|
|
53
|
+
else if (l[0] === 'variable') {
|
|
54
|
+
oLines.variables.push(l[1]);
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
const lLines = [];
|
|
58
|
+
if (oLines.templates.length) {
|
|
59
|
+
lLines.push('The following templates are invalid: ' + oLines.templates.join(', '));
|
|
60
|
+
}
|
|
61
|
+
if (oLines.variables.length) {
|
|
62
|
+
lLines.push('The following variables are invalid: ' + oLines.variables.join(', '));
|
|
63
|
+
}
|
|
64
|
+
// Show the errors
|
|
65
|
+
if (onError) {
|
|
66
|
+
onError({ code: 0, msg: lLines.join('\n') });
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
lLines.push('The following templates are invalid: ' + oLines.templates.join(', '));
|
|
60
|
-
}
|
|
61
|
-
if (oLines.variables.length) {
|
|
62
|
-
lLines.push('The following variables are invalid: ' + oLines.variables.join(', '));
|
|
69
|
+
else if (onError) {
|
|
70
|
+
onError(res.error);
|
|
63
71
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
onError({ code: 0, msg: lLines.join('\n') });
|
|
72
|
+
else {
|
|
73
|
+
throw new Error(JSON.stringify(res.error));
|
|
67
74
|
}
|
|
75
|
+
return;
|
|
68
76
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
77
|
+
// Let the parent know it was updated
|
|
78
|
+
onUpdated({ type: value.type, ...record });
|
|
72
79
|
});
|
|
73
80
|
}
|
|
74
81
|
// Called when any fields in the record are changed
|
|
@@ -94,9 +101,12 @@ export default function Update({ onError, onUpdated, value }) {
|
|
|
94
101
|
if (error.code === errors.body.DATA_FIELDS) {
|
|
95
102
|
fieldErrorsSet(errorTree(error.msg));
|
|
96
103
|
}
|
|
97
|
-
else {
|
|
104
|
+
else if (onError) {
|
|
98
105
|
onError(error);
|
|
99
106
|
}
|
|
107
|
+
else {
|
|
108
|
+
throw new Error(JSON.stringify(error));
|
|
109
|
+
}
|
|
100
110
|
previewSet(false);
|
|
101
111
|
}, value: { ...record, type: value.type } }))));
|
|
102
112
|
}
|
|
@@ -11,7 +11,7 @@ import React from 'react';
|
|
|
11
11
|
import { responseErrorStruct } from '@ouroboros/body';
|
|
12
12
|
import { contentStruct } from '../..';
|
|
13
13
|
export type ViewProps = {
|
|
14
|
-
onError
|
|
14
|
+
onError?: (error: responseErrorStruct) => void;
|
|
15
15
|
value: contentStruct;
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
@@ -27,7 +27,7 @@ export type ViewProps = {
|
|
|
27
27
|
declare function View({ onError, value }: ViewProps): React.JSX.Element;
|
|
28
28
|
declare namespace View {
|
|
29
29
|
var propTypes: {
|
|
30
|
-
onError: PropTypes.
|
|
30
|
+
onError: PropTypes.Requireable<(...args: any[]) => any>;
|
|
31
31
|
value: PropTypes.Requireable<PropTypes.InferProps<{
|
|
32
32
|
_id: PropTypes.Validator<string>;
|
|
33
33
|
type: PropTypes.Validator<string>;
|
|
@@ -41,7 +41,7 @@ export default function View({ onError, value }) {
|
|
|
41
41
|
}
|
|
42
42
|
// Valid props
|
|
43
43
|
View.propTypes = {
|
|
44
|
-
onError: PropTypes.func
|
|
44
|
+
onError: PropTypes.func,
|
|
45
45
|
value: PropTypes.shape({
|
|
46
46
|
_id: PropTypes.string.isRequired,
|
|
47
47
|
type: PropTypes.oneOf(['email', 'sms']).isRequired
|
|
@@ -33,7 +33,7 @@ export type typeOption = 'email' | 'sms';
|
|
|
33
33
|
export type TemplateProps = {
|
|
34
34
|
locales: Record<string, string>;
|
|
35
35
|
onChange: (template: templateStruct) => void;
|
|
36
|
-
onError
|
|
36
|
+
onError?: (error: responseErrorStruct) => void;
|
|
37
37
|
onContent: (type: string) => void;
|
|
38
38
|
rights: {
|
|
39
39
|
template: idStruct;
|
|
@@ -58,7 +58,7 @@ declare namespace Template {
|
|
|
58
58
|
[x: string]: string | null | undefined;
|
|
59
59
|
}>;
|
|
60
60
|
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
61
|
-
onError: PropTypes.
|
|
61
|
+
onError: PropTypes.Requireable<(...args: any[]) => any>;
|
|
62
62
|
onContent: PropTypes.Validator<(...args: any[]) => any>;
|
|
63
63
|
rights: PropTypes.Requireable<Required<PropTypes.InferProps<{
|
|
64
64
|
template: PropTypes.Validator<Required<PropTypes.InferProps<{
|