@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.
- package/lib/components/pages/Locales.d.ts +1 -3
- package/lib/components/pages/Locales.js +32 -23
- package/lib/components/pages/Templates/Create.d.ts +1 -1
- package/lib/components/pages/Templates/Create.js +11 -14
- package/lib/components/pages/Templates/Template/Content/Create/Email.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Create/Email.js +6 -10
- package/lib/components/pages/Templates/Template/Content/Create/SMS.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Create/SMS.js +4 -6
- package/lib/components/pages/Templates/Template/Content/Create/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Create/index.js +14 -20
- package/lib/components/pages/Templates/Template/Content/Preview/Email.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Preview/Email.js +6 -7
- package/lib/components/pages/Templates/Template/Content/Preview/SMS.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Preview/SMS.js +3 -4
- package/lib/components/pages/Templates/Template/Content/Preview/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Preview/index.js +3 -6
- package/lib/components/pages/Templates/Template/Content/Update/Email.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Update/Email.js +6 -11
- package/lib/components/pages/Templates/Template/Content/Update/SMS.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Content/Update/SMS.js +4 -6
- package/lib/components/pages/Templates/Template/Content/Update/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/Update/index.js +17 -23
- package/lib/components/pages/Templates/Template/Content/View/Email.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/View/Email.js +6 -7
- package/lib/components/pages/Templates/Template/Content/View/SMS.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/View/SMS.js +3 -4
- package/lib/components/pages/Templates/Template/Content/View/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/Content/View/index.js +5 -6
- package/lib/components/pages/Templates/Template/Variables.d.ts +1 -1
- package/lib/components/pages/Templates/Template/Variables.js +6 -7
- package/lib/components/pages/Templates/Template/index.d.ts +1 -3
- package/lib/components/pages/Templates/Template/index.js +27 -45
- package/lib/components/pages/Templates/index.d.ts +1 -3
- package/lib/components/pages/Templates/index.js +9 -21
- package/lib/shared.d.ts +12 -0
- package/lib/shared.js +25 -0
- package/package.json +7 -8
- package/src/components/pages/Locales.tsx +40 -27
- package/src/components/pages/Templates/Create.tsx +12 -15
- package/src/components/pages/Templates/Template/Content/Create/Email.tsx +15 -19
- package/src/components/pages/Templates/Template/Content/Create/SMS.tsx +7 -9
- package/src/components/pages/Templates/Template/Content/Create/index.tsx +15 -23
- package/src/components/pages/Templates/Template/Content/Preview/Email.tsx +7 -9
- package/src/components/pages/Templates/Template/Content/Preview/SMS.tsx +3 -9
- package/src/components/pages/Templates/Template/Content/Preview/index.tsx +2 -9
- package/src/components/pages/Templates/Template/Content/Update/Email.tsx +15 -18
- package/src/components/pages/Templates/Template/Content/Update/SMS.tsx +7 -9
- package/src/components/pages/Templates/Template/Content/Update/index.tsx +19 -29
- package/src/components/pages/Templates/Template/Content/View/Email.tsx +6 -8
- package/src/components/pages/Templates/Template/Content/View/SMS.tsx +3 -5
- package/src/components/pages/Templates/Template/Content/View/index.tsx +9 -12
- package/src/components/pages/Templates/Template/Variables.tsx +6 -7
- package/src/components/pages/Templates/Template/index.tsx +37 -59
- package/src/components/pages/Templates/index.tsx +19 -31
- package/src/shared.ts +29 -0
- package/ouroboros-mouth-mui-1.3.2.tgz +0 -0
- package/src/types/xhr2.d.ts +0 -3
|
@@ -8,12 +8,11 @@
|
|
|
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/
|
|
16
|
-
import {
|
|
14
|
+
import TemplateDef from '@ouroboros/mouth/define/template.json';
|
|
15
|
+
import { arrayFindMerge, omap, ucfirst } from '@ouroboros/tools';
|
|
17
16
|
|
|
18
17
|
// NPM modules
|
|
19
18
|
import PropTypes from 'prop-types';
|
|
@@ -61,7 +60,6 @@ export type templateStruct = {
|
|
|
61
60
|
export type typeOption = 'email' | 'sms';
|
|
62
61
|
export type TemplateProps = {
|
|
63
62
|
locales: Record<string, string>,
|
|
64
|
-
mobile: boolean,
|
|
65
63
|
onChange: (template: templateStruct) => void,
|
|
66
64
|
onError: (error: responseErrorStruct) => void,
|
|
67
65
|
onContent: (type: string) => void,
|
|
@@ -85,62 +83,46 @@ const oNameNode = new Node(TemplateDef.name);
|
|
|
85
83
|
* @param Object props Properties passed to the component
|
|
86
84
|
* @returns React.Component
|
|
87
85
|
*/
|
|
88
|
-
export default function Template(
|
|
86
|
+
export default function Template(
|
|
87
|
+
{ locales, onChange, onError, onContent, rights, value }: TemplateProps
|
|
88
|
+
) {
|
|
89
89
|
|
|
90
90
|
// State
|
|
91
|
-
const [contents, contentsSet] = useState<contentStruct[] | false>(false);
|
|
92
|
-
const [tab, tabSet] = useState<number>(0);
|
|
93
|
-
const [edit, editSet] = useState<templateStruct | false>(false);
|
|
94
|
-
const [view, viewSet] = useState<boolean>(false);
|
|
91
|
+
const [ contents, contentsSet ] = useState<contentStruct[] | false>(false);
|
|
92
|
+
const [ tab, tabSet ] = useState<number>(0);
|
|
93
|
+
const [ edit, editSet ] = useState<templateStruct | false>(false);
|
|
94
|
+
const [ view, viewSet ] = useState<boolean>(false);
|
|
95
95
|
|
|
96
96
|
// Refs
|
|
97
97
|
const refName = useRef<DefineNode>(null);
|
|
98
98
|
|
|
99
99
|
// Called when the update record changes
|
|
100
|
-
function change(field: string,
|
|
100
|
+
function change(field: string, val: any) {
|
|
101
101
|
|
|
102
102
|
// Set the new record
|
|
103
|
-
editSet(o => {
|
|
104
|
-
const oRecord = clone(o);
|
|
105
|
-
oRecord[field] = value;
|
|
106
|
-
return oRecord;
|
|
107
|
-
});
|
|
103
|
+
editSet(o => { return { ...o as templateStruct, [field]: val } });
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
// Called when a single conent record is created
|
|
111
107
|
function contentCreated(content: contentStruct) {
|
|
112
108
|
|
|
113
109
|
// Notify the parent
|
|
114
|
-
|
|
110
|
+
onContent('create');
|
|
115
111
|
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// Add the new record to the end of the array
|
|
120
|
-
lContents.push(content);
|
|
121
|
-
|
|
122
|
-
// Set the new contents
|
|
123
|
-
contentsSet(lContents);
|
|
112
|
+
// Add it to the end
|
|
113
|
+
contentsSet(l => [ ...l as contentStruct[], content ]);
|
|
124
114
|
}
|
|
125
115
|
|
|
126
116
|
// Called when a single content record is updated
|
|
127
117
|
function contentUpdated(content: contentStruct) {
|
|
128
118
|
|
|
129
119
|
// Notify the parent
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// Find the index of the record
|
|
133
|
-
const i = afindi(contents as contentStruct[], '_id', content._id);
|
|
120
|
+
onContent('update');
|
|
134
121
|
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// new one, and set the new contents
|
|
140
|
-
const lContents = clone(contents);
|
|
141
|
-
lContents[i] = {...lContents[i], ...content};
|
|
142
|
-
contentsSet(lContents);
|
|
143
|
-
}
|
|
122
|
+
// Work on latest
|
|
123
|
+
contentsSet(l => arrayFindMerge(
|
|
124
|
+
l as contentStruct[], '_id', content._id, content, true
|
|
125
|
+
) as contentStruct[]);
|
|
144
126
|
}
|
|
145
127
|
|
|
146
128
|
// Called to delete the template
|
|
@@ -158,7 +140,7 @@ export default function Template(props: TemplateProps) {
|
|
|
158
140
|
editSet(false);
|
|
159
141
|
|
|
160
142
|
// Let the parent know
|
|
161
|
-
|
|
143
|
+
onChange(edit as templateStruct);
|
|
162
144
|
|
|
163
145
|
}, (error: responseErrorStruct) => {
|
|
164
146
|
if(error.code === errors.body.DB_DUPLICATE) {
|
|
@@ -176,7 +158,7 @@ export default function Template(props: TemplateProps) {
|
|
|
176
158
|
} else {
|
|
177
159
|
if(contents === false) {
|
|
178
160
|
mouth.read('template/contents', {
|
|
179
|
-
template:
|
|
161
|
+
template: value._id
|
|
180
162
|
}).then(contentsSet);
|
|
181
163
|
}
|
|
182
164
|
viewSet(true);
|
|
@@ -189,19 +171,19 @@ export default function Template(props: TemplateProps) {
|
|
|
189
171
|
<Box className="flexColumns">
|
|
190
172
|
<Box className="flexGrow link" onClick={viewToggle}>
|
|
191
173
|
<h2>
|
|
192
|
-
{ucfirst(
|
|
174
|
+
{ucfirst(value.name.replace(/_/g, ' '))}
|
|
193
175
|
<i className={'fa-solid fa-angle-' + (view ? 'up' : 'down')} />
|
|
194
176
|
</h2>
|
|
195
177
|
</Box>
|
|
196
178
|
<Box className="flexStatic">
|
|
197
|
-
{
|
|
179
|
+
{rights.template.update &&
|
|
198
180
|
<Tooltip title="Edit the Template">
|
|
199
|
-
<IconButton className="icon" onClick={ev => editSet(edit ? false :
|
|
181
|
+
<IconButton className="icon" onClick={ev => editSet(edit ? false : { ...value })}>
|
|
200
182
|
<i className={'fa-solid fa-edit ' + (edit ? 'open' : 'closed')} />
|
|
201
183
|
</IconButton>
|
|
202
184
|
</Tooltip>
|
|
203
185
|
}
|
|
204
|
-
{
|
|
186
|
+
{rights.template.delete &&
|
|
205
187
|
<Tooltip title="Delete the Template">
|
|
206
188
|
<IconButton className="icon" onClick={remove}>
|
|
207
189
|
<i className="fa-solid fa-trash-alt" />
|
|
@@ -221,7 +203,7 @@ export default function Template(props: TemplateProps) {
|
|
|
221
203
|
label="none"
|
|
222
204
|
name="name"
|
|
223
205
|
node={oNameNode}
|
|
224
|
-
onChange={
|
|
206
|
+
onChange={val => change('name', val)}
|
|
225
207
|
onEnterPressed={update}
|
|
226
208
|
ref={refName}
|
|
227
209
|
type="update"
|
|
@@ -231,7 +213,7 @@ export default function Template(props: TemplateProps) {
|
|
|
231
213
|
<Grid item lg={6} md={12}>
|
|
232
214
|
<Typography><strong>Variables</strong></Typography>
|
|
233
215
|
<Variables
|
|
234
|
-
onChange={
|
|
216
|
+
onChange={val => change('variables', val)}
|
|
235
217
|
value={edit.variables || {}}
|
|
236
218
|
/>
|
|
237
219
|
</Grid>
|
|
@@ -254,9 +236,9 @@ export default function Template(props: TemplateProps) {
|
|
|
254
236
|
value={tab}
|
|
255
237
|
>
|
|
256
238
|
{contents && contents.map(o =>
|
|
257
|
-
<Tab key={o._id} label={
|
|
239
|
+
<Tab key={o._id} label={locales[o.locale] + ' ' + o.type} />
|
|
258
240
|
)}
|
|
259
|
-
{
|
|
241
|
+
{rights.content.create &&
|
|
260
242
|
<Tab label={
|
|
261
243
|
<i className="fa-solid fa-plus" />
|
|
262
244
|
} />
|
|
@@ -265,37 +247,34 @@ export default function Template(props: TemplateProps) {
|
|
|
265
247
|
<Box className="padding">
|
|
266
248
|
<br />
|
|
267
249
|
{(contents && tab < contents.length &&
|
|
268
|
-
(
|
|
250
|
+
(rights.content.update ?
|
|
269
251
|
<ContentUpdate
|
|
270
252
|
key={contents[tab]._id}
|
|
271
|
-
|
|
272
|
-
onError={props.onError}
|
|
253
|
+
onError={onError}
|
|
273
254
|
onUpdated={contentUpdated}
|
|
274
255
|
value={contents[tab]}
|
|
275
256
|
/>
|
|
276
257
|
:
|
|
277
258
|
<ContentView
|
|
278
259
|
key={contents[tab]._id}
|
|
279
|
-
|
|
280
|
-
onError={props.onError}
|
|
260
|
+
onError={onError}
|
|
281
261
|
value={contents[tab]}
|
|
282
262
|
/>
|
|
283
263
|
)
|
|
284
264
|
) ||
|
|
285
|
-
((
|
|
265
|
+
((rights.content.create && contents && tab === contents.length) &&
|
|
286
266
|
<ContentCreate
|
|
287
|
-
locales={
|
|
288
|
-
mobile={props.mobile}
|
|
267
|
+
locales={locales}
|
|
289
268
|
onCreated={contentCreated}
|
|
290
|
-
onError={
|
|
291
|
-
template={
|
|
269
|
+
onError={onError}
|
|
270
|
+
template={value._id as string}
|
|
292
271
|
/>
|
|
293
272
|
)}
|
|
294
273
|
</Box>
|
|
295
274
|
</Grid>
|
|
296
275
|
<Grid item xs={12} md={3} xl={2}>
|
|
297
276
|
<h4>Available Variables</h4>
|
|
298
|
-
{
|
|
277
|
+
{value && omap(value.variables, (v,k) =>
|
|
299
278
|
<Typography key={k}>{'{' + k + '}'}</Typography>
|
|
300
279
|
)}
|
|
301
280
|
</Grid>
|
|
@@ -309,7 +288,6 @@ export default function Template(props: TemplateProps) {
|
|
|
309
288
|
// Valid props
|
|
310
289
|
Template.propTypes = {
|
|
311
290
|
locales: PropTypes.objectOf(PropTypes.string).isRequired,
|
|
312
|
-
mobile: PropTypes.bool.isRequired,
|
|
313
291
|
onChange: PropTypes.func.isRequired,
|
|
314
292
|
onError: PropTypes.func.isRequired,
|
|
315
293
|
onContent: PropTypes.func.isRequired,
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
// Ouroboros modules
|
|
11
11
|
import { useRights } from '@ouroboros/brain-react';
|
|
12
|
-
import clone from '@ouroboros/clone';
|
|
13
12
|
import mouth from '@ouroboros/mouth';
|
|
14
|
-
import {
|
|
13
|
+
import { arrayFindOverwrite } from '@ouroboros/tools';
|
|
15
14
|
|
|
16
15
|
// NPM modules
|
|
17
16
|
import PropTypes from 'prop-types';
|
|
@@ -29,7 +28,6 @@ import Template, { templateStruct } from './Template';
|
|
|
29
28
|
// Types
|
|
30
29
|
import { responseErrorStruct } from '@ouroboros/body';
|
|
31
30
|
export type TemplatesProps = {
|
|
32
|
-
mobile: boolean,
|
|
33
31
|
onError: (error: responseErrorStruct) => void,
|
|
34
32
|
onSuccess: (type: string) => void
|
|
35
33
|
}
|
|
@@ -44,12 +42,12 @@ export type TemplatesProps = {
|
|
|
44
42
|
* @param Object props Properties passed to the component
|
|
45
43
|
* @returns React.Component
|
|
46
44
|
*/
|
|
47
|
-
export default function Templates(
|
|
45
|
+
export default function Templates({ onError, onSuccess }: TemplatesProps) {
|
|
48
46
|
|
|
49
47
|
// State
|
|
50
|
-
const [create, createSet] = useState<boolean>(false);
|
|
51
|
-
const [locales, localesSet] = useState<Record<string, string>>({});
|
|
52
|
-
const [templates, templatesSet] = useState<templateStruct[]>([]);
|
|
48
|
+
const [ create, createSet ] = useState<boolean>(false);
|
|
49
|
+
const [ locales, localesSet ] = useState<Record<string, string>>({ });
|
|
50
|
+
const [ templates, templatesSet ] = useState<templateStruct[]>([ ]);
|
|
53
51
|
|
|
54
52
|
// Hooks
|
|
55
53
|
const rightsContent = useRights('mouth_content');
|
|
@@ -78,42 +76,34 @@ export default function Templates(props: TemplatesProps) {
|
|
|
78
76
|
createSet(false);
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
}, [rightsTemplate]);
|
|
79
|
+
}, [ rightsTemplate ]);
|
|
82
80
|
|
|
83
81
|
// Called when a template has been created
|
|
84
82
|
function templateCreated(template: templateStruct) {
|
|
85
83
|
|
|
86
84
|
// Notify parent
|
|
87
|
-
|
|
85
|
+
onSuccess('template_create');
|
|
88
86
|
|
|
89
87
|
// Hide the create form
|
|
90
88
|
createSet(false);
|
|
91
89
|
|
|
92
90
|
// Clone the current templates, add the new one to the front, and set
|
|
93
91
|
// the new templates
|
|
94
|
-
|
|
95
|
-
lTemplates.unshift(template);
|
|
96
|
-
templatesSet(lTemplates);
|
|
92
|
+
templatesSet(l => [ template, ...l ])
|
|
97
93
|
}
|
|
98
94
|
|
|
99
95
|
// Called when a template has been updated
|
|
100
96
|
function templateUpdated(template: templateStruct) {
|
|
101
97
|
|
|
102
98
|
// Notify parent
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// Clone the current templates, update the index, and set the new
|
|
112
|
-
// templates
|
|
113
|
-
const lTemplates = clone(templates);
|
|
114
|
-
lTemplates[i] = template;
|
|
115
|
-
templatesSet(lTemplates);
|
|
116
|
-
}
|
|
99
|
+
onSuccess('template_update');
|
|
100
|
+
|
|
101
|
+
// Work on latest
|
|
102
|
+
templatesSet(l =>
|
|
103
|
+
arrayFindOverwrite(
|
|
104
|
+
l, '_id', template._id, template, true
|
|
105
|
+
) as templateStruct[]
|
|
106
|
+
);
|
|
117
107
|
}
|
|
118
108
|
|
|
119
109
|
// Render
|
|
@@ -135,17 +125,16 @@ export default function Templates(props: TemplatesProps) {
|
|
|
135
125
|
<Create
|
|
136
126
|
onCancel={() => createSet(false)}
|
|
137
127
|
onCreated={templateCreated}
|
|
138
|
-
onError={
|
|
128
|
+
onError={onError}
|
|
139
129
|
/>
|
|
140
130
|
}
|
|
141
131
|
{templates.map((o: templateStruct) =>
|
|
142
132
|
<Template
|
|
143
133
|
key={o._id}
|
|
144
134
|
locales={locales}
|
|
145
|
-
mobile={props.mobile}
|
|
146
135
|
onChange={templateUpdated}
|
|
147
|
-
onContent={type =>
|
|
148
|
-
onError={
|
|
136
|
+
onContent={type => onSuccess(`content_${type}`)}
|
|
137
|
+
onError={onError}
|
|
149
138
|
rights={{
|
|
150
139
|
content: rightsContent,
|
|
151
140
|
template: rightsTemplate
|
|
@@ -159,7 +148,6 @@ export default function Templates(props: TemplatesProps) {
|
|
|
159
148
|
|
|
160
149
|
// Valid props
|
|
161
150
|
Templates.propTypes = {
|
|
162
|
-
mobile: PropTypes.bool.isRequired,
|
|
163
151
|
onError: PropTypes.func.isRequired,
|
|
164
152
|
onSuccess: PropTypes.func.isRequired
|
|
165
153
|
}
|
package/src/shared.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
|
|
11
|
+
// Ouroboros imports
|
|
12
|
+
import { Tree } from '@ouroboros/define';
|
|
13
|
+
|
|
14
|
+
// Mouth definition files
|
|
15
|
+
import TemplateEmailDef from '@ouroboros/mouth/define/template_email.json';
|
|
16
|
+
import TemplateSMSDef from '@ouroboros/mouth/define/template_sms.json';
|
|
17
|
+
|
|
18
|
+
// Generate the email Tree
|
|
19
|
+
export const EmailTree = new Tree(TemplateEmailDef, {
|
|
20
|
+
__name__: 'record',
|
|
21
|
+
text: { __ui__: { __title__: 'Plain Text', __type__: 'textarea' } },
|
|
22
|
+
html: { __ui__: { __title__: 'Raw HTML', __type__: 'textarea' } }
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Generate the sms Tree
|
|
26
|
+
export const SmsTree = new Tree(TemplateSMSDef, {
|
|
27
|
+
__name__: 'record',
|
|
28
|
+
content: { __ui__: { __title__: 'Content', __type__: 'textarea' } }
|
|
29
|
+
});
|
|
Binary file
|
package/src/types/xhr2.d.ts
DELETED