ui-soxo-bootstrap-core 2.4.25-dev.37 → 2.4.25-dev.41

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.
@@ -1,9 +1,9 @@
1
1
  /**
2
- *
2
+ *
3
3
  * @author Ashique Mohammed
4
4
  * @description Generic Form create accepts an array of fields to update any resource
5
5
  * @version
6
- *
6
+ *
7
7
  */
8
8
 
9
9
  // let forms = [{
@@ -13,13 +13,13 @@
13
13
  // tabs: [{}]
14
14
  // }]
15
15
 
16
- import React, { useState } from "react"
16
+ import React, { useState } from 'react';
17
17
 
18
18
  import moment from 'moment';
19
19
 
20
- import Button from "../../../../../lib/elements/basic/button/button";
20
+ import Button from '../../../../../lib/elements/basic/button/button';
21
21
 
22
- import { Form, Input, Radio, InputNumber, DatePicker, TimePicker, Checkbox, Select, Row, Col, Tabs } from 'antd';
22
+ import { Form, Input, Radio, InputNumber, DatePicker, TimePicker, Checkbox, Select, Row, Col, Tabs } from 'antd';
23
23
 
24
24
  // import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
25
25
 
@@ -29,9 +29,9 @@ import Camera from './../../../../components/camera/camera';
29
29
 
30
30
  // import { ColumnHeightOutlined } from '@ant-design/icons';
31
31
 
32
- import { DateUtils } from "../../../../utils";
32
+ import { DateUtils } from '../../../../utils';
33
33
 
34
- import { FieldCustomizer, TabCustomizer } from "./../../../../";
34
+ import { FieldCustomizer, TabCustomizer, ReferenceSelect } from './../../../../';
35
35
 
36
36
  import { prepareAndExecuteScript } from './../../../../utils/script.utils';
37
37
 
@@ -43,163 +43,148 @@ const { TabPane } = Tabs;
43
43
 
44
44
  // const grid = 4;
45
45
 
46
-
47
- import './form-creator.scss'
46
+ import './form-creator.scss';
48
47
 
49
48
  /**
50
49
  * Component accepts fields to render the necessary components and returns the values on submission
51
- *
52
- * @param {*} param0
53
- * @returns
50
+ *
51
+ * @param {*} param0
52
+ * @returns
54
53
  */
