@visns-studio/visns-components 2.3.2 → 2.3.4

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.
@@ -93,14 +93,12 @@ const loadData = async (
93
93
 
94
94
  const DataGrid = ({
95
95
  ajaxSetting,
96
- form,
97
96
  columns,
97
+ form,
98
+ gridHeight,
98
99
  settings,
99
100
  setFilterData,
100
101
  style,
101
- tableFilters,
102
- historySearch,
103
- historyUrl,
104
102
  }) => {
105
103
  const navigate = useNavigate();
106
104
 
@@ -325,7 +323,6 @@ const DataGrid = ({
325
323
 
326
324
  const sortTrigger = () => {
327
325
  const url = form.url.replace('/ajax', '');
328
- console.info(url);
329
326
  const newState = {
330
327
  form: form,
331
328
  };
@@ -1294,7 +1291,9 @@ const DataGrid = ({
1294
1291
  const [dataCount, setDataCount] = useState(0);
1295
1292
  const [gridStyle, setGridStyle] = useState({
1296
1293
  minHeight:
1297
- dataCount > 5
1294
+ gridHeight && gridHeight > 0
1295
+ ? gridHeight
1296
+ : dataCount > 5
1298
1297
  ? dataCount > 8
1299
1298
  ? windowHeight * 0.7 > 550
1300
1299
  ? windowHeight * 0.7
@@ -1311,7 +1310,9 @@ const DataGrid = ({
1311
1310
  setGridStyle((prevState) => ({
1312
1311
  ...prevState,
1313
1312
  minHeight:
1314
- dataCount > 5
1313
+ gridHeight && gridHeight > 0
1314
+ ? gridHeight
1315
+ : dataCount > 5
1315
1316
  ? dataCount > 8
1316
1317
  ? windowHeight * 0.7 > 550
1317
1318
  ? windowHeight * 0.7
@@ -1321,7 +1322,9 @@ const DataGrid = ({
1321
1322
  }));
1322
1323
 
1323
1324
  let dgHeight =
1324
- dataCount > 5
1325
+ gridHeight && gridHeight > 0
1326
+ ? gridHeight
1327
+ : dataCount > 5
1325
1328
  ? dataCount > 8
1326
1329
  ? windowHeight * 0.7 > 550
1327
1330
  ? windowHeight * 0.7
@@ -1329,7 +1332,7 @@ const DataGrid = ({
1329
1332
  : 450
1330
1333
  : 400;
1331
1334
 
1332
- let rowCount = Math.floor((dgHeight - 50) / 50);
1335
+ let rowCount = Math.floor((dgHeight - 100) / 40);
1333
1336
  setLimit(rowCount);
1334
1337
  }, [dataCount]);
1335
1338
 
@@ -1,25 +1,25 @@
1
- import React, { useState, useEffect } from "react";
2
- import CustomFetch from "../crm/Fetch";
3
- import Field from "./Field";
4
- import slugify from "react-slugify";
5
- import moment from "moment";
6
- import Reveal from "react-reveal/Reveal";
7
- import parse from "html-react-parser";
8
- import { confirmAlert } from "react-confirm-alert";
9
- import { toast } from "react-toastify";
10
- import { Copy, TrashBin } from "akar-icons";
11
-
12
- import "react-confirm-alert/src/react-confirm-alert.css";
1
+ import React, { useState, useEffect } from 'react';
2
+ import CustomFetch from '../crm/Fetch';
3
+ import Field from './Field';
4
+ import slugify from 'react-slugify';
5
+ import moment from 'moment';
6
+ import Reveal from 'react-reveal/Reveal';
7
+ import parse from 'html-react-parser';
8
+ import { confirmAlert } from 'react-confirm-alert';
9
+ import { toast } from 'react-toastify';
10
+ import { Copy, TrashBin } from 'akar-icons';
11
+
12
+ import 'react-confirm-alert/src/react-confirm-alert.css';
13
13
 
14
14
  function Form(props) {
15
- const { dataId, navigate, form, setActiveNav } = props;
15
+ const { dataId, navigate, form } = props;
16
16
  const [data, setData] = useState({});
17
17
  const [dataClass, setDataClass] = useState({});
18
18
  const [audit, setAudit] = useState({
19
19
  createdBy: {},
20
- created: "",
20
+ created: '',
21
21
  updatedBy: {},
22
- updated: "",
22
+ updated: '',
23
23
  });
24
24
  const [uploadProgress, setUploadProgress] = useState({});
25
25
 
@@ -28,7 +28,7 @@ function Form(props) {
28
28
  const { name, value } = e.target;
29
29
 
30
30
  switch (e.target.name) {
31
- case "title":
31
+ case 'title':
32
32
  setData((prevState) => ({
33
33
  ...prevState,
34
34
  [name]: value,
@@ -39,7 +39,7 @@ function Form(props) {
39
39
  slug: slugify(value),
40
40
  }));
41
41
  break;
42
- case "name":
42
+ case 'name':
43
43
  setData((prevState) => ({
44
44
  ...prevState,
45
45
  [name]: value,
@@ -118,7 +118,7 @@ function Form(props) {
118
118
  }));
119
119
  },
120
120
  }).then((response) => {
121
- if (data.hasOwnProperty("files")) {
121
+ if (data.hasOwnProperty('files')) {
122
122
  let _files = data.files;
123
123
  let _new = true;
124
124
 
@@ -184,32 +184,32 @@ function Form(props) {
184
184
  if (e) {
185
185
  e.preventDefault();
186
186
 
187
- let error = "";
188
- let url = "";
189
- let method = "";
190
- let message = "";
187
+ let error = '';
188
+ let url = '';
189
+ let method = '';
190
+ let message = '';
191
191
 
192
- if (data.title === "") {
193
- error += "Please enter a title.<br />";
192
+ if (data.title === '') {
193
+ error += 'Please enter a title.<br />';
194
194
  }
195
195
 
196
- if (data.summary === "") {
197
- error += "Please enter a summary.<br />";
196
+ if (data.summary === '') {
197
+ error += 'Please enter a summary.<br />';
198
198
  }
199
199
 
200
- if (error === "") {
201
- if (dataId === "create") {
200
+ if (error === '') {
201
+ if (dataId === 'create') {
202
202
  url = form.url;
203
- method = "POST";
204
- message = "You have successfully created a new entry.";
203
+ method = 'POST';
204
+ message = 'You have successfully created a new entry.';
205
205
  } else {
206
- url = form.url + "/" + dataId;
207
- method = "PUT";
208
- message = "You have successfully updated this entry.";
206
+ url = form.url + '/' + dataId;
207
+ method = 'PUT';
208
+ message = 'You have successfully updated this entry.';
209
209
  }
210
210
 
211
211
  CustomFetch(url, method, data, function (result) {
212
- if (result.error === "") {
212
+ if (result.error === '') {
213
213
  let _uploadProgress = uploadProgress;
214
214
 
215
215
  Object.keys(_uploadProgress).forEach((a, b) => {
@@ -221,10 +221,10 @@ function Form(props) {
221
221
 
222
222
  toast.success(message);
223
223
 
224
- if (dataId === "create") {
224
+ if (dataId === 'create') {
225
225
  navigate(
226
- form.url.replace("/ajax", "") +
227
- "/" +
226
+ form.url.replace('/ajax', '') +
227
+ '/' +
228
228
  result.data.id,
229
229
  {
230
230
  state: {
@@ -246,21 +246,21 @@ function Form(props) {
246
246
  const handleDelete = (e) => {
247
247
  if (e) {
248
248
  confirmAlert({
249
- title: "Delete this entry",
250
- message: "Are you sure you want to delete it?",
249
+ title: 'Delete this entry',
250
+ message: 'Are you sure you want to delete it?',
251
251
  buttons: [
252
252
  {
253
- label: "Yes",
253
+ label: 'Yes',
254
254
  onClick: () =>
255
255
  CustomFetch(
256
256
  `${form.url}/${dataId}`,
257
- "DELETE",
257
+ 'DELETE',
258
258
  {},
259
259
  function (result) {
260
- if (result.error === "") {
261
- navigate(form.url.replace("/ajax", ""));
260
+ if (result.error === '') {
261
+ navigate(form.url.replace('/ajax', ''));
262
262
  toast.success(
263
- "You have successfully deleted this entry."
263
+ 'You have successfully deleted this entry.'
264
264
  );
265
265
  } else {
266
266
  toast.error(result.error);
@@ -269,7 +269,7 @@ function Form(props) {
269
269
  ),
270
270
  },
271
271
  {
272
- label: "No",
272
+ label: 'No',
273
273
  onClick: () => close(),
274
274
  },
275
275
  ],
@@ -281,14 +281,14 @@ function Form(props) {
281
281
  form.fields.forEach((a) => {
282
282
  setData((prevState) => ({
283
283
  ...prevState,
284
- [a.id]: "",
284
+ [a.id]: '',
285
285
  }));
286
286
  });
287
287
 
288
- if (dataId !== "create") {
288
+ if (dataId !== 'create') {
289
289
  CustomFetch(
290
290
  `${form.url}/${dataId}`,
291
- "GET",
291
+ 'GET',
292
292
  {},
293
293
  function (result) {
294
294
  let now = moment();
@@ -306,32 +306,32 @@ function Form(props) {
306
306
  created:
307
307
  created.hours() > 24
308
308
  ? created.days() +
309
- " Days " +
309
+ ' Days ' +
310
310
  created.hours() +
311
- " Hour(s) " +
311
+ ' Hour(s) ' +
312
312
  created.minutes() +
313
- " Minutes"
313
+ ' Minutes'
314
314
  : created.hours() +
315
- " Hour(s) " +
315
+ ' Hour(s) ' +
316
316
  created.minutes() +
317
- " Minutes",
317
+ ' Minutes',
318
318
  updatedBy: result.audit_latest,
319
319
  updated:
320
320
  updated.hours() > 24
321
321
  ? updated.days() +
322
- " Days " +
322
+ ' Days ' +
323
323
  updated.hours() +
324
- " Hour(s) " +
324
+ ' Hour(s) ' +
325
325
  updated.minutes() +
326
- " Minutes"
326
+ ' Minutes'
327
327
  : updated.hours() +
328
- " Hour(s) " +
328
+ ' Hour(s) ' +
329
329
  updated.minutes() +
330
- " Minutes",
330
+ ' Minutes',
331
331
  }));
332
332
  },
333
333
  function (error) {
334
- navigate("/");
334
+ navigate('/');
335
335
 
336
336
  toast.error(String(error));
337
337
  }
@@ -341,7 +341,7 @@ function Form(props) {
341
341
 
342
342
  useEffect(() => {
343
343
  form.fields.forEach((a) => {
344
- if (a.type === "image") {
344
+ if (a.type === 'image') {
345
345
  setUploadProgress((prevState) => ({
346
346
  ...prevState,
347
347
  [a.id]: 0,
@@ -350,17 +350,16 @@ function Form(props) {
350
350
 
351
351
  setData((prevState) => ({
352
352
  ...prevState,
353
- [a.id]: "",
353
+ [a.id]: '',
354
354
  }));
355
355
 
356
356
  setDataClass((prevState) => ({
357
357
  ...prevState,
358
- [a.id]: "",
358
+ [a.id]: '',
359
359
  }));
360
360
  });
361
361
 
362
362
  fetchData();
363
- setActiveNav();
364
363
  }, [dataId]);
365
364
 
366
365
  return (
@@ -371,7 +370,7 @@ function Form(props) {
371
370
  <h1>
372
371
  {data.title
373
372
  ? data.title
374
- : dataId !== "create"
373
+ : dataId !== 'create'
375
374
  ? form.update.title
376
375
  : form.create.title}
377
376
  </h1>
@@ -380,8 +379,8 @@ function Form(props) {
380
379
  className="btn actionbtn"
381
380
  onClick={handleSubmit}
382
381
  >
383
- <Copy size={18} strokeWidth={2} />{" "}
384
- {dataId !== "create" ? "Save" : "Create"}
382
+ <Copy size={18} strokeWidth={2} />{' '}
383
+ {dataId !== 'create' ? 'Save' : 'Create'}
385
384
  </button>
386
385
  </div>
387
386
  </div>
@@ -396,19 +395,19 @@ function Form(props) {
396
395
  settings={a}
397
396
  key={
398
397
  b +
399
- "-fields-" +
400
- (a.hasOwnProperty("key")
401
- ? a.id + "-" + a.key
398
+ '-fields-' +
399
+ (a.hasOwnProperty('key')
400
+ ? a.id + '-' + a.key
402
401
  : a.id)
403
402
  }
404
403
  inputValue={
405
- a.hasOwnProperty("key")
404
+ a.hasOwnProperty('key')
406
405
  ? data[a.key]
407
406
  : Array.isArray(data[a.id]) &&
408
- a.type === "image"
407
+ a.type === 'image'
409
408
  ? data[a.id].length > 0
410
409
  ? data[a.id][0]
411
- : ""
410
+ : ''
412
411
  : data[a.id]
413
412
  }
414
413
  inputClass={dataClass}
@@ -432,7 +431,7 @@ function Form(props) {
432
431
  Created: <span>{audit.created} Ago</span>
433
432
  </li>
434
433
  <li>
435
- By:{" "}
434
+ By:{' '}
436
435
  <span>
437
436
  {audit &&
438
437
  audit.createdBy &&
@@ -445,7 +444,7 @@ function Form(props) {
445
444
  Last Update: <span>{audit.updated} Ago</span>
446
445
  </li>
447
446
  <li>
448
- by:{" "}
447
+ by:{' '}
449
448
  <span>
450
449
  {audit &&
451
450
  audit.updatedBy &&
@@ -454,13 +453,13 @@ function Form(props) {
454
453
  : null}
455
454
  </span>
456
455
  </li>
457
- {dataId !== "create" ? (
456
+ {dataId !== 'create' ? (
458
457
  <li>
459
458
  <button
460
459
  className="btn actionbtn deletebtn"
461
460
  onClick={handleDelete}
462
461
  >
463
- <TrashBin size={14} strokeWidth={2} />{" "}
462
+ <TrashBin size={14} strokeWidth={2} />{' '}
464
463
  Delete Entry
465
464
  </button>
466
465
  </li>
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { useParams, useNavigate, useLocation } from 'react-router-dom';
3
+ import Reveal from 'react-reveal/Reveal';
4
+ import CmsForm from '../Form';
5
+
6
+ import 'react-confirm-alert/src/react-confirm-alert.css';
7
+
8
+ function CmsDetail({}) {
9
+ const { dataId } = useParams();
10
+ const navigate = useNavigate();
11
+ const location = useLocation();
12
+ const { form } = location.state;
13
+
14
+ return (
15
+ <Reveal effect="fadeInUp">
16
+ <div className="grid">
17
+ <div className="grid__row">
18
+ <div className="grid__full">
19
+ <CmsForm
20
+ dataId={dataId}
21
+ navigate={navigate}
22
+ form={form}
23
+ />
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </Reveal>
28
+ );
29
+ }
30
+
31
+ export default CmsDetail;
@@ -0,0 +1,72 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { Outlet } from 'react-router-dom';
3
+ import Reveal from 'react-reveal/Reveal';
4
+ import DataGrid from '../DataGrid';
5
+
6
+ function CmsIndex({ setting, userProfile }) {
7
+ const { ajaxSetting, columns, form, filters, page, settings } = setting;
8
+
9
+ const [config, setConfig] = useState({});
10
+ const [windowHeight, setWindowHeight] = useState(window.innerHeight);
11
+ const pageTitle = page?.title;
12
+
13
+ useEffect(() => {
14
+ setConfig(() => ({
15
+ ajaxSetting,
16
+ form,
17
+ columns,
18
+ settings,
19
+ }));
20
+ }, [setting]);
21
+
22
+ useEffect(() => {
23
+ const handleResize = () => {
24
+ setWindowHeight(window.innerHeight);
25
+ };
26
+
27
+ window.addEventListener('resize', handleResize);
28
+
29
+ // Clean up the event listener
30
+ return () => {
31
+ window.removeEventListener('resize', handleResize);
32
+ };
33
+ }, []);
34
+
35
+ return (
36
+ <>
37
+ <Reveal effect="fadeInUp">
38
+ <>
39
+ <div className="grid">
40
+ <div className="grid__row">
41
+ <div className="grid__full cmstitle">
42
+ <h1>{pageTitle}</h1>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ {config.ajaxSetting &&
47
+ config.form &&
48
+ config.columns &&
49
+ config.settings && (
50
+ <div className="grid">
51
+ <div className="grid__row">
52
+ <div className="grid__full">
53
+ <DataGrid
54
+ {...config}
55
+ gridHeight={windowHeight * 0.65}
56
+ style={
57
+ userProfile?.settings?.style ||
58
+ {}
59
+ }
60
+ />
61
+ </div>
62
+ </div>
63
+ </div>
64
+ )}
65
+ <Outlet />
66
+ </>
67
+ </Reveal>
68
+ </>
69
+ );
70
+ }
71
+
72
+ export default CmsIndex;
@@ -0,0 +1,69 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { useLocation } from 'react-router-dom';
3
+ import Reveal from 'react-reveal/Reveal';
4
+ import { arrayMoveImmutable } from 'array-move';
5
+ import { toast } from 'react-toastify';
6
+ import CustomFetch from '../../crm/Fetch';
7
+ import SortableList from '../sorting/List';
8
+
9
+ function CmsSort({}) {
10
+ const location = useLocation();
11
+ const { form } = location.state;
12
+ const [data, setData] = useState([]);
13
+ const url = form.url;
14
+
15
+ const onSortEnd = ({ oldIndex, newIndex }) => {
16
+ setData((prevItem) => arrayMoveImmutable(prevItem, oldIndex, newIndex));
17
+ };
18
+
19
+ useEffect(() => {
20
+ if (data.length > 0) {
21
+ CustomFetch(
22
+ url + '/sort_update',
23
+ 'POST',
24
+ {
25
+ list: data,
26
+ },
27
+ function (result) {
28
+ if (result.error === '') {
29
+ } else {
30
+ toast.error(String(result.error));
31
+ }
32
+ }
33
+ );
34
+ }
35
+ }, [data]);
36
+
37
+ useEffect(() => {
38
+ CustomFetch(url + '/sort_list', 'POST', {}, function (result) {
39
+ setData(result);
40
+ });
41
+ }, []);
42
+
43
+ return (
44
+ <Reveal effect="fadeInUp">
45
+ <div className="grid">
46
+ <div className="grid__row">
47
+ <div className="grid__full cmstitle">
48
+ <h1>{form.sort.title}</h1>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ <div className="grid">
53
+ <div className="grid__row">
54
+ <div className="grid__full">
55
+ <SortableList
56
+ items={data}
57
+ onSortEnd={onSortEnd}
58
+ axis="xy"
59
+ helperClass="dragitem"
60
+ transitionDuration={250}
61
+ />
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </Reveal>
66
+ );
67
+ }
68
+
69
+ export default CmsSort;
@@ -163,12 +163,12 @@ function Form(props) {
163
163
 
164
164
  Object.keys(inputValue).forEach((a) => {
165
165
  if (formData.hasOwnProperty(a)) {
166
- updateFormData({
166
+ updateFormData((prevState) => ({
167
167
  [a]:
168
- prevState[a] !== ''
168
+ prevState && prevState[a] !== ''
169
169
  ? prevState[a]
170
170
  : inputValue[a],
171
- });
171
+ }));
172
172
  }
173
173
  });
174
174
 
@@ -224,20 +224,22 @@ function Form(props) {
224
224
 
225
225
  const id = e.target.dataset.jsonkey || e.target.dataset.name;
226
226
 
227
- setFormData((prevState) => ({
228
- ...prevState,
229
- [id]: e.target.checked,
230
- }));
227
+ const updateFormData = (dataToUpdate) => {
228
+ setFormData((prevState) => ({
229
+ ...prevState,
230
+ ...dataToUpdate,
231
+ }));
232
+ };
231
233
 
232
- if (id === 'same_address') {
233
- const postalData = e.target.checked
234
+ const updatePostalData = (checked) => {
235
+ const postalData = checked
234
236
  ? {
235
- postal_address1: prevState.address1,
236
- postal_address2: prevState.address2,
237
- postal_suburb: prevState.suburb,
238
- postal_postcode: prevState.postcode,
239
- postal_state: prevState.state,
240
- postal_country: prevState.country,
237
+ postal_address1: formData.address1,
238
+ postal_address2: formData.address2,
239
+ postal_suburb: formData.suburb,
240
+ postal_postcode: formData.postcode,
241
+ postal_state: formData.state,
242
+ postal_country: formData.country,
241
243
  }
242
244
  : {
243
245
  postal_address1: '',
@@ -248,10 +250,11 @@ function Form(props) {
248
250
  postal_country: '',
249
251
  };
250
252
 
251
- setFormData((prevState) => ({
252
- ...prevState,
253
- ...postalData,
254
- }));
253
+ updateFormData(postalData);
254
+ };
255
+
256
+ if (id === 'same_address') {
257
+ updatePostalData(e.target.checked);
255
258
  }
256
259
 
257
260
  if (e.target.dataset.show) {
@@ -260,28 +263,26 @@ function Form(props) {
260
263
  : [];
261
264
 
262
265
  if (_show.length > 0) {
263
- const _fields = [...formSettings.fields];
264
-
265
- _show.forEach((showObject) => {
266
- const { id, value } = showObject;
267
-
268
- if (id && value && value.length > 0) {
269
- const index = _fields.findIndex(
270
- (field) => field.id === id
266
+ const updatedFields = formSettings.fields.map((field) => {
267
+ const showObject = _show.find(
268
+ (showItem) => showItem.id === field.id
269
+ );
270
+ if (
271
+ showObject &&
272
+ showObject.value &&
273
+ showObject.value.length > 0
274
+ ) {
275
+ field.hide = !showObject.value.includes(
276
+ e.target.checked
271
277
  );
272
-
273
- if (index !== -1) {
274
- _fields[index].hide = !value.includes(
275
- e.target.checked
276
- );
277
- }
278
278
  }
279
+ return field;
279
280
  });
280
281
 
281
282
  if (updateForm) {
282
283
  updateForm((prevState) => ({
283
284
  ...prevState,
284
- fields: _fields,
285
+ fields: updatedFields,
285
286
  }));
286
287
  }
287
288
  }
@@ -776,50 +777,36 @@ function Form(props) {
776
777
  }, []);
777
778
 
778
779
  useEffect(() => {
779
- formSettings.fields.forEach((a) => {
780
- if (a.hasOwnProperty('show') && a.show.length > 0) {
781
- let _show = a.show;
782
- if (_show.length > 0) {
783
- _show.forEach((showObject) => {
784
- if (
785
- showObject.hasOwnProperty('id') &&
786
- showObject.hasOwnProperty('value')
787
- ) {
788
- if (
789
- showObject.id !== '' &&
790
- showObject.value.length > 0
791
- ) {
792
- let _fields = formSettings.fields;
793
- let _counter;
794
- _fields.forEach((a, b) => {
795
- if (a.id === showObject.id) {
796
- _counter = b;
797
- }
798
- });
780
+ formSettings.fields.forEach((field) => {
781
+ const showConditions = field.show || [];
799
782
 
800
- let _valueChecker = formData[a.id];
783
+ showConditions.forEach((showObject) => {
784
+ const { id, value } = showObject;
801
785
 
802
- if (
803
- _counter >= 0 &&
804
- showObject.value.includes(_valueChecker) ===
805
- true
806
- ) {
807
- _fields[_counter].hide = false;
808
- } else {
809
- _fields[_counter].hide = true;
810
- }
786
+ if (id !== '' && value.length > 0) {
787
+ const targetField = formSettings.fields.find(
788
+ (f) => f.id === id
789
+ );
811
790
 
812
- if (updateForm) {
813
- updateForm((prevState) => ({
814
- ...prevState,
815
- fields: _fields,
816
- }));
817
- }
791
+ if (targetField) {
792
+ const valueChecker = formData[field.id];
793
+
794
+ if (valueChecker) {
795
+ const shouldShow =
796
+ valueChecker && value.includes(valueChecker);
797
+
798
+ targetField.hide = !shouldShow;
799
+
800
+ if (updateForm) {
801
+ updateForm((prevState) => ({
802
+ ...prevState,
803
+ fields: [...formSettings.fields],
804
+ }));
818
805
  }
819
806
  }
820
- });
807
+ }
821
808
  }
822
- }
809
+ });
823
810
  });
824
811
  }, [fetchTrigger]);
825
812
 
@@ -9,18 +9,22 @@ import {
9
9
  Clipboard,
10
10
  DoubleSword,
11
11
  Draft,
12
+ Gear,
12
13
  Grid,
13
14
  Home,
14
15
  LightBulb,
15
16
  Microphone,
16
17
  Newspaper,
18
+ Paper,
17
19
  PeopleGroup,
18
20
  PeopleMultiple,
19
21
  Person,
20
22
  SettingsVertical,
23
+ ShippingBoxV1,
21
24
  SignOut,
22
25
  Shield,
23
26
  StatisticUp,
27
+ TextAlignLeft,
24
28
  Ticket,
25
29
  Utensils,
26
30
  } from 'akar-icons';
@@ -28,12 +32,21 @@ import {
28
32
  import CustomFetch from './Fetch';
29
33
  import Notification from './Notification';
30
34
 
31
- function Navigation({ logo, logout, navConfig, setSystemAuth, userProfile }) {
35
+ function Navigation({
36
+ children,
37
+ layout = 'full',
38
+ logo,
39
+ navConfig,
40
+ searchComponent,
41
+ setSystemAuth,
42
+ userProfile,
43
+ }) {
32
44
  const location = useLocation();
33
45
  const navigate = useNavigate();
34
46
  const currentPage = location.pathname.substr(1) || 'dashboard';
35
- const [navData, setNavData] = useState(navConfig);
47
+ const [isOpen, setOpen] = useState('false');
36
48
  const [isScrolled, setIsScrolled] = useState(false);
49
+ const [navData, setNavData] = useState(navConfig);
37
50
  const appNavClasses = `app-nav ${isScrolled ? 'navscrolled' : ''}`;
38
51
 
39
52
  const handleLogout = () => {
@@ -100,15 +113,20 @@ function Navigation({ logo, logout, navConfig, setSystemAuth, userProfile }) {
100
113
  clipboard: Clipboard,
101
114
  doubleSword: DoubleSword,
102
115
  draft: Draft,
116
+ gear: Gear,
103
117
  grid: Grid,
104
118
  home: Home,
105
119
  lightBulb: LightBulb,
106
120
  microphone: Microphone,
107
121
  newspaper: Newspaper,
122
+ paper: Paper,
108
123
  peopleGroup: PeopleGroup,
109
124
  peopleMultiple: PeopleMultiple,
110
125
  settingsVertical: SettingsVertical,
126
+ signOut: SignOut,
127
+ shippingboxv1: ShippingBoxV1,
111
128
  statisticUp: StatisticUp,
129
+ textAlignLeft: TextAlignLeft,
112
130
  ticket: Ticket,
113
131
  utensils: Utensils,
114
132
  };
@@ -235,9 +253,12 @@ function Navigation({ logo, logout, navConfig, setSystemAuth, userProfile }) {
235
253
  };
236
254
 
237
255
  const currentUrl = cleanUrl(currentPage);
256
+ const navUrl = cleanUrl(nav.url)
257
+ ? cleanUrl(nav.url)
258
+ : 'dashboard';
238
259
 
239
260
  if (
240
- cleanUrl(nav.url) === currentUrl ||
261
+ navUrl === currentUrl ||
241
262
  (nav.children &&
242
263
  nav.children.some(
243
264
  (child) => cleanUrl(child.url) === currentUrl
@@ -267,7 +288,73 @@ function Navigation({ logo, logout, navConfig, setSystemAuth, userProfile }) {
267
288
  };
268
289
  }, []);
269
290
 
270
- return (
291
+ return layout === 'simple' || layout === 'cms' ? (
292
+ <div className="cwrap">
293
+ <aside
294
+ className={
295
+ layout === 'cms'
296
+ ? 'aside--cms aside--cms--open'
297
+ : 'aside aside--open'
298
+ }
299
+ >
300
+ <div className="logo">
301
+ <Link to="/">
302
+ <img src={logo} alt="Visns Studio CRM" />
303
+ </Link>
304
+ </div>
305
+ <div className="awrap">
306
+ <nav className="navwrap">
307
+ <ul className={appNavClasses}>
308
+ {navData.navigations.map((nav, navKey) =>
309
+ nav.permission === true ||
310
+ nav.permissionKey === '' ? (
311
+ <React.Fragment key={`nav-item-${navKey}`}>
312
+ {renderNav(nav)}
313
+ </React.Fragment>
314
+ ) : null
315
+ )}
316
+ </ul>
317
+ </nav>
318
+ </div>
319
+ </aside>
320
+ <main className="content">
321
+ <div className="content-header">
322
+ {searchComponent}
323
+ <div className="content-title">
324
+ <button
325
+ className={
326
+ isOpen ? 'mobmenu' : 'mobmenu mobmenu--open'
327
+ }
328
+ onClick={() => {
329
+ setOpen(!isOpen);
330
+ }}
331
+ >
332
+ <span></span>
333
+ <span></span>
334
+ <span></span>
335
+ <span></span>
336
+ <span></span>
337
+ <span></span>
338
+ </button>
339
+ </div>
340
+ <div className="hactions">
341
+ <ul>
342
+ {navData.settings.map((setting, settingKey) =>
343
+ setting.permission === true ? (
344
+ <React.Fragment
345
+ key={`setting-${settingKey}`}
346
+ >
347
+ {renderSetting(setting)}
348
+ </React.Fragment>
349
+ ) : null
350
+ )}
351
+ </ul>
352
+ </div>
353
+ </div>
354
+ {children}
355
+ </main>
356
+ </div>
357
+ ) : (
271
358
  <header className="header">
272
359
  <div className="hwrap">
273
360
  <div className="logo">
@@ -3,8 +3,8 @@ import { Outlet } from 'react-router-dom';
3
3
  import Table from '../DataGrid';
4
4
  import TableFilter from '../TableFilter';
5
5
 
6
- function GenericIndex({ setting, userProfile }) {
7
- const { filters, page, tabs, ajaxSetting, form, columns, settings } =
6
+ function GenericIndex({ layout = 'full', setting, userProfile }) {
7
+ const { ajaxSetting, columns, form, filters, page, settings, tabs } =
8
8
  setting;
9
9
 
10
10
  const [config, setConfig] = useState({});
@@ -27,7 +27,7 @@ function GenericIndex({ setting, userProfile }) {
27
27
  }, [setting]);
28
28
 
29
29
  useEffect(() => {
30
- if (tabs && tabs.length > 0) {
30
+ if (tabs && tabs.length > 0 && subnav) {
31
31
  const activeTab = subnav.find((s) => s.show === true);
32
32
 
33
33
  if (activeTab) {
@@ -81,25 +81,64 @@ function GenericIndex({ setting, userProfile }) {
81
81
  <div className="grid">
82
82
  {subnav && subnav.length > 0 ? (
83
83
  <div className="grid__subrow">
84
- <div className="grid__subnav">
85
- <TableFilter
86
- filters={subnav}
87
- setFilters={setSubnav}
88
- setSettings={setConfig}
89
- />
90
- </div>
91
- <div className="grid__subcontent">
92
- <Table
93
- {...config}
94
- gridHeight={windowHeight * 0.65}
95
- setConfig={setConfig}
96
- setTotal={setTotal}
97
- style={
98
- userProfile?.settings?.style ||
99
- {}
100
- }
101
- />
102
- </div>
84
+ {layout === 'full' ? (
85
+ <>
86
+ <div className={`grid__subnav`}>
87
+ <TableFilter
88
+ filters={subnav}
89
+ setFilters={setSubnav}
90
+ setSettings={setConfig}
91
+ type={layout}
92
+ />
93
+ </div>
94
+ <div className={`grid__subcontent`}>
95
+ <Table
96
+ {...config}
97
+ gridHeight={
98
+ windowHeight * 0.65
99
+ }
100
+ setConfig={setConfig}
101
+ setTotal={setTotal}
102
+ style={
103
+ userProfile?.settings
104
+ ?.style || {}
105
+ }
106
+ />
107
+ </div>
108
+ </>
109
+ ) : (
110
+ <div className="grid__full">
111
+ <div className="tabcontent">
112
+ <div
113
+ className={`tabcontent__menu`}
114
+ >
115
+ <TableFilter
116
+ filters={subnav}
117
+ setFilters={setSubnav}
118
+ setSettings={setConfig}
119
+ type={layout}
120
+ />
121
+ </div>
122
+ <div
123
+ className={`tabcontent__main`}
124
+ >
125
+ <Table
126
+ {...config}
127
+ gridHeight={
128
+ windowHeight * 0.65
129
+ }
130
+ setConfig={setConfig}
131
+ setTotal={setTotal}
132
+ style={
133
+ userProfile
134
+ ?.settings
135
+ ?.style || {}
136
+ }
137
+ />
138
+ </div>
139
+ </div>
140
+ </div>
141
+ )}
103
142
  </div>
104
143
  ) : (
105
144
  <div className="grid__full">
package/index.js CHANGED
@@ -27,7 +27,12 @@ import Profile from './components/crm/auth/Profile';
27
27
  import Reset from './components/crm/auth/Reset';
28
28
  import Verify from './components/crm/auth/Verify';
29
29
 
30
- /** Generic Components */
30
+ /** CMS Generic Components */
31
+ import CmsDetail from './components/cms/generic/CmsDetail';
32
+ import CmsIndex from './components/cms/generic/CmsIndex';
33
+ import CmsSort from './components/cms/generic/CmsSort';
34
+
35
+ /** CRM Generic Components */
31
36
  import GenericDetail from './components/crm/generic/GenericDetail';
32
37
  import GenericIndex from './components/crm/generic/GenericIndex';
33
38
  import NotificationList from './components/crm/generic/NotificationList';
@@ -36,7 +41,10 @@ export {
36
41
  AsyncSelect,
37
42
  Autocomplete,
38
43
  Call,
44
+ CmsDetail,
39
45
  CmsForm,
46
+ CmsIndex,
47
+ CmsSort,
40
48
  CustomFetch,
41
49
  DataGrid,
42
50
  Download,
package/package.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "@inovua/reactdatagrid-community": "^5.10.2",
4
4
  "add": "^2.0.6",
5
5
  "akar-icons": "^1.9.28",
6
+ "array-move": "^4.0.0",
6
7
  "awesome-debounce-promise": "^2.1.0",
7
8
  "axios": "^1.4.0",
8
9
  "framer-motion": "^10.15.1",
@@ -41,7 +42,7 @@
41
42
  "react-dom": "^17.0.1"
42
43
  },
43
44
  "name": "@visns-studio/visns-components",
44
- "version": "2.3.2",
45
+ "version": "2.3.4",
45
46
  "description": "Various packages to assist in the development of our Custom Applications.",
46
47
  "main": "index.js",
47
48
  "scripts": {