@visns-studio/visns-components 5.5.6 → 5.5.8

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.
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "@nivo/line": "^0.88.0",
10
10
  "@nivo/pie": "^0.88.0",
11
11
  "@tinymce/tinymce-react": "^6.1.0",
12
- "@vitejs/plugin-react": "^4.4.0",
12
+ "@vitejs/plugin-react": "^4.4.1",
13
13
  "add": "^2.0.6",
14
14
  "akar-icons": "^1.9.31",
15
15
  "array-move": "^4.0.0",
@@ -19,12 +19,12 @@
19
19
  "dayjs": "^1.11.13",
20
20
  "fabric": "^6.6.4",
21
21
  "file-saver": "^2.0.5",
22
- "framer-motion": "^11.18.2",
22
+ "framer-motion": "^12.7.4",
23
23
  "html-react-parser": "^5.2.3",
24
24
  "lodash": "^4.17.21",
25
25
  "lodash.debounce": "^4.0.8",
26
26
  "moment": "^2.30.1",
27
- "motion": "^10.18.0",
27
+ "motion": "^12.7.4",
28
28
  "numeral": "^2.0.6",
29
29
  "pluralize": "^8.0.0",
30
30
  "qrcode.react": "^4.2.0",
@@ -33,7 +33,7 @@
33
33
  "react-color": "^2.19.3",
34
34
  "react-confirm-alert": "^3.0.6",
35
35
  "react-copy-to-clipboard": "^5.1.0",
36
- "react-datepicker": "^7.6.0",
36
+ "react-datepicker": "^8.3.0",
37
37
  "react-dropzone": "^14.3.8",
38
38
  "react-grid-gallery": "^1.0.1",
39
39
  "react-number-format": "^5.4.4",
@@ -46,8 +46,8 @@
46
46
  "react-signature-pad-wrapper": "^4.1.0",
47
47
  "react-slugify": "^4.0.1",
48
48
  "react-sortable-hoc": "^2.0.0",
49
- "react-to-print": "^2.15.1",
50
- "react-toastify": "^10.0.6",
49
+ "react-to-print": "^3.0.6",
50
+ "react-toastify": "^11.0.5",
51
51
  "react-toggle": "^4.1.3",
52
52
  "react-tooltip": "^5.28.1",
53
53
  "react-window": "^1.8.11",
@@ -56,7 +56,7 @@
56
56
  "swapy": "^1.0.5",
57
57
  "sweetalert2": "^11.19.1",
58
58
  "truncate": "^3.0.0",
59
- "uuid": "^10.0.0",
59
+ "uuid": "^11.1.0",
60
60
  "validator": "^13.15.0",
61
61
  "vite": "^5.4.18",
62
62
  "yarn": "^1.22.22",
@@ -67,8 +67,8 @@
67
67
  "@babel/plugin-transform-runtime": "^7.26.10",
68
68
  "@babel/preset-env": "^7.26.9",
69
69
  "@babel/preset-react": "^7.26.3",
70
- "babel-loader": "^9.2.1",
71
- "copy-webpack-plugin": "^12.0.2",
70
+ "babel-loader": "^10.0.0",
71
+ "copy-webpack-plugin": "^13.0.0",
72
72
  "css-loader": "^7.1.2",
73
73
  "css-minimizer-webpack-plugin": "^7.0.2",
74
74
  "mini-css-extract-plugin": "^2.9.2",
@@ -82,7 +82,7 @@
82
82
  "react-dom": "^17.0.0 || ^18.0.0"
83
83
  },
84
84
  "name": "@visns-studio/visns-components",
85
- "version": "5.5.6",
85
+ "version": "5.5.8",
86
86
  "description": "Various packages to assist in the development of our Custom Applications.",
87
87
  "main": "src/index.js",
88
88
  "files": [
@@ -103,5 +103,5 @@
103
103
  "url": "https://github.com/visnsstudio/visns-components/issues"
104
104
  },
105
105
  "homepage": "https://github.com/visnsstudio/visns-components#readme",
106
- "packageManager": "yarn@4.7.0"
106
+ "packageManager": "yarn@4.8.1"
107
107
  }
