diginet-core-ui 1.4.1 → 1.4.2

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.
@@ -1,7 +1,7 @@
1
1
  /** @jsxRuntime classic */
2
2
  /** @jsx jsx */
3
3
  import { css, jsx } from '@emotion/core';
4
- import { Avatar, ButtonIcon, Checkbox, Chip, CircularProgress, HelperText, InputBase, Label, TreeView, Typography } from "../..";
4
+ import { Avatar, ButtonIcon, Checkbox, Chip, CircularProgress, HelperText, InputBase, Label, Popup, TreeView, Typography } from "../..";
5
5
  import Popover from "../../popover";
6
6
  import { getGlobal } from "../../../global";
7
7
  import PropTypes from 'prop-types';
@@ -83,6 +83,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
83
83
  searchExpr,
84
84
  searchMode,
85
85
  selectBox,
86
+ skip,
86
87
  style,
87
88
  subText,
88
89
  total,
@@ -110,6 +111,11 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
110
111
  // const timeout = useRef(null);
111
112
  const loadMoreTimer = useRef(null);
112
113
  const dataChosen = useRef([]);
114
+ const popupRef = useRef(null);
115
+ const filter = useRef({
116
+ skip: skip || 0,
117
+ limit: limit || 50
118
+ });
113
119
  const [unique] = useState(randomString(6, {
114
120
  allowNumber: false,
115
121
  allowSymbol: false
@@ -119,6 +125,14 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
119
125
  const [textValue, setTextValue] = useState('');
120
126
  const [txtSearch, setTxtSearch] = useState('');
121
127
  const [popoverWidth, setPopoverWidth] = useState(0);
128
+ const [loadingState, setLoadingState] = useState(loading);
129
+ const [totalState, setTotalState] = useState(total);
130
+ const [dataSourceState, setDataSourceState] = useState(dataSource);
131
+ const [popupDataState, setPopupDataState] = useState({
132
+ title: '',
133
+ substitle: '',
134
+ description: ''
135
+ });
122
136
  let valueTemp = valueProp || defaultValue || [];
123
137
 
124
138
  // only mode multi
@@ -131,7 +145,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
131
145
  const _DropdownInputCSS = DropdownInputCSS(viewType, multiple, placeholder, disabled, readOnly, multilineSelectedItem);
132
146
  const _IconCSS = IconCSS(viewType);
133
147
  const _DropdownFormCSS = DropdownFormCSS(viewType, multiple, disabled, placeholder, _DropdownInputCSS.name);
134
- const _DropdownListCSS = DropdownListCSS(loading);
148
+ const _DropdownListCSS = DropdownListCSS(loadingState);
135
149
  const _DropdownItemCSS = DropdownItemCSS(multiple, selectBox);
136
150
  const _DropdownRootCSS = DropdownRootCSS(_DropdownFormCSS.name, _DropdownInputCSS.name);
137
151
 
@@ -148,7 +162,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
148
162
  !!blur && inputRef.current.blur();
149
163
  };
150
164
  const onClickInput = e => {
151
- if (disabled || readOnly || loading) return;
165
+ if (disabled || readOnly || loadingState) return;
152
166
  if (!dropdownListRef.current) {
153
167
  if (!multiple || !Array.from(inputRef.current.querySelectorAll('.DGN-UI-Chip')).some(item => item.contains(e === null || e === void 0 ? void 0 : e.target))) {
154
168
  setOpenState(true);
@@ -181,7 +195,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
181
195
  className: 'DGN-Dropdown-List',
182
196
  onKeyDown: moveOnItem,
183
197
  tabIndex: -1
184
- }, dataSource !== null && dataSource !== void 0 && dataSource.length ? children : EmptyDataText) : itemMode === 'normal' ? mapDropdown() : mapTreeView();
198
+ }, dataSourceState !== null && dataSourceState !== void 0 && dataSourceState.length ? children : EmptyDataText) : itemMode === 'normal' ? mapDropdown() : mapTreeView();
185
199
  // const { innerHeight } = window;
186
200
  // const { top, left, height, width } = formRef.current.getBoundingClientRect();
187
201
 
@@ -220,12 +234,13 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
220
234
  marginBottom: 1
221
235
  },
222
236
  onKeyDown: pressESCHandler,
237
+ readOnly: loadingState,
223
238
  autoFocus: true
