@onehat/ui 0.4.118 → 0.4.120
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 +2 -2
- package/src/Components/Container/Container.js +3 -2
- package/src/Components/Form/Field/Combo/IntervalsCombo.js +6 -6
- package/src/Components/Form/Field/Date.js +1 -0
- package/src/Components/Form/Form.js +2 -1
- package/src/Components/Report/Report.js +263 -33
- package/src/PlatformImports/Web/Attachments.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onehat/ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.120",
|
|
4
4
|
"description": "Base UI for OneHat apps",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"react-native-progress": "^5.0.1",
|
|
70
70
|
"react-redux": "^9.3.0",
|
|
71
71
|
"tailwind-scrollbar": "^4.0.2",
|
|
72
|
-
"tailwindcss": "^4.
|
|
72
|
+
"tailwindcss": "^3.4.17",
|
|
73
73
|
"yup": "^1.7.1"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
@@ -2,6 +2,7 @@ import { cloneElement, useState, useEffect, useRef, useCallback, } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
BoxNative,
|
|
4
4
|
HStack,
|
|
5
|
+
HStackNative,
|
|
5
6
|
VStack,
|
|
6
7
|
} from '@project-components/Gluestack';
|
|
7
8
|
import clsx from 'clsx';
|
|
@@ -681,7 +682,7 @@ function Container(props) {
|
|
|
681
682
|
return <VStack className="Container-all flex-1 min-w-0">
|
|
682
683
|
{northComponent}
|
|
683
684
|
{!getNorthIsCollapsed() && northSplitter}
|
|
684
|
-
<
|
|
685
|
+
<HStackNative
|
|
685
686
|
className="Container-mid w-full flex-[100] min-w-0"
|
|
686
687
|
onLayout={(e) => {
|
|
687
688
|
// Measure available horizontal space for side panels.
|
|
@@ -707,7 +708,7 @@ function Container(props) {
|
|
|
707
708
|
</VStack>
|
|
708
709
|
{!getEastIsCollapsed() && eastSplitter}
|
|
709
710
|
{eastComponent}
|
|
710
|
-
</
|
|
711
|
+
</HStackNative>
|
|
711
712
|
{!getSouthIsCollapsed() && southSplitter}
|
|
712
713
|
{southComponent}
|
|
713
714
|
</VStack>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import ArrayCombo from './ArrayCombo.js';
|
|
2
2
|
|
|
3
3
|
const data = [
|
|
4
|
-
['
|
|
5
|
-
['
|
|
6
|
-
['
|
|
7
|
-
['
|
|
8
|
-
['
|
|
9
|
-
['
|
|
4
|
+
['1 day', 'Daily'],
|
|
5
|
+
['1 week', 'Weekly'],
|
|
6
|
+
// ['2 week', 'Bi-weekly'], // ambibuous, don't use
|
|
7
|
+
['1 month', 'Monthly'],
|
|
8
|
+
['1 quarter', 'Quarterly'],
|
|
9
|
+
['1 year', 'Yearly']
|
|
10
10
|
];
|
|
11
11
|
|
|
12
12
|
export default function IntervalsCombo(props) {
|
|
@@ -1040,6 +1040,7 @@ function Form(props) {
|
|
|
1040
1040
|
icon,
|
|
1041
1041
|
selectorId,
|
|
1042
1042
|
selectorSelectedField,
|
|
1043
|
+
disableTitleSuffix = false,
|
|
1043
1044
|
...itemPropsToPass
|
|
1044
1045
|
} = item,
|
|
1045
1046
|
titleElement;
|
|
@@ -1076,7 +1077,7 @@ function Form(props) {
|
|
|
1076
1077
|
initialEditorMode={ancillaryInitialEditorMode}
|
|
1077
1078
|
/>;
|
|
1078
1079
|
if (title) {
|
|
1079
|
-
if (record?.displayValue) {
|
|
1080
|
+
if (record?.displayValue && !disableTitleSuffix) {
|
|
1080
1081
|
title += ' for ' + record.displayValue;
|
|
1081
1082
|
}
|
|
1082
1083
|
titleElement = <Text
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cloneElement, isValidElement } from 'react';
|
|
1
|
+
import { cloneElement, isValidElement, useState, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
HStack,
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
VStackNative,
|
|
10
10
|
} from '@project-components/Gluestack';
|
|
11
11
|
import clsx from 'clsx';
|
|
12
|
+
import { useSelector, useDispatch } from 'react-redux';
|
|
12
13
|
import { EDITOR_TYPE__PLAIN } from '../../Constants/Editor';
|
|
14
|
+
import {
|
|
15
|
+
selectUser,
|
|
16
|
+
} from '../../Models/Slices/AuthSlice.js';
|
|
13
17
|
import {
|
|
14
18
|
UI_MODE_WEB,
|
|
15
19
|
CURRENT_MODE,
|
|
@@ -18,6 +22,7 @@ import {
|
|
|
18
22
|
REPORT_TYPES__EXCEL,
|
|
19
23
|
REPORT_TYPES__PDF,
|
|
20
24
|
} from '../../Constants/ReportTypes.js';
|
|
25
|
+
import oneHatData from '@onehat/data';
|
|
21
26
|
import Form from '../Form/Form.js';
|
|
22
27
|
import IconButton from '../Buttons/IconButton.js';
|
|
23
28
|
import withComponent from '../Hoc/withComponent.js';
|
|
@@ -28,8 +33,10 @@ import ChartLine from '../Icons/ChartLine.js';
|
|
|
28
33
|
import Calendar from '../Icons/Calendar.js';
|
|
29
34
|
import Plus from '../Icons/Plus.js';
|
|
30
35
|
import Pdf from '../Icons/Pdf.js';
|
|
36
|
+
import Share from '../Icons/Share.js';
|
|
31
37
|
import Excel from '../Icons/Excel.js';
|
|
32
38
|
import getReport from '../../Functions/getReport.js';
|
|
39
|
+
import * as yup from 'yup';
|
|
33
40
|
import _ from 'lodash';
|
|
34
41
|
|
|
35
42
|
function Report(props) {
|
|
@@ -41,7 +48,9 @@ function Report(props) {
|
|
|
41
48
|
description,
|
|
42
49
|
reportId,
|
|
43
50
|
disablePdf = false,
|
|
51
|
+
pdfButtonText = 'Download PDF',
|
|
44
52
|
disableExcel = false,
|
|
53
|
+
excelButtonText = 'Download Excel',
|
|
45
54
|
showReportHeaders = true,
|
|
46
55
|
isQuickReport = false,
|
|
47
56
|
isDisabled = false,
|
|
@@ -51,9 +60,41 @@ function Report(props) {
|
|
|
51
60
|
disabledMessage = 'Report is Disabled',
|
|
52
61
|
additionalData = {},
|
|
53
62
|
quickReportData = {},
|
|
63
|
+
|
|
64
|
+
// withAlert
|
|
54
65
|
alert,
|
|
66
|
+
showInfo,
|
|
67
|
+
showModal,
|
|
68
|
+
hideModal,
|
|
69
|
+
|
|
70
|
+
// withComponent
|
|
71
|
+
self,
|
|
55
72
|
} = props,
|
|
56
73
|
formProps = props._form || {},
|
|
74
|
+
hasFormItems = formProps?.items?.[0]?.items?.length,
|
|
75
|
+
showPresets = usePresets && hasFormItems,
|
|
76
|
+
user = useSelector(selectUser),
|
|
77
|
+
[isValid, setIsValid] = useState(!hasFormItems), // if there are no form items, consider the form valid by default; otherwise, start as invalid until the form says otherwise
|
|
78
|
+
getCurrentReportFormData = () => {
|
|
79
|
+
const
|
|
80
|
+
form = self?.children?.form,
|
|
81
|
+
formValues = form?.formGetValues?.();
|
|
82
|
+
if (!_.isPlainObject(formValues)) {
|
|
83
|
+
alert('Unable to get form data');
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
return formValues;
|
|
87
|
+
},
|
|
88
|
+
setCurrentReportFormData = (data) => {
|
|
89
|
+
const form = self?.children?.form;
|
|
90
|
+
if (!form || !_.isPlainObject(data)) {
|
|
91
|
+
alert('Unable to set form data');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
_.each(data, (value, key) => {
|
|
95
|
+
form.formSetValue(key, value);
|
|
96
|
+
});
|
|
97
|
+
},
|
|
57
98
|
footerProps = formProps.footerProps || {},
|
|
58
99
|
footerClassName = clsx(
|
|
59
100
|
footerProps.className,
|
|
@@ -77,6 +118,161 @@ function Report(props) {
|
|
|
77
118
|
} catch (error) {
|
|
78
119
|
alert(error?.message || 'Unable to download report. Please try again.');
|
|
79
120
|
}
|
|
121
|
+
},
|
|
122
|
+
manageReportSchedules = async (formData) => {
|
|
123
|
+
if (hasFormItems) {
|
|
124
|
+
// check to make sure there is at least one ReportPreset for this report, since the schedule needs to be based on a preset (which captures the form config)
|
|
125
|
+
// If not, show alert saying create preset first
|
|
126
|
+
const ReportPresets = self?.children?.reportPresetsComboEditor?.repository;
|
|
127
|
+
if (!ReportPresets) {
|
|
128
|
+
alert('Unable to access report presets. Please try again.');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
let reportPresets = ReportPresets.getEntities();
|
|
132
|
+
if (!reportPresets?.length) {
|
|
133
|
+
await ReportPresets.load();
|
|
134
|
+
reportPresets = ReportPresets.getEntities();
|
|
135
|
+
}
|
|
136
|
+
if (!reportPresets?.length) {
|
|
137
|
+
alert('Please create at least one report preset first, since schedules are based on presets.');
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const ReportSchedulesGridEditor = getComponentFromType('ReportSchedulesGridEditor');
|
|
142
|
+
showModal({
|
|
143
|
+
title: 'Schedules for "' + title + '"',
|
|
144
|
+
body: <ReportSchedulesGridEditor
|
|
145
|
+
baseParams={{
|
|
146
|
+
'conditions[reportid]': reportId,
|
|
147
|
+
}}
|
|
148
|
+
_editor={{
|
|
149
|
+
hasFormItems,
|
|
150
|
+
reportId,
|
|
151
|
+
}}
|
|
152
|
+
defaultValues={{
|
|
153
|
+
report_schedules__additional_data: additionalData,
|
|
154
|
+
}}
|
|
155
|
+
/>,
|
|
156
|
+
canClose: true,
|
|
157
|
+
whichModal: 'schedulesModal',
|
|
158
|
+
h: 800,
|
|
159
|
+
w: 1100,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
getRepository = () => {
|
|
163
|
+
let repository;
|
|
164
|
+
try {
|
|
165
|
+
// There is no 'Reports' repository (bc there is no 'Reports' model),
|
|
166
|
+
// so just get the first OneBuild repository; doesn't matter which one
|
|
167
|
+
|
|
168
|
+
repository = oneHatData.getRepositoriesByType('onebuild', true); // true to get the first only
|
|
169
|
+
|
|
170
|
+
} catch (error) {
|
|
171
|
+
alert('Error getting repository: ' + (error?.message || error));
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
return repository;
|
|
175
|
+
},
|
|
176
|
+
addToQueue = async (formData) => {
|
|
177
|
+
const
|
|
178
|
+
repository = getRepository(),
|
|
179
|
+
data = {
|
|
180
|
+
report_id: reportId,
|
|
181
|
+
...formData,
|
|
182
|
+
...additionalData,
|
|
183
|
+
},
|
|
184
|
+
result = await repository._send('POST', 'Reports/addToQueue', data),
|
|
185
|
+
response = repository._processServerResponse(result);
|
|
186
|
+
if (!response.success) {
|
|
187
|
+
alert(response.message || 'Failed to add report to queue');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
showInfo('Report added to queue.');
|
|
192
|
+
},
|
|
193
|
+
selectReportPreset = (reportPresetId) => {
|
|
194
|
+
// Change the form settings based on the selected preset
|
|
195
|
+
const
|
|
196
|
+
form = self?.children?.form,
|
|
197
|
+
ReportPresets = self?.children?.reportPresetsComboEditor?.repository;
|
|
198
|
+
if (!form || !ReportPresets) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const reportPreset = ReportPresets?.getById(reportPresetId);
|
|
203
|
+
if (!reportPreset) {
|
|
204
|
+
alert('Selected report preset not found');
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// apply the config to the form
|
|
209
|
+
const config = reportPreset.properties.report_presets__config.getParsedValue(); // get the actual JS object
|
|
210
|
+
setCurrentReportFormData(config);
|
|
211
|
+
},
|
|
212
|
+
shareReportPreset = (parent) => {
|
|
213
|
+
|
|
214
|
+
// show a Modal with UserSelector, excluding current user.
|
|
215
|
+
showModal({
|
|
216
|
+
title: 'Share Report Preset',
|
|
217
|
+
body: <Form
|
|
218
|
+
instructions="Please select which user to share with."
|
|
219
|
+
editorType={EDITOR_TYPE__PLAIN}
|
|
220
|
+
className="flex-1"
|
|
221
|
+
items={[
|
|
222
|
+
{
|
|
223
|
+
name: 'instructions',
|
|
224
|
+
type: 'DisplayField',
|
|
225
|
+
text: 'Please select which user to share with.',
|
|
226
|
+
className: 'mb-3',
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
type: 'Column',
|
|
230
|
+
flex: 1,
|
|
231
|
+
items: [
|
|
232
|
+
{
|
|
233
|
+
name: 'user_id',
|
|
234
|
+
type: 'UsersCombo',
|
|
235
|
+
label: 'User',
|
|
236
|
+
baseParams: {
|
|
237
|
+
'conditions[id <>]': user.id,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
]}
|
|
243
|
+
validator={yup.object({
|
|
244
|
+
user_id: yup.number().integer().required(),
|
|
245
|
+
})}
|
|
246
|
+
onCancel={(e) => {
|
|
247
|
+
hideModal();
|
|
248
|
+
}}
|
|
249
|
+
onClose={(e) => {
|
|
250
|
+
hideModal();
|
|
251
|
+
}}
|
|
252
|
+
onSubmit={async (data, e) => {
|
|
253
|
+
const
|
|
254
|
+
ReportPresets = self?.children?.reportPresetsComboEditor?.repository,
|
|
255
|
+
reportPreset = parent.selection[0],
|
|
256
|
+
params = {
|
|
257
|
+
report_preset_id: reportPreset.id,
|
|
258
|
+
user_id: data.user_id,
|
|
259
|
+
},
|
|
260
|
+
result = await ReportPresets._send('POST', 'ReportPresets/share', params),
|
|
261
|
+
response = ReportPresets._processServerResponse(result);
|
|
262
|
+
|
|
263
|
+
// Close the modal
|
|
264
|
+
hideModal();
|
|
265
|
+
|
|
266
|
+
if (response.success) {
|
|
267
|
+
showInfo('Report preset shared successfully.');
|
|
268
|
+
}
|
|
269
|
+
}}
|
|
270
|
+
/>,
|
|
271
|
+
canClose: true,
|
|
272
|
+
whichModal: 'shareReportPresetModal',
|
|
273
|
+
h: 220,
|
|
274
|
+
w: 500,
|
|
275
|
+
});
|
|
80
276
|
};
|
|
81
277
|
|
|
82
278
|
const propsIcon = props._icon || {};
|
|
@@ -177,37 +373,54 @@ function Report(props) {
|
|
|
177
373
|
}
|
|
178
374
|
|
|
179
375
|
let footerItems = [];
|
|
180
|
-
if (
|
|
376
|
+
if (showPresets) { // if no form items, no need for ReportPresets!
|
|
181
377
|
footerItems.push({
|
|
182
378
|
...testProps('reportPresetsComboEditor'),
|
|
379
|
+
parent: self,
|
|
380
|
+
reference: 'reportPresetsComboEditor',
|
|
183
381
|
key: 'reportPresetsComboEditor',
|
|
184
382
|
type: 'ReportPresetsComboEditor',
|
|
185
383
|
tooltip: 'Report Presets',
|
|
186
|
-
placeholder: '
|
|
187
|
-
disableEdit: true,
|
|
188
|
-
className: 'w-[
|
|
384
|
+
placeholder: 'Presets',
|
|
385
|
+
disableEdit: true, // too complicated to edit, just allow add/delete/share
|
|
386
|
+
className: 'w-[130px]',
|
|
189
387
|
baseParams: {
|
|
190
|
-
reportId,
|
|
388
|
+
'conditions[reportid]': reportId, // reportid is a generated field, so you can search on it, but change capitalization
|
|
389
|
+
},
|
|
390
|
+
onChangeValue: selectReportPreset,
|
|
391
|
+
_grid: {
|
|
392
|
+
canRecordBeAdded: () => isValid, // only allow creating a preset if the form is valid, since the preset will capture the current form config
|
|
393
|
+
onBeforeAdd: (addValues) => {
|
|
394
|
+
// add the current form values to ReportPresets.config when creating a new preset
|
|
395
|
+
return {
|
|
396
|
+
...addValues,
|
|
397
|
+
report_presets__config: {
|
|
398
|
+
...getCurrentReportFormData(),
|
|
399
|
+
report_id: reportId,
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
},
|
|
403
|
+
additionalToolbarButtons: [
|
|
404
|
+
{
|
|
405
|
+
...testProps('shareBtn'),
|
|
406
|
+
key: 'shareBtn',
|
|
407
|
+
text: 'Share Report Preset',
|
|
408
|
+
icon: Share,
|
|
409
|
+
getIsButtonDisabled: (selection) => !selection?.[0]?.id,
|
|
410
|
+
handler: shareReportPreset,
|
|
411
|
+
},
|
|
412
|
+
],
|
|
191
413
|
},
|
|
192
414
|
});
|
|
193
415
|
}
|
|
194
416
|
if (useScheduledReports) {
|
|
195
417
|
footerItems.push({
|
|
196
|
-
...testProps('
|
|
197
|
-
key: '
|
|
418
|
+
...testProps('manageReportSchedulesBtn'),
|
|
419
|
+
key: 'manageReportSchedulesBtn',
|
|
198
420
|
type: 'Button',
|
|
199
|
-
tooltip: '
|
|
421
|
+
tooltip: 'Manage delivery schedules for this report',
|
|
200
422
|
icon: Calendar,
|
|
201
|
-
onPress:
|
|
202
|
-
reportId,
|
|
203
|
-
data: {
|
|
204
|
-
...data,
|
|
205
|
-
...additionalData,
|
|
206
|
-
},
|
|
207
|
-
reportType: REPORT_TYPES__EXCEL,
|
|
208
|
-
showReportHeaders,
|
|
209
|
-
}),
|
|
210
|
-
disableOnInvalid: true,
|
|
423
|
+
onPress: manageReportSchedules,
|
|
211
424
|
});
|
|
212
425
|
}
|
|
213
426
|
if (useQueue) {
|
|
@@ -215,17 +428,9 @@ function Report(props) {
|
|
|
215
428
|
...testProps('queueBtn'),
|
|
216
429
|
key: 'queueBtn',
|
|
217
430
|
type: 'Button',
|
|
218
|
-
tooltip: '
|
|
431
|
+
tooltip: 'Immediately add to Queue',
|
|
219
432
|
icon: Plus,
|
|
220
|
-
onPress:
|
|
221
|
-
reportId,
|
|
222
|
-
data: {
|
|
223
|
-
...data,
|
|
224
|
-
...additionalData,
|
|
225
|
-
},
|
|
226
|
-
reportType: REPORT_TYPES__EXCEL,
|
|
227
|
-
showReportHeaders,
|
|
228
|
-
}),
|
|
433
|
+
onPress: addToQueue,
|
|
229
434
|
disableOnInvalid: true,
|
|
230
435
|
});
|
|
231
436
|
}
|
|
@@ -234,8 +439,9 @@ function Report(props) {
|
|
|
234
439
|
...testProps('excelBtn'),
|
|
235
440
|
key: 'excelBtn',
|
|
236
441
|
type: 'Button',
|
|
237
|
-
text:
|
|
442
|
+
text: excelButtonText,
|
|
238
443
|
icon: Excel,
|
|
444
|
+
tooltip: excelButtonText !== 'Download Excel' ? 'Download Excel' : null,
|
|
239
445
|
onPress: (data) => downloadReport({
|
|
240
446
|
reportId,
|
|
241
447
|
data: {
|
|
@@ -253,8 +459,9 @@ function Report(props) {
|
|
|
253
459
|
...testProps('pdfBtn'),
|
|
254
460
|
key: 'pdfBtn',
|
|
255
461
|
type: 'Button',
|
|
256
|
-
text:
|
|
462
|
+
text: pdfButtonText,
|
|
257
463
|
icon: Pdf,
|
|
464
|
+
tooltip: pdfButtonText !== 'Download PDF' ? 'Download PDF' : null,
|
|
258
465
|
onPress: (data) => downloadReport({
|
|
259
466
|
reportId,
|
|
260
467
|
data: {
|
|
@@ -270,9 +477,17 @@ function Report(props) {
|
|
|
270
477
|
if (footerItems.length) {
|
|
271
478
|
footerItems = footerItems.map(item => {
|
|
272
479
|
const Component = getComponentFromType(item.type);
|
|
273
|
-
|
|
480
|
+
const { key, ...componentProps } = item;
|
|
481
|
+
return <Component key={key} {...componentProps} />;
|
|
274
482
|
});
|
|
275
483
|
}
|
|
484
|
+
let additionalDataComponent = null;
|
|
485
|
+
if (!_.isEmpty(additionalData)) {
|
|
486
|
+
const ReportAdditionalData = getComponentFromType('ReportAdditionalData');
|
|
487
|
+
additionalDataComponent = <ReportAdditionalData
|
|
488
|
+
additionalData={additionalData}
|
|
489
|
+
/>;
|
|
490
|
+
}
|
|
276
491
|
return <VStackNative
|
|
277
492
|
{...testProps('Report-' + reportId)}
|
|
278
493
|
className={clsx(
|
|
@@ -298,9 +513,12 @@ function Report(props) {
|
|
|
298
513
|
<VStack className="flex-1">
|
|
299
514
|
<Text className="text-2xl max-w-full">{title}</Text>
|
|
300
515
|
<Text className="text-sm">{description}</Text>
|
|
516
|
+
{additionalDataComponent}
|
|
301
517
|
</VStack>
|
|
302
518
|
</HStack>
|
|
303
519
|
<Form
|
|
520
|
+
parent={self}
|
|
521
|
+
reference="form"
|
|
304
522
|
editorType={EDITOR_TYPE__PLAIN}
|
|
305
523
|
additionalFooterItems={footerItems}
|
|
306
524
|
{...formProps}
|
|
@@ -308,6 +526,9 @@ function Report(props) {
|
|
|
308
526
|
...footerProps,
|
|
309
527
|
className: footerClassName,
|
|
310
528
|
}}
|
|
529
|
+
onValidityChange={(isValid) => {
|
|
530
|
+
setIsValid(isValid);
|
|
531
|
+
}}
|
|
311
532
|
/>
|
|
312
533
|
</Box>
|
|
313
534
|
{isDisabled &&
|
|
@@ -353,4 +574,13 @@ function Report(props) {
|
|
|
353
574
|
</VStackNative>;
|
|
354
575
|
}
|
|
355
576
|
|
|
356
|
-
|
|
577
|
+
function withAdditionalProps(WrappedComponent) {
|
|
578
|
+
return (props) => {
|
|
579
|
+
return <WrappedComponent
|
|
580
|
+
reference={props.reference || 'report'}
|
|
581
|
+
{...props}
|
|
582
|
+
/>;
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
export default withAdditionalProps(withComponent(withAlert(Report)));
|
|
@@ -233,7 +233,7 @@ function AttachmentsElement(props) {
|
|
|
233
233
|
|
|
234
234
|
} = props,
|
|
235
235
|
styles = UiGlobals.styles,
|
|
236
|
-
model = _.isArray(selectorSelected) && selectorSelected[0] ? selectorSelected[0].
|
|
236
|
+
model = _.isArray(selectorSelected) && selectorSelected[0] ? selectorSelected[0].schema?.name : selectorSelected?.schema?.name,
|
|
237
237
|
modelidCalc = _.isArray(selectorSelected) ? _.map(selectorSelected, (entity) => entity[selectorSelectedField]) : selectorSelected?.[selectorSelectedField],
|
|
238
238
|
modelid = useRef(modelidCalc),
|
|
239
239
|
id = props.id || (model && modelid.current ? `attachments-${model}-${modelid.current}` : 'attachments'),
|
|
@@ -770,7 +770,7 @@ function AttachmentsElement(props) {
|
|
|
770
770
|
wasAlreadyLoaded = AttachmentDirectories.isLoaded,
|
|
771
771
|
currentConditions = AttachmentDirectories.getParamConditions() || {},
|
|
772
772
|
newConditions = {
|
|
773
|
-
'conditions[AttachmentDirectories.model]': selectorSelected.
|
|
773
|
+
'conditions[AttachmentDirectories.model]': selectorSelected.schema.name,
|
|
774
774
|
'conditions[AttachmentDirectories.modelid]': selectorSelected[selectorSelectedField],
|
|
775
775
|
};
|
|
776
776
|
let doReload = false;
|