@@ -223,7 +223,47 @@ function VisnsAsyncSelect({
223
223
  minHeight:
224
224
  style && style.multi_select_height
225
225
  ? style.multi_select_height
226
- : '52px',
226
+ : '50px',
227
+ height: 'auto', // Allow height to grow with content
228
+ }),
229
+ valueContainer: (base) => ({
230
+ ...base,
231
+ padding: '2px 8px',
232
+ display: 'flex',
233
+ alignItems: 'flex-start',
234
+ flexWrap: 'wrap',
235
+ maxHeight: '100px', // Set a max height
236
+ overflowY: 'auto', // Add scrolling when needed
237
+ }),
238
+ indicatorsContainer: (base) => ({
239
+ ...base,
240
+ height: 'auto',
241
+ display: 'flex',
242
+ alignItems: 'center',
243
+ alignSelf: 'stretch', // Stretch to full height of container
244
+ }),
245
+ dropdownIndicator: (base) => ({
246
+ ...base,
247
+ padding: '8px',
248
+ display: 'flex',
249
+ alignItems: 'center',
250
+ alignSelf: 'stretch', // Stretch to full height
251
+ }),
252
+ clearIndicator: (base) => ({
253
+ ...base,
254
+ padding: '8px',
255
+ display: 'flex',
256
+ alignItems: 'center',
257
+ alignSelf: 'stretch', // Stretch to full height
258
+ }),
259
+ indicatorSeparator: (base) => ({
260
+ ...base,
261
+ alignSelf: 'stretch', // Stretch to full height
262
+ margin: '4px 0',
263
+ }),
264
+ multiValue: (base) => ({
265
+ ...base,
266
+ margin: '2px',
227
267
  }),
