@visns-studio/visns-components 5.10.2 → 5.10.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.
@@ -0,0 +1,19 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ const AudioPlayer = ({ audioSource }) => {
4
+ const audioRef = useRef(null);
5
+
6
+ useEffect(() => {
7
+ if (audioSource) {
8
+ audioRef.current.play();
9
+ }
10
+ }, [audioSource]);
11
+
12
+ if (!audioSource) {
13
+ return null;
14
+ }
15
+
16
+ return <audio src={audioSource} ref={audioRef} />;
17
+ };
18
+
19
+ export default AudioPlayer;
@@ -0,0 +1,37 @@
1
+ import styles from '../styles/DataGrid.module.scss';
2
+
3
+ const AutoRefreshControls = ({
4
+ ajaxSetting,
5
+ autoRefreshEnabled,
6
+ setAutoRefreshEnabled,
7
+ refreshInterval,
8
+ isRelocated = false,
9
+ }) => {
10
+ // Only show auto-refresh if the setting is present in ajaxSetting
11
+ if (!ajaxSetting || ajaxSetting.autoRefresh === undefined) {
12
+ return null;
13
+ }
14
+
15
+ const containerClass = isRelocated
16
+ ? styles.autoRefreshContainerRelocated
17
+ : styles.autoRefreshContainer;
18
+
19
+ return (
20
+ <div className={containerClass}>
21
+ <label className={styles.autoRefreshLabel}>
22
+ <input
23
+ type="checkbox"
24
+ checked={autoRefreshEnabled}
25
+ onChange={() =>
26
+ setAutoRefreshEnabled(!autoRefreshEnabled)
27
+ }
28
+ className={styles.autoRefreshCheckbox}
29
+ />
30
+ Auto Refresh{' '}
31
+ {refreshInterval && `(${refreshInterval}s)`}
32
+ </label>
33
+ </div>
34
+ );
35
+ };
36
+
37
+ export default AutoRefreshControls;
@@ -0,0 +1,238 @@
1
+ import { useNavigate } from 'react-router-dom';
2
+ import { toast } from 'react-toastify';
3
+ import { saveAs } from 'file-saver';
4
+ import {
5
+ LinkOut,
6
+ Plus,
7
+ Search,
8
+ Sort,
9
+ } from 'akar-icons';
10
+ import Download from '../Download';
11
+ import styles from '../styles/DataGrid.module.scss';
12
+
13
+ const DataGridSearch = ({
14
+ form,
15
+ search,
16
+ onSearchChange,
17
+ onModalOpen,
18
+ // Export dependencies
19
+ dataRef,
20
+ filterValue,
21
+ paramValue,
22
+ // Sort dependencies
23
+ pageData,
24
+ pageSetting,
25
+ }) => {
26
+ const navigate = useNavigate();
27
+
28
+ const handleChangeSearch = (e) => {
29
+ const { value } = e.target;
30
+ onSearchChange(value);
31
+ };
32
+
33
+ const exportTrigger = async () => {
34
+ try {
35
+ toast.success('Starting export please wait...');
36
+
37
+ let payload;
38
+
39
+ if (form.export.useData) {
40
+ payload = { data: dataRef.current };
41
+ } else {
42
+ payload = {
43
+ filter: filterValue,
44
+ paramId: paramValue || '',
45
+ };
46
+ }
47
+
48
+ const res = await Download(form.export.url, 'POST', payload);
49
+
50
+ if (res.data.error) {
51
+ toast.error(res.data.error);
52
+ } else {
53
+ // Assuming the response contains a Blob or similar data
54
+ if (res.data && res.data instanceof Blob) {
55
+ const fileName = `${form.export.filename}`;
56
+ saveAs(res.data, fileName);
57
+ } else {
58
+ // Handle the case where the response is not a Blob
59
+ toast.error('Invalid file format received.');
60
+ }
61
+ }
62
+ } catch (error) {
63
+ console.info(error);
64
+ }
65
+ };
66
+
67
+ const sortTrigger = () => {
68
+ let baseUrl = form.url.replace('/ajax', '');
69
+ let sortUrl = paramValue
70
+ ? `${baseUrl}/${paramValue}/sort`
71
+ : `${baseUrl}/sort`;
72
+
73
+ if (form.sort?.url) {
74
+ sortUrl = form.sort.url;
75
+ }
76
+
77
+ const newState = {
78
+ form,
79
+ page: {
80
+ data: pageData,
81
+ setting: pageSetting,
82
+ },
83
+ paramValue,
84
+ };
85
+
86
+ navigate(sortUrl, { state: newState });
87
+ };
88
+
89
+ const renderCreateButton = () => {
90
+ if (form.createDisable && form.createDisable === true) {
91
+ return null;
92
+ }
93
+
94
+ const isSearchEnabled = !(form.searchDisable === true);
95
+ const buttonClassName = isSearchEnabled
96
+ ? styles.actionButtons
97
+ : styles.actionButtonsStandalone;
98
+
99
+ return (
100
+ <div className={buttonClassName}>
101
+ {form.export && form.export.url && (
102
+ <button className={styles.btn} onClick={exportTrigger}>
103
+ <LinkOut
104
+ strokeWidth={2}
105
+ size={16}
106
+ style={{ marginRight: '10px' }}
107
+ />{' '}
108
+ Export
109
+ </button>
110
+ )}
111
+ {form.sort && form.sort.title && (
112
+ <button className={styles.btn} onClick={sortTrigger}>
113
+ <Sort
114
+ strokeWidth={2}
115
+ size={16}
116
+ style={{ marginRight: '10px' }}
117
+ />{' '}
118
+ Sort Order
119
+ </button>
120
+ )}
121
+
122
+ {(form.create &&
123
+ form.create.title &&
124
+ form.create.title !== '') ||
125
+ (form.url && form.create?.title !== '') ? (
126
+ <button
127
+ className={styles.btn}
128
+ onClick={(e) => {
129
+ e.preventDefault();
130
+
131
+ if (form.create) {
132
+ if (form.create.url) {
133
+ // Check if URL is external
134
+ if (
135
+ form.create.url.startsWith(
136
+ 'http://'
137
+ ) ||
138
+ form.create.url.startsWith(
139
+ 'https://'
140
+ )
141
+ ) {
142
+ window.open(
143
+ form.create.url,
144
+ '_blank'
145
+ );
146
+ } else {
147
+ navigate(form.create.url);
148
+ }
149
+ } else {
150
+ onModalOpen('create', 0);
151
+ }
152
+ } else {
153
+ if (form.url) {
154
+ window.open(
155
+ form.url,
156
+ '',
157
+ 'width=1440,height=1024,menubar=1,resizable=1,status=1,titlebar=1,toolbar=1'
158
+ );
159
+ }
160
+ }
161
+ }}
162
+ >
163
+ <Plus
164
+ strokeWidth={2}
165
+ size={16}
166
+ style={{ marginRight: '10px' }}
167
+ />
168
+ Add New
169
+ </button>
170
+ ) : form.url && form.modal === false ? (
171
+ <button
172
+ className={styles.btn}
173
+ onClick={(e) => {
174
+ e.preventDefault();
175
+
176
+ window.open(
177
+ form.url,
178
+ '',
179
+ 'width=1440,height=1024,menubar=1,resizable=1,status=1,titlebar=1,toolbar=1'
180
+ );
181
+ }}
182
+ >
183
+ <Plus
184
+ strokeWidth={2}
185
+ size={16}
186
+ style={{ marginRight: '10px' }}
187
+ />
188
+ Add New
189
+ </button>
190
+ ) : null}
191
+ </div>
192
+ );
193
+ };
194
+
195
+ const isSearchEnabled = !(form.searchDisable === true);
196
+ const isCreateDisabled = form.createDisable === true;
197
+
198
+ // Don't render anything if both search and create are disabled
199
+ if (!isSearchEnabled && isCreateDisabled) {
200
+ return null;
201
+ }
202
+
203
+ // If search is disabled but create button is enabled, render only the button with its own container
204
+ if (!isSearchEnabled && !isCreateDisabled) {
205
+ return (
206
+ <div className={styles.actionButtonsContainer}>
207
+ {renderCreateButton()}
208
+ </div>
209
+ );
210
+ }
211
+
212
+ // If search is enabled, render the full search container with both search and buttons
213
+ return (
214
+ <div className={styles.searchContainer}>
215
+ <div className={styles.searchInputWrapper}>
216
+ <div
217
+ className={styles['icon-search']}
218
+ style={{ left: 25, color: '#000' }}
219
+ >
220
+ <Search strokeWidth={2} size={14} />
221
+ </div>
222
+ <input
223
+ type="text"
224
+ placeholder="Search"
225
+ value={search}
226
+ onChange={handleChangeSearch}
227
+ style={{ borderRadius: 0, paddingLeft: 55 }}
228
+ className={styles.searchInput}
229
+ />
230
+ </div>
231
+ <div className={styles.actionButtonsWrapper}>
232
+ {!isCreateDisabled && renderCreateButton()}
233
+ </div>
234
+ </div>
235
+ );
236
+ };
237
+
238
+ export default DataGridSearch;