@visns-studio/visns-components 2.3.3 → 2.3.5

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;
@@ -24,6 +24,7 @@ import {
24
24
  SignOut,
25
25
  Shield,
26
26
  StatisticUp,
27
+ TextAlignLeft,
27
28
  Ticket,
28
29
  Utensils,
29
30
  } from 'akar-icons';
@@ -122,8 +123,10 @@ function Navigation({
122
123
  peopleGroup: PeopleGroup,
123
124
  peopleMultiple: PeopleMultiple,
124
125
  settingsVertical: SettingsVertical,
126
+ signOut: SignOut,
125
127
  shippingboxv1: ShippingBoxV1,
126
128
  statisticUp: StatisticUp,
129
+ textAlignLeft: TextAlignLeft,
127
130
  ticket: Ticket,
128
131
  utensils: Utensils,
129
132
  };
@@ -250,9 +253,12 @@ function Navigation({
250
253
  };
251
254
 
252
255
  const currentUrl = cleanUrl(currentPage);
256
+ const navUrl = cleanUrl(nav.url)
257
+ ? cleanUrl(nav.url)
258
+ : 'dashboard';
253
259
 
254
260
  if (
255
- cleanUrl(nav.url) === currentUrl ||
261
+ navUrl === currentUrl ||
256
262
  (nav.children &&
257
263
  nav.children.some(
258
264
  (child) => cleanUrl(child.url) === currentUrl
@@ -282,9 +288,15 @@ function Navigation({
282
288
  };
283
289
  }, []);
284
290
 
285
- return layout === 'simple' ? (
291
+ return layout === 'simple' || layout === 'cms' ? (
286
292
  <div className="cwrap">
287
- <aside className={'aside aside--open'}>
293
+ <aside
294
+ className={
295
+ layout === 'cms'
296
+ ? 'aside--cms aside--cms--open'
297
+ : 'aside aside--open'
298
+ }
299
+ >
288
300
  <div className="logo">
289
301
  <Link to="/">
290
302
  <img src={logo} alt="Visns Studio CRM" />
@@ -110,6 +110,17 @@ function GenericDetail({ setting, urlParam, userProfile }) {
110
110
  return value ? 'Yes' : 'No';
111
111
  case 'latest_notes':
112
112
  return formatNoteValue();
113
+ case 'richtext':
114
+ if (value) {
115
+ const lines = value.split('\n');
116
+ return (
117
+ <>
118
+ {lines.map((line, index) => (
119
+ <p key={index}>{line}</p>
120
+ ))}
121
+ </>
122
+ );
123
+ }
113
124
  case 'total':
114
125
  return formatTotalValue();
115
126
  default:
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.3",
45
+ "version": "2.3.5",
45
46
  "description": "Various packages to assist in the development of our Custom Applications.",
46
47
  "main": "index.js",
47
48
  "scripts": {