@visns-studio/visns-components 1.8.4 → 2.0.0

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.
Files changed (36) hide show
  1. package/.prettierrc.json +7 -0
  2. package/components/cms/{visns-data-grid.jsx → DataGrid.jsx} +2 -2
  3. package/components/cms/DropZone.jsx +161 -0
  4. package/components/cms/Field.jsx +747 -0
  5. package/components/cms/Form.jsx +475 -0
  6. package/components/cms/sorting/{list.jsx → List.jsx} +3 -3
  7. package/components/crm/{visns-async-select.jsx → AsyncSelect.jsx} +9 -9
  8. package/components/crm/Call.jsx +220 -0
  9. package/components/crm/{visns-data-grid.jsx → DataGrid.jsx} +263 -274
  10. package/components/crm/{visns-field.jsx → Field.jsx} +5 -5
  11. package/components/crm/{visns-form.jsx → Form.jsx} +302 -205
  12. package/components/crm/{visns-multi-select.jsx → MultiSelect.jsx} +1 -1
  13. package/components/crm/{visns-navigation.jsx → Navigation.jsx} +22 -18
  14. package/components/crm/{visns-notification.jsx → Notification.jsx} +1 -1
  15. package/components/crm/TableFilter.jsx +125 -0
  16. package/components/crm/auth/Login.jsx +158 -0
  17. package/components/crm/auth/Profile.jsx +163 -0
  18. package/components/crm/auth/Reset.jsx +87 -0
  19. package/components/crm/auth/Verify.jsx +162 -0
  20. package/components/crm/generic/GenericDetail.jsx +380 -0
  21. package/components/crm/generic/GenericIndex.jsx +112 -0
  22. package/components/crm/generic/NotificationList.jsx +64 -0
  23. package/index.js +37 -19
  24. package/package.json +6 -6
  25. package/components/cms/visns-dropzone.jsx +0 -161
  26. package/components/cms/visns-field.jsx +0 -747
  27. package/components/cms/visns-form.jsx +0 -475
  28. package/components/crm/visns-call.jsx +0 -220
  29. package/components/crm/visns-table-filter.jsx +0 -153
  30. /package/components/cms/sorting/{item.jsx → Item.jsx} +0 -0
  31. /package/components/crm/{visns-autocomplete.jsx → Autocomplete.jsx} +0 -0
  32. /package/components/crm/{visns-download.jsx → Download.jsx} +0 -0
  33. /package/components/crm/{visns-fetch.jsx → Fetch.jsx} +0 -0
  34. /package/components/crm/{visns-loader.jsx → Loader.jsx} +0 -0
  35. /package/components/crm/{visns-select.jsx → Select.jsx} +0 -0
  36. /package/components/crm/{visns-select-list.jsx → SelectList.jsx} +0 -0
