@onehat/ui 0.3.309 → 0.3.311

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.3.309",
3
+ "version": "0.3.311",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -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 withPdfButton from '../Hoc/withPdfButton.js';
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(withPdfButton(Form))));
1126
+ export const FormEditor = withComponent(withAlert(withEditor(withPdfButtons(Form))));
1127
1127
 
1128
- export default withComponent(withAlert(withPdfButton(Form)));
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
- >OK</Button>);
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
- Button,
5
- Modal,
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 FormPanel from '../Panel/FormPanel.js';
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 useAdjustedWindowSize from '../../Hooks/useAdjustedWindowSize.js';
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 withPdfButton(WrappedComponent) {
19
- return (props) => {
19
+ export default function withPdfButtons(WrappedComponent) {
20
+ return withModal((props) => {
20
21
 
21
- if (!props.showViewPdfBtn) {
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
- getPdf = (data) => {
158
- data.id = selection[0].id;
159
-
167
+ onChooseFields = (userWantsToEmail = false) => {
160
168
  const
161
- url = UiGlobals.baseURL + model + '/viewModelPdf?',
162
- queryString = qs.stringify(data);
169
+ modalItems = buildModalItems(),
170
+ startingValues = getStartingValues(modalItems),
171
+ validator = buildValidator();
163
172
 
164
- window.open(url + queryString, '_blank');
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
- const button = {
168
- key: 'viewPdfBtn',
169
- text: 'View PDF',
170
- icon: Pdf,
171
- isDisabled: selection.length !== 1,
172
- handler: () => {
173
- setIsModalShown(true);
174
- },
175
- };
176
- if (!_.find(additionalEditButtons, btn => button.key === btn.key)) {
177
- additionalEditButtons.push(button);
178
- }
179
- if (!_.find(additionalViewButtons, btn => button.key === btn.key)) {
180
- additionalViewButtons.push(button);
181
- }
182
-
183
- let modal = null;
184
- if (isModalShown) {
185
- const
186
- modalItems = buildModalItems(),
187
- startingValues = getStartingValues(modalItems),
188
- validator = buildValidator();
189
- modal = <Modal
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
- onClose={(e) => {
205
- setIsModalShown(false);
210
+ disableFooter={true}
211
+ columnDefaults={{
212
+ labelWidth: '100%',
206
213
  }}
207
- onSubmit={(data, e) => {
208
- getPdf(data);
209
- setIsModalShown(false);
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
- submitBtnLabel="View PDF"
212
- useAdditionalEditButtons={false}
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
- </Modal>;
216
- }
217
- return <>
218
- <WrappedComponent
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
- {modal}
224
- </>;
225
- };
328
+ />;
329
+ });
226
330
  }
@@ -11,7 +11,7 @@ import {
11
11
  } from '../../Constants/Editor.js';
12
12
  import UiGlobals from '../../UiGlobals.js';
13
13
  import withComponent from '../Hoc/withComponent.js';
14
- import withPdfButton from '../Hoc/withPdfButton.js';
14
+ import withPdfButtons from '../Hoc/withPdfButtons.js';
15
15
  import inArray from '../../Functions/inArray.js';
16
16
  import getComponentFromType from '../../Functions/getComponentFromType.js';
17
17
  import buildAdditionalButtons from '../../Functions/buildAdditionalButtons.js';
@@ -305,4 +305,4 @@ function Viewer(props) {
305
305
  </Column>;
306
306
  }
307
307
 
308
- export default withComponent(withPdfButton(Viewer));
308
+ export default withComponent(withPdfButtons(Viewer));
@@ -134,9 +134,9 @@ export function setComboValue(selectors, value) {
134
134
  .wait('@getWaiter'); // allow dropdown to load
135
135
 
136
136
  cy.get(field)
137
- .wait(1000) // render
137
+ .wait(1500) // render
138
138
  .type('{downarrow}')
139
- .wait(250) // allow time for selection
139
+ .wait(1000) // allow time for selection
140
140
 
141
141
  .type('{enter}')
142
142
  .wait(250); // allow time to register enter key
@@ -175,9 +175,9 @@ export function setTagValue(selectors, value) {
175
175
  .wait('@getWaiter'); // allow dropdown to load
176
176
 
177
177
  cy.get(field)
178
- .wait(1000) // render
178
+ .wait(1500) // render
179
179
  .type('{downarrow}')
180
- .wait(500); // allow time for selection
180
+ .wait(1000); // allow time for selection
181
181
  });
182
182
 
183
183
  // press trigger to hide dropdown