228
268
  input: (styles) => ({
229
269
  ...styles,
@@ -1,4 +1,5 @@
1
1
  import '../styles/global.css';
2
+ import './styles/global-datagrid.css';
2
3
 
3
4
  import React, {
4
5
  forwardRef,
@@ -53,6 +54,7 @@ import {
53
54
  LinkOut,
54
55
  LockOn,
55
56
  Network,
57
+ Plus,
56
58
  Ribbon,
57
59
  Search,
58
60
  ShippingBoxV1,
@@ -1081,15 +1083,36 @@ const DataGrid = forwardRef(
1081
1083
  return null;
1082
1084
  }
1083
1085
 
1086
+ const isSearchEnabled = !(form.searchDisable === true);
1087
+ const buttonClassName = isSearchEnabled
1088
+ ? styles.actionButtons
1089
+ : styles.actionButtonsStandalone;
1090
+
1084
1091
  return (
1085
- <div className={styles['filterAction--alt']}>
1092
+ <div className={buttonClassName}>
1086
1093
  {form.export && form.export.url && (
1087
- <button className={styles.btn} onClick={exportTrigger}>
1094
+ <button
1095
+ className={styles.btn}
1096
+ style={{
1097
+ borderRadius: isSearchEnabled
1098
+ ? 0
1099
+ : 'var(--br, 4px)',
1100
+ }}
1101
+ onClick={exportTrigger}
1102
+ >
1088
1103
  Export
1089
1104
  </button>
1090
1105
  )}
1091
1106
  {form.sort && form.sort.title && (
1092
- <button className={styles.btn} onClick={sortTrigger}>
1107
+ <button
1108
+ className={styles.btn}
1109
+ style={{
1110
+ borderRadius: isSearchEnabled
1111
+ ? 0
1112
+ : 'var(--br, 4px)',
1113
+ }}
1114
+ onClick={sortTrigger}
1115
+ >
1093
1116
  <div className="icon-plus"></div> Sort Order
1094
1117
  </button>
1095
1118
  )}
@@ -1100,6 +1123,11 @@ const DataGrid = forwardRef(
1100
1123
  (form.url && form.create?.title !== '') ? (
1101
1124
  <button
1102
1125
  className={styles.btn}
1126
+ style={{
1127
+ borderRadius: isSearchEnabled
1128
+ ? 0
1129
+ : 'var(--br, 4px)',
1130
+ }}
1103
1131
  onClick={(e) => {
1104
1132
  e.preventDefault();
1105
1133
 
@@ -1135,11 +1163,21 @@ const DataGrid = forwardRef(
1135
1163
  }
1136
1164
  }}
1137
1165
  >
1138
- <div className="icon-plus"></div> Create
1166
+ <Plus
1167
+ strokeWidth={2}
1168
+ size={16}
1169
+ style={{ marginRight: '10px' }}
1170
+ />
1171
+ Add New
1139
1172
  </button>
1140
1173
  ) : form.url && form.modal === false ? (
1141
1174
  <button
1142
1175
  className={styles.btn}
1176
+ style={{
1177
+ borderRadius: isSearchEnabled
1178
+ ? 0
1179
+ : 'var(--br, 4px)',
1180
+ }}
1143
1181
  onClick={(e) => {
1144
1182
  e.preventDefault();
1145
1183
 
@@ -1150,7 +1188,12 @@ const DataGrid = forwardRef(
1150
1188
  );
1151
1189
  }}
1152
1190
  >
1153
- <div className="icon-plus"></div> Create
1191
+ <Plus
1192
+ strokeWidth={2}
1193
+ size={16}
1194
+ style={{ marginRight: '10px' }}
1195
+ />
1196
+ Add New
1154
1197
  </button>
1155
1198
  ) : null}
1156
1199
  </div>
@@ -1161,34 +1204,46 @@ const DataGrid = forwardRef(
1161
1204
  const isSearchEnabled = !(form.searchDisable === true);
1162
1205
  const isCreateDisabled = form.createDisable === true;
1163
1206
 
1164
- if (isSearchEnabled) {
1207
+ // Don't render anything if both search and create are disabled
1208
+ if (!isSearchEnabled && isCreateDisabled) {
1209
+ return null;
1210
+ }
1211
+
1212
+ // If search is disabled but create button is enabled, render only the button with its own container
1213
+ if (!isSearchEnabled && !isCreateDisabled) {
1165
1214
  return (
1166
- <div className={styles['filterInput--alt']}>
1167
- <div className={styles['icon-search']}>
1168
- <Search strokeWidth={2} size={18} />
1215
+ <div className={styles.actionButtonsContainer}>
1216
+ {renderCreateButton()}
1217
+ </div>
1218
+ );
1219
+ }
1220
+
1221
+ // If search is enabled, render the full search container with both search and buttons
1222
+ return (
1223
+ <div className={styles.searchContainer}>
1224
+ <div className={styles.searchInputWrapper}>
1225
+ <div
1226
+ className={styles['icon-search']}
1227
+ style={{ left: 25, opacity: 0.5 }}
1228
+ >
1229
+ <Search strokeWidth={1} size={14} />
1169
1230
  </div>
1170
1231
  <input
1171
1232
  type="text"
1172
1233
  placeholder="Search"
1173
1234
  value={search}
1174
1235
  onChange={handleChangeSearch}
1236
+ style={{ borderRadius: 0, paddingLeft: 55 }}
1237
+ className={styles.searchInput}
1175
1238
  />
1176
1239
  </div>
1177
- );
1178
- } else if (!isCreateDisabled) {
1179
- return (
1180
- <div
1181
- className={styles['filterInput--alt']}
1182
- style={{
1183
- height: style.data_grid_search_height
1184
- ? style.data_grid_search_height
1185
- : '58px',
1186
- }}
1187
- ></div>
1188
- );
1189
- }
1190
-
1191
- return null; // Return null if neither search is enabled nor create is disabled
1240
+ {!isCreateDisabled && (
1241
+ <div className={styles.actionButtonsWrapper}>
1242
+ {renderCreateButton()}
1243
+ </div>
1244
+ )}
1245
+ </div>
1246
+ );
1192
1247
  };
1193
1248
 
1194
1249
  const renderRowContextMenu = useCallback(
@@ -3078,11 +3133,25 @@ const DataGrid = forwardRef(
3078
3133
  }, []);
3079
3134
 
3080
3135
  return (
3081
- <>
3082
- {renderSearch()}
3083
- {renderCreateButton()}
3084
- {limit && limit > 0 ? (
3085
- <>
3136
+ <div
3137
+ style={{
3138
+ display: 'flex',
3139
+ flexDirection: 'column',
3140
+ border: 'none',
3141
+ borderRadius: '0',
3142
+ overflow: 'hidden',
3143
+ }}
3144
+ >
3145
+ {/* Search and action buttons container - separated from the DataGrid */}
3146
+ {renderSearch() && (
3147
+ <div className={styles.dataGridTopContainer}>
3148
+ {renderSearch()}
3149
+ </div>
3150
+ )}
3151
+
3152
+ {/* DataGrid container with its own border */}
3153
+ <div className={styles.dataGridContainer}>
3154
+ {limit && limit > 0 ? (
3086
3155
  <ReactDataGrid
3087
3156
  {...tableSetting}
3088
3157
  columns={gridColumns}
@@ -3124,10 +3193,15 @@ const DataGrid = forwardRef(
3124
3193
  }
3125
3194
  : null
3126
3195
  }
3127
- style={gridStyle}
3196
+ style={{
3197
+ ...gridStyle,
3198
+ border: '1px solid #d1d5db',
3199
+ borderRadius: 'var(--br, 4px)',
3200
+ overflow: 'hidden',
3201
+ }}
3128
3202
  />
3129
- </>
3130
- ) : null}
3203
+ ) : null}
3204
+ </div>
3131
3205
  {audioSource && <audio src={audioSource} ref={audioRef} />}
3132
3206
  <Popup
3133
3207
  open={modalShow}
@@ -3373,7 +3447,7 @@ const DataGrid = forwardRef(
3373
3447
  index={lightboxIndex}
3374
3448
  slides={galleryData.map((img) => ({ src: img.src }))}
3375
3449
  />
3376
- </>
3450
+ </div>
3377
3451
  );
3378
3452
  }
3379
3453
  );
@@ -108,6 +108,7 @@ function MultiSelect({
108
108
  filterOption={createFilter({ ignoreAccents: false })}
109
109
  components={{ SelectList }}
110
110
  options={selectOptions}
111
+ menuPortalTarget={document.body}
111
112
  onChange={(inputValue, action) => {
112
113
  // Special handling for limit=1: keep only the most recent selection
113
114
  if (
@@ -130,13 +131,60 @@ function MultiSelect({
130
131
  }
131
132
  classNamePrefix="visns-select"
132
133
  styles={{
133
- menu: (provided) => ({ ...provided, zIndex: 9999 }),
134
+ menu: (provided) => ({
135
+ ...provided,
136
+ zIndex: 99999,
137
+ }),
138
+ menuPortal: (base) => ({
139
+ ...base,
140
+ zIndex: 99999,
141
+ }),
134
142
  control: (base) => ({
135
143
  ...base,
136
144
  minHeight:
137
145
  style && style.multi_select_height
138
146
  ? style.multi_select_height
139
- : '52px',
147
+ : '50px',
148
+ height: 'auto', // Allow height to grow with content
149
+ }),
150
+ valueContainer: (base) => ({
151
+ ...base,
152
+ padding: '2px 8px',
153
+ display: 'flex',
154
+ alignItems: 'flex-start',
155
+ flexWrap: 'wrap',
156
+ maxHeight: '100px', // Set a max height
157
+ overflowY: 'auto', // Add scrolling when needed
158
+ }),
159
+ indicatorsContainer: (base) => ({
160
+ ...base,
161
+ height: 'auto',
162
+ display: 'flex',
163
+ alignItems: 'center',
164
+ alignSelf: 'stretch', // Stretch to full height of container
165
+ }),
166
+ dropdownIndicator: (base) => ({
167
+ ...base,
168
+ padding: '8px',
169
+ display: 'flex',
170
+ alignItems: 'center',
171
+ alignSelf: 'stretch', // Stretch to full height
172
+ }),
173
+ clearIndicator: (base) => ({
174
+ ...base,
175
+ padding: '8px',
176
+ display: 'flex',
177
+ alignItems: 'center',
178
+ alignSelf: 'stretch', // Stretch to full height
179
+ }),
180
+ indicatorSeparator: (base) => ({
181
+ ...base,
182
+ alignSelf: 'stretch', // Stretch to full height
183
+ margin: '4px 0',
184
+ }),
185
+ multiValue: (base) => ({
186
+ ...base,
187
+ margin: '2px',
140
188
  }),
141
189
  }}
142
190
  value={selectValue}
@@ -337,7 +337,17 @@ function Navigation({
337
337
  );
338
338
  };
339
339
 
340
- const getFirstRolePermissions = () => {
340
+ const getUserPermissions = () => {
341
+ // First check if userProfile has direct permissions
342
+ if (
343
+ userProfile.permissions &&
344
+ Array.isArray(userProfile.permissions) &&
345
+ userProfile.permissions.length > 0
346
+ ) {
347
+ return userProfile.permissions.map((permission) => permission.name);
348
+ }
349
+
350
+ // Fall back to role-based permissions if direct permissions don't exist
341
351
  if (
342
352
  userProfile.roles &&
343
353
  userProfile.roles.length > 0 &&
@@ -351,7 +361,7 @@ function Navigation({
351
361
  };
352
362
 
353
363
  useEffect(() => {
354
- const permissions = getFirstRolePermissions();
364
+ const permissions = getUserPermissions();
355
365
 
356
366
  setNavData((prevNavData) => {
357
367
  const updatePermissions = (nav) => {