@@ -0,0 +1,747 @@
1
+ import React, { useState, useEffect, useRef } from "react";
2
+ import DatePicker from "react-datepicker";
3
+ import _ from "lodash";
4
+ import ReactQuill, { Quill } from "react-quill";
5
+ import ImageUploader from "quill-image-uploader";
6
+ import Toggle from "react-toggle";
7
+ import { NumericFormat, PatternFormat } from "react-number-format";
8
+ import { motion } from "framer-motion";
9
+ import { toast } from "react-toastify";
10
+
11
+ import "react-toggle/style.css";
12
+ import "react-quill/dist/quill.snow.css";
13
+ import "react-datepicker/dist/react-datepicker.css";
14
+ import "quill-image-uploader/dist/quill.imageUploader.min.css";
15
+
16
+ import CustomFetch from "../crm/Fetch";
17
+ import Select from "../crm/Select";
18
+ import MultiSelect from "../crm/MultiSelect";
19
+ import VisnsAutocomplete from "../crm/Autocomplete";
20
+ import moment from "moment";
21
+
22
+ Quill.register("modules/imageUploader", ImageUploader);
23
+
24
+ const modules = {
25
+ toolbar: {
26
+ container: [
27
+ [{ header: [1, 2, false] }],
28
+ ["bold", "italic", "underline", "strike", "blockquote"],
29
+ [{ list: "ordered" }, { list: "bullet" }],
30
+ ["link", "image"],
31
+ ["clean"],
32
+ ],
33
+ },
34
+ imageUploader: {
35
+ upload: async (file) => {
36
+ return new Promise((resolve, reject) => {
37
+ Vapor.store(file, {
38
+ progress: (progress) => {
39
+ console.info(progress * 100);
40
+ },
41
+ }).then((response) => {
42
+ CustomFetch(
43
+ "/ajax/file/upload",
44
+ "POST",
45
+ response,
46
+ function (res) {
47
+ if (res.error === "") {
48
+ resolve(res.path);
49
+ } else {
50
+ toast.error(
51
+ res.error !== undefined ? res.error : ""
52
+ );
53
+ }
54
+ }
55
+ );
56
+ });
57
+ });
58
+ },
59
+ },
60
+ };
61
+
62
+ const Field = ({
63
+ settings,
64
+ inputValue,
65
+ inputClass,
66
+ onChange,
67
+ onChangeDate,
68
+ onChangeFile,
69
+ onChangeRicheditor,
70
+ onChangeSelect,
71
+ onChangeToggle,
72
+ setFormData,
73
+ uploadProgress,
74
+ }) => {
75
+ const inputFile = useRef(null);
76
+ const [options, setOptions] = useState([]);
77
+ const [dataOptions, setDataOptions] = useState([]);
78
+ const [formItemStyle, setFormItemStyle] = useState({});
79
+ const [formItemClass, setFormItemClass] = useState("formItem");
80
+
81
+ useEffect(() => {
82
+ switch (settings.type) {
83
+ case "hidden":
84
+ setFormItemStyle({
85
+ display: "none",
86
+ });
87
+ break;
88
+ case "dropdown-ajax":
89
+ let filter = {};
90
+
91
+ if (
92
+ settings.hasOwnProperty("where") &&
93
+ settings.where.length > 0
94
+ ) {
95
+ filter = {
96
+ where: settings.where,
97
+ };
98
+ }
99
+
100
+ CustomFetch(settings.url, "POST", filter, function (result) {
101
+ setOptions(result.data);
102
+
103
+ let dataArray = [];
104
+
105
+ result.data.forEach((a) => {
106
+ let _tempObject = a;
107
+
108
+ if (!_.isEmpty(_tempObject)) {
109
+ let modifiedObject = {};
110
+
111
+ Object.keys(_tempObject).forEach(function (c) {
112
+ if (c !== "id" && c !== "label") {
113
+ modifiedObject["data-" + c] =
114
+ _tempObject[c];
115
+ }
116
+ });
117
+
118
+ dataArray.push(modifiedObject);
119
+ }
120
+ });
121
+
122
+ if (dataArray.length > 0) {
123
+ setDataOptions(dataArray);
124
+ }
125
+ });
126
+ break;
127
+ case "multi-dropdown-ajax":
128
+ let multiFilter = {};
129
+
130
+ if (
131
+ settings.hasOwnProperty("where") &&
132
+ settings.where.length > 0
133
+ ) {
134
+ multiFilter = {
135
+ where: settings.where,
136
+ };
137
+ }
138
+
139
+ CustomFetch(
140
+ settings.url,
141
+ "POST",
142
+ multiFilter,
143
+ function (result) {
144
+ setOptions(result.data);
145
+
146
+ let dataArray = [];
147
+
148
+ result.data.forEach((a) => {
149
+ let _tempObject = a;
150
+
151
+ if (!_.isEmpty(_tempObject)) {
152
+ let modifiedObject = {};
153
+
154
+ Object.keys(_tempObject).forEach(function (c) {
155
+ if (c !== "id" && c !== "label") {
156
+ modifiedObject["data-" + c] =
157
+ _tempObject[c];
158
+ }
159
+ });
160
+
161
+ dataArray.push(modifiedObject);
162
+ }
163
+ });
164
+
165
+ if (dataArray.length > 0) {
166
+ setDataOptions(dataArray);
167
+ }
168
+ }
169
+ );
170
+ break;
171
+ default:
172
+ break;
173
+ }
174
+
175
+ if (settings.size === "full") {
176
+ setFormItemClass("formItem fwItem");
177
+ }
178
+ }, [settings]);
179
+
180
+ useEffect(() => {
181
+ let filter = {};
182
+
183
+ if (settings.hasOwnProperty("child")) {
184
+ if (inputValue > 0) {
185
+ filter = {
186
+ where: [
187
+ {
188
+ id: settings.id,
189
+ value: inputValue,
190
+ },
191
+ ],
192
+ };
193
+
194
+ CustomFetch(
195
+ settings.child.url,
196
+ "POST",
197
+ filter,
198
+ function (result) {
199
+ childDropdownCallback({
200
+ id: settings.child.id,
201
+ data: result.data,
202
+ });
203
+ }
204
+ );
205
+ }
206
+ }
207
+ }, [inputValue, settings]);
208
+
209
+ useEffect(() => {
210
+ if (settings.hasOwnProperty("options")) {
211
+ if (settings.options.length > 0) {
212
+ let dataArray = [];
213
+
214
+ settings.options.forEach((a) => {
215
+ let _tempObject = a;
216
+
217
+ if (!_.isEmpty(_tempObject)) {
218
+ let modifiedObject = {};
219
+
220
+ Object.keys(_tempObject).forEach(function (c) {
221
+ if (c !== "id" && c !== "label") {
222
+ modifiedObject["data-" + c] = _tempObject[c];
223
+ }
224
+ });
225
+
226
+ dataArray.push(modifiedObject);
227
+ }
228
+ });
229
+
230
+ if (dataArray.length > 0) {
231
+ setDataOptions(dataArray);
232
+ }
233
+ }
234
+ }
235
+ }, [settings.options, settings]);
236
+
237
+ return (
238
+ <div className={formItemClass} style={formItemStyle}>
239
+ <label
240
+ className={
241
+ settings.type === "image"
242
+ ? "fi__flabel"
243
+ : settings.type === "richeditor"
244
+ ? "fi__flabel"
245
+ : "fi__label"
246
+ }
247
+ >
248
+ {(() => {
249
+ if (
250
+ settings.type === "address" ||
251
+ settings.type === "date" ||
252
+ settings.type === "datetime" ||
253
+ settings.type === "checkbox" ||
254
+ settings.type === "multi-dropdown" ||
255
+ settings.type === "multi-dropdown-ajax"
256
+ ) {
257
+ return (
258
+ <span className="fi__span prefocus">
259
+ {settings.label}{" "}
260
+ {settings.required === true ? "*" : ""}
261
+ </span>
262
+ );
263
+ }
264
+ })()}
265
+
266
+ {(() => {
267
+ if (
268
+ settings.type === "image" ||
269
+ settings.type === "richeditor"
270
+ ) {
271
+ return (
272
+ <>
273
+ {settings.label}{" "}
274
+ {settings.required === true ? "*" : ""}
275
+ </>
276
+ );
277
+ }
278
+ })()}
279
+
280
+ {(() => {
281
+ let htmlContainer;
282
+ switch (settings.type) {
283
+ case "text":
284
+ htmlContainer = (
285
+ <input
286
+ type="text"
287
+ name={settings.id}
288
+ readOnly={
289
+ settings.hasOwnProperty("readOnly")
290
+ ? settings.readOnly
291
+ : false
292
+ }
293
+ className={inputClass[settings.id]}
294
+ placeholder=" "
295
+ onChange={onChange}
296
+ value={
297
+ inputValue && inputValue !== "null"
298
+ ? inputValue
299
+ : ""
300
+ }
301
+ />
302
+ );
303
+ break;
304
+ case "json":
305
+ htmlContainer = (
306
+ <input
307
+ type="text"
308
+ name={settings.id}
309
+ data-jsonkey={settings.key}
310
+ className={inputClass[settings.id]}
311
+ placeholder=" "
312
+ onChange={onChange}
313
+ value={
314
+ inputValue && inputValue !== "null"
315
+ ? inputValue
316
+ : ""
317
+ }
318
+ />
319
+ );
320
+ break;
321
+ case "password":
322
+ htmlContainer = (
323
+ <input
324
+ type="password"
325
+ name={settings.id}
326
+ className={inputClass[settings.id]}
327
+ placeholder=" "
328
+ onChange={onChange}
329
+ value={
330
+ inputValue && inputValue !== "null"
331
+ ? inputValue
332
+ : ""
333
+ }
334
+ />
335
+ );
336
+ break;
337
+ case "phone":
338
+ htmlContainer = (
339
+ <PatternFormat
340
+ name={settings.id}
341
+ className={inputClass[settings.id]}
342
+ onValueChange={(values) => {
343
+ onChangeNumberFormat(
344
+ values,
345
+ settings.id
346
+ );
347
+ }}
348
+ format="## #### ####"
349
+ allowEmptyFormatting
350
+ mask="_"
351
+ value={
352
+ inputValue && inputValue !== "null"
353
+ ? inputValue
354
+ : ""
355
+ }
356
+ />
357
+ );
358
+ break;
359
+ case "mobile":
360
+ htmlContainer = (
361
+ <PatternFormat
362
+ className={inputClass[settings.id]}
363
+ onValueChange={(values) => {
364
+ onChangeNumberFormat(
365
+ values,
366
+ settings.id
367
+ );
368
+ }}
369
+ format="#### ### ###"
370
+ allowEmptyFormatting
371
+ mask="_"
372
+ value={
373
+ inputValue && inputValue !== "null"
374
+ ? inputValue
375
+ : ""
376
+ }
377
+ />
378
+ );
379
+ break;
380
+ case "currency":
381
+ htmlContainer = (
382
+ <NumericFormat
383
+ name={settings.id}
384
+ className={inputClass[settings.id]}
385
+ onValueChange={(values) => {
386
+ onChangeNumberFormat(
387
+ values,
388
+ settings.id
389
+ );
390
+ }}
391
+ thousandSeparator={true}
392
+ prefix={"$"}
393
+ value={
394
+ inputValue && inputValue !== "null"
395
+ ? inputValue
396
+ : ""
397
+ }
398
+ />
399
+ );
400
+ break;
401
+ case "textarea":
402
+ htmlContainer = (
403
+ <textarea
404
+ name={settings.id}
405
+ className={inputClass[settings.id]}
406
+ onChange={onChange}
407
+ value={
408
+ inputValue && inputValue !== "null"
409
+ ? inputValue
410
+ : ""
411
+ }
412
+ style={{ height: "200px" }}
413
+ ></textarea>
414
+ );
415
+ break;
416
+ case "address":
417
+ htmlContainer = (
418
+ <VisnsAutocomplete
419
+ onSelect={(place) =>
420
+ autocompleteCallback(place)
421
+ }
422
+ field={settings.id}
423
+ setFormData={setFormData}
424
+ api="pk.eyJ1IjoidmlzbnMtc3R1ZGlvIiwiYSI6ImNrbGlraW5vZDBhMDYycHBsdmk5b3ljbGQifQ.ZGUBk0PWac5GahUeVHdTpg"
425
+ inputValue={inputValue}
426
+ />
427
+ );
428
+ break;
429
+ case "dropdown":
430
+ htmlContainer = (
431
+ <Select
432
+ settings={settings}
433
+ className={inputClass[settings.id]}
434
+ onChange={onChange}
435
+ inputValue={
436
+ inputValue === null ? "" : inputValue
437
+ }
438
+ options={settings.options}
439
+ dataOptions={dataOptions}
440
+ />
441
+ );
442
+ break;
443
+ case "dropdown-ajax":
444
+ htmlContainer = (
445
+ <Select
446
+ settings={settings}
447
+ className={inputClass[settings.id]}
448
+ onChange={onChange}
449
+ inputValue={
450
+ inputValue === null ? "" : inputValue
451
+ }
452
+ options={options}
453
+ dataOptions={dataOptions}
454
+ />
455
+ );
456
+ break;
457
+ case "multi-dropdown":
458
+ htmlContainer = (
459
+ <MultiSelect
460
+ settings={settings}
461
+ className={inputClass[settings.id]}
462
+ onChange={onChangeSelect}
463
+ inputValue={
464
+ inputValue === null ? "" : inputValue
465
+ }
466
+ options={settings.options}
467
+ dataOptions={dataOptions}
468
+ />
469
+ );
470
+ break;
471
+ case "multi-dropdown-ajax":
472
+ htmlContainer = (
473
+ <MultiSelect
474
+ settings={settings}
475
+ className={inputClass[settings.id]}
476
+ onChange={onChangeSelect}
477
+ inputValue={
478
+ inputValue === null ? "" : inputValue
479
+ }
480
+ options={options}
481
+ dataOptions={dataOptions}
482
+ />
483
+ );
484
+ break;
485
+ case "file":
486
+ htmlContainer = (
487
+ <input
488
+ type="file"
489
+ name={settings.id}
490
+ className={inputClass[settings.id]}
491
+ onChange={onChangeFile}
492
+ />
493
+ );
494
+ break;
495
+
496
+ case "line-break":
497
+ htmlContainer = (
498
+ <div className="formbreak">
499
+ <span>
500
+ {settings.label}{" "}
501
+ {settings.required === true ? "*" : ""}
502
+ </span>
503
+ </div>
504
+ );
505
+ break;
506
+ case "checkbox":
507
+ htmlContainer = (
508
+ <input
509
+ type="checkbox"
510
+ name={settings.id}
511
+ className={inputClass[settings.id]}
512
+ placeholder=" "
513
+ onChange={onChange}
514
+ value={inputValue || ""}
515
+ />
516
+ );
517
+ break;
518
+ default:
519
+ htmlContainer = "";
520
+ break;
521
+ }
522
+
523
+ return htmlContainer;
524
+ })()}
525
+
526
+ {(() => {
527
+ if (
528
+ settings.type !== "address" &&
529
+ settings.type !== "date" &&
530
+ settings.type !== "datetime" &&
531
+ settings.type !== "line-break" &&
532
+ settings.type !== "checkbox" &&
533
+ settings.type !== "multi-dropdown" &&
534
+ settings.type !== "multi-dropdown-ajax" &&
535
+ settings.type !== "toggle" &&
536
+ settings.type !== "richeditor" &&
537
+ settings.type !== "image"
538
+ ) {
539
+ return (
540
+ <span className="fi__span">
541
+ {settings.label}{" "}
542
+ {settings.required === true ? "*" : ""}
543
+ </span>
544
+ );
545
+ }
546
+ })()}
547
+ </label>
548
+
549
+ {(() => {
550
+ let htmlContainer;
551
+ switch (settings.type) {
552
+ case "date":
553
+ htmlContainer = (
554
+ <DatePicker
555
+ dateFormat={
556
+ settings.format
557
+ ? settings.format
558
+ : "dd-MM-yyyy"
559
+ }
560
+ className={inputClass[settings.id]}
561
+ selected={
562
+ inputValue
563
+ ? moment(inputValue).toDate()
564
+ : ""
565
+ }
566
+ showMonthDropdown
567
+ showYearDropdown
568
+ dropdownMode="select"
569
+ onChange={(date) =>
570
+ onChangeDate(date, settings.id)
571
+ }
572
+ />
573
+ );
574
+ break;
575
+ case "datetime":
576
+ htmlContainer = (
577
+ <DatePicker
578
+ dateFormat={
579
+ settings.format
580
+ ? settings.format
581
+ : "dd-MM-yyyy hh:mm aa"
582
+ }
583
+ showTimeSelect
584
+ className={inputClass[settings.id]}
585
+ selected={
586
+ inputValue
587
+ ? moment(inputValue).toDate()
588
+ : ""
589
+ }
590
+ showMonthDropdown
591
+ showYearDropdown
592
+ dropdownMode="select"
593
+ onChange={(date) =>
594
+ onChangeDate(date, settings.id)
595
+ }
596
+ shouldCloseOnSelect={true}
597
+ />
598
+ );
599
+ break;
600
+ case "time":
601
+ htmlContainer = (
602
+ <DatePicker
603
+ dateFormat={
604
+ settings.format
605
+ ? settings.format
606
+ : "hh:mm aa"
607
+ }
608
+ showTimeSelect
609
+ showTimeSelectOnly
610
+ timeIntervals={15}
611
+ timeCaption="Time"
612
+ className={inputClass[settings.id]}
613
+ selected={
614
+ inputValue
615
+ ? moment(inputValue).toDate()
616
+ : ""
617
+ }
618
+ onChange={(date) =>
619
+ onChangeDate(date, settings.id)
620
+ }
621
+ shouldCloseOnSelect={true}
622
+ />
623
+ );
624
+ break;
625
+ case "toggle":
626
+ htmlContainer = (
627
+ <div>
628
+ <Toggle
629
+ name={settings.id}
630
+ data-show={
631
+ settings.show
632
+ ? JSON.stringify(settings.show)
633
+ : ""
634
+ }
635
+ checked={
636
+ inputValue !== undefined
637
+ ? inputValue === ""
638
+ ? false
639
+ : inputValue === "on"
640
+ ? false
641
+ : Boolean(inputValue)
642
+ : false
643
+ }
644
+ onChange={onChangeToggle}
645
+ />
646
+ <span className="fi__toggletxt">
647
+ {settings.label}{" "}
648
+ {settings.required === true ? "*" : ""}
649
+ </span>
650
+ </div>
651
+ );
652
+ break;
653
+ case "richeditor":
654
+ htmlContainer = (
655
+ <>
656
+ <ReactQuill
657
+ theme="snow"
658
+ name={settings.id}
659
+ onChange={(value) => {
660
+ onChangeRicheditor(value, settings.id);
661
+ }}
662
+ value={inputValue || ""}
663
+ modules={modules}
664
+ formats={[
665
+ "header",
666
+ "bold",
667
+ "italic",
668
+ "underline",
669
+ "strike",
670
+ "blockquote",
671
+ "list",
672
+ "bullet",
673
+ "link",
674
+ "image",
675
+ ]}
676
+ />
677
+ </>
678
+ );
679
+ break;
680
+ case "image":
681
+ htmlContainer = (
682
+ <>
683
+ <motion.div
684
+ className="progress__bar"
685
+ initial={{ width: "0%" }}
686
+ animate={{
687
+ width:
688
+ uploadProgress[settings.id] + "%",
689
+ }}
690
+ transition={{
691
+ duration: 3,
692
+ ease: [0.165, 0.84, 0.44, 1.0],
693
+ }}
694
+ />
695
+ <input
696
+ type="file"
697
+ name={settings.id}
698
+ className={inputClass[settings.id]}
699
+ onChange={onChangeFile}
700
+ ref={inputFile}
701
+ style={{ display: "none" }}
702
+ />
703
+ <div
704
+ onClick={() => {
705
+ inputFile.current.click();
706
+ }}
707
+ >
708
+ {inputValue && inputValue !== "" ? (
709
+ <>
710
+ {inputValue.file_url &&
711
+ inputValue.file_url !== "" ? (
712
+ <img
713
+ src={inputValue.file_url}
714
+ width="200"
715
+ />
716
+ ) : (
717
+ <img
718
+ src={URL.createObjectURL(
719
+ inputValue
720
+ )}
721
+ width="200"
722
+ />
723
+ )}
724
+ </>
725
+ ) : (
726
+ <div className="imageupload">
727
+ <span>
728
+ Click here to upload an image
729
+ </span>
730
+ </div>
731
+ )}
732
+ </div>
733
+ </>
734
+ );
735
+ break;
736
+ default:
737
+ htmlContainer = "";
738
+ break;
739
+ }
740
+
741
+ return htmlContainer;
742
+ })()}
743
+ </div>
744
+ );
745
+ };
746
+
747
+ export default Field;