@visns-studio/visns-components 5.5.7 → 5.5.9

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.7",
85
+ "version": "5.5.9",
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(
@@ -1508,14 +1563,17 @@ const DataGrid = forwardRef(
1508
1563
  500
1509
1564
  );
1510
1565
 
1511
- const getDropdownData = async (ids, url, fields) => {
1566
+ const getDropdownData = async (ids, url, fields, where) => {
1512
1567
  // Concatenate id array into a single string if it's an array
1513
1568
  const uniqueId = Array.isArray(ids) ? ids.join('') : ids;
1514
1569
 
1515
1570
  // Return a promise that includes the concatenated uniqueId in the resolution
1516
1571
  return new Promise(async (resolve, reject) => {
1517
1572
  try {
1518
- const res = await CustomFetch(url, 'POST', { fields });
1573
+ const res = await CustomFetch(url, 'POST', {
1574
+ fields,
1575
+ where,
1576
+ });
1519
1577
  resolve({ [uniqueId]: res.data.data }); // Correctly use uniqueId as the key
1520
1578
  } catch (err) {
1521
1579
  console.error(err);
@@ -1528,7 +1586,12 @@ const DataGrid = forwardRef(
1528
1586
  const dropdownFetches = columns
1529
1587
  .filter((column) => column.type === 'dropdown')
1530
1588
  .map((column) =>
1531
- getDropdownData(column.id, column.url, column.fields)
1589
+ getDropdownData(
1590
+ column.id,
1591
+ column.url,
1592
+ column.fields,
1593
+ column.where
1594
+ )
1532
1595
  );
1533
1596
 
1534
1597
  Promise.all(dropdownFetches)
@@ -3078,11 +3141,25 @@ const DataGrid = forwardRef(
3078
3141
  }, []);
3079
3142
 
3080
3143
  return (
3081
- <>
3082
- {renderSearch()}
3083
- {renderCreateButton()}
3084
- {limit && limit > 0 ? (
3085
- <>
3144
+ <div
3145
+ style={{
3146
+ display: 'flex',
3147
+ flexDirection: 'column',
3148
+ border: 'none',
3149
+ borderRadius: '0',
3150
+ overflow: 'hidden',
3151
+ }}
3152
+ >
3153
+ {/* Search and action buttons container - separated from the DataGrid */}
3154
+ {renderSearch() && (
3155
+ <div className={styles.dataGridTopContainer}>
3156
+ {renderSearch()}
3157
+ </div>
3158
+ )}
3159
+
3160
+ {/* DataGrid container with its own border */}
3161
+ <div className={styles.dataGridContainer}>
3162
+ {limit && limit > 0 ? (
3086
3163
  <ReactDataGrid
3087
3164
  {...tableSetting}
3088
3165
  columns={gridColumns}
@@ -3124,10 +3201,15 @@ const DataGrid = forwardRef(
3124
3201
  }
3125
3202
  : null
3126
3203
  }
3127
- style={gridStyle}
3204
+ style={{
3205
+ ...gridStyle,
3206
+ border: '1px solid #d1d5db',
3207
+ borderRadius: 'var(--br, 4px)',
3208
+ overflow: 'hidden',
3209
+ }}
3128
3210
  />
3129
- </>
3130
- ) : null}
3211
+ ) : null}
3212
+ </div>
3131
3213
  {audioSource && <audio src={audioSource} ref={audioRef} />}
3132
3214
  <Popup
3133
3215
  open={modalShow}
@@ -3373,7 +3455,7 @@ const DataGrid = forwardRef(
3373
3455
  index={lightboxIndex}
3374
3456
  slides={galleryData.map((img) => ({ src: img.src }))}
3375
3457
  />
3376
- </>
3458
+ </div>
3377
3459
  );
3378
3460
  }
3379
3461
  );
@@ -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) => {
@@ -167,11 +167,14 @@
167
167
  .InovuaReactDataGrid__row-cell-wrap {
168
168
  background: var(--hover-color, rgb(230, 240, 250)) !important;
169
169
  cursor: pointer;
170
+ border-radius: 0 !important;
170
171
  }
171
172
  }
172
173
 
173
174
  .InovuaReactDataGrid {
174
175
  color: var(--paragraph-color) !important;
176
+ border-radius: var(--br, 4px) !important;
177
+ overflow: hidden !important;
175
178
  }
176
179
 
177
180
  .InovuaReactDataGrid__header {
@@ -181,10 +184,12 @@
181
184
  .InovuaReactDataGrid__row-hover-target:hover {
182
185
  color: var(--primary-color) !important;
183
186
  background: var(--hover-color, rgb(230, 240, 250)) !important;
187
+ border-radius: 0 !important;
184
188
  }
185
189
 
186
190
  .InovuaReactDataGrid__row:hover {
187
191
  cursor: pointer;
192
+ border-radius: 0 !important;
188
193
  }
189
194
 
190
195
  #smartTableSearchInput {
@@ -206,45 +211,13 @@
206
211
  transform: translateY(0);
207
212
  }
208
213
 
209
- .filterInput--alt {
210
- position: relative;
211
- display: flex;
212
- align-items: center;
214
+ /* Main filterInput--alt styling moved to the nested version below */
213
215
 
214
- input {
215
- padding-left: 3rem !important;
216
- }
217
- }
216
+ /* Main icon-search styling moved to the nested version below */
218
217
 
219
- .icon-search {
220
- width: max-content;
221
- height: auto;
222
- position: absolute;
223
- z-index: 500;
224
- padding-top: 4px;
225
- padding-left: 20px;
226
- }
227
-
228
- .filterAction--alt {
229
- position: absolute;
230
- right: 8px;
231
- top: 8px;
232
- gap: 5px;
233
- display: flex;
234
-
235
- > .btn {
236
- padding: 10px 70px;
237
- }
238
- }
218
+ /* Standalone filterAction--alt styling moved to the nested version inside filterInput--alt */
239
219
 
240
- .icon-search {
241
- width: max-content;
242
- height: auto;
243
- position: absolute;
244
- z-index: 500;
245
- padding-top: 4px;
246
- padding-left: 20px;
247
- }
220
+ /* Duplicate icon-search styling removed */
248
221
 
249
222
  .tdactions {
250
223
  width: 100%;
@@ -621,6 +594,172 @@
621
594
  }
622
595
  }
623
596
 
597
+ /* DataGrid top container and search container styles */
598
+ .dataGridTopContainer {
599
+ margin-bottom: 8px;
600
+ }
601
+
602
+ .searchContainer {
603
+ display: flex;
604
+ align-items: center;
605
+ justify-content: space-between;
606
+ width: 100%;
607
+ border: 1px solid #d1d5db;
608
+ border-radius: var(--br, 4px);
609
+ overflow: hidden;
610
+ background-color: #fff;
611
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
612
+
613
+ &:focus-within {
614
+ border-color: var(--primary-color, #3b82f6);
615
+ box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 59, 130, 246), 0.2);
616
+ }
617
+ }
618
+
619
+ .searchInputWrapper {
620
+ flex: 1;
621
+ position: relative;
622
+ display: flex;
623
+ align-items: center;
624
+ }
625
+
626
+ .searchInput {
627
+ height: 38px;
628
+ border-radius: 0;
629
+ border: none;
630
+ padding: 0 10px 0 50px;
631
+ width: 100%;
632
+ font-size: 0.9rem;
633
+ box-sizing: border-box;
634
+
635
+ &:focus {
636
+ outline: none;
637
+ border-color: transparent;
638
+ box-shadow: none;
639
+ z-index: 1;
640
+ position: relative;
641
+ }
642
+
643
+ &::placeholder {
644
+ color: #9ca3af;
645
+ }
646
+ }
647
+
648
+ .actionButtonsWrapper {
649
+ display: flex;
650
+ align-items: center;
651
+ justify-content: flex-end;
652
+ }
653
+
654
+ /* Container for when only the action button is shown (search disabled) */
655
+ .actionButtonsContainer {
656
+ display: flex;
657
+ justify-content: flex-end;
658
+ width: 100%;
659
+ margin-bottom: 8px; /* Reduced spacing to match when searchbar is present */
660
+ }
661
+
662
+ .actionButtons {
663
+ display: flex;
664
+ align-items: center;
665
+ height: 38px;
666
+ gap: 0;
667
+
668
+ > .btn {
669
+ height: 38px;
670
+ border-radius: 0;
671
+ display: flex;
672
+ align-items: center;
673
+ justify-content: center;
674
+ padding: 0 20px;
675
+ margin-left: 0;
676
+ font-size: 0.9rem;
677
+ border: none;
678
+ box-sizing: border-box;
679
+
680
+ &:last-child {
681
+ border-top-right-radius: var(--br, 4px);
682
+ border-bottom-right-radius: var(--br, 4px);
683
+ }
684
+
685
+ &:focus,
686
+ &:active {
687
+ outline: none;
688
+ position: relative;
689
+ z-index: 2;
690
+ }
691
+ }
692
+ }
693
+
694
+ /* Standalone button styling when search is disabled */
695
+ .actionButtonsStandalone {
696
+ display: flex;
697
+ align-items: center;
698
+ height: 38px;
699
+ gap: 0;
700
+
701
+ > .btn {
702
+ height: 38px;
703
+ border-radius: var(--br, 4px);
704
+ display: flex;
705
+ align-items: center;
706
+ justify-content: center;
707
+ padding: 0 20px;
708
+ margin-left: 0;
709
+ font-size: 0.9rem;
710
+ border: 1px solid rgba(var(--primary-rgb, 59, 130, 246), 1.1);
711
+ box-sizing: border-box;
712
+ background-color: var(--primary-color, #3b82f6);
713
+ color: var(--tertiary-color, white);
714
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
715
+ transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
716
+
717
+ &:hover {
718
+ color: var(--tertiary-color, white);
719
+ background-color: var(--secondary-color, #2563eb);
720
+ border: 1px solid rgba(var(--secondary-rgb, 37, 99, 235), 1.05);
721
+ }
722
+
723
+ &:focus,
724
+ &:active {
725
+ outline: none;
726
+ box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 59, 130, 246), 0.2);
727
+ position: relative;
728
+ z-index: 2;
729
+ }
730
+ }
731
+ }
732
+
733
+ .icon-search {
734
+ position: absolute;
735
+ left: 22px;
736
+ color: #9ca3af;
737
+ width: 16px;
738
+ height: 16px;
739
+ z-index: 500;
740
+ top: 50%;
741
+ transform: translateY(-50%);
742
+ display: flex;
743
+ align-items: center;
744
+ justify-content: center;
745
+ pointer-events: none;
746
+ opacity: 0.7;
747
+ }
748
+
749
+ /* DataGrid container styles */
750
+ .dataGridContainer {
751
+ width: 100%;
752
+ border-radius: var(--br, 4px);
753
+ overflow: hidden;
754
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
755
+
756
+ &:focus-within {
757
+ box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 59, 130, 246), 0.2),
758
+ 0 1px 3px rgba(0, 0, 0, 0.05);
759
+ }
760
+ }
761
+
762
+ /* Original filter input styles kept for backward compatibility */
624
763
  .filterInput {
625
764
  display: flex;
626
765
  align-items: center;
@@ -632,28 +771,71 @@
632
771
  display: flex;
633
772
  align-items: center;
634
773
  justify-content: flex-start;
635
- margin-bottom: 10px;
774
+ margin-bottom: 0;
636
775
  width: 100%;
637
- height: 58px;
776
+ height: 38px;
777
+ position: relative;
778
+ border: 1px solid #d1d5db;
779
+ border-bottom: none;
638
780
 
639
781
  .icon-search {
640
782
  position: absolute;
641
- left: 10px;
642
- color: #6b7280;
783
+ left: 22px;
784
+ color: #9ca3af;
785
+ width: 16px;
786
+ height: 16px;
787
+ z-index: 500;
788
+ top: 50%;
789
+ transform: translateY(-50%);
790
+ display: flex;
791
+ align-items: center;
792
+ justify-content: center;
793
+ pointer-events: none;
794
+ opacity: 0.7;
643
795
  }
644
796
 
645
797
  input {
646
798
  height: 38px;
647
- border-radius: 4px;
648
- border: 1px solid #d1d5db;
649
- padding: 0 10px 0 35px;
799
+ border-radius: 0;
800
+ border: none;
801
+ padding: 0 10px 0 50px;
650
802
  width: 100%;
651
- max-width: 300px;
803
+ padding-right: 10px;
804
+ font-size: 0.9rem;
805
+ box-sizing: border-box;
652
806
 
653
807
  &:focus {
654
808
  outline: none;
655
809
  border-color: var(--primary-color, #3b82f6);
656
810
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
811
+ z-index: 1; /* Ensure the focus outline appears above the button */
812
+ position: relative;
813
+ }
814
+
815
+ &::placeholder {
816
+ color: #9ca3af;
817
+ }
818
+ }
819
+
820
+ .filterAction--alt {
821
+ position: relative;
822
+ height: 38px;
823
+ z-index: 5;
824
+ display: flex;
825
+ gap: 0;
826
+ /* margin-left is now controlled in the component */
827
+
828
+ > .btn {
829
+ height: 38px;
830
+ border-radius: 0;
831
+ display: flex;
832
+ align-items: center;
833
+ justify-content: center;
834
+ padding: 0 20px;
835
+ margin-left: 0;
836
+ font-size: 0.9rem;
837
+ border: none;
838
+ box-sizing: border-box;
657
839
  }
658
840
  }
659
841
  }
@@ -1,5 +1,5 @@
1
1
  .visns__ms {
2
- max-height: 52px !important;
2
+ max-height: none !important; /* Allow height to grow with content */
3
3
  }
4
4
 
5
5
  .visns__ms input:hover {
@@ -10,3 +10,107 @@
10
10
  .visns__ms input:focus {
11
11
  box-shadow: none !important;
12
12
  }
13
+
14
+ /* Global styles for react-select to ensure it works in modals */
15
+ :global {
16
+ .visns-select__menu-portal {
17
+ z-index: 99999 !important;
18
+ }
19
+
20
+ .visns-select__menu {
21
+ z-index: 99999 !important;
22
+ max-height: 300px !important;
23
+ overflow-y: auto !important;
24
+ }
25
+
26
+ /* Control styles */
27
+ .visns-select__control {
28
+ min-height: 50px !important;
29
+ height: auto !important; /* Allow height to grow with content */
30
+ overflow: visible !important;
31
+ }
32
+
33
+ /* Value container styles */
34
+ .visns-select__value-container {
35
+ padding: 2px 8px !important;
36
+ flex-wrap: wrap !important;
37
+ max-height: 100px !important; /* Set a max height */
38
+ overflow-y: auto !important; /* Add scrolling when needed */
39
+ }
40
+
41
+ /* Indicator styles */
42
+ .visns-select__indicators {
43
+ display: flex !important;
44
+ align-items: center !important;
45
+ align-self: stretch !important;
46
+ height: auto !important;
47
+ }
48
+
49
+ .visns-select__indicator {
50
+ padding: 8px !important;
51
+ display: flex !important;
52
+ align-items: center !important;
53
+ align-self: stretch !important;
54
+ }
55
+
56
+ .visns-select__indicator-separator {
57
+ align-self: stretch !important;
58
+ margin: 4px 0 !important;
59
+ }
60
+
61
+ .visns-select__placeholder {
62
+ margin-left: 2px !important;
63
+ }
64
+
65
+ /* Multi-value styles */
66
+ .visns-select__multi-value {
67
+ margin: 2px !important;
68
+ }
69
+
70
+ /* Fix for modals */
71
+ .popup-content {
72
+ overflow: visible !important;
73
+ }
74
+
75
+ .modal__content {
76
+ overflow: visible !important;
77
+ }
78
+
79
+ /* CSS class fixes for React Select */
80
+ .css-13cymwt-control,
81
+ .css-t3ipsp-control {
82
+ min-height: 50px !important;
83
+ height: auto !important;
84
+ overflow: visible !important;
85
+ }
86
+
87
+ .css-1fdsijx-ValueContainer {
88
+ padding: 2px 8px !important;
89
+ flex-wrap: wrap !important;
90
+ max-height: 100px !important;
91
+ overflow-y: auto !important;
92
+ }
93
+
94
+ /* Indicators container */
95
+ .css-1hb7zxy-IndicatorsContainer {
96
+ display: flex !important;
97
+ align-items: center !important;
98
+ align-self: stretch !important;
99
+ height: auto !important;
100
+ }
101
+
102
+ /* Individual indicators */
103
+ .css-1xc3v61-indicatorContainer,
104
+ .css-15lsz6c-indicatorContainer {
105
+ padding: 8px !important;
106
+ display: flex !important;
107
+ align-items: center !important;
108
+ align-self: stretch !important;
109
+ }
110
+
111
+ /* Separator */
112
+ .css-1u9des2-indicatorSeparator {
113
+ align-self: stretch !important;
114
+ margin: 4px 0 !important;
115
+ }
116
+ }
@@ -0,0 +1,34 @@
1
+ /* Global styles for DataGrid components */
2
+ .InovuaReactDataGrid {
3
+ border-radius: var(--br, 4px) !important;
4
+ overflow: hidden !important;
5
+ }
6
+
7
+ .InovuaReactDataGrid__header-wrapper {
8
+ border-top-left-radius: var(--br, 4px) !important;
9
+ border-top-right-radius: var(--br, 4px) !important;
10
+ }
11
+
12
+ .InovuaReactDataGrid__body {
13
+ border-bottom-left-radius: var(--br, 4px) !important;
14
+ border-bottom-right-radius: var(--br, 4px) !important;
15
+ }
16
+
17
+ /* Fix for focus/hover effect styling */
18
+ .InovuaReactDataGrid__row-hover-target:hover,
19
+ .InovuaReactDataGrid__row-hover-target:focus,
20
+ .InovuaReactDataGrid__row-hover-target:focus-within {
21
+ border-radius: 0 !important;
22
+ }
23
+
24
+ /* Ensure consistent border radius for cells */
25
+ .InovuaReactDataGrid__cell {
26
+ border-radius: 0 !important;
27
+ }
28
+
29
+ /* Fix for focus outline */
30
+ .InovuaReactDataGrid:focus,
31
+ .InovuaReactDataGrid:focus-within {
32
+ outline: none !important;
33
+ box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 59, 130, 246), 0.2) !important;
34
+ }