@visns-studio/visns-components 1.4.9 → 1.4.11

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.
@@ -12,6 +12,7 @@ import DateFilter from "@inovua/reactdatagrid-community/DateFilter";
12
12
  import ReactDataGrid from "@inovua/reactdatagrid-community";
13
13
  import { confirmAlert } from "react-confirm-alert";
14
14
  import { toast } from "react-toastify";
15
+ import Toggle from "react-toggle";
15
16
  import {
16
17
  Backspace,
17
18
  Check,
@@ -25,11 +26,14 @@ import {
25
26
  Ribbon,
26
27
  Search,
27
28
  ShippingBoxV1,
29
+ ToggleOff,
30
+ ToggleOnFill,
28
31
  TriangleAlert,
29
32
  } from "akar-icons";
30
33
 
31
34
  import "@inovua/reactdatagrid-community/index.css";
32
35
  import "react-confirm-alert/src/react-confirm-alert.css";
36
+ import "react-toggle/style.css";
33
37
 
34
38
  import CustomFetch from "../crm/visns-fetch";
35
39
  import Form from "./visns-form";
@@ -246,7 +250,11 @@ const DataGrid = ({
246
250
  };
247
251
 
248
252
  const handleReload = () => {
249
- setDataReload(dataReload + 1);
253
+ const min = 0;
254
+ const max = 999999999;
255
+ const randomNumber = Math.floor(Math.random() * (max - min + 1) + min);
256
+
257
+ setDataReload(randomNumber);
250
258
  };
251
259
 
252
260
  const onRowClick = useCallback((rowProps, event) => {
@@ -255,30 +263,45 @@ const DataGrid = ({
255
263
  cellElement
256
264
  );
257
265
 
258
- if (
259
- rowProps.columns[columnIndex].link &&
260
- rowProps.columns[columnIndex].link.url
261
- ) {
262
- if (rowProps.columns[columnIndex].link.folder) {
263
- window.location.href =
264
- rowProps.columns[columnIndex].link.url +
265
- rowProps.data[rowProps.columns[columnIndex].link.key] +
266
- "/" +
267
- rowProps.columns[columnIndex].link.folder;
266
+ let proceed = true;
267
+
268
+ columns.forEach((a, b) => {
269
+ if (
270
+ a.id === rowProps.columns[columnIndex].id &&
271
+ a.type === "toggle"
272
+ ) {
273
+ proceed = false;
274
+ }
275
+ });
276
+
277
+ if (proceed) {
278
+ if (
279
+ rowProps.columns[columnIndex].link &&
280
+ rowProps.columns[columnIndex].link.url
281
+ ) {
282
+ if (rowProps.columns[columnIndex].link.folder) {
283
+ window.location.href =
284
+ rowProps.columns[columnIndex].link.url +
285
+ rowProps.data[rowProps.columns[columnIndex].link.key] +
286
+ "/" +
287
+ rowProps.columns[columnIndex].link.folder;
288
+ } else {
289
+ navigate(
290
+ `${rowProps.columns[columnIndex].link.url}${
291
+ rowProps.data[
292
+ rowProps.columns[columnIndex].link.key
293
+ ]
294
+ }`,
295
+ {
296
+ state: {
297
+ form: form,
298
+ },
299
+ }
300
+ );
301
+ }
268
302
  } else {
269
- navigate(
270
- `${rowProps.columns[columnIndex].link.url}${
271
- rowProps.data[rowProps.columns[columnIndex].link.key]
272
- }`,
273
- {
274
- state: {
275
- form: form,
276
- },
277
- }
278
- );
303
+ modalOpen("update", rowProps.data[form.primaryKey]);
279
304
  }
280
- } else {
281
- modalOpen("update", rowProps.data[form.primaryKey]);
282
305
  }
283
306
  }, []);
284
307
 
@@ -294,6 +317,16 @@ const DataGrid = ({
294
317
  };
295
318
  }, []);
296
319
 
320
+ const sortTrigger = () => {
321
+ let _url = form.url.replace("/ajax", "");
322
+
323
+ navigate(_url + "/sort", {
324
+ state: {
325
+ form: form,
326
+ },
327
+ });
328
+ };
329
+
297
330
  /** Table Hooks */
298
331
  useEffect(() => {
299
332
  const delayedSetDSearch = debounce(() => {
@@ -1015,6 +1048,40 @@ const DataGrid = ({
1015
1048
  }
1016
1049
  },
1017
1050
  };
1051
+ case "toggle":
1052
+ return {
1053
+ ...commonProps,
1054
+ name: column.id,
1055
+ render: ({ data }) => {
1056
+ return (
1057
+ <Toggle
1058
+ name={column.id}
1059
+ checked={
1060
+ data[column.id] === 1 ? true : false
1061
+ }
1062
+ onChange={() => {
1063
+ CustomFetch(
1064
+ `/ajax/projects/toggleFeature/${data.id}`,
1065
+ "POST",
1066
+ {
1067
+ [column.id]:
1068
+ data[column.id] === 1
1069
+ ? 0
1070
+ : 1,
1071
+ },
1072
+ (res) => {
1073
+ if (res.error === "") {
1074
+ handleReload();
1075
+ } else {
1076
+ toast.error(res.error);
1077
+ }
1078
+ }
1079
+ );
1080
+ }}
1081
+ />
1082
+ );
1083
+ },
1084
+ };
1018
1085
  case "url":
1019
1086
  return {
1020
1087
  ...commonProps,
@@ -1227,6 +1294,12 @@ const DataGrid = ({
1227
1294
  />
1228
1295
  </div>
1229
1296
  <div className="filterAction--alt">
1297
+ {form.sort && form.sort.title && (
1298
+ <button className="btn" onClick={sortTrigger}>
1299
+ <div className="icon-plus"></div> Sort Order
1300
+ </button>
1301
+ )}
1302
+
1230
1303
  <button
1231
1304
  className="btn"
1232
1305
  onClick={() => {
@@ -13,23 +13,53 @@ import "react-toggle/style.css";
13
13
  import "react-quill/dist/quill.snow.css";
14
14
  import "react-datepicker/dist/react-datepicker.css";
15
15
 
16
- function Field(props) {
16
+ const Field = ({
17
+ settings,
18
+ inputValue,
19
+ inputClass,
20
+ onChange,
21
+ onChangeFile,
22
+ onChangeRicheditor,
23
+ onChangeSelect,
24
+ onChangeToggle,
25
+ setFormData,
26
+ uploadProgress,
27
+ }) => {
28
+ const quillFileInputRef = useRef(null);
29
+ const quillRef = useRef(null);
17
30
  const inputFile = useRef(null);
18
31
  const [options, setOptions] = useState([]);
19
32
  const [dataOptions, setDataOptions] = useState([]);
20
33
  const [formItemStyle, setFormItemStyle] = useState({});
21
34
  const [formItemClass, setFormItemClass] = useState("formItem");
22
- const {
23
- settings,
24
- inputValue,
25
- inputClass,
26
- onChange,
27
- onChangeFile,
28
- onChangeRicheditor,
29
- onChangeSelect,
30
- setFormData,
31
- uploadProgress,
32
- } = props;
35
+ const modules = {
36
+ toolbar: {
37
+ container: [
38
+ [{ header: [1, 2, false] }],
39
+ ["bold", "italic", "underline", "strike", "blockquote"],
40
+ [{ list: "ordered" }, { list: "bullet" }],
41
+ ["link", "image"],
42
+ ["clean"],
43
+ ],
44
+ },
45
+ };
46
+
47
+ const handleImageUpload = async (e) => {
48
+ try {
49
+ const file = e.target.files[0];
50
+ const reader = new FileReader();
51
+
52
+ reader.onload = () => {
53
+ const dataUrl = reader.result;
54
+ const range = quillRef.getEditor().getSelection();
55
+ quillRef.getEditor().insertEmbed(range.index, "image", dataUrl);
56
+ };
57
+
58
+ reader.readAsDataURL(file);
59
+ } catch (error) {
60
+ console.error("Error uploading image:", error);
61
+ }
62
+ };
33
63
 
34
64
  useEffect(() => {
35
65
  switch (settings.type) {
@@ -579,7 +609,7 @@ function Field(props) {
579
609
  ? false
580
610
  : inputValue === "on"
581
611
  ? false
582
- : inputValue
612
+ : Boolean(inputValue)
583
613
  : false
584
614
  }
585
615
  onChange={onChangeToggle}
@@ -593,14 +623,35 @@ function Field(props) {
593
623
  break;
594
624
  case "richeditor":
595
625
  htmlContainer = (
596
- <ReactQuill
597
- theme="snow"
598
- name={settings.id}
599
- onChange={(value) => {
600
- onChangeRicheditor(value, settings.id);
601
- }}
602
- value={inputValue || ""}
603
- />
626
+ <>
627
+ <input
628
+ type="file"
629
+ style={{ display: "none" }}
630
+ ref={quillFileInputRef}
631
+ onChange={handleImageUpload}
632
+ />
633
+ <ReactQuill
634
+ theme="snow"
635
+ name={settings.id}
636
+ onChange={(value) => {
637
+ onChangeRicheditor(value, settings.id);
638
+ }}
639
+ value={inputValue || ""}
640
+ modules={modules}
641
+ formats={[
642
+ "header",
643
+ "bold",
644
+ "italic",
645
+ "underline",
646
+ "strike",
647
+ "blockquote",
648
+ "list",
649
+ "bullet",
650
+ "link",
651
+ "image",
652
+ ]}
653
+ />
654
+ </>
604
655
  );
605
656
  break;
606
657
  case "image":
@@ -668,6 +719,6 @@ function Field(props) {
668
719
  })()}
669
720
  </div>
670
721
  );
671
- }
722
+ };
672
723
 
673
724
  export default Field;
@@ -34,6 +34,17 @@ function Form(props) {
34
34
  [name]: value,
35
35
  }));
36
36
 
37
+ setData((prevState) => ({
38
+ ...prevState,
39
+ slug: slugify(value),
40
+ }));
41
+ break;
42
+ case "name":
43
+ setData((prevState) => ({
44
+ ...prevState,
45
+ [name]: value,
46
+ }));
47
+
37
48
  setData((prevState) => ({
38
49
  ...prevState,
39
50
  slug: slugify(value),
@@ -72,6 +83,19 @@ function Form(props) {
72
83
  }));
73
84
  };
74
85
 
86
+ const handleChangeToggle = (e) => {
87
+ if (!e) {
88
+ return;
89
+ }
90
+
91
+ const { name, checked } = e.target;
92
+
93
+ setData((prevState) => ({
94
+ ...prevState,
95
+ [name]: checked,
96
+ }));
97
+ };
98
+
75
99
  const handleChangeFile = (e) => {
76
100
  if (e) {
77
101
  setData((prevState) => ({
@@ -337,7 +361,13 @@ function Form(props) {
337
361
  <div className="grid">
338
362
  <div className="grid__row">
339
363
  <div className="grid__full cmstitle">
340
- <h1>{data.title ? data.title : form.update.title}</h1>
364
+ <h1>
365
+ {data.title
366
+ ? data.title
367
+ : dataId !== "create"
368
+ ? form.update.title
369
+ : form.create.title}
370
+ </h1>
341
371
  <div className="cmstitle__actions">
342
372
  <button
343
373
  className="btn actionbtn"
@@ -379,6 +409,7 @@ function Form(props) {
379
409
  onChangeFile={handleChangeFile}
380
410
  onChangeRicheditor={handleChangeRicheditor}
381
411
  onChangeSelect={handleChangeSelect}
412
+ onChangeToggle={handleChangeToggle}
382
413
  setFormData={setData}
383
414
  uploadProgress={uploadProgress}
384
415
  />
@@ -270,7 +270,13 @@ const DataGrid = forwardRef(
270
270
  };
271
271
 
272
272
  const handleReload = () => {
273
- setDataReload(dataReload + 1);
273
+ const min = 0;
274
+ const max = 999999999;
275
+ const randomNumber = Math.floor(
276
+ Math.random() * (max - min + 1) + min
277
+ );
278
+
279
+ setDataReload(randomNumber);
274
280
  };
275
281
 
276
282
  const onRowClick = useCallback((rowProps, event) => {
@@ -429,7 +435,7 @@ const DataGrid = forwardRef(
429
435
  }
430
436
  };
431
437
 
432
- c.config.forEach((config) => {
438
+ c.config.forEach((config, configKey) => {
433
439
  const fieldValue = config.id.reduce((acc, id) => {
434
440
  if (acc === "") {
435
441
  return data[id];
@@ -453,7 +459,7 @@ const DataGrid = forwardRef(
453
459
  iconData.icon ? iconData.icon : null,
454
460
  iconData.alt,
455
461
  iconData.tooltipContent,
456
- `coding-${config.id[0]}`
462
+ `coding-${config.id[0]}-${configKey}`
457
463
  );
458
464
  }
459
465
  });
@@ -609,8 +615,23 @@ const DataGrid = forwardRef(
609
615
  },
610
616
  };
611
617
  case "age":
618
+ if (column.filter && column.filter.type) {
619
+ switch (column.filter.type) {
620
+ case "number":
621
+ filterEditor = NumberFilter;
622
+ break;
623
+ default:
624
+ filterEditor = null;
625
+ break;
626
+ }
627
+ } else {
628
+ filterEditor = null;
629
+ }
630
+
612
631
  return {
613
632
  ...commonProps,
633
+ type: "number",
634
+ filterEditor: filterEditor,
614
635
  name: `${column.type}.${column.id}`,
615
636
  render: ({ data }) => {
616
637
  value = column.id.reduce((acc, id) => {
@@ -655,7 +676,7 @@ const DataGrid = forwardRef(
655
676
  case "coding":
656
677
  return {
657
678
  ...commonProps,
658
- name: "audits.name",
679
+ name: `${column.type}.${column.id}`,
659
680
  sortable: false,
660
681
  render: ({ data }) => {
661
682
  if (data) {
@@ -668,7 +689,7 @@ const DataGrid = forwardRef(
668
689
  case "created_by":
669
690
  return {
670
691
  ...commonProps,
671
- name: "audits.name",
692
+ name: `${column.type}.${column.id}`,
672
693
  sortable: false,
673
694
  render: ({ data }) => {
674
695
  if (
@@ -613,6 +613,7 @@ function Field({
613
613
  ? settings.format
614
614
  : "dd-MM-yyyy"
615
615
  }
616
+ isClearable
616
617
  className={inputClass[settings.id]}
617
618
  selected={inputValue || ""}
618
619
  showMonthDropdown
@@ -632,6 +633,7 @@ function Field({
632
633
  ? settings.format
633
634
  : "dd-MM-yyyy hh:mm aa"
634
635
  }
636
+ isClearable
635
637
  showTimeSelect
636
638
  className={inputClass[settings.id]}
637
639
  selected={inputValue || null}
@@ -653,6 +655,7 @@ function Field({
653
655
  ? settings.format
654
656
  : "hh:mm aa"
655
657
  }
658
+ isClearable
656
659
  showTimeSelect
657
660
  showTimeSelectOnly
658
661
  timeIntervals={15}
package/package.json CHANGED
@@ -34,7 +34,7 @@
34
34
  "react-dom": "^17.0.1"
35
35
  },
36
36
  "name": "@visns-studio/visns-components",
37
- "version": "1.4.9",
37
+ "version": "1.4.11",
38
38
  "description": "Various packages to assist in the development of our Custom Applications.",
39
39
  "main": "index.js",
40
40
  "devDependencies": {},