224
239
  })) : null, multiple && maximumSelectionLength ? jsx(Typography, {
225
240
  css: pd([2, 4])
226
241
  }, getGlobal('selected'), " ", (valueMulti === null || valueMulti === void 0 ? void 0 : valueMulti.length) || 0, "/", maximumSelectionLength) : null, jsx("div", {
227
242
  className: 'DGN-Dropdown-Box'
228
- }, dropdown), loading ? jsx("div", {
243
+ }, dropdown), loadingState ? jsx("div", {
229
244
  css: LoadingProgressCSS,
230
245
  className: 'DGN-Dropdown-Loading-Progress'
231
246
  }, jsx(CircularProgress, {
@@ -239,7 +254,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
239
254
  window.addEventListener('resize', customizeWidthDropdown);
240
255
  // document.addEventListener('wheel', onWheelHandler);
241
256
  // document.addEventListener('mousedown', onClickOutsideOfInput);
242
- if (onLoadMore && dataSource.length < total) {
257
+ if (onLoadMore && dataSourceState.length < totalState) {
243
258
  dropdownListRef.current && dropdownListRef.current.addEventListener('scroll', onLoadMoreHandler);
244
259
  }
245
260
  }, 10);
@@ -317,13 +332,14 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
317
332
  // }
318
333
  // };
319
334
 
320
- /**
321
- * So sánh text đầu vào cáo map với txtSearch
322
- * @param text
323
- * @return {boolean}
335
+ /**
336
+ * So sánh text đầu vào cáo map với txtSearch
337
+ * @param text
338
+ * @return {boolean}
324
339
  */
325
340
  const handleRenderBySearch = (text = '') => {
326
- if (!txtSearch || typeof text !== 'string') return true;
341
+ if (typeof text !== 'string') text = text.toString();
342
+ if (!txtSearch) return true;
327
343
  if (searchMode === 'startswith') {
328
344
  return text.toLowerCase().startsWith(txtSearch.toLowerCase());
329
345
  } else if (searchMode === 'equals') {
@@ -331,10 +347,10 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
331
347
  } else return text.toLowerCase().includes(txtSearch.toLowerCase());
332
348
  };
333
349
 
334
- /**
335
- * Chuyển đổi data thành giá trị cần hiện thị dựa vào displayExpr [string, string object {field} - {field}], renderSelectedItem, displayExpr, valueExpr
336
- * @param data {object} rowData of dataSource
337
- * @return {string}
350
+ /**
351
+ * Chuyển đổi data thành giá trị cần hiện thị dựa vào displayExpr [string, string object {field} - {field}], renderSelectedItem, displayExpr, valueExpr
352
+ * @param data {object} rowData of dataSource
353
+ * @return {string}
338
354
  */
339
355
  const displayValue = data => {
340
356
  let text = '';
@@ -353,20 +369,23 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
353
369
  return text;
354
370
  };
355
371
  const mapDropdown = () => {
356
- var _dataSourceUsable, _currentObjectDefault;
372
+ var _currentObjectDefault;
357
373
  const items = [];
358
- let dataSourceUsable = [...dataSource];
374
+ let dataSourceUsable = [...dataSourceState];
359
375
 
360
376
  // search dataSource dựa trên txtSearch
361
- dataSourceUsable = (_dataSourceUsable = dataSourceUsable) === null || _dataSourceUsable === void 0 ? void 0 : _dataSourceUsable.filter(i => {
362
- if (searchExpr) {
363
- // nếu map đc vs 1 trong những <key>(data[key]) của searchExpr
364
- return !!searchExpr.find(j => handleRenderBySearch(i[j]));
365
- } else {
366
- // nếu map đc vs displayValue
367
- return handleRenderBySearch(displayValue(i)) || handleRenderBySearch(i === null || i === void 0 ? void 0 : i[valueExpr]);
368
- }
369
- });
377
+ if (!onInput || action !== null && action !== void 0 && action.loadData) {
378
+ var _dataSourceUsable;
379
+ dataSourceUsable = (_dataSourceUsable = dataSourceUsable) === null || _dataSourceUsable === void 0 ? void 0 : _dataSourceUsable.filter(i => {
380
+ if (searchExpr) {
381
+ // nếu map đc vs 1 trong những <key>(data[key]) của searchExpr
382
+ return !!searchExpr.find(j => handleRenderBySearch(i[j]));
383
+ } else {
384
+ // nếu map đc vs displayValue
385
+ return handleRenderBySearch(displayValue(i)) || handleRenderBySearch(i === null || i === void 0 ? void 0 : i[valueExpr]);
386
+ }
387
+ });
388
+ }
370
389
  if (currentObjectDefault[unique] && (_currentObjectDefault = currentObjectDefault[unique]) !== null && _currentObjectDefault !== void 0 && _currentObjectDefault.length) {
371
390
  const length = currentObjectDefault[unique].length;
372
391
  let existItemQuantity = 0;
@@ -385,6 +404,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
385
404
  const length = dataSourceUsable.length;
386
405
  for (let index = 0; index < length; index++) {
387
406
  const data = dataSourceUsable[index];
407
+ if (!data) continue;
388
408
  const itemHidden = typeof data === 'object' ? data['hidden'] : false;
389
409
  if (itemHidden) continue;
390
410
  let displayText = displayValue(data);
@@ -477,8 +497,8 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
477
497
  className: 'DGN-Dropdown-List',
478
498
  onKeyDown: moveOnItem,
479
499
  tabIndex: -1
480
- }, dataSource !== null && dataSource !== void 0 && dataSource.length ? jsx(TreeView, {
481
- dataSource: dataSource,
500
+ }, dataSourceState !== null && dataSourceState !== void 0 && dataSourceState.length ? jsx(TreeView, {
501
+ dataSource: dataSourceState,
482
502
  displayExpr: displayExpr,
483
503
  valueExpr: valueExpr,
484
504
  multiple: multiple,
@@ -500,7 +520,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
500
520
  // remove item cũ và append child item mới khi load more
501
521
  const loadMoreItemsDropdown = (i = 0, pattern) => {
502
522
  var _currentObjectDefault2, _displayExpr2;
503
- const dataSourceUsable = [...dataSource];
523
+ const dataSourceUsable = [...dataSourceState];
504
524
  // Nếu có load more thì đẩy đội tượng mặc định lên đầu
505
525
  let notExistItem = 0;
506
526
  if (onLoadMore && (_currentObjectDefault2 = currentObjectDefault[unique]) !== null && _currentObjectDefault2 !== void 0 && _currentObjectDefault2.length) {
@@ -648,6 +668,65 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
648
668
  // : updatePosition(formRef.current, dropdownRef.current, closeDropdown);
649
669
  // };
650
670
 
671
+ const handleActionLoadData = isReset => {
672
+ const {
673
+ skip,
674
+ limit,
675
+ strSearch: search
676
+ } = filter.current;
677
+ const params = onLoadMore ? {
678
+ skip,
679
+ limit,
680
+ search
681
+ } : {
682
+ search
683
+ };
684
+ const callbackSave = (error, data) => {
685
+ setLoadingState(false);
686
+ if (error) {
687
+ let _data = {};
688
+ if (error.originalError) {
689
+ const {
690
+ message,
691
+ originalError,
692
+ customMessage,
693
+ code: codeError
694
+ } = error;
695
+ const _customMessage = customMessage && typeof customMessage === 'object' ? customMessage[codeError] : customMessage;
696
+ let messageError = '';
697
+ Object.keys(originalError).forEach(key => {
698
+ messageError += `${key}: ${JSON.stringify(originalError[key], null, 8)}\n`;
699
+ });
700
+ _data = {
701
+ title: getGlobal('error') + (codeError ? `: ${codeError}` : ''),
702
+ subtitle: _customMessage || message || getGlobal('unknownError'),
703
+ description: messageError
704
+ };
705
+ } else {
706
+ var _data$data;
707
+ const message = (data === null || data === void 0 ? void 0 : data.message) || (data === null || data === void 0 ? void 0 : (_data$data = data.data) === null || _data$data === void 0 ? void 0 : _data$data.Message) || data;
708
+ _data = {
709
+ description: message || getGlobal('unknownError')
710
+ };
711
+ }
712
+ setPopupDataState(_data);
713
+ popupRef.current.instance.show();
714
+ return false;
715
+ } else if (data) {
716
+ let rows = [];
717
+ if (Array.isArray(data)) {
718
+ rows = data;
719
+ } else {
720
+ rows = data && data.rows ? data.rows : dataSourceState;
721
+ const total = data && data.total ? data.total : data.length;
722
+ setTotalState(total);
723
+ }
724
+ setDataSourceState(isReset ? rows : dataSourceState.concat(rows));
725
+ }
726
+ };
727
+ setLoadingState(true);
728
+ action.loadData(params, callbackSave);
729
+ };
651
730
  const onLoadMoreHandler = e => {
652
731
  if (loadMoreTimer.current) {
653
732
  clearTimeout(loadMoreTimer.current);
@@ -662,12 +741,16 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
662
741
  var _dropdownListRef$curr, _currentObjectDefault3;
663
742
  const length = ((_dropdownListRef$curr = dropdownListRef.current.children) === null || _dropdownListRef$curr === void 0 ? void 0 : _dropdownListRef$curr.length) - (((_currentObjectDefault3 = currentObjectDefault[unique]) === null || _currentObjectDefault3 === void 0 ? void 0 : _currentObjectDefault3.length) || 0);
664
743
  dropdownListRef.current.removeEventListener('scroll', onLoadMoreHandler);
665
- !!onLoadMore && onLoadMore({
744
+ if (!!onLoadMore && typeof onLoadMore === 'boolean' && action !== null && action !== void 0 && action.loadData) {
745
+ filter.current.skip = length;
746
+ filter.current.limit = limit;
747
+ handleActionLoadData();
748
+ } else !!onLoadMore && onLoadMore({
666
749
  skip: length,
667
750
  limit: limit
668
751
  });
669
752
  }
670
- });
753
+ }, 300);
671
754
  };
672
755
  const onPreventKeyDownHandler = e => {
673
756
  e.preventDefault();
@@ -700,6 +783,11 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
700
783
  // }
701
784
  // return;
702
785
  }
786
+
787
+ if (action !== null && action !== void 0 && action.loadData && !!onLoadMore) {
788
+ filter.current.strSearch = e.target.value;
789
+ handleActionLoadData(true);
790
+ }
703
791
  // const value = e.target.value || e.target.textContent;
704
792
  // if (
705
793
  // typeof renderSelectedItem === 'function' &&
@@ -721,7 +809,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
721
809
  if (valueProp === undefined) {
722
810
  setValueMulti(value);
723
811
  setValueIntoInput(value);
724
- setShowClear(clearAble && checkHasValue(value) && !disabled && !readOnly && !loading);
812
+ setShowClear(clearAble && checkHasValue(value) && !disabled && !readOnly && !loadingState);
725
813
  }
726
814
  !!onChange && onChange({
727
815
  value
@@ -840,7 +928,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
840
928
  });
841
929
  };
842
930
  const onClear = e => {
843
- if (disabled || readOnly || loading || !clearAble) return;
931
+ if (disabled || readOnly || loadingState || !clearAble) return;
844
932
  currentValue[unique] = multiple ? [] : '';
845
933
  if (multiple) {
846
934
  setValueMulti([]);
@@ -886,7 +974,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
886
974
  }
887
975
  return;
888
976
  }
889
- const length = dataSource.length;
977
+ const length = dataSourceState.length;
890
978
  const displayKey = typeof renderSelectedItem === 'string' ? renderSelectedItem : displayExpr;
891
979
  if (displayKey && Array.isArray(displayKey)) {
892
980
  displayExpr = displayExpr.join(' - ');
@@ -903,8 +991,9 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
903
991
  valueArr.forEach(v => {
904
992
  var _currentObjectDefault4;
905
993
  for (let i = 0; i < length; i++) {
906
- if (typeof dataSource[i] === 'object' && dataSource[i][valueExpr] === v || dataSource[i] === v) {
907
- setMultipleValueHandler(dataSource[i], v, keyArr, i);
994
+ if (!dataSourceState[i]) continue;
995
+ if (typeof dataSourceState[i] === 'object' && dataSourceState[i][valueExpr] === v || dataSourceState[i] === v) {
996
+ setMultipleValueHandler(dataSourceState[i], v, keyArr, i);
908
997
  return;
909
998
  }
910
999
  }
@@ -919,8 +1008,9 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
919
1008
  var _currentObjectDefault5;
920
1009
  currentValue[unique] = source;
921
1010
  for (let i = 0; i < length; i++) {
922
- if (dataSource[i][valueExpr] === source || dataSource[i] === source) {
923
- setSingleValueHandler(dataSource[i], keyArr);
1011
+ if (!dataSourceState[i]) continue;
1012
+ if (dataSourceState[i][valueExpr] === source || dataSourceState[i] === source) {
1013
+ setSingleValueHandler(dataSourceState[i], keyArr);
924
1014
  return;
925
1015
  }
926
1016
  }
@@ -1027,8 +1117,17 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1027
1117
  return currentRef;
1028
1118
  });
1029
1119
  useEffect(() => {
1030
- setShowClear(clearAble && checkHasValue(valueProp !== null && valueProp !== void 0 ? valueProp : defaultValue) && !disabled && !readOnly && !loading);
1031
- }, [clearAble, valueProp, defaultValue, disabled, readOnly, loading]);
1120
+ setLoadingState(loading);
1121
+ }, [loading]);
1122
+ useEffect(() => {
1123
+ setTotalState(total);
1124
+ }, [total]);
1125
+ useEffect(() => {
1126
+ setDataSourceState(dataSource);
1127
+ }, [dataSource]);
1128
+ useEffect(() => {
1129
+ setShowClear(clearAble && checkHasValue(valueProp !== null && valueProp !== void 0 ? valueProp : defaultValue) && !disabled && !readOnly && !loadingState);
1130
+ }, [clearAble, valueProp, defaultValue, disabled, readOnly, loadingState]);
1032
1131
  useEffect(() => {
1033
1132
  if (valueObjectDefault) {
1034
1133
  if (Array.isArray(valueObjectDefault)) {
@@ -1047,8 +1146,9 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1047
1146
  allValue[unique] = [];
1048
1147
  if (defaultValue !== undefined && JSON.stringify(defaultValue) !== '[]') {
1049
1148
  setValueIntoInput(defaultValue);
1050
- setShowClear(clearAble && checkHasValue(defaultValue) && !disabled && !readOnly && !loading);
1149
+ setShowClear(clearAble && checkHasValue(defaultValue) && !disabled && !readOnly && !loadingState);
1051
1150
  }
1151
+ if (action !== null && action !== void 0 && action.loadData) handleActionLoadData();
1052
1152
  return () => {
1053
1153
  allValue[unique] = null;
1054
1154
  closeDropdown();
@@ -1087,10 +1187,12 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1087
1187
  }
1088
1188
  }, [valueProp]);
1089
1189
  useEffect(() => {
1090
- if (valueProp !== undefined && (!dropdownListRef.current || children || JSON.stringify(valueProp) !== JSON.stringify(currentValue[unique]))) {
1190
+ if (
1191
+ // valueProp !== undefined &&
1192
+ !dropdownListRef.current || children || JSON.stringify(valueProp) !== JSON.stringify(currentValue[unique])) {
1091
1193
  setValueIntoInput(valueProp);
1092
1194
  }
1093
- }, [valueProp, dataSource]);
1195
+ }, [valueProp, dataSourceState]);
1094
1196
  useEffect(() => {
1095
1197
  inputRef.current.readOnly = readOnly || inputProps.readOnly;
1096
1198
  if (!readOnly && !disabled) {
@@ -1133,9 +1235,9 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1133
1235
  inputRef.current.addEventListener('input', onChangeInput);
1134
1236
  }
1135
1237
  const length = (_dropdownListRef$curr2 = dropdownListRef.current) === null || _dropdownListRef$curr2 === void 0 ? void 0 : (_dropdownListRef$curr3 = _dropdownListRef$curr2.children) === null || _dropdownListRef$curr3 === void 0 ? void 0 : _dropdownListRef$curr3.length;
1136
- if (length < dataSource.length + ((_currentObjectDefault6 = currentObjectDefault[unique]) === null || _currentObjectDefault6 === void 0 ? void 0 : _currentObjectDefault6.length) && !isSearch[unique]) {
1238
+ if (length < dataSourceState.length + ((_currentObjectDefault6 = currentObjectDefault[unique]) === null || _currentObjectDefault6 === void 0 ? void 0 : _currentObjectDefault6.length) && !isSearch[unique]) {
1137
1239
  loadMoreItemsDropdown(length);
1138
- !!onLoadMore && dataSource.length < total && dropdownListRef.current.addEventListener('scroll', onLoadMoreHandler);
1240
+ !!onLoadMore && dataSourceState.length < totalState && dropdownListRef.current.addEventListener('scroll', onLoadMoreHandler);
1139
1241
  } else {
1140
1242
  isSearch[unique] = false;
1141
1243
  }
@@ -1151,7 +1253,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1151
1253
  }
1152
1254
  !!dropdownListRef.current && dropdownListRef.current.removeEventListener('scroll', onLoadMoreHandler);
1153
1255
  };
1154
- }, [dataSource]);
1256
+ }, [dataSourceState]);
1155
1257
  useLayoutEffect(() => {
1156
1258
  if (ref.current) {
1157
1259
  const {
@@ -1173,7 +1275,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1173
1275
  ...labelProps
1174
1276
  }, label) : null, [label, required, disabled, labelProps]);
1175
1277
  const getData = () => {
1176
- let dataFilter = JSON.parse(JSON.stringify(dataSource));
1278
+ let dataFilter = JSON.parse(JSON.stringify(dataSourceState));
1177
1279
  if (Array.isArray(valueObjectDefault)) {
1178
1280
  dataFilter = [...dataFilter, ...dataChosen.current, ...valueObjectDefault];
1179
1281
  } else if (typeof valueObjectDefault === 'object') {
@@ -1269,14 +1371,14 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1269
1371
  ref: iconRef,
1270
1372
  css: _IconCSS,
1271
1373
  className: 'DGN-UI-Dropdown-Icon'
1272
- }, loading ? jsx(CircularProgress, {
1374
+ }, loadingState ? jsx(CircularProgress, {
1273
1375
  size: 24
1274
1376
  }) : null, showClear ? jsx(ButtonIcon, {
1275
1377
  css: mgr([1]),
1276
1378
  viewType: 'ghost',
1277
1379
  name: 'Close',
1278
1380
  onClick: onClear
1279
- }) : null, !loading ? jsx(ButtonIcon, {
1381
+ }) : null, !loadingState ? jsx(ButtonIcon, {
1280
1382
  key: openState,
1281
1383
  css: animation,
1282
1384
  viewType: 'ghost',
@@ -1284,7 +1386,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1284
1386
  onClick: setShowDropdown,
1285
1387
  disabled: disabled || readOnly
1286
1388
  }) : null));
1287
- }, [openState, showClear, textValue, valueMulti, clearAble, dataSource, disabled, displayExpr, inputProps, inputStyle, loading, multilineSelectedItem, multiple, onChange, placeholder, readOnly, renderSelectedItem, valueExpr, valueObjectDefault, viewType]);
1389
+ }, [openState, showClear, textValue, valueMulti, loadingState, dataSourceState, clearAble, dataSource, disabled, displayExpr, inputProps, inputStyle, multilineSelectedItem, multiple, onChange, placeholder, readOnly, renderSelectedItem, valueExpr, valueObjectDefault, viewType]);
1288
1390
  const ErrorView = useMemo(() => {
1289
1391
  return error ? jsx(HelperText, {
1290
1392
  ...helperTextProps,
@@ -1301,15 +1403,19 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
1301
1403
  onClose: closeDropdown
1302
1404
  }, showDropdown());
1303
1405
  // return openState ? createPortal(showDropdown(), document.body) : null;
1304
- }, [openState, popoverWidth, valueMulti, dataSource, loading, maximumSelectionLength, multilineSelectedItem, multiple, selectBox, txtSearch]);
1406
+ }, [openState, popoverWidth, valueMulti, loadingState, dataSourceState, dataSource, maximumSelectionLength, multilineSelectedItem, multiple, selectBox, txtSearch]);
1305
1407
  /* End component */
