@onehat/ui 0.3.308 → 0.3.310
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/package.json
CHANGED
|
@@ -26,7 +26,7 @@ import UiGlobals from '../../UiGlobals.js';
|
|
|
26
26
|
import withAlert from '../Hoc/withAlert.js';
|
|
27
27
|
import withComponent from '../Hoc/withComponent.js';
|
|
28
28
|
import withEditor from '../Hoc/withEditor.js';
|
|
29
|
-
import
|
|
29
|
+
import withPdfButtons from '../Hoc/withPdfButtons.js';
|
|
30
30
|
import inArray from '../../Functions/inArray.js';
|
|
31
31
|
import getComponentFromType from '../../Functions/getComponentFromType.js';
|
|
32
32
|
import buildAdditionalButtons from '../../Functions/buildAdditionalButtons.js';
|
|
@@ -1123,6 +1123,6 @@ function getNullFieldValues(initialValues, Repository) {
|
|
|
1123
1123
|
return ret;
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
1126
|
-
export const FormEditor = withComponent(withAlert(withEditor(
|
|
1126
|
+
export const FormEditor = withComponent(withAlert(withEditor(withPdfButtons(Form))));
|
|
1127
1127
|
|
|
1128
|
-
export default withComponent(withAlert(
|
|
1128
|
+
export default withComponent(withAlert(withPdfButtons(Form)));
|
|
@@ -35,6 +35,7 @@ export default function withModal(WrappedComponent) {
|
|
|
35
35
|
[h, setHeight] = useState(250),
|
|
36
36
|
[w, setWidth] = useState(400),
|
|
37
37
|
[onOk, setOnOk] = useState(),
|
|
38
|
+
[okBtnLabel, setOkBtnLabel] = useState('OK'),
|
|
38
39
|
[onYes, setOnYes] = useState(),
|
|
39
40
|
[onNo, setOnNo] = useState(),
|
|
40
41
|
[customButtons, setCustomButtons] = useState(),
|
|
@@ -53,6 +54,7 @@ export default function withModal(WrappedComponent) {
|
|
|
53
54
|
canClose = true,
|
|
54
55
|
includeCancel = false,
|
|
55
56
|
onOk,
|
|
57
|
+
okBtnLabel,
|
|
56
58
|
onYes,
|
|
57
59
|
onNo,
|
|
58
60
|
customButtons,
|
|
@@ -81,6 +83,9 @@ export default function withModal(WrappedComponent) {
|
|
|
81
83
|
if (onOk) {
|
|
82
84
|
setOnOk(() => onOk);
|
|
83
85
|
}
|
|
86
|
+
if (okBtnLabel) {
|
|
87
|
+
setOkBtnLabel(okBtnLabel);
|
|
88
|
+
}
|
|
84
89
|
if (onYes) {
|
|
85
90
|
setOnYes(() => onYes);
|
|
86
91
|
}
|
|
@@ -132,7 +137,7 @@ export default function withModal(WrappedComponent) {
|
|
|
132
137
|
key="okBtn"
|
|
133
138
|
ref={autoFocusRef}
|
|
134
139
|
onPress={onOk}
|
|
135
|
-
>
|
|
140
|
+
>{okBtnLabel}</Button>);
|
|
136
141
|
}
|
|
137
142
|
if (onYes) {
|
|
138
143
|
buttons.push(<Button
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import { useState, } from 'react';
|
|
2
1
|
import {
|
|
3
2
|
Column,
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Icon,
|
|
4
|
+
Row,
|
|
5
|
+
Text,
|
|
6
6
|
} from 'native-base';
|
|
7
7
|
import * as yup from 'yup'; // https://github.com/jquense/yup#string
|
|
8
8
|
import Inflector from 'inflector-js';
|
|
9
9
|
import qs from 'qs';
|
|
10
|
-
import
|
|
10
|
+
import Form from '../Form/Form.js';
|
|
11
11
|
import inArray from '../../Functions/inArray.js';
|
|
12
12
|
import Pdf from '../Icons/Pdf.js';
|
|
13
|
-
import
|
|
13
|
+
import TriangleExclamation from '../Icons/TriangleExclamation.js';
|
|
14
|
+
import withModal from './withModal.js';
|
|
14
15
|
import { EDITOR_TYPE__PLAIN } from '../../Constants/Editor.js';
|
|
15
16
|
import UiGlobals from '../../UiGlobals.js';
|
|
16
17
|
import _ from 'lodash';
|
|
17
18
|
|
|
18
|
-
export default function
|
|
19
|
-
return (props) => {
|
|
19
|
+
export default function withPdfButtons(WrappedComponent) {
|
|
20
|
+
return withModal((props) => {
|
|
20
21
|
|
|
21
|
-
if (!props.
|
|
22
|
+
if (!props.showPdfBtns) {
|
|
22
23
|
// bypass everything.
|
|
23
24
|
// If we don't do this, we get an infinite recursion with Form
|
|
24
25
|
// because this HOC wraps Form and uses Form itself.
|
|
@@ -33,6 +34,9 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
33
34
|
ancillaryItems = [],
|
|
34
35
|
columnDefaults = {},
|
|
35
36
|
|
|
37
|
+
// withComponent
|
|
38
|
+
self,
|
|
39
|
+
|
|
36
40
|
// withData
|
|
37
41
|
Repository,
|
|
38
42
|
model,
|
|
@@ -40,9 +44,15 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
40
44
|
// withSelection
|
|
41
45
|
selection,
|
|
42
46
|
|
|
47
|
+
// withAlert
|
|
48
|
+
alert,
|
|
49
|
+
showInfo,
|
|
50
|
+
|
|
51
|
+
// withModal
|
|
52
|
+
showModal,
|
|
53
|
+
hideModal,
|
|
54
|
+
|
|
43
55
|
} = props,
|
|
44
|
-
[isModalShown, setIsModalShown] = useState(false),
|
|
45
|
-
[width, height] = useAdjustedWindowSize(510, 800), // 510 so it's over the stack threshold
|
|
46
56
|
propertyNames = [],
|
|
47
57
|
buildModalItems = () => {
|
|
48
58
|
const modalItems = _.map(_.cloneDeep(items), (item, ix) => buildNextLayer(item, ix, columnDefaults)); // clone, as we don't want to alter the item by reference
|
|
@@ -108,7 +118,6 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
108
118
|
return item;
|
|
109
119
|
}
|
|
110
120
|
|
|
111
|
-
|
|
112
121
|
if (item.isHiddenInViewMode || type === 'Button') {
|
|
113
122
|
return null;
|
|
114
123
|
}
|
|
@@ -138,6 +147,7 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
138
147
|
if (!item) {
|
|
139
148
|
return;
|
|
140
149
|
}
|
|
150
|
+
|
|
141
151
|
let {
|
|
142
152
|
name,
|
|
143
153
|
items,
|
|
@@ -154,46 +164,42 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
154
164
|
_.each(modalItems, walkTree);
|
|
155
165
|
return startingValues;
|
|
156
166
|
},
|
|
157
|
-
|
|
158
|
-
data.id = selection[0].id;
|
|
159
|
-
|
|
167
|
+
onChooseFields = (userWantsToEmail = false) => {
|
|
160
168
|
const
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
modalItems = buildModalItems(),
|
|
170
|
+
startingValues = getStartingValues(modalItems),
|
|
171
|
+
validator = buildValidator();
|
|
163
172
|
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
showModal({
|
|
174
|
+
title: 'PDF Fields to Show',
|
|
175
|
+
message: 'Please select which fields to show in the PDF. (1)',
|
|
176
|
+
includeCancel: true,
|
|
177
|
+
onOk: () => {
|
|
178
|
+
hideModal();
|
|
166
179
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
isOpen={true}
|
|
191
|
-
onClose={() => setIsModalShown(false)}
|
|
192
|
-
>
|
|
193
|
-
<Column bg="#fff" w={width} h={height}>
|
|
194
|
-
<FormPanel
|
|
195
|
-
title="PDF Fields to Show"
|
|
196
|
-
instructions="Please select which parts to show in the PDF."
|
|
180
|
+
const
|
|
181
|
+
form = self.children.ModalForm,
|
|
182
|
+
data = form.formGetValues();
|
|
183
|
+
|
|
184
|
+
if (userWantsToEmail) {
|
|
185
|
+
onChooseEmailAddress(data);
|
|
186
|
+
} else {
|
|
187
|
+
getPdf(data);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
okBtnLabel: userWantsToEmail ? 'Choose Email' : 'Get PDF',
|
|
191
|
+
w: 530, // 510 so it's over the stack threshold
|
|
192
|
+
h: 800,
|
|
193
|
+
body: <Column w="100%">
|
|
194
|
+
<Row px={10}>
|
|
195
|
+
<Column w="40px" mr={5} justifyContent="flex-start">
|
|
196
|
+
<Icon as={TriangleExclamation} size={10} color="#000" />
|
|
197
|
+
</Column>
|
|
198
|
+
<Text flex={1}>Please select which fields to show in the PDF. (2)</Text>
|
|
199
|
+
</Row>
|
|
200
|
+
<Form
|
|
201
|
+
parent={self}
|
|
202
|
+
reference="ModalForm"
|
|
197
203
|
editorType={EDITOR_TYPE__PLAIN}
|
|
198
204
|
flex={1}
|
|
199
205
|
Repository={Repository}
|
|
@@ -201,26 +207,124 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
201
207
|
startingValues={startingValues}
|
|
202
208
|
validator={validator}
|
|
203
209
|
checkIsEditingDisabled={false}
|
|
204
|
-
|
|
205
|
-
|
|
210
|
+
disableFooter={true}
|
|
211
|
+
columnDefaults={{
|
|
212
|
+
labelWidth: '100%',
|
|
206
213
|
}}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
214
|
+
/>
|
|
215
|
+
</Column>,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
onChooseEmailAddress = (data) => {
|
|
219
|
+
showModal({
|
|
220
|
+
title: 'Email To',
|
|
221
|
+
message: 'Please enter an email address to send the PDF to. (1)',
|
|
222
|
+
includeCancel: true,
|
|
223
|
+
onOk: () => {
|
|
224
|
+
hideModal();
|
|
225
|
+
|
|
226
|
+
const
|
|
227
|
+
fv = self.children.ModalForm.formGetValues(),
|
|
228
|
+
email = fv.email;
|
|
229
|
+
|
|
230
|
+
sendEmail({
|
|
231
|
+
...data,
|
|
232
|
+
email,
|
|
233
|
+
});
|
|
234
|
+
},
|
|
235
|
+
okBtnLabel: 'Email PDF',
|
|
236
|
+
w: 510, // 510 so it's over the stack threshold
|
|
237
|
+
h: 300,
|
|
238
|
+
body: <Column w="100%">
|
|
239
|
+
<Row>
|
|
240
|
+
<Column w="40px" mr={5} justifyContent="flex-start">
|
|
241
|
+
<Icon as={TriangleExclamation} size={10} color="#000" />
|
|
242
|
+
</Column>
|
|
243
|
+
<Text flex={1}>Please enter an email address to send the PDF to. (2)</Text>
|
|
244
|
+
</Row>
|
|
245
|
+
<Form
|
|
246
|
+
parent={self}
|
|
247
|
+
reference="ModalForm"
|
|
248
|
+
editorType={EDITOR_TYPE__PLAIN}
|
|
249
|
+
disableFooter={true}
|
|
250
|
+
columnDefaults={{
|
|
251
|
+
labelWidth: '100%',
|
|
210
252
|
}}
|
|
211
|
-
|
|
212
|
-
|
|
253
|
+
items={[
|
|
254
|
+
{
|
|
255
|
+
name: 'email',
|
|
256
|
+
label: 'Email Address',
|
|
257
|
+
type: 'Input',
|
|
258
|
+
required: true,
|
|
259
|
+
},
|
|
260
|
+
]}
|
|
261
|
+
validator={yup.object({
|
|
262
|
+
email: yup.string().email().required(),
|
|
263
|
+
})}
|
|
213
264
|
/>
|
|
214
|
-
</Column
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
265
|
+
</Column>,
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
getPdf = (data) => {
|
|
269
|
+
data.id = selection[0].id;
|
|
270
|
+
|
|
271
|
+
const
|
|
272
|
+
url = UiGlobals.baseURL + model + '/viewModelPdf?',
|
|
273
|
+
queryString = qs.stringify(data);
|
|
274
|
+
|
|
275
|
+
window.open(url + queryString, '_blank');
|
|
276
|
+
},
|
|
277
|
+
sendEmail = async (data) => {
|
|
278
|
+
|
|
279
|
+
data.id = selection[0].id;
|
|
280
|
+
|
|
281
|
+
const result = await Repository._send('POST', model + '/emailModelPdf', data);
|
|
282
|
+
|
|
283
|
+
const {
|
|
284
|
+
root,
|
|
285
|
+
success,
|
|
286
|
+
total,
|
|
287
|
+
message
|
|
288
|
+
} = Repository._processServerResponse(result);
|
|
289
|
+
|
|
290
|
+
if (!success) {
|
|
291
|
+
alert('Email could not be sent.');
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
showInfo('Email sent successfully.');
|
|
296
|
+
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const buttons = [
|
|
300
|
+
{
|
|
301
|
+
key: 'emailPdfBtn',
|
|
302
|
+
text: 'Email PDF',
|
|
303
|
+
icon: Pdf,
|
|
304
|
+
isDisabled: selection.length !== 1,
|
|
305
|
+
handler: () => onChooseFields(true),
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: 'viewPdfBtn',
|
|
309
|
+
text: 'View PDF',
|
|
310
|
+
icon: Pdf,
|
|
311
|
+
isDisabled: selection.length !== 1,
|
|
312
|
+
handler: () => onChooseFields(),
|
|
313
|
+
},
|
|
314
|
+
];
|
|
315
|
+
_.each(buttons, (button) => {
|
|
316
|
+
if (!_.find(additionalEditButtons, btn => button.key === btn.key)) {
|
|
317
|
+
additionalEditButtons.push(button);
|
|
318
|
+
}
|
|
319
|
+
if (!_.find(additionalViewButtons, btn => button.key === btn.key)) {
|
|
320
|
+
additionalViewButtons.push(button);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
return <WrappedComponent
|
|
219
325
|
{...props}
|
|
220
326
|
additionalEditButtons={additionalEditButtons}
|
|
221
327
|
additionalViewButtons={additionalViewButtons}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
</>;
|
|
225
|
-
};
|
|
328
|
+
/>;
|
|
329
|
+
});
|
|
226
330
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* e.g. ['parent', 'child'] will be converted to '[data-testid="parent"] [data-testid="child"]'
|
|
8
8
|
* @return Cypress chainer
|
|
9
9
|
*/
|
|
10
|
-
export function getDomNode(selectors) {
|
|
11
|
-
return cy.get(getTestIdSelectors(selectors, true));
|
|
10
|
+
export function getDomNode(selectors, options = {}) {
|
|
11
|
+
return cy.get(getTestIdSelectors(selectors, true), options);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -18,8 +18,8 @@ export function getDomNode(selectors) {
|
|
|
18
18
|
* e.g. ['parent', 'child'] will be converted to '[data-testid="parent"] [data-testid="child"]'
|
|
19
19
|
* @return Cypress chainer
|
|
20
20
|
*/
|
|
21
|
-
export function getDomNodes(selectors) {
|
|
22
|
-
return cy.get(getTestIdSelectors(selectors));
|
|
21
|
+
export function getDomNodes(selectors, options = {}) {
|
|
22
|
+
return cy.get(getTestIdSelectors(selectors), options);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -128,12 +128,15 @@ export function setComboValue(selectors, value) {
|
|
|
128
128
|
getDomNode([...selectors, 'input']).then((field) => {
|
|
129
129
|
cy.get(field).clear({ force: true });
|
|
130
130
|
if (value) {
|
|
131
|
+
cy.intercept('GET', '**/get**').as('getWaiter'); // set up waiter
|
|
131
132
|
cy.get(field)
|
|
132
133
|
.type(value, { delay: 40, force: true }) // slow it down a bit, so React has time to re-render
|
|
133
|
-
.wait(
|
|
134
|
-
|
|
134
|
+
.wait('@getWaiter'); // allow dropdown to load
|
|
135
|
+
|
|
136
|
+
cy.get(field)
|
|
137
|
+
.wait(1500) // render
|
|
135
138
|
.type('{downarrow}')
|
|
136
|
-
.wait(
|
|
139
|
+
.wait(1000) // allow time for selection
|
|
137
140
|
|
|
138
141
|
.type('{enter}')
|
|
139
142
|
.wait(250); // allow time to register enter key
|
|
@@ -166,12 +169,15 @@ export function setTagValue(selectors, value) {
|
|
|
166
169
|
if (!_.isEmpty(values)) {
|
|
167
170
|
_.each(values, (value) => {
|
|
168
171
|
const id = value.id;
|
|
172
|
+
cy.intercept('GET', '**/get**').as('getWaiter'); // set up waiter
|
|
169
173
|
cy.get(field)
|
|
170
174
|
.type('id:' + id, { delay: 40, force: true }) // slow it down a bit, so React has time to re-render
|
|
171
|
-
.wait(
|
|
172
|
-
|
|
175
|
+
.wait('@getWaiter'); // allow dropdown to load
|
|
176
|
+
|
|
177
|
+
cy.get(field)
|
|
178
|
+
.wait(1500) // render
|
|
173
179
|
.type('{downarrow}')
|
|
174
|
-
.wait(
|
|
180
|
+
.wait(1000); // allow time for selection
|
|
175
181
|
});
|
|
176
182
|
|
|
177
183
|
// press trigger to hide dropdown
|