@visns-studio/visns-components 1.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.
@@ -0,0 +1,28 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { usePromiseTracker } from 'react-promise-tracker';
3
+
4
+ function VisnsLoader(props) {
5
+ const { promiseInProgress } = usePromiseTracker();
6
+ const [loaderStyle, setLoaderStyle] = useState({
7
+ opacity: 0,
8
+ });
9
+
10
+ useEffect(() => {
11
+ setLoaderStyle({
12
+ opacity: promiseInProgress === true ? 1 : 0,
13
+ });
14
+ }, [promiseInProgress]);
15
+
16
+ return (
17
+ <div className="preloader" style={loaderStyle}>
18
+ <div className="preloader__icn">
19
+ <div className="preloader__cut">
20
+ <div className="preloader__donut"></div>
21
+ </div>
22
+ </div>
23
+ <span>Processing Data</span>
24
+ </div>
25
+ );
26
+ }
27
+
28
+ export default VisnsLoader;
@@ -0,0 +1,76 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import SelectList from './visns-select-list';
3
+ import Select, { createFilter } from 'react-select';
4
+
5
+ function MultiSelect(props) {
6
+ const { inputValue, onChange, options, settings, multi } = props;
7
+ const [selectOptions, setSelectOptions] = useState([]);
8
+
9
+ useEffect(() => {
10
+ let _options = [];
11
+
12
+ options.forEach((a) => {
13
+ let _optionItem = {
14
+ value: a.id,
15
+ label: a.label,
16
+ };
17
+
18
+ if (a.hasOwnProperty('description')) {
19
+ _optionItem = {
20
+ ..._optionItem,
21
+ description: a.description,
22
+ };
23
+ }
24
+
25
+ if (a.hasOwnProperty('rate')) {
26
+ _optionItem = {
27
+ ..._optionItem,
28
+ rate: a.rate,
29
+ };
30
+ }
31
+
32
+ if (a.hasOwnProperty('buy_price')) {
33
+ _optionItem = {
34
+ ..._optionItem,
35
+ buy_price: a.buy_price,
36
+ };
37
+ }
38
+
39
+ if (a.hasOwnProperty('sell_price')) {
40
+ _optionItem = {
41
+ ..._optionItem,
42
+ sell_price: a.sell_price,
43
+ };
44
+ }
45
+
46
+ _options.push(_optionItem);
47
+ });
48
+
49
+ setSelectOptions(_options);
50
+ }, [options]);
51
+
52
+ return (
53
+ <Select
54
+ isClearable
55
+ isSearchable
56
+ isMulti={multi}
57
+ filterOption={createFilter({ ignoreAccents: false })}
58
+ components={{ SelectList }}
59
+ options={selectOptions}
60
+ onChange={(inputValue, action) => {
61
+ onChange(inputValue, action, settings.id);
62
+ }}
63
+ className="visns__ms"
64
+ styles={{
65
+ menu: (provided) => ({ ...provided, zIndex: 9999 }),
66
+ control: (base) => ({
67
+ ...base,
68
+ minHeight: '52px',
69
+ }),
70
+ }}
71
+ value={inputValue}
72
+ />
73
+ );
74
+ }
75
+
76
+ export default MultiSelect;
@@ -0,0 +1,202 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import { useNavigate } from 'react-router-dom';
3
+ import moment from 'moment';
4
+ import parse from 'html-react-parser';
5
+ import { TooltipWrapper } from 'react-tooltip';
6
+ import { toast } from 'react-toastify';
7
+ import { Bell, CircleX } from 'akar-icons';
8
+
9
+ import CustomFetch from './visns-fetch';
10
+
11
+ function Notification(props) {
12
+ let interval;
13
+ const navigate = useNavigate();
14
+ const wrapperRef = useRef(null);
15
+ const [containerClass] = useState('notibox');
16
+ const [divClass] = useState('notibox-item');
17
+ const [iconBellBlinkClass] = useState('cis-bell-exclamation noti');
18
+ const [iconBellClass] = useState('cis-bell-exclamation');
19
+ const [iconXClass] = useState('cis-x-circle noti-read');
20
+ const [actionClass] = useState('notibox-actions');
21
+ const [items, setItems] = useState([]);
22
+ const [show, setShow] = useState(false);
23
+ const { setSystemAuth } = props;
24
+
25
+ const fetchNotification = () => {
26
+ CustomFetch(
27
+ '/ajax/user/notifications',
28
+ 'POST',
29
+ {},
30
+ function (result) {
31
+ setItems(result.data);
32
+ },
33
+ function (error) {
34
+ if (String(error) === 'CSRF token mismatch.') {
35
+ window.open('/login');
36
+ } else {
37
+ if (error === 'Unauthenticated.') {
38
+ setSystemAuth(false);
39
+ }
40
+
41
+ toast.error(String(error));
42
+ }
43
+ }
44
+ );
45
+ };
46
+
47
+ const handleClick = (e) => {
48
+ if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
49
+ setShow(false);
50
+ }
51
+ };
52
+
53
+ const markAsRead = (e) => {
54
+ e.preventDefault();
55
+
56
+ let array = items;
57
+ let index = e.target.dataset.index;
58
+ let id = e.target.dataset.id;
59
+
60
+ if (index >= 0) {
61
+ array.splice(index, 1);
62
+ setItems(array);
63
+ }
64
+
65
+ let formData = {
66
+ id: id,
67
+ };
68
+
69
+ CustomFetch(
70
+ '/ajax/user/notification/markasread',
71
+ 'POST',
72
+ formData,
73
+ function () {
74
+ fetchNotification();
75
+ }
76
+ );
77
+ };
78
+
79
+ const markAllAsRead = (e) => {
80
+ e.preventDefault();
81
+
82
+ let array = items;
83
+ setItems([]);
84
+
85
+ {
86
+ array.map((item) => {
87
+ let formData = {
88
+ id: item.id,
89
+ };
90
+
91
+ CustomFetch(
92
+ '/ajax/user/notification/markasread',
93
+ 'POST',
94
+ formData,
95
+ function () {
96
+ fetchNotification();
97
+ }
98
+ );
99
+ });
100
+ }
101
+ };
102
+
103
+ const toggleNotification = () => {
104
+ if (show === false) {
105
+ setShow(true);
106
+ } else {
107
+ setShow(false);
108
+ }
109
+ };
110
+
111
+ const showAllNotifications = () => {
112
+ navigate('/notifications');
113
+ setShow(false);
114
+ };
115
+
116
+ useEffect(() => {
117
+ fetchNotification();
118
+
119
+ interval = setInterval(() => {
120
+ fetchNotification();
121
+ }, 60000);
122
+
123
+ document.addEventListener('mousedown', handleClick, false);
124
+
125
+ return function cleanup() {
126
+ clearInterval(interval);
127
+
128
+ document.addEventListener('mousedown', handleClick, false);
129
+ };
130
+ }, []);
131
+
132
+ return (
133
+ <TooltipWrapper content="Notifications">
134
+ <a href="#" onClick={toggleNotification}>
135
+ <Bell
136
+ size={19}
137
+ strokeWidth={2}
138
+ className={
139
+ items.length > 0 ? iconBellBlinkClass : iconBellClass
140
+ }
141
+ />
142
+ </a>
143
+
144
+ {show === true ? (
145
+ <div ref={wrapperRef}>
146
+ {items.length > 0 ? (
147
+ <div className={containerClass}>
148
+ {items.map((item, index) => (
149
+ <div className={divClass} key={item.id}>
150
+ <Bell
151
+ size={19}
152
+ strokeWidth={2}
153
+ className={iconBellClass}
154
+ />{' '}
155
+ {parse(item.data.label)}{' '}
156
+ <span>
157
+ [
158
+ {moment(item.created_at).format(
159
+ 'DD/MM - H:mma'
160
+ )}
161
+ ]
162
+ </span>{' '}
163
+ <button onClick={markAsRead}>
164
+ <CircleX
165
+ size={24}
166
+ data-id={item.id}
167
+ data-index={index}
168
+ className={iconXClass}
169
+ />
170
+ </button>
171
+ </div>
172
+ ))}
173
+ <div className={actionClass}>
174
+ <button onClick={showAllNotifications}>
175
+ View All
176
+ </button>
177
+ <button onClick={markAllAsRead}>
178
+ Clear All
179
+ </button>
180
+ </div>
181
+ </div>
182
+ ) : (
183
+ <div className={containerClass}>
184
+ <div className={divClass}>
185
+ No new notifications available.
186
+ </div>
187
+ <div className={actionClass}>
188
+ <button onClick={showAllNotifications}>
189
+ View All
190
+ </button>
191
+ </div>
192
+ </div>
193
+ )}
194
+ </div>
195
+ ) : (
196
+ <div></div>
197
+ )}
198
+ </TooltipWrapper>
199
+ );
200
+ }
201
+
202
+ export default Notification;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { FixedSizeList } from 'react-window';
3
+
4
+ function SelectList(props) {
5
+ const { options, children, maxHeight, getValue } = props;
6
+ const [value] = getValue();
7
+ const initialOffset = options.indexOf(value) * 50;
8
+
9
+ return (
10
+ <FixedSizeList
11
+ height={maxHeight}
12
+ itemCount={children.length}
13
+ itemSize={height}
14
+ initialScrollOffset={initialOffset}
15
+ >
16
+ {({ index, style }) => <div style={style}>{children[index]}</div>}
17
+ </FixedSizeList>
18
+ );
19
+ }
20
+
21
+ export default SelectList;
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+
3
+ function Select(props) {
4
+ const { className, dataOptions, inputValue, onChange, options, settings } =
5
+ props;
6
+
7
+ return (
8
+ <select
9
+ data-name={settings.id}
10
+ className={className}
11
+ onChange={onChange}
12
+ value={inputValue}
13
+ data-show={settings.show ? JSON.stringify(settings.show) : ''}
14
+ >
15
+ <option>Please select an option</option>
16
+ {options.map((item, index) => (
17
+ <option
18
+ key={settings.id + '-' + item.id}
19
+ value={item.id}
20
+ {...dataOptions[index]}
21
+ >
22
+ {item.label}
23
+ </option>
24
+ ))}
25
+ </select>
26
+ );
27
+ }
28
+
29
+ export default Select;
@@ -0,0 +1,124 @@
1
+ import React, { useState, useEffect } from 'react';
2
+
3
+ function TableFilter(props) {
4
+ const { filters, setFilters, setSettings } = props;
5
+ const [data, setData] = useState([]);
6
+
7
+ const filterTable = (e) => {
8
+ if (props.hasOwnProperty('setSettings') === true) {
9
+ setSettings((prevState) => {
10
+ if (prevState.ajaxSetting) {
11
+ let _where = [];
12
+
13
+ prevState.ajaxSetting.where.forEach((a) => {
14
+ if (a.id === e.target.dataset.id) {
15
+ let _push = true;
16
+
17
+ _where.forEach((b) => {
18
+ if (b.id === e.target.dataset.id) {
19
+ _push = false;
20
+ }
21
+ });
22
+
23
+ if (_push === true) {
24
+ _where.push({
25
+ id: e.target.dataset.id,
26
+ value: e.target.dataset.value,
27
+ });
28
+ }
29
+ } else {
30
+ _where.push(a);
31
+ }
32
+ });
33
+
34
+ let _push = true;
35
+
36
+ _where.forEach((a) => {
37
+ if (a.id === e.target.dataset.id) {
38
+ _push = false;
39
+ }
40
+ });
41
+
42
+ if (_push === true) {
43
+ _where.push({
44
+ id: e.target.dataset.id,
45
+ value: e.target.dataset.value,
46
+ });
47
+ }
48
+
49
+ return {
50
+ ...prevState,
51
+ ajaxSetting: {
52
+ ...prevState.ajaxSetting,
53
+ where: _where,
54
+ },
55
+ };
56
+ } else {
57
+ let w = prevState.where;
58
+
59
+ prevState.where.forEach((a, b) => {
60
+ if (e.target.dataset.id === a.id) {
61
+ w[b].value = e.target.dataset.value;
62
+ }
63
+ });
64
+
65
+ return { ...prevState, where: w };
66
+ }
67
+ });
68
+ }
69
+
70
+ let tempFilters = filters;
71
+
72
+ filters.map((item, index) => {
73
+ if (
74
+ e.target.dataset.hasOwnProperty('value') &&
75
+ parseInt(e.target.dataset.value) >= 0
76
+ ) {
77
+ if (parseInt(e.target.dataset.value) === parseInt(item.value)) {
78
+ tempFilters[index].class = 'subactive';
79
+ tempFilters[index].show = true;
80
+ } else {
81
+ tempFilters[index].class = '';
82
+ tempFilters[index].show = false;
83
+ }
84
+ } else {
85
+ if (e.target.dataset.id === item.id) {
86
+ tempFilters[index].class = 'subactive';
87
+ tempFilters[index].show = true;
88
+ } else {
89
+ tempFilters[index].class = '';
90
+ tempFilters[index].show = false;
91
+ }
92
+ }
93
+ });
94
+
95
+ setFilters(tempFilters);
96
+ setFilters((prevState) => [...prevState]);
97
+ };
98
+
99
+ useEffect(() => {
100
+ setData(filters);
101
+ }, [filters]);
102
+
103
+ return (
104
+ <ul>
105
+ {data.map((item, key) => (
106
+ <li key={'table-filter-' + key}>
107
+ <a
108
+ data-id={item.id}
109
+ data-value={
110
+ item.hasOwnProperty('value') ? item.value : ''
111
+ }
112
+ data-url={item.url || ''}
113
+ onClick={filterTable}
114
+ className={item.class}
115
+ >
116
+ {item.label}
117
+ </a>
118
+ </li>
119
+ ))}
120
+ </ul>
121
+ );
122
+ }
123
+
124
+ export default TableFilter;
package/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom";
3
+ import DataGrid from "./components/visns-data-grid";
4
+ import Fetch from "./components/visns-fetch";
5
+
6
+ ReactDOM.render(
7
+ <React.Fragment>
8
+ <DataGrid />
9
+ <Fetch />
10
+ </React.Fragment>,
11
+ document.getElementById("root")
12
+ );
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "dependencies": {
3
+ "@inovua/reactdatagrid-community": "^5.9.4",
4
+ "akar-icons": "^1.9.28",
5
+ "awesome-debounce-promise": "^2.1.0",
6
+ "axios": "^1.4.0",
7
+ "framer-motion": "^10.12.16",
8
+ "html-react-parser": "^4.0.0",
9
+ "lodash": "^4.17.21",
10
+ "moment": "^2.29.4",
11
+ "numeral": "^2.0.6",
12
+ "react": "^18.2.0",
13
+ "react-confirm-alert": "^3.0.6",
14
+ "react-datepicker": "^4.14.0",
15
+ "react-number-format": "^5.2.2",
16
+ "react-promise-tracker": "^2.1.1",
17
+ "react-quill": "^2.0.0",
18
+ "react-router-dom": "^6.13.0",
19
+ "react-select": "^5.7.3",
20
+ "react-toastify": "^9.1.3",
21
+ "react-toggle": "^4.1.3",
22
+ "react-tooltip": "^5.14.0",
23
+ "react-window": "^1.8.9",
24
+ "reactjs-popup": "^2.0.5"
25
+ },
26
+ "name": "@visns-studio/visns-components",
27
+ "version": "1.0.0",
28
+ "description": "Various packages to assist in the development of our Custom Applications.",
29
+ "main": "index.js",
30
+ "devDependencies": {},
31
+ "scripts": {
32
+ "test": "echo \"Error: no test specified\" && exit 1"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/visnsstudio/visns-components.git"
37
+ },
38
+ "author": "Visns Studio",
39
+ "license": "ISC",
40
+ "bugs": {
41
+ "url": "https://github.com/visnsstudio/visns-components/issues"
42
+ },
43
+ "homepage": "https://github.com/visnsstudio/visns-components#readme"
44
+ }