1306
1408
 
1307
1409
  return jsx(Fragment, null, jsx("div", {
1308
1410
  ref: ref,
1309
1411
  css: _DropdownRootCSS,
1310
1412
  style: style,
1311
- className: classNames('DGN-UI-Dropdown', className, error && 'error', loading && 'dgn-dropdown-loading', disabled ? 'disabled' : readOnly && 'readOnly')
1312
- }, LabelView, InputView, ErrorView), DropdownView);
1413
+ className: classNames('DGN-UI-Dropdown', className, error && 'error', loadingState && 'dgn-dropdown-loading', disabled ? 'disabled' : readOnly && 'readOnly')
1414
+ }, LabelView, InputView, ErrorView), DropdownView, jsx(Popup, {
1415
+ ref: popupRef,
1416
+ type: 'danger',
1417
+ ...popupDataState
1418
+ }));
1313
1419
  }));
1314
1420
 
1315
1421
  /* Start styled */
@@ -1633,6 +1739,9 @@ Dropdown.defaultProps = {
1633
1739
  viewType: 'underlined'
1634
1740
  };
1635
1741
  Dropdown.propTypes = {
1742
+ action: PropTypes.shape({
1743
+ loadData: PropTypes.func
1744
+ }),
1636
1745
  /** If `true`, display input box search. */
1637
1746
  allowSearch: PropTypes.bool,
1638
1747
  /** The contents in Dropdown box (Exp: TreeView). */
@@ -1649,9 +1758,9 @@ Dropdown.propTypes = {
1649
1758
  defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
1650
1759
  /** If `true`, the component is disabled. */
1651
1760
  disabled: PropTypes.bool,
1652
- /** Field name used for text display in dropdown list.<br/>
1653
- * Example: 'name', '{id} - {name}', '{age} age(s)'<br/>
1654
- * Note: don't use 'id - name', return undefined
1761
+ /** Field name used for text display in dropdown list.<br/>
1762
+ * Example: 'name', '{id} - {name}', '{age} age(s)'<br/>
1763
+ * Note: don't use 'id - name', return undefined
1655
1764
  */
1656
1765
  displayExpr: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
1657
1766
  /** Style inline of dropdown items. */
@@ -1660,14 +1769,14 @@ Dropdown.propTypes = {
1660
1769
  error: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
1661
1770
  /** Props applied to the [HelperText](https://core.diginet.com.vn/ui/?path=/story/form-control-text-helpertext) element. */
1662
1771
  helperTextProps: PropTypes.object,
1663
- /** Field name used for icon display.<br/>
1664
- * Example:<br/>
1665
- * &nbsp;&nbsp;string: 'icon'<br/>
1666
- * &nbsp;&nbsp;object: {<br/>
1667
- * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key: 'icon',<br/>
1668
- * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prefix: 'https://imglink.com',<br/>
1669
- * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;suffix: '.jpg'<br/>
1670
- * &nbsp;&nbsp;}
1772
+ /** Field name used for icon display.<br/>
1773
+ * Example:<br/>
1774
+ * &nbsp;&nbsp;string: 'icon'<br/>
1775
+ * &nbsp;&nbsp;object: {<br/>
1776
+ * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key: 'icon',<br/>
1777
+ * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prefix: 'https://imglink.com',<br/>
1778
+ * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;suffix: '.jpg'<br/>
1779
+ * &nbsp;&nbsp;}
1671
1780
  */
1672
1781
  iconExpr: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
1673
1782
  key: PropTypes.string,
@@ -1701,33 +1810,33 @@ Dropdown.propTypes = {
1701
1810
  onChange: PropTypes.func,
1702
1811
  /** Callback fired when dropdown closed. */
1703
1812
  onClosed: PropTypes.func,
1704
- /** Callback fired when the input value changes.<br/>
1705
- * if undefined: the filter function will run (default)
1813
+ /** Callback fired when the input value changes.<br/>
1814
+ * if undefined: the filter function will run (default)
1706
1815
  */
1707
1816
  onInput: PropTypes.func,
1708
1817
  /** Callback fired when key down input */
1709
1818
  onKeyDown: PropTypes.func,
1710
1819
  /** Callback fired when scroll near the end. */
1711
- onLoadMore: PropTypes.func,
1820
+ onLoadMore: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
1712
1821
  /** The short hint displayed in the input before the user select a value. */
1713
1822
  placeholder: PropTypes.string,
1714
1823
  /** If `true`, the component is read-only. */
1715
1824
  readOnly: PropTypes.bool,
1716
- /** Function displays items by custom.<br/>
1717
- * renderItem={(data, index) => data.name + ' - ' + data.role}<br/>
1718
- * --> such as: displayExpr={'name - role'}
1825
+ /** Function displays items by custom.<br/>
1826
+ * renderItem={(data, index) => data.name + ' - ' + data.role}<br/>
1827
+ * --> such as: displayExpr={'name - role'}
1719
1828
  */
1720
1829
  renderItem: PropTypes.func,
1721
- /** Function or field name used for display selected items, example:<br/>
1722
- * renderSelectedItem={(data, index) => index + ' - ' + data.name}<br/>
1830
+ /** Function or field name used for display selected items, example:<br/>
1831
+ * renderSelectedItem={(data, index) => index + ' - ' + data.name}<br/>
1723
1832
  */
1724
1833
  renderSelectedItem: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
1725
1834
  /** If `true`, the label will indicate that the input is required. */
1726
1835
  required: PropTypes.bool,
1727
- /**
1728
- * Duration wait enter search content on search.<br/>
1729
- * Example: 700 -> 700ms, '700ms' -> 700ms, '0.7s' -> 700ms, '1m' -> 60000ms
1730
- * If `true`, used default delayOnInput.
1836
+ /**
1837
+ * Duration wait enter search content on search.<br/>
1838
+ * Example: 700 -> 700ms, '700ms' -> 700ms, '0.7s' -> 700ms, '1m' -> 60000ms
1839
+ * If `true`, used default delayOnInput.
1731
1840
  */
1732
1841
  searchDelayTime: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
1733
1842
  /** Specifies a data object's field name or an expression whose value is compared to the search string. */
@@ -1754,19 +1863,19 @@ Dropdown.propTypes = {
1754
1863
  valueObjectDefault: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
1755
1864
  /**The variant to use. */
1756
1865
  viewType: PropTypes.oneOf(['underlined', 'outlined', 'none'])
1757
- /**
1758
- * ref methods
1759
- *
1760
- * how to get component element? ref.current
1761
- *
1762
- * how to call method? ref.current.instance.{method}
1763
- *
1764
- * * showDropdown(): Show dropdown
1765
- * * closeDropdown(): Close dropdown
1766
- * * onClear(): Clear selected value
1767
- * * setPreviousValue(): Set value to previous value
1768
- * * setValue(value): Set value of dropdown
1769
- * * @param {value} - string || number || array
1866
+ /**
1867
+ * ref methods
1868
+ *
1869
+ * how to get component element? ref.current
1870
+ *
1871
+ * how to call method? ref.current.instance.{method}
1872
+ *
1873
+ * * showDropdown(): Show dropdown
1874
+ * * closeDropdown(): Close dropdown
1875
+ * * onClear(): Clear selected value
1876
+ * * setPreviousValue(): Set value to previous value
1877
+ * * setValue(value): Set value of dropdown
1878
+ * * @param {value} - string || number || array
1770
1879
  */
1771
1880
  };
1772
1881
 
package/global/index.js CHANGED
@@ -7,6 +7,7 @@ const globalObject = {
7
7
  close: 'Đóng',
8
8
  confirm: 'Xác nhận',
9
9
  error: 'Lỗi',
10
+ unknownError: 'Lỗi chưa xác định',
10
11
  no: 'Không',
11
12
  noDataText: 'Không có dữ liệu',
12
13
  notify: 'Thông báo',
@@ -79,6 +80,7 @@ const globalObject = {
79
80
  close: 'Close',
80
81
  confirm: 'Confirm',
81
82
  error: 'Error',
83
+ unknownError: 'Unknown Error',
82
84
  no: 'No',
83
85
  noDataText: 'No data',
84
86
  notify: 'Notify',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diginet-core-ui",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "The DigiNet core ui",
5
5
  "homepage": "https://diginet.com.vn",
6
6
  "main": "index.js",
package/readme.md CHANGED
@@ -38,6 +38,11 @@ npm test
38
38
  ```
39
39
 
40
40
  ## Changelog
41
+ ## 1.4.2
42
+ - \[Changed\]: Dropdown – Add action loadData
43
+ - \[Fixed\]: Dropdown – Fix bug search filter data when using remote; Fix bug not render invalid html tag
44
+ - \[Fixed\]: Dropdown – Fix bug if item of dataSource is null
45
+
41
46
  ## 1.4.1
42
47
  - \[Fixed\]: Dropdown – Fix bug render data wrong after search when not have searchExpr
43
48
 
package/styles/general.js CHANGED
@@ -417,9 +417,15 @@ const selfEnd = css`
417
417
  const selfStart = css`
418
418
  align-self: flex-start;
419
419
  `;
420
+ const shadowLarge = css`
421
+ box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25);
422
+ `;
420
423
  const shadowNone = css`
421
424
  box-shadow: none;
422
425
  `;
426
+ const shadowSmall = css`
427
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.25);
428
+ `;
423
429
  const textCapitalize = css`
424
430
  text-transform: capitalize;
425
431
  `;
@@ -487,4 +493,4 @@ const whiteSpacePreWrap = css`
487
493
  const z = vl => css`
488
494
  z-index: ${zIndex(vl)};
489
495
  `;
490
- export { animation, aspectSquare, bgColor, bgCurrent, bgTransparent, border, borderBottom, borderBottomColor, borderColor, borderDashed, borderNone, borderRadius, borderRadius100, borderRadius4px, borderRadius50, borderRight, borderTop, borderTopColor, bottom, boxBorder, boxContent, breakAll, breakWord, cursorDefault, cursorInherit, cursorInitial, cursorMove, cursorNoDrop, cursorNotAllowed, cursorPointer, cursorText, displayBlock, displayFlex, displayInlineBlock, displayInlineFlex, displayNone, fill, flexCol, flexColReverse, flexNowrap, flexRow, flexRowReverse, flexShrink, flexShrink0, flexWrap, flexWrapReverse, floatLeft, floatNone, floatRight, gap, gapX, gapY, inset, insetX, insetY, invisible, italic, itemsCenter, itemsEnd, itemsStart, justifyAround, justifyBetween, justifyCenter, justifyEnd, justifyEvenly, justifyStart, left, listNone, mg, mgb, mgl, mgr, mgt, mgx, mgy, noBorder, noBoxShadow, noMargin, noPadding, objectContain, objectCover, objectFill, objectNone, order, outlineNone, overflowAuto, overflowHidden, overflowXHidden, parseHeight, parseMaxHeight, parseMaxWidth, parseMaxWidthHeight, parseMinHeight, parseMinWidth, parseMinWidthHeight, parseWidth, parseWidthHeight, pd, pdb, pdl, pdr, pdt, pdx, pdy, pointerEventsAuto, pointerEventsInherit, pointerEventsInitial, pointerEventsNone, positionAbsolute, positionFixed, positionRelative, positionSticky, right, scale, scaleX, scaleY, selfCenter, selfEnd, selfStart, shadowNone, textCapitalize, textCenter, textColor, textCurrent, textEllipsis, textLeft, textLineThrough, textLowercase, textRight, textSentence, textUnderline, textUppercase, top, truncate, userSelectNone, visible, whiteSpaceBreakSpaces, whiteSpaceNoWrap, whiteSpacePreWrap, z };
496
+ export { animation, aspectSquare, bgColor, bgCurrent, bgTransparent, border, borderBottom, borderBottomColor, borderColor, borderDashed, borderNone, borderRadius, borderRadius100, borderRadius4px, borderRadius50, borderRight, borderTop, borderTopColor, bottom, boxBorder, boxContent, breakAll, breakWord, cursorDefault, cursorInherit, cursorInitial, cursorMove, cursorNoDrop, cursorNotAllowed, cursorPointer, cursorText, displayBlock, displayFlex, displayInlineBlock, displayInlineFlex, displayNone, fill, flexCol, flexColReverse, flexNowrap, flexRow, flexRowReverse, flexShrink, flexShrink0, flexWrap, flexWrapReverse, floatLeft, floatNone, floatRight, gap, gapX, gapY, inset, insetX, insetY, invisible, italic, itemsCenter, itemsEnd, itemsStart, justifyAround, justifyBetween, justifyCenter, justifyEnd, justifyEvenly, justifyStart, left, listNone, mg, mgb, mgl, mgr, mgt, mgx, mgy, noBorder, noBoxShadow, noMargin, noPadding, objectContain, objectCover, objectFill, objectNone, order, outlineNone, overflowAuto, overflowHidden, overflowXHidden, parseHeight, parseMaxHeight, parseMaxWidth, parseMaxWidthHeight, parseMinHeight, parseMinWidth, parseMinWidthHeight, parseWidth, parseWidthHeight, pd, pdb, pdl, pdr, pdt, pdx, pdy, pointerEventsAuto, pointerEventsInherit, pointerEventsInitial, pointerEventsNone, positionAbsolute, positionFixed, positionRelative, positionSticky, right, scale, scaleX, scaleY, selfCenter, selfEnd, selfStart, shadowLarge, shadowNone, shadowSmall, textCapitalize, textCenter, textColor, textCurrent, textEllipsis, textLeft, textLineThrough, textLowercase, textRight, textSentence, textUnderline, textUppercase, top, truncate, userSelectNone, visible, whiteSpaceBreakSpaces, whiteSpaceNoWrap, whiteSpacePreWrap, z };
@@ -1,5 +1,16 @@
1
1
  const parseHTML = (text, output = 'innerHTML') => {
2
2
  if (!text) return null;
3
+
4
+ // Check if text contains unescaped angle brackets that are not valid HTML tags
5
+ const invalidTagsRegex = /<(?!\s*\/?\s*(a|abbr|acronym|address|area|article|aside|audio|b|base|bdi|bdo|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|data|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|head|header|h1|h2|h3|h4|h5|h6|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|main|map|mark|meta|meter|nav|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|u|ul|var|video|wbr)\b)[^>]*>/g;
6
+ const invalidTags = text.match(invalidTagsRegex);
7
+
8
+ // If text contains invalid tags, replace angle brackets with HTML entities for those tags only
9
+ if (invalidTags) {
10
+ invalidTags.forEach(tag => {
11
+ text = text.replace(tag, tag.replace(/</g, '&lt;').replace(/>/g, '&gt;'));
12
+ });
13
+ }
3
14
  const DOM = new DOMParser().parseFromString(text, 'text/html').querySelector('body');
4
15
  const result = DOM[output];
5
16
  return result && result.trim ? result.trim() : result;