55
54
  function FormCreator({
56
- /**If we want to change the existing information first we need the current information ie, selectedInformation*/
57
- selectedInformation,
58
- model,
59
- formContent = {},
60
- onSubmit,
61
- fields = [],
62
- callback,
63
- layout,
64
- // Below are arguments for use in form display
65
- onFieldUpdate,
66
- // onListUpdate,
67
- onFieldRemove,
55
+ /**If we want to change the existing information first we need the current information ie, selectedInformation*/
56
+ selectedInformation,
57
+ model,
58
+ formContent = {},
59
+ onSubmit,
60
+ fields = [],
61
+ callback,
62
+ layout,
63
+ // Below are arguments for use in form display
64
+ onFieldUpdate,
65
+ // onListUpdate,
66
+ onFieldRemove,
68
67
  }) {
69
- const [form] = Form.useForm();
70
-
71
- let layoutValue;
72
-
73
- if (layout) {
74
- layoutValue = layout
75
- } else {
76
- layoutValue = {
77
- labelCol: { span: 12 },
78
- wrapperCol: { span: 12 },
79
- };
80
- }
81
-
82
- // Variable used for loading state
83
- const [loading, setLoading] = useState(false);
84
-
85
- // Variable stores the form body values
86
- const [content, setContent] = useState(() => {
87
-
88
- // Body for the files
89
- let body = formContent || { [model.name]: {} };
90
-
91
- fields.forEach((entry) => {
92
-
93
- if (entry.transform) {
94
-
95
- body[entry.field] = entry.transform(body[entry.field]);
96
- }
97
-
98
- // If its a date
99
- if (['date'].indexOf(entry.type) !== -1 && formContent[entry.field]) {
100
-
101
- body[entry.field] = DateUtils.getMomentObject(formContent[entry.field]);
102
- }
103
-
104
- })
105
-
106
- return body;
107
-
68
+ const [form] = Form.useForm();
69
+
70
+ let layoutValue;
71
+
72
+ if (layout) {
73
+ layoutValue = layout;
74
+ } else {
75
+ layoutValue = {
76
+ labelCol: { span: 12 },
77
+ wrapperCol: { span: 12 },
78
+ };
79
+ }
80
+
81
+ // Variable used for loading state
82
+ const [loading, setLoading] = useState(false);
83
+
84
+ // Variable stores the form body values
85
+ const [content, setContent] = useState(() => {
86
+ // Body for the files
87
+ let body = formContent || { [model.name]: {} };
88
+
89
+ fields.forEach((entry) => {
90
+ if (entry.transform) {
91
+ body[entry.field] = entry.transform(body[entry.field]);
92
+ }
93
+
94
+ // If its a date
95
+ if (['date'].indexOf(entry.type) !== -1 && formContent[entry.field]) {
96
+ body[entry.field] = DateUtils.getMomentObject(formContent[entry.field]);
97
+ }
108
98
  });
109
99
 
110
- /**
111
- * Function handles trigger of onupload
112
- *
113
- * @param {*} element
114
- * @param {*} attachments
115
- */
116
- function onUpload(element, attachments) {
117
- form.setFieldsValue({ [element.field]: attachments });
118
- }
119
-
120
- /**
121
- * Custom Listener for onchange of input
122
- *
123
- * @param {*} element
124
- * @param {*} attachments
125
- */
126
- function onChange(element, value) {
127
-
128
- // Though we initially gave less respect to this method
129
- // This is the game changer - 29/01/23
130
-
131
- // Being able to listen to script , Bind onChange listeners to each input
132
- // can avoid the need for building custom forms again
133
-
134
- // console.log(element);
135
-
136
- /** */
137
- if (element.field) {
138
-
139
- form.setFieldsValue({ [element.field]: value });
140
- }
141
- }
142
-
143
- // const onDragEnd = (result) => {
144
-
145
- // onListUpdate(result.source, result.destination);
146
- // }
147
-
148
- // const getListStyle = (isDraggingOver) => ({
149
- // // background: isDraggingOver ? 'lightblue' : '',
150
- // boxShadow: isDraggingOver ? '0px 0px 5px 5px #eeeeee' : '',
151
-
152
- // // padding: grid,
153
- // // width: 250
154
- // });
155
-
156
- /**
157
- * Function triggered for any onChange of input
158
- *
159
- * @param {*} formFields
160
- */
161
- const onFieldsChange = (formFields) => {
162
-
163
- formFields.forEach((field) => {
164
- if (field.name[0].includes('date')) {
165
-
166
- // values[field.field] = new Timestamp(moment(field.value).valueOf());
167
-
168
- // content[field.name[0]] = moment(field.value).format('DD/MM/YYYY');
169
- } else {
170
- // content[field.name[0]] = field.value;
171
- }
172
- })
173
- // setContent({ ...content })
100
+ return body;
101
+ });
102
+
103
+ /**
104
+ * Function handles trigger of onupload
105
+ *
106
+ * @param {*} element
107
+ * @param {*} attachments
108
+ */
109
+ function onUpload(element, attachments) {
110
+ form.setFieldsValue({ [element.field]: attachments });
111
+ }
112
+
113
+ /**
114
+ * Custom Listener for onchange of input
115
+ *
116
+ * @param {*} element
117
+ * @param {*} attachments
118
+ */
119
+ function onChange(element, value) {
120
+ // Though we initially gave less respect to this method
121
+ // This is the game changer - 29/01/23
122
+
123
+ // Being able to listen to script , Bind onChange listeners to each input
124
+ // can avoid the need for building custom forms again
125
+
126
+ // console.log(element);
127
+
128
+ /** */
129
+ if (element.field) {
130
+ form.setFieldsValue({ [element.field]: value });
174
131
  }
175
-
176
- /**
177
- * Values Change
178
- *
179
- * @param {*} field
180
- * @param {*} values
181
- */
182
- const onValuesChange = async (field, values) => {
183
-
184
- // Find the input that is changed
185
- let key = Object.keys(field)[0];
186
-
187
- // Configuration
188
- let fieldConfiguration = fields.filter((config) => config.field === key)[0];
189
-
190
- // We have to check if there is an onChange script for the field
191
- if (fieldConfiguration.on_change) {
192
-
193
- // Before Submit of form , execute the script
194
- values = await prepareAndExecuteScript(values, null, fieldConfiguration.on_change);
195
-
196
- }
132
+ }
133
+
134
+ // const onDragEnd = (result) => {
135
+
136
+ // onListUpdate(result.source, result.destination);
137
+ // }
138
+
139
+ // const getListStyle = (isDraggingOver) => ({
140
+ // // background: isDraggingOver ? 'lightblue' : '',
141
+ // boxShadow: isDraggingOver ? '0px 0px 5px 5px #eeeeee' : '',
142
+
143
+ // // padding: grid,
144
+ // // width: 250
145
+ // });
146
+
147
+ /**
148
+ * Function triggered for any onChange of input
149
+ *
150
+ * @param {*} formFields
151
+ */
152
+ const onFieldsChange = (formFields) => {
153
+ formFields.forEach((field) => {
154
+ if (field.name[0].includes('date')) {
155
+ // values[field.field] = new Timestamp(moment(field.value).valueOf());
156
+ // content[field.name[0]] = moment(field.value).format('DD/MM/YYYY');
157
+ } else {
158
+ // content[field.name[0]] = field.value;
159
+ }
160
+ });
161
+ // setContent({ ...content })
162
+ };
163
+
164
+ /**
165
+ * Values Change
166
+ *
167
+ * @param {*} field
168
+ * @param {*} values
169
+ */
170
+ const onValuesChange = async (field, values) => {
171
+ // Find the input that is changed
172
+ let key = Object.keys(field)[0];
173
+
174
+ // Configuration
175
+ let fieldConfiguration = fields.filter((config) => config.field === key)[0];
176
+
177
+ // We have to check if there is an onChange script for the field
178
+ if (fieldConfiguration.on_change) {
179
+ // Before Submit of form , execute the script
180
+ values = await prepareAndExecuteScript(values, null, fieldConfiguration.on_change);
197
181
  }
182
+ };
198
183
 
199
- return (
200
- <section className="form-creator">
201
- <div>
202
- {/* <DragDropContext onDragEnd={onDragEnd}>
184
+ return (
185
+ <section className="form-creator">
186
+ <div>
187
+ {/* <DragDropContext onDragEnd={onDragEnd}>
203
188
  <Droppable droppableId="droppable">
204
189
 
205
190
  {(provided, snapshot) => (
@@ -209,362 +194,344 @@ function FormCreator({
209
194
  {...provided.droppableProps}
210
195
  > */}
211
196
 
212
- <Form
213
-
214
- form={form}
215
- // layout="inline"
216
- {...layoutValue}
217
- className="new-record"
218
- name="new-record"
219
- onFinish={(values) => {
220
-
221
- setLoading(true);
222
-
223
- // Do a screening to check if date fields are
224
- fields.forEach((field) => {
225
-
226
- if (field.field && field.field.includes('date')) {
227
-
228
- // values[field.field] = new Timestamp(new Date());
229
-
230
- values[field.field] = moment(values[field.field]).valueOf();
231
-
232
- } else {
233
-
234
- }
235
-
236
- if (field.type === ('time')) {
237
-
238
- // values[field.field] = new Timestamp(new Date());
239
-
240
- values[field.field] = moment(values[field.field]).format('HH:mm A');
241
-
242
- } else {
243
-
244
- }
245
- })
246
-
247
- onSubmit(values).then(() => {
248
-
249
- setLoading(false);
250
-
251
- });
252
-
253
- }}
254
- onFieldsChange={onFieldsChange}
255
-
256
- onValuesChange={onValuesChange}
257
- layout={layoutValue}
258
- // validateMessages={validateMessages}
259
- initialValues={{
260
- ...content,
261
- remarks: ''
262
- }}
263
- >
264
-
265
- {/* Mapper maps each fields to build the form */}
266
- <FieldMapper
267
- fields={fields}
268
- onChange={onChange}
269
- selectedInformation={selectedInformation}
270
- onUpload={onUpload}
271
- onFieldUpdate={onFieldUpdate}
272
- onFieldRemove={onFieldRemove}
273
- />
274
-
275
- {/* Mapper Ends */}
276
-
277
- <Button loading={loading} type="primary" htmlType="submit" className="submit-button">
278
- SUBMIT
279
- </Button>
280
- </Form>
281
- </div>
282
- {/* </div>)}
197
+ <Form
198
+ form={form}
199
+ // layout="inline"
200
+ {...layoutValue}
201
+ className="new-record"
202
+ name="new-record"
203
+ onFinish={(values) => {
204
+ setLoading(true);
205
+
206
+ // Do a screening to check if date fields are
207
+ fields.forEach((field) => {
208
+ if (field.field && field.field.includes('date')) {
209
+ // values[field.field] = new Timestamp(new Date());
210
+
211
+ values[field.field] = moment(values[field.field]).valueOf();
212
+ } else {
213
+ }
214
+
215
+ if (field.type === 'time') {
216
+ // values[field.field] = new Timestamp(new Date());
217
+
218
+ values[field.field] = moment(values[field.field]).format('HH:mm A');
219
+ } else {
220
+ }
221
+ });
222
+
223
+ onSubmit(values).then(() => {
224
+ setLoading(false);
225
+ });
226
+ }}
227
+ onFieldsChange={onFieldsChange}
228
+ onValuesChange={onValuesChange}
229
+ layout={layoutValue}
230
+ // validateMessages={validateMessages}
231
+ initialValues={{
232
+ ...content,
233
+ remarks: '',
234
+ }}
235
+ >
236
+ {/* Mapper maps each fields to build the form */}
237
+ <FieldMapper
238
+ fields={fields}
239
+ onChange={onChange}
240
+ selectedInformation={selectedInformation}
241
+ onUpload={onUpload}
242
+ onFieldUpdate={onFieldUpdate}
243
+ onFieldRemove={onFieldRemove}
244
+ formContent={formContent}
245
+ />
246
+
247
+ {/* Mapper Ends */}
248
+
249
+ <Button loading={loading} type="primary" htmlType="submit" className="submit-button">
250
+ SUBMIT
251
+ </Button>
252
+ </Form>
253
+ </div>
254
+ {/* </div>)}
283
255
 
284
256
  </Droppable>
285
257
  </DragDropContext> */}
286
-
287
- </section>
288
- );
258
+ </section>
259
+ );
289
260
  }
290
261
 
291
262
  export default FormCreator;
292
263
 
293
-
294
264
  /**
295
265
  * Field Mapper accepts fields to build the form
296
- *
297
- * @param {*} param0
298
- * @returns
266
+ *
267
+ * @param {*} param0
268
+ * @returns
299
269
  */
300
- function FieldMapper({
301
- fields = [],
302
- onChange,
303
- selectedInformation,
304
- onUpload,
305
- onFieldUpdate,
306
- onFieldRemove
307
- }) {
270
+ function FieldMapper({ fields = [], onChange, selectedInformation, onUpload, onFieldUpdate, onFieldRemove, formContent }) {
271
+ return (
272
+ <>
273
+ {fields.map((field, index) => {
274
+ // For Tabs
275
+ if (field.type === 'Tabs') {
276
+ return (
277
+ <Tabs defaultActiveKey="0">
278
+ {field.tabs.map((tab, tabIndex) => {
279
+ return (
280
+ <TabPane tab={`${tab.caption}`} key={tabIndex}>
281
+ {/* Customizes the Tab */}
282
+ <TabCustomizer
283
+ tab={tab}
284
+ field={field}
285
+ onFieldUpdate={onFieldUpdate}
286
+ fieldIndex={tabIndex}
287
+ index={index}
288
+ onFieldRemove={onFieldRemove}
289
+ />
290
+ {/* Customizes the Tab Ends */}
308
291
 
309
- return (<>
310
-
311
- {
312
- fields.map((field, index) => {
313
-
314
- // For Tabs
315
- if (field.type === 'Tabs') {
316
-
317
- return (<Tabs defaultActiveKey="0">
318
-
319
- {
320
- field.tabs.map((tab, tabIndex) => {
321
-
322
- return (
323
- <TabPane tab={`${tab.caption}`} key={tabIndex} >
324
-
325
- {/* Customizes the Tab */}
326
- <TabCustomizer
327
-
328
- tab={tab}
329
- field={field}
330
-
331
- onFieldUpdate={onFieldUpdate}
332
- fieldIndex={tabIndex}
333
- index={index}
334
- onFieldRemove={onFieldRemove} />
335
- {/* Customizes the Tab Ends */}
336
-
337
- {/* Mapper maps each fields to build the form */}
338
- <FieldMapper
339
- fields={tab.fields}
340
- onChange={onChange}
341
- onUpload={onUpload}
342
- onFieldUpdate={onFieldUpdate}
343
- onFieldRemove={onFieldRemove}
344
- />
345
-
346
- </TabPane>
347
- )
348
- })
349
- }
350
-
351
- </Tabs>)
352
-
353
- } else {
354
-
355
- if (field.condition) {
356
-
357
- return field.condition(content)
358
- ?
359
- <UserInput
360
- onChange={onChange}
361
- index={index}
362
- key={index}
363
- onUpload={onUpload}
364
- field={field}
365
- onFieldUpdate={onFieldUpdate}
366
- onFieldRemove={onFieldRemove}
367
- />
368
- :
369
- null
370
-
371
- } else {
372
- return <UserInput
373
- onChange={onChange}
374
- key={index}
375
- selectedInformation={selectedInformation}
376
- index={index}
377
- field={field}
378
- onUpload={onUpload}
379
- onFieldUpdate={onFieldUpdate}
380
-
381
- onFieldRemove={onFieldRemove}
382
-
383
- />;
384
- }
385
- }
386
- })
292
+ {/* Mapper maps each fields to build the form */}
293
+ <FieldMapper
294
+ fields={tab.fields}
295
+ onChange={onChange}
296
+ onUpload={onUpload}
297
+ onFieldUpdate={onFieldUpdate}
298
+ onFieldRemove={onFieldRemove}
299
+ />
300
+ </TabPane>
301
+ );
302
+ })}
303
+ </Tabs>
304
+ );
305
+ } else {
306
+ if (field.condition) {
307
+ return field.condition(content) ? (
308
+ <UserInput
309
+ onChange={onChange}
310
+ index={index}
311
+ key={index}
312
+ onUpload={onUpload}
313
+ field={field}
314
+ onFieldUpdate={onFieldUpdate}
315
+ onFieldRemove={onFieldRemove}
316
+ formContent={formContent}
317
+ />
318
+ ) : null;
319
+ } else {
320
+ return (
321
+ <UserInput
322
+ onChange={onChange}
323
+ key={index}
324
+ selectedInformation={selectedInformation}
325
+ index={index}
326
+ field={field}
327
+ onUpload={onUpload}
328
+ onFieldUpdate={onFieldUpdate}
329
+ onFieldRemove={onFieldRemove}
330
+ formContent={formContent}
331
+ />
332
+ );
333
+ }
387
334
  }
388
-
389
- </>)
390
-
335
+ })}
336
+ </>
337
+ );
391
338
  }
392
339
 
393
-
394
-
395
340
  /**
396
341
  * Component accepts user input according to type
397
- *
398
- * @param {*} param0
342
+ *
343
+ * @param {*} param0
399
344
  */
400
- function UserInput({ field, onUpload, selectedInformation, onChange, onFieldUpdate, onFieldRemove, index }) {
401
-
402
- let props = {};
403
-
404
- // The extra text
405
- if (field.extra) {
406
- props.extra = field.extra;
345
+ function UserInput({ field, onUpload, selectedInformation, onChange, onFieldUpdate, onFieldRemove, index, formContent }) {
346
+ let props = {};
347
+
348
+ // The extra text
349
+ if (field.extra) {
350
+ props.extra = field.extra;
351
+ }
352
+
353
+ const isVisible = field.visible !== undefined ? field.visible : true;
354
+
355
+ /**
356
+ * According to the type render each element
357
+ *
358
+ * @param {*} field
359
+ */
360
+ const inputElement = (field, onChange) => {
361
+ if (field.visible) {
362
+ if (field.visible === false) return null;
407
363
  }
408
364
 
409
- const isVisible = field.visible !== undefined ? field.visible : true;
365
+ switch (field.type) {
366
+ case 'number':
367
+ return <InputNumber required={field.required} />;
368
+
369
+ case 'input':
370
+ return <Input required={field.required} />;
371
+
372
+ case 'radio':
373
+ return (
374
+ <Radio.Group>
375
+ {field.options.map((option, key) => (
376
+ <Radio key={key} value={option}>
377
+ {option ? 'Yes' : 'No'}
378
+ </Radio>
379
+ ))}
380
+ </Radio.Group>
381
+ );
382
+
383
+ case 'checkbox':
384
+ return (
385
+ <Checkbox.Group style={{ width: '100%' }}>
386
+ <Col>
387
+ {field.options.map((option, key) => {
388
+ let opt = typeof option === 'string' ? option : option.value;
410
389
 
411
- /**
412
- * According to the type render each element
413
- *
414
- * @param {*} field
415
- */
416
- const inputElement = (field, onChange) => {
417
-
418
- if (field.visible) {
419
-
420
- if (field.visible === false) return null;
421
-
422
- }
423
-
424
- switch (field.type) {
425
-
426
- case 'number':
427
- return <InputNumber required={field.required} />
428
-
429
- case 'input':
430
- return <Input required={field.required} />
431
-
432
- case 'radio':
433
390
  return (
434
- <Radio.Group>
435
-
436
- {field.options.map((option, key) => <Radio key={key} value={option}>{option ? 'Yes' : 'No'}</Radio>)}
437
-
438
- </Radio.Group>
439
-
391
+ <Row>
392
+ <Checkbox key={key} value={opt}>
393
+ {opt}
394
+ </Checkbox>
395
+ </Row>
440
396
  );
441
-
442
- case 'checkbox':
443
- return <Checkbox.Group style={{ width: '100%' }}>
444
- <Col>
445
- {
446
- field.options.map((option, key) => {
447
-
448
- let opt = typeof option === 'string' ? option : option.value;
449
-
450
- return <Row><Checkbox key={key} value={opt}>{opt}</Checkbox></Row>
451
- })
452
- }
453
- </Col>
454
- </Checkbox.Group>
455
-
456
- // case 'checkbox':
457
- // return <Checkbox.Group options={field.options}/>
458
- case 'textarea':
459
- return <TextArea rows={4} required={field.required} />
460
-
461
- case 'boolean':
462
- return <Select style={{ width: 120 }} required={field.required}>
463
- {[true, false].map((option, key) => <Option key={key} value={option}>{option ? 'Yes' : 'No'}</Option>)}
464
- </Select>
465
-
466
- case 'select':
467
- // Handle static select options
468
- if (Array.isArray(field.options)) {
469
-
470
- let defaultValue = field.default ? field.default : '';
471
-
472
- /**If there is selected Information ie, for change info if there is selected guest information
473
- * then we will match and set a default value from the guest details
474
- */
475
- if (selectedInformation) {
476
- // Get the field value dynamically from selectedInformation[0] using field.field
477
- const fieldValue = selectedInformation[0] && selectedInformation[0][field.caption];
478
-
479
- // Find the default value based on field value and matching DisplayMember or description
480
- const defaultOption = field.options.find(
481
- (option) =>
482
- option.displayMember?.toLowerCase() === fieldValue?.toLowerCase()
483
- )
484
-
485
- // If a matching option is found, set the default value; otherwise, do not set a default value (i.e., null or undefined)
486
- defaultValue = defaultOption ? defaultOption.valueMember : null;
487
-
488
- }
489
- /**In case of default selection we need to call the onchange manually */
490
- if (defaultValue) {
491
-
492
- onChange(field, defaultValue);
493
- }
494
-
495
- return (
496
- <Select defaultValue={defaultValue}
497
- required={field.required}
498
- style={{ width: 120 }}
499
- onChange={(value) => onChange(field, value)}
500
- >
501
- {field.options.map((option, key) => (
502
- <Option key={key} value={option.valueMember}>
503
- {option.displayMember}
504
- </Option>
505
- ))}
506
- </Select>
507
- );
508
- }
509
- // case 'checkbox':
510
- // return <Checkbox.Group options={field.options} />
511
-
512
- case 'datetime':
513
- return <DatePicker format={"DD/MM/YYYY"} onChange={(record) => {
514
-
515
- onChange(field, record.format('DD/MM/YYYY'))
516
-
517
- }} />
518
-
519
- case 'date':
520
- return <DatePicker format={"DD/MM/YYYY"} />
521
-
522
-
523
- case 'time':
524
- return <TimePicker format={"HH:mm A"} />
525
-
526
- // onChange={(record) => {
527
-
528
- // console.log(record);
529
-
530
- // onChange(field, record.format('HH:mm A'))
531
-
532
- // }}
533
-
534
-
535
- case 'upload':
536
- return <FileUpload multiple={field.multiple} maxSize={field.maxSize || 3} callback={(attachment) => onUpload(field, attachment)} onProgress={() => { }} />
537
-
538
- case 'camera':
539
- return <Camera />
540
-
541
-
542
- default:
543
- return <Input />
397
+ })}
398
+ </Col>
399
+ </Checkbox.Group>
400
+ );
401
+
402
+ // case 'checkbox':
403
+ // return <Checkbox.Group options={field.options}/>
404
+ case 'textarea':
405
+ return <TextArea rows={4} required={field.required} />;
406
+
407
+ case 'boolean':
408
+ return (
409
+ <Select style={{ width: 120 }} required={field.required}>
410
+ {[true, false].map((option, key) => (
411
+ <Option key={key} value={option}>
412
+ {option ? 'Yes' : 'No'}
413
+ </Option>
414
+ ))}
415
+ </Select>
416
+ );
417
+
418
+ case 'select':
419
+ // Handle static select options
420
+ if (Array.isArray(field.options)) {
421
+ let defaultValue = field.default ? field.default : '';
422
+
423
+ /**If there is selected Information ie, for change info if there is selected guest information
424
+ * then we will match and set a default value from the guest details
425
+ */
426
+ if (selectedInformation) {
427
+ // Get the field value dynamically from selectedInformation[0] using field.field
428
+ const fieldValue = selectedInformation[0] && selectedInformation[0][field.caption];
429
+
430
+ // Find the default value based on field value and matching DisplayMember or description
431
+ const defaultOption = field.options.find((option) => option.displayMember?.toLowerCase() === fieldValue?.toLowerCase());
432
+
433
+ // If a matching option is found, set the default value; otherwise, do not set a default value (i.e., null or undefined)
434
+ defaultValue = defaultOption ? defaultOption.valueMember : null;
435
+ }
436
+ /**In case of default selection we need to call the onchange manually */
437
+ if (defaultValue) {
438
+ onChange(field, defaultValue);
439
+ }
440
+
441
+ return (
442
+ <Select defaultValue={defaultValue} required={field.required} style={{ width: 120 }} onChange={(value) => onChange(field, value)}>
443
+ {field.options.map((option, key) => (
444
+ <Option key={key} value={option.valueMember}>
445
+ {option.displayMember}
446
+ </Option>
447
+ ))}
448
+ </Select>
449
+ );
544
450
  }
451
+ // case 'checkbox':
452
+ // return <Checkbox.Group options={field.options} />
453
+ case 'reference-select':
454
+ // If a default value is provided in the field configuration
455
+ if (field.default) {
456
+ onChange(field, field.default);
457
+ }
458
+ // Render the ReferenceSelect component
459
+
460
+ return (
461
+ <ReferenceSelect
462
+ style={{ width: 120 }}
463
+ field={field.code}
464
+ model={formContent[field.modelName]}
465
+ {...field}
466
+ onChange={(value) => onChange(field, value)}
467
+ defaultValue={field.default}
468
+ allowClear={true}
469
+ // defaultValue={'1'}
470
+ />
471
+ );
472
+
473
+ case 'datetime':
474
+ return (
475
+ <DatePicker
476
+ format={'DD/MM/YYYY'}
477
+ onChange={(record) => {
478
+ onChange(field, record.format('DD/MM/YYYY'));
479
+ }}
480
+ />
481
+ );
482
+
483
+ case 'date':
484
+ return <DatePicker format={'DD/MM/YYYY'} />;
485
+
486
+ case 'time':
487
+ return <TimePicker format={'HH:mm A'} />;
488
+
489
+ // onChange={(record) => {
490
+
491
+ // console.log(record);
492
+
493
+ // onChange(field, record.format('HH:mm A'))
494
+
495
+ // }}
496
+
497
+ case 'upload':
498
+ return (
499
+ <FileUpload
500
+ multiple={field.multiple}
501
+ maxSize={field.maxSize || 3}
502
+ callback={(attachment) => onUpload(field, attachment)}
503
+ onProgress={() => {}}
504
+ />
505
+ );
506
+
507
+ case 'camera':
508
+ return <Camera />;
509
+
510
+ default:
511
+ return <Input />;
545
512
  }
513
+ };
546
514
 
547
- // const getItemStyle = (draggableStyle, isDragging) => ({
548
- // // some basic styles to make the items look a bit nicer
549
- // userSelect: 'none',
550
- // // padding: grid,
551
- // // margin: `0 0 ${grid}px 0`,
552
- // // position: `absolute`,
553
- // // right: '40px',
554
-
555
- // // change background colour if dragging
556
- // // background: isDragging ? 'lightgreen' : 'whitesmoke',
515
+ // const getItemStyle = (draggableStyle, isDragging) => ({
516
+ // // some basic styles to make the items look a bit nicer
517
+ // userSelect: 'none',
518
+ // // padding: grid,
519
+ // // margin: `0 0 ${grid}px 0`,
520
+ // // position: `absolute`,
521
+ // // right: '40px',
557
522
 
558
- // boxShadow: isDragging ? '0px 0px 5px 5px #eeeeee' : '',
523
+ // // change background colour if dragging
524
+ // // background: isDragging ? 'lightgreen' : 'whitesmoke',
559
525
 
560
- // // styles we need to apply on draggables
561
- // ...draggableStyle
562
- // });
526
+ // boxShadow: isDragging ? '0px 0px 5px 5px #eeeeee' : '',
563
527
 
528
+ // // styles we need to apply on draggables
529
+ // ...draggableStyle
530
+ // });
564
531
 
565
- return (
566
- <>
567
- {/* <Draggable
532
+ return (
533
+ <>
534
+ {/* <Draggable
568
535
  key={`${field.caption}-${index}`}
569
536
  draggableId={`${field.caption}-${index}`}
570
537
  index={index}
@@ -582,10 +549,9 @@ function UserInput({ field, onUpload, selectedInformation, onChange, onFieldUpda
582
549
  )}
583
550
 
584
551
  > */}
585
- {isVisible === true ? (
586
- <div className="form-item-element">
587
-
588
- {/* <Button
552
+ {isVisible === true ? (
553
+ <div className="form-item-element">
554
+ {/* <Button
589
555
  size="small"
590
556
  ref={provided.innerRef}
591
557
  {...provided.dragHandleProps}
@@ -600,25 +566,25 @@ function UserInput({ field, onUpload, selectedInformation, onChange, onFieldUpda
600
566
 
601
567
  </Button> */}
602
568
 
603
-
604
- {/* Customizes the form */}
605
- <FieldCustomizer field={field} onFieldUpdate={onFieldUpdate} index={index} onFieldRemove={onFieldRemove} />
606
- {/* Customizes the form Ends */}
607
-
608
- <Form.Item {...props} name={field.field} label={field.caption} rules={[{ required: field.required, message: field.placeholder || 'Please enter ' + field.caption }]}>
609
-
610
- {inputElement(field, onChange)}
611
- {/* <InputElement field={field} /> */}
612
-
613
- </Form.Item>
614
-
615
- </div>
616
- ) : null}
617
- {/* </div>
569
+ {/* Customizes the form */}
570
+ <FieldCustomizer field={field} onFieldUpdate={onFieldUpdate} index={index} onFieldRemove={onFieldRemove} />
571
+ {/* Customizes the form Ends */}
572
+
573
+ <Form.Item
574
+ {...props}
575
+ name={field.field}
576
+ label={field.caption}
577
+ rules={[{ required: field.required, message: field.placeholder || 'Please enter ' + field.caption }]}
578
+ >
579
+ {inputElement(field, onChange)}
580
+ {/* <InputElement field={field} /> */}
581
+ </Form.Item>
582
+ </div>
583
+ ) : null}
584
+ {/* </div>
618
585
  </div>
619
586
  )}
620
587
  </Draggable> */}
621
-
622
- </>
623
- )
588
+ </>
589
+ );
624
590
  }
@@ -423,13 +423,15 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
423
423
 
424
424
  // add new model
425
425
  UsersAPI.create(values).then((result) => {
426
- // callback();
427
- if (result.success) message.success(result.message);
428
- else message.error(result.message);
429
-
430
426
  setLoading(false);
431
427
 
432
- callback();
428
+ if (result.success) {
429
+ message.success(result.message);
430
+ // close modal
431
+ callback();
432
+ } else {
433
+ message.error(result.message);
434
+ }
433
435
  });
434
436
  }
435
437
  };
@@ -605,8 +607,26 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
605
607
 
606
608
  <Col span={8}>
607
609
  {/* Mobile */}
608
- <Form.Item name="mobile" label="Mobile" rules={[{ required: true, message: 'Please enter your mobile number' }]}>
609
- <Input placeholder="Enter Mobile" maxLength={10} />
610
+ <Form.Item
611
+ name="mobile"
612
+ label="Mobile"
613
+ rules={[
614
+ { required: true, message: 'Please enter your mobile number' },
615
+ {
616
+ pattern: /^[0-9]{10}$/,
617
+ message: 'Mobile number must be exactly 10 digits',
618
+ },
619
+ ]}
620
+ >
621
+ <Input
622
+ placeholder="Enter Mobile"
623
+ maxLength={10}
624
+ onKeyPress={(e) => {
625
+ if (!/[0-9]/.test(e.key)) {
626
+ e.preventDefault();
627
+ }
628
+ }}
629
+ />
610
630
  </Form.Item>
611
631
  </Col>
612
632
  <Col span={8}>
@@ -651,7 +671,7 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
651
671
  <Form.Item label="Default Branch" name="defaultBranch" rules={[{ required: true, message: 'Please select default branch' }]}>
652
672
  <Select placeholder="Select Default Branch" onChange={setDefaultBranch}>
653
673
  {branchOptions
654
- .filter((opt) => selectedBranches.includes(Number(opt.value)))
674
+ .filter((opt) => selectedBranches.includes(Number(opt.value)))
655
675
  .map((opt) => (
656
676
  <Option key={opt.value} value={Number(opt.value)}>
657
677
  {opt.label}
@@ -365,7 +365,7 @@ const UserList = ({ model, match, relativeAdd = false, additional_queries = [],
365
365
  )}
366
366
 
367
367
  {/* Add Modal */}
368
- <Modal destroyOnClose confirmLoading={loading} visible={visible} onCancel={closeModal} footer={null}>
368
+ <Modal destroyOnClose={false} confirmLoading={loading} visible={visible} onCancel={closeModal} footer={null}>
369
369
  <model.ModalAddComponent
370
370
  match={match}
371
371
  model={model}
@@ -220,7 +220,7 @@ export default function ReportingDashboard({
220
220
  if (['reference-select', 'reference-search', 'select'].indexOf(record.type) !== -1) {
221
221
  // let model = "";
222
222
  let model = CustomModels[record.modelName];
223
-
223
+ formContent[record.modelName] = model;
224
224
  return {
225
225
  ...record,
226
226
  model,
@@ -261,7 +261,7 @@ export default function ReportingDashboard({
261
261
  getPatientDetails();
262
262
  }
263
263
 
264
- const fetchReportData = async (id, values, dbPtr, pagination) => {
264
+ const fetchReportData = async (id, values, dbPtr, pagination, paramsString) => {
265
265
  const { current, pageSize } = pagination || {};
266
266
  // If card script id is exist load that id otherwise load id
267
267
  const coreScriptId = scriptId.current ? scriptId.current : id;
@@ -270,10 +270,23 @@ export default function ReportingDashboard({
270
270
  try {
271
271
  // Prepare payload for backend: format only here
272
272
  const formattedValues = {};
273
- Object.keys(values).forEach((key) => {
274
- const val = values[key];
275
- formattedValues[key] = moment.isMoment(val) ? val.format('YYYY-MM-DD') : val;
273
+ let inputParams = [];
274
+ inputParams = JSON.parse(paramsString);
275
+ // Iterate through all keys in the values object
276
+
277
+ inputParams.forEach(({ field }) => {
278
+ const val = values[field];
279
+
280
+ // field exists in values → format & assign
281
+ if (val !== undefined) {
282
+ formattedValues[field] = moment.isMoment(val) ? val.format('YYYY-MM-DD') : val;
283
+ }
284
+ // field missing in values → set null
285
+ else {
286
+ formattedValues[field] = null;
287
+ }
276
288
  });
289
+ // });
277
290
  // Pagination Data
278
291
  const paginationData = {
279
292
  page: pagination.current || 1,
@@ -290,6 +303,7 @@ export default function ReportingDashboard({
290
303
  if (scope) {
291
304
  formBody = { body: { ...scope, ...paginationData } };
292
305
  }
306
+
293
307
  // Fetch result
294
308
  const result = await CoreScripts.getReportingLisitng(coreScriptId, formBody, dbPtr);
295
309
  // Handle both result formats
@@ -410,7 +424,7 @@ export default function ReportingDashboard({
410
424
  Object.entries(urlsToUpdate).filter(([_, value]) => value !== undefined && value !== null && value !== '')
411
425
  );
412
426
 
413
- setformContents(formContent);
427
+ setformContents((prev) => ({ ...prev, ...formContent }));
414
428
  Location.search({ ...Location.search(), ...filteredParams });
415
429
  }
416
430
 
@@ -423,7 +437,7 @@ export default function ReportingDashboard({
423
437
 
424
438
  // Call API
425
439
  try {
426
- await fetchReportData(id, values, dbPtr, paginationData);
440
+ await fetchReportData(id, values, dbPtr, paginationData, paramsString);
427
441
  } finally {
428
442
  setLoading(false);
429
443
  setCardLoading(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-soxo-bootstrap-core",
3
- "version": "2.4.25-dev.37",
3
+ "version": "2.4.25-dev.41",
4
4
  "description": "All the Core Components for you to start",
5
5
  "keywords": [
6
6
  "all in one"