@iobroker/adapter-react-v5 7.7.5 → 8.0.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.
- package/LICENSE +22 -22
- package/README.md +249 -243
- package/build/AdminConnection.js.map +1 -1
- package/build/Components/404.js +13 -13
- package/build/Components/404.js.map +1 -1
- package/build/Components/ColorPicker.js.map +1 -1
- package/build/Components/CopyToClipboard.js.map +1 -1
- package/build/Components/Icon.js.map +1 -1
- package/build/Components/IobUri.d.ts +1 -1
- package/build/Components/IobUri.js.map +1 -1
- package/build/Components/Loader.js +223 -223
- package/build/Components/Loader.js.map +1 -1
- package/build/Components/Loaders/MV.js.map +1 -1
- package/build/Components/Loaders/PT.js +103 -103
- package/build/Components/Loaders/PT.js.map +1 -1
- package/build/Components/Loaders/Vendor.js +7 -7
- package/build/Components/Loaders/Vendor.js.map +1 -1
- package/build/Components/MDUtils.js.map +1 -1
- package/build/Components/ObjectBrowser.d.ts +3 -4
- package/build/Components/ObjectBrowser.js +253 -154
- package/build/Components/ObjectBrowser.js.map +1 -1
- package/build/Components/Router.js.map +1 -1
- package/build/Components/SaveCloseButtons.js.map +1 -1
- package/build/Components/SimpleCron/cronText.js.map +1 -1
- package/build/Components/SimpleCron/index.js.map +1 -1
- package/build/Components/TabContainer.js.map +1 -1
- package/build/Components/TabContent.js.map +1 -1
- package/build/Components/TabHeader.js.map +1 -1
- package/build/Components/TableResize.js.map +1 -1
- package/build/Components/TreeTable.js.map +1 -1
- package/build/Components/UploadImage.js +305 -305
- package/build/Components/UploadImage.js.map +1 -1
- package/build/Connection.js.map +1 -1
- package/build/Dialogs/ComplexCron.js.map +1 -1
- package/build/Dialogs/Confirm.js.map +1 -1
- package/build/Dialogs/Cron.js.map +1 -1
- package/build/Dialogs/Error.js.map +1 -1
- package/build/Dialogs/Message.js.map +1 -1
- package/build/Dialogs/SimpleCron.js.map +1 -1
- package/build/Dialogs/TextInput.js.map +1 -1
- package/build/Prompt.js +7 -7
- package/build/Prompt.js.map +1 -1
- package/build/assets/devices/parseNames.js.map +1 -1
- package/build/assets/devices.json +1 -1
- package/build/assets/lamp_ceiling.svg +8 -8
- package/build/assets/lamp_table.svg +7 -7
- package/build/assets/no_icon.svg +9 -9
- package/build/assets/rooms/parseNames.js.map +1 -1
- package/build/assets/rooms.json +1 -1
- package/build/dictionary.js.map +1 -1
- package/build/globals.d.ts +19 -0
- package/build/i18n.js.map +1 -1
- package/build/index.css +56 -56
- package/index.css +56 -56
- package/package.json +84 -82
- package/tasksExample.js +91 -91
|
@@ -789,12 +789,13 @@ excludeTranslations) {
|
|
|
789
789
|
result[key] = isObject ? filterObject(value, filterKeys, excludeTranslations) : value;
|
|
790
790
|
});
|
|
791
791
|
}
|
|
792
|
+
// It is an export function and used somewhere else
|
|
792
793
|
export function filterRoles(roleArray, type, defaultRoles) {
|
|
793
794
|
const bigRoleArray = [];
|
|
794
795
|
roleArray.forEach(role => (role.type === 'mixed' || role.type) === type &&
|
|
795
796
|
!bigRoleArray.includes(role.role) &&
|
|
796
797
|
bigRoleArray.push(role.role));
|
|
797
|
-
defaultRoles
|
|
798
|
+
defaultRoles?.forEach(role => (role.type === 'mixed' || role.type) === type &&
|
|
798
799
|
!bigRoleArray.includes(role.role) &&
|
|
799
800
|
bigRoleArray.push(role.role));
|
|
800
801
|
bigRoleArray.sort();
|
|
@@ -826,6 +827,158 @@ options) {
|
|
|
826
827
|
el.click();
|
|
827
828
|
document.body.removeChild(el);
|
|
828
829
|
}
|
|
830
|
+
class CustomFilterSelect extends Component {
|
|
831
|
+
hasIcons;
|
|
832
|
+
timer = null;
|
|
833
|
+
constructor(props) {
|
|
834
|
+
super(props);
|
|
835
|
+
this.state = {
|
|
836
|
+
value: props.initialValue || [],
|
|
837
|
+
};
|
|
838
|
+
this.hasIcons = !!props.values?.find(item => item.icon);
|
|
839
|
+
}
|
|
840
|
+
componentWillUnmount() {
|
|
841
|
+
if (this.timer) {
|
|
842
|
+
clearTimeout(this.timer);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
render() {
|
|
846
|
+
return (React.createElement("div", { style: { position: 'relative' } },
|
|
847
|
+
React.createElement(Select, { variant: "standard", key: this.props.name, sx: styles.headerCellInput, className: "no-underline", multiple: true, renderValue: value => {
|
|
848
|
+
if (!value?.length) {
|
|
849
|
+
return this.props.name === 'custom'
|
|
850
|
+
? this.props.texts.showAll
|
|
851
|
+
: this.props.texts[`filter_${this.props.name}`];
|
|
852
|
+
}
|
|
853
|
+
return value.map(val => {
|
|
854
|
+
const item = this.props.values.find(i => typeof i === 'object' ? i.value === val : i === val);
|
|
855
|
+
let id;
|
|
856
|
+
let _name;
|
|
857
|
+
let icon;
|
|
858
|
+
if (typeof item === 'object') {
|
|
859
|
+
id = item.value;
|
|
860
|
+
_name = item.name;
|
|
861
|
+
icon = item.icon;
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
id = item;
|
|
865
|
+
_name = item;
|
|
866
|
+
}
|
|
867
|
+
return (React.createElement(Box, { component: "span", sx: styles.headerCellSelectItem, key: id },
|
|
868
|
+
icon || (this.hasIcons ? React.createElement("div", { className: "itemIcon" }) : null),
|
|
869
|
+
_name));
|
|
870
|
+
});
|
|
871
|
+
}, value: this.state.value, onChange: event => {
|
|
872
|
+
let selectedValues = event.target.value;
|
|
873
|
+
// '_' may be selected only alone
|
|
874
|
+
if (this.state.value[0] === '_' && selectedValues.includes('_') && selectedValues.length > 1) {
|
|
875
|
+
const pos = selectedValues.indexOf('_');
|
|
876
|
+
if (pos !== -1) {
|
|
877
|
+
selectedValues.splice(pos, 1);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
else if (this.state.value[0] !== '_' && selectedValues.includes('_')) {
|
|
881
|
+
selectedValues = ['_'];
|
|
882
|
+
}
|
|
883
|
+
// '_' may be selected only alone
|
|
884
|
+
if (selectedValues.includes('')) {
|
|
885
|
+
selectedValues = [];
|
|
886
|
+
}
|
|
887
|
+
this.setState({ value: selectedValues }, () => {
|
|
888
|
+
if (this.timer) {
|
|
889
|
+
clearTimeout(this.timer);
|
|
890
|
+
}
|
|
891
|
+
this.timer = setTimeout(() => {
|
|
892
|
+
this.timer = null;
|
|
893
|
+
this.props.onChange(this.props.name, selectedValues);
|
|
894
|
+
}, 400);
|
|
895
|
+
});
|
|
896
|
+
}, onClose: () => {
|
|
897
|
+
if (this.timer) {
|
|
898
|
+
clearTimeout(this.timer);
|
|
899
|
+
this.timer = null;
|
|
900
|
+
this.props.onChange(this.props.name, this.state.value);
|
|
901
|
+
}
|
|
902
|
+
}, inputProps: { name: this.props.name, id: this.props.name }, displayEmpty: true },
|
|
903
|
+
React.createElement(MenuItem, { key: "empty", value: "" },
|
|
904
|
+
React.createElement("span", { style: styles.selectNone }, this.props.name === 'custom'
|
|
905
|
+
? this.props.texts.showAll
|
|
906
|
+
: this.props.texts[`filter_${this.props.name}`])),
|
|
907
|
+
this.props.values?.map(item => {
|
|
908
|
+
let id;
|
|
909
|
+
let _name;
|
|
910
|
+
let icon;
|
|
911
|
+
if (typeof item === 'object') {
|
|
912
|
+
id = item.value;
|
|
913
|
+
_name = item.name;
|
|
914
|
+
icon = item.icon;
|
|
915
|
+
}
|
|
916
|
+
else {
|
|
917
|
+
id = item;
|
|
918
|
+
_name = item;
|
|
919
|
+
}
|
|
920
|
+
return (React.createElement(MenuItem, { sx: styles.headerCellSelectItem, key: id, value: id },
|
|
921
|
+
icon || (this.hasIcons ? React.createElement("div", { className: "itemIcon" }) : null),
|
|
922
|
+
_name));
|
|
923
|
+
})),
|
|
924
|
+
this.state.value.length ? (React.createElement(Box, { component: "div", sx: styles.selectClearButton },
|
|
925
|
+
React.createElement(IconButton, { size: "small", onClick: () => {
|
|
926
|
+
if (this.timer) {
|
|
927
|
+
clearTimeout(this.timer);
|
|
928
|
+
this.timer = null;
|
|
929
|
+
}
|
|
930
|
+
this.setState({ value: [] }, () => this.props.onChange(this.props.name, undefined));
|
|
931
|
+
} },
|
|
932
|
+
React.createElement(IconClose, null)))) : null));
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
class CustomFilterInput extends Component {
|
|
936
|
+
timer = null;
|
|
937
|
+
constructor(props) {
|
|
938
|
+
super(props);
|
|
939
|
+
this.state = {
|
|
940
|
+
value: props.initialValue || '',
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
componentWillUnmount() {
|
|
944
|
+
if (this.timer) {
|
|
945
|
+
clearTimeout(this.timer);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
render() {
|
|
949
|
+
return (React.createElement(FormControl, { sx: this.props.styles, key: this.props.name, title: this.props.t('ra_You can use * as wildcard'), margin: "dense" },
|
|
950
|
+
React.createElement(Input, { classes: { underline: 'no-underline' }, id: this.props.name, placeholder: this.props.texts[`filter_${this.props.name}`], value: this.state.value, onChange: event => {
|
|
951
|
+
const selectedValues = event.target.value;
|
|
952
|
+
this.setState({ value: selectedValues }, () => {
|
|
953
|
+
if (this.timer) {
|
|
954
|
+
clearTimeout(this.timer);
|
|
955
|
+
}
|
|
956
|
+
this.timer = setTimeout(() => {
|
|
957
|
+
this.timer = null;
|
|
958
|
+
this.props.onChange(this.props.name, selectedValues);
|
|
959
|
+
}, 400);
|
|
960
|
+
});
|
|
961
|
+
}, onBlur: () => {
|
|
962
|
+
if (this.timer) {
|
|
963
|
+
clearTimeout(this.timer);
|
|
964
|
+
this.timer = null;
|
|
965
|
+
this.props.onChange(this.props.name, this.state.value);
|
|
966
|
+
}
|
|
967
|
+
}, autoComplete: "off" }),
|
|
968
|
+
this.state.value ? (React.createElement("div", { style: {
|
|
969
|
+
position: 'absolute',
|
|
970
|
+
right: 0,
|
|
971
|
+
} },
|
|
972
|
+
React.createElement(IconButton, { size: "small", onClick: () => {
|
|
973
|
+
if (this.timer) {
|
|
974
|
+
clearTimeout(this.timer);
|
|
975
|
+
this.timer = null;
|
|
976
|
+
}
|
|
977
|
+
this.setState({ value: '' }, () => this.props.onChange(this.props.name, undefined));
|
|
978
|
+
} },
|
|
979
|
+
React.createElement(IconClose, null)))) : null));
|
|
980
|
+
}
|
|
981
|
+
}
|
|
829
982
|
// d=data, t=target, s=start, e=end, m=middle
|
|
830
983
|
function binarySearch(list, find, _start, _end) {
|
|
831
984
|
_start ||= 0;
|
|
@@ -1123,15 +1276,18 @@ function applyFilter(item, filters, lang, objects, context, counter, customFilte
|
|
|
1123
1276
|
}
|
|
1124
1277
|
if (!filteredOut && context.custom?.length) {
|
|
1125
1278
|
if (common) {
|
|
1126
|
-
if (context.custom
|
|
1279
|
+
if (context.custom[0] === '_') {
|
|
1127
1280
|
filteredOut = !!common.custom;
|
|
1128
1281
|
}
|
|
1129
1282
|
else if (common.custom) {
|
|
1130
1283
|
filteredOut = !context.custom.find(custom => common.custom[custom]);
|
|
1131
1284
|
}
|
|
1285
|
+
else {
|
|
1286
|
+
filteredOut = true;
|
|
1287
|
+
}
|
|
1132
1288
|
}
|
|
1133
1289
|
else {
|
|
1134
|
-
filteredOut =
|
|
1290
|
+
filteredOut = context.custom[0] !== '_';
|
|
1135
1291
|
}
|
|
1136
1292
|
}
|
|
1137
1293
|
}
|
|
@@ -1884,7 +2040,6 @@ export class ObjectBrowserClass extends Component {
|
|
|
1884
2040
|
localStorage = window._localStorage || window.localStorage;
|
|
1885
2041
|
lastAppliedFilter = null;
|
|
1886
2042
|
tableRef;
|
|
1887
|
-
filterRefs;
|
|
1888
2043
|
pausedSubscribes = false;
|
|
1889
2044
|
selectFirst;
|
|
1890
2045
|
root = null;
|
|
@@ -1893,7 +2048,6 @@ export class ObjectBrowserClass extends Component {
|
|
|
1893
2048
|
unsubscribeTimer = null;
|
|
1894
2049
|
statesUpdateTimer = null;
|
|
1895
2050
|
objectsUpdateTimer = null;
|
|
1896
|
-
filterTimer = null;
|
|
1897
2051
|
visibleCols;
|
|
1898
2052
|
texts;
|
|
1899
2053
|
possibleCols;
|
|
@@ -1932,7 +2086,7 @@ export class ObjectBrowserClass extends Component {
|
|
|
1932
2086
|
styles = {};
|
|
1933
2087
|
customColumnDialog = null;
|
|
1934
2088
|
/** Namespaces which are allowed to be edited by non-expert users */
|
|
1935
|
-
static
|
|
2089
|
+
static NON_EXPERT_NAMESPACES = ['0_userdata.0.', 'alias.0.'];
|
|
1936
2090
|
constructor(props) {
|
|
1937
2091
|
super(props);
|
|
1938
2092
|
const lastSelectedItemStr = this.localStorage.getItem(`${props.dialogName || 'App'}.objectSelected`) || '';
|
|
@@ -1976,20 +2130,35 @@ export class ObjectBrowserClass extends Component {
|
|
|
1976
2130
|
filter = { ...DEFAULT_FILTER };
|
|
1977
2131
|
}
|
|
1978
2132
|
// Migrate old filters to new one
|
|
1979
|
-
if (typeof filter.room === 'string') {
|
|
1980
|
-
filter.room = [filter.room];
|
|
2133
|
+
if (typeof filter.room === 'string' && filter.room) {
|
|
2134
|
+
filter.room = [filter.room].filter(s => s);
|
|
2135
|
+
if (!filter.room.length) {
|
|
2136
|
+
delete filter.room;
|
|
2137
|
+
}
|
|
1981
2138
|
}
|
|
1982
|
-
if (typeof filter.func === 'string') {
|
|
1983
|
-
filter.func = [filter.func];
|
|
2139
|
+
if (typeof filter.func === 'string' && filter.func) {
|
|
2140
|
+
filter.func = [filter.func].filter(s => s);
|
|
2141
|
+
if (!filter.func.length) {
|
|
2142
|
+
delete filter.func;
|
|
2143
|
+
}
|
|
1984
2144
|
}
|
|
1985
|
-
if (typeof filter.role === 'string') {
|
|
1986
|
-
filter.role = [filter.role];
|
|
2145
|
+
if (typeof filter.role === 'string' && filter.role) {
|
|
2146
|
+
filter.role = [filter.role].filter(s => s);
|
|
2147
|
+
if (!filter.role.length) {
|
|
2148
|
+
delete filter.role;
|
|
2149
|
+
}
|
|
1987
2150
|
}
|
|
1988
2151
|
if (typeof filter.type === 'string') {
|
|
1989
|
-
filter.type = [filter.type];
|
|
2152
|
+
filter.type = [filter.type].filter(s => s);
|
|
2153
|
+
if (!filter.type.length) {
|
|
2154
|
+
delete filter.type;
|
|
2155
|
+
}
|
|
1990
2156
|
}
|
|
1991
2157
|
if (typeof filter.custom === 'string') {
|
|
1992
|
-
filter.custom = [filter.custom];
|
|
2158
|
+
filter.custom = [filter.custom].filter(s => s);
|
|
2159
|
+
if (!filter.custom.length) {
|
|
2160
|
+
delete filter.custom;
|
|
2161
|
+
}
|
|
1993
2162
|
}
|
|
1994
2163
|
filter.expertMode =
|
|
1995
2164
|
props.expertMode !== undefined
|
|
@@ -1997,8 +2166,6 @@ export class ObjectBrowserClass extends Component {
|
|
|
1997
2166
|
: (window._sessionStorage || window.sessionStorage).getItem('App.expertMode') ===
|
|
1998
2167
|
'true';
|
|
1999
2168
|
this.tableRef = createRef();
|
|
2000
|
-
this.filterRefs = {};
|
|
2001
|
-
Object.keys(DEFAULT_FILTER).forEach(name => (this.filterRefs[name] = createRef()));
|
|
2002
2169
|
this.visibleCols = props.columns || SCREEN_WIDTHS[props.width || 'lg'].fields;
|
|
2003
2170
|
// remove type column if only one type must be selected
|
|
2004
2171
|
if (props.types && props.types.length === 1) {
|
|
@@ -2308,16 +2475,17 @@ export class ObjectBrowserClass extends Component {
|
|
|
2308
2475
|
this.info = info;
|
|
2309
2476
|
// Show first selected item
|
|
2310
2477
|
const node = this.state.selected?.length && findNode(this.root, this.state.selected[0]);
|
|
2311
|
-
this.lastAppliedFilter = null;
|
|
2312
2478
|
// If the selected ID is not visible, reset filter
|
|
2313
2479
|
if (node &&
|
|
2314
2480
|
!applyFilter(node, this.state.filter, props.lang, this.objects, undefined, undefined, props.customFilter, props.types)) {
|
|
2315
2481
|
// reset filter
|
|
2316
2482
|
this.setState({ filter: { ...DEFAULT_FILTER }, columnsForAdmin }, () => {
|
|
2483
|
+
this.doFilter();
|
|
2317
2484
|
this.setState({ loaded: true, updating: false }, () => this.expandAllSelected(() => this.onAfterSelect()));
|
|
2318
2485
|
});
|
|
2319
2486
|
}
|
|
2320
2487
|
else {
|
|
2488
|
+
this.doFilter();
|
|
2321
2489
|
this.setState({ loaded: true, updating: false, columnsForAdmin }, () => this.expandAllSelected(() => this.onAfterSelect()));
|
|
2322
2490
|
}
|
|
2323
2491
|
}
|
|
@@ -2331,7 +2499,7 @@ export class ObjectBrowserClass extends Component {
|
|
|
2331
2499
|
static isNonExpertId(
|
|
2332
2500
|
/** id to test */
|
|
2333
2501
|
id) {
|
|
2334
|
-
return !!ObjectBrowserClass
|
|
2502
|
+
return !!ObjectBrowserClass.NON_EXPERT_NAMESPACES.find(saveNamespace => id.startsWith(saveNamespace));
|
|
2335
2503
|
}
|
|
2336
2504
|
expandAllSelected(cb) {
|
|
2337
2505
|
const expanded = [...this.state.expanded];
|
|
@@ -2471,10 +2639,6 @@ export class ObjectBrowserClass extends Component {
|
|
|
2471
2639
|
* Called when component is unmounted.
|
|
2472
2640
|
*/
|
|
2473
2641
|
componentWillUnmount() {
|
|
2474
|
-
if (this.filterTimer) {
|
|
2475
|
-
clearTimeout(this.filterTimer);
|
|
2476
|
-
this.filterTimer = null;
|
|
2477
|
-
}
|
|
2478
2642
|
window.removeEventListener('contextmenu', this.onContextMenu, true);
|
|
2479
2643
|
window.removeEventListener('keydown', this.onKeyPress, true);
|
|
2480
2644
|
window.removeEventListener('keyup', this.onKeyPress, true);
|
|
@@ -3032,129 +3196,52 @@ export class ObjectBrowserClass extends Component {
|
|
|
3032
3196
|
this.subscribes.forEach(id => this.props.socket.subscribeState(id, this.onStateChange));
|
|
3033
3197
|
}
|
|
3034
3198
|
}
|
|
3035
|
-
onFilter(name, value) {
|
|
3036
|
-
this.filterTimer = null;
|
|
3037
|
-
const filter = { ...this.state.filter };
|
|
3038
|
-
Object.keys(this.filterRefs).forEach((_name) => {
|
|
3039
|
-
if (this.filterRefs[_name]?.current) {
|
|
3040
|
-
const filterRef = this.filterRefs[_name].current;
|
|
3041
|
-
for (let i = 0; i < filterRef.children.length; i++) {
|
|
3042
|
-
if (filterRef.children[i].tagName === 'INPUT') {
|
|
3043
|
-
if (_name === 'role' ||
|
|
3044
|
-
_name === 'type' ||
|
|
3045
|
-
_name === 'func' ||
|
|
3046
|
-
_name === 'custom' ||
|
|
3047
|
-
_name === 'room') {
|
|
3048
|
-
const value = filterRef.children[i].value;
|
|
3049
|
-
if (value) {
|
|
3050
|
-
filter[_name] = value.split(',');
|
|
3051
|
-
}
|
|
3052
|
-
else {
|
|
3053
|
-
filter[_name] = undefined;
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
else {
|
|
3057
|
-
filter[_name] = filterRef.children[i].value;
|
|
3058
|
-
}
|
|
3059
|
-
break;
|
|
3060
|
-
}
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
3063
|
-
});
|
|
3064
|
-
if (name) {
|
|
3065
|
-
filter[name] = value;
|
|
3066
|
-
if (name === 'expertMode') {
|
|
3067
|
-
(window._sessionStorage || window.sessionStorage).setItem('App.expertMode', value ? 'true' : 'false');
|
|
3068
|
-
}
|
|
3069
|
-
}
|
|
3070
|
-
if (JSON.stringify(this.state.filter) !== JSON.stringify(filter)) {
|
|
3071
|
-
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectFilter`, JSON.stringify(filter));
|
|
3072
|
-
this.setState({ filter }, () => this.props.onFilterChanged && this.props.onFilterChanged(filter));
|
|
3073
|
-
}
|
|
3074
|
-
}
|
|
3075
3199
|
clearFilter() {
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
const item = filterRef.childNodes[i];
|
|
3082
|
-
if (item.tagName === 'INPUT') {
|
|
3083
|
-
filter[name] = '';
|
|
3084
|
-
item.value = '';
|
|
3085
|
-
break;
|
|
3086
|
-
}
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
});
|
|
3090
|
-
if (JSON.stringify(this.state.filter) !== JSON.stringify(filter)) {
|
|
3091
|
-
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectFilter`, JSON.stringify(filter));
|
|
3092
|
-
this.setState({ filter, filterKey: this.state.filterKey + 1 }, () => this.props.onFilterChanged?.(filter));
|
|
3200
|
+
if (JSON.stringify(this.state.filter) !== JSON.stringify(DEFAULT_FILTER)) {
|
|
3201
|
+
this.setState({ filter: { ...DEFAULT_FILTER }, filterKey: this.state.filterKey + 1 }, () => {
|
|
3202
|
+
this.doFilter();
|
|
3203
|
+
this.props.onFilterChanged?.({ ...DEFAULT_FILTER });
|
|
3204
|
+
});
|
|
3093
3205
|
}
|
|
3094
3206
|
}
|
|
3095
3207
|
isFilterEmpty() {
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
} },
|
|
3119
|
-
React.createElement(IconClose, null)))) : null));
|
|
3208
|
+
return (!!this.state.filter.id ||
|
|
3209
|
+
!!this.state.filter.name ||
|
|
3210
|
+
!!this.state.filter.room?.length ||
|
|
3211
|
+
!!this.state.filter.func?.length ||
|
|
3212
|
+
!!this.state.filter.role?.length ||
|
|
3213
|
+
!!this.state.filter.type?.length ||
|
|
3214
|
+
!!this.state.filter.custom?.length);
|
|
3215
|
+
}
|
|
3216
|
+
getFilterInput(name) {
|
|
3217
|
+
return (React.createElement(CustomFilterInput, { key: `${name}_${this.state.filterKey}`, styles: this.styles.filterInput, name: name, texts: this.texts, t: this.props.t, initialValue: this.state.filter[name], onChange: (name, value) => {
|
|
3218
|
+
const filter = { ...this.state.filter };
|
|
3219
|
+
if (value === undefined) {
|
|
3220
|
+
delete filter[name];
|
|
3221
|
+
}
|
|
3222
|
+
else {
|
|
3223
|
+
filter[name] = value;
|
|
3224
|
+
}
|
|
3225
|
+
this.setState({ filter }, () => {
|
|
3226
|
+
this.doFilter();
|
|
3227
|
+
this.props.onFilterChanged?.(filter);
|
|
3228
|
+
});
|
|
3229
|
+
} }));
|
|
3120
3230
|
}
|
|
3121
3231
|
getFilterSelect(name, values) {
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
}
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
let icon;
|
|
3136
|
-
if (typeof item === 'object') {
|
|
3137
|
-
id = item.value;
|
|
3138
|
-
_name = item.name;
|
|
3139
|
-
icon = item.icon;
|
|
3140
|
-
}
|
|
3141
|
-
else {
|
|
3142
|
-
id = item;
|
|
3143
|
-
_name = item;
|
|
3144
|
-
}
|
|
3145
|
-
return (React.createElement(MenuItem, { sx: styles.headerCellSelectItem, key: id, value: id },
|
|
3146
|
-
icon || (hasIcons ? React.createElement("div", { className: "itemIcon" }) : null),
|
|
3147
|
-
_name));
|
|
3148
|
-
})),
|
|
3149
|
-
this.filterRefs[name]?.current?.childNodes[1]?.value ? (React.createElement(Box, { component: "div", sx: styles.selectClearButton },
|
|
3150
|
-
React.createElement(IconButton, { size: "small", onClick: () => {
|
|
3151
|
-
const newFilter = { ...this.state.filter };
|
|
3152
|
-
delete newFilter[name];
|
|
3153
|
-
(this.filterRefs[name].current?.childNodes[1]).value = '';
|
|
3154
|
-
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectFilter`, JSON.stringify(newFilter));
|
|
3155
|
-
this.setState({ filter: newFilter, filterKey: this.state.filterKey + 1 }, () => this.props.onFilterChanged && this.props.onFilterChanged(newFilter));
|
|
3156
|
-
} },
|
|
3157
|
-
React.createElement(IconClose, null)))) : null));
|
|
3232
|
+
return (React.createElement(CustomFilterSelect, { key: `${name}_${this.state.filterKey}`, name: name, texts: this.texts, initialValue: this.state.filter[name] || [], values: values, onChange: (name, value) => {
|
|
3233
|
+
const filter = { ...this.state.filter };
|
|
3234
|
+
if (value === undefined) {
|
|
3235
|
+
delete filter[name];
|
|
3236
|
+
}
|
|
3237
|
+
else {
|
|
3238
|
+
filter[name] = value;
|
|
3239
|
+
}
|
|
3240
|
+
this.setState({ filter }, () => {
|
|
3241
|
+
this.doFilter();
|
|
3242
|
+
this.props.onFilterChanged?.(filter);
|
|
3243
|
+
});
|
|
3244
|
+
} }));
|
|
3158
3245
|
}
|
|
3159
3246
|
getFilterSelectRole() {
|
|
3160
3247
|
return this.getFilterSelect('role', this.info.roles.map(it => it.role));
|
|
@@ -3674,7 +3761,14 @@ export class ObjectBrowserClass extends Component {
|
|
|
3674
3761
|
React.createElement(IconButton, { onClick: () => this.refreshComponent(), disabled: this.state.updating, size: "large" },
|
|
3675
3762
|
React.createElement(RefreshIcon, null)))),
|
|
3676
3763
|
this.props.showExpertButton && !this.props.expertMode && (React.createElement(Tooltip, { title: this.props.t('ra_expertMode'), slotProps: { popper: { sx: styles.tooltip } } },
|
|
3677
|
-
React.createElement(IconButton, { key: "expertMode", color: this.state.filter.expertMode ? 'secondary' : 'default', onClick: () =>
|
|
3764
|
+
React.createElement(IconButton, { key: "expertMode", color: this.state.filter.expertMode ? 'secondary' : 'default', onClick: () => {
|
|
3765
|
+
const filter = { ...this.state.filter };
|
|
3766
|
+
filter.expertMode = !filter.expertMode;
|
|
3767
|
+
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectFilter`, JSON.stringify(filter));
|
|
3768
|
+
this.setState({
|
|
3769
|
+
filter,
|
|
3770
|
+
});
|
|
3771
|
+
}, size: "large" },
|
|
3678
3772
|
React.createElement(IconExpert, null)))),
|
|
3679
3773
|
!this.props.disableColumnSelector && this.props.width !== 'xs' && (React.createElement(Tooltip, { title: this.props.t('ra_Configure'), slotProps: { popper: { sx: styles.tooltip } } },
|
|
3680
3774
|
React.createElement(IconButton, { key: "columnSelector", color: this.state.columnsAuto ? 'primary' : 'default', onClick: () => this.setState({ columnsSelectorShow: true }), size: "large" },
|
|
@@ -4250,7 +4344,9 @@ export class ObjectBrowserClass extends Component {
|
|
|
4250
4344
|
this.setState({ enumDialogEnums });
|
|
4251
4345
|
}, secondaryAction: icon },
|
|
4252
4346
|
React.createElement(ListItemIcon, { sx: { '&.MuiListItemIcon-root': styles.enumCheckbox } },
|
|
4253
|
-
React.createElement(Checkbox, { edge: "start", checked: itemEnums.includes(id), tabIndex: -1, disableRipple: true,
|
|
4347
|
+
React.createElement(Checkbox, { edge: "start", checked: itemEnums.includes(id), tabIndex: -1, disableRipple: true, slotProps: {
|
|
4348
|
+
input: { 'aria-labelledby': labelId },
|
|
4349
|
+
} })),
|
|
4254
4350
|
React.createElement(ListItemText, { id: labelId }, name)));
|
|
4255
4351
|
}))));
|
|
4256
4352
|
}
|
|
@@ -6126,6 +6222,22 @@ export class ObjectBrowserClass extends Component {
|
|
|
6126
6222
|
}
|
|
6127
6223
|
}, width: this.props.width }));
|
|
6128
6224
|
}
|
|
6225
|
+
doFilter(doNotStore) {
|
|
6226
|
+
if (!this.objects || !this.root) {
|
|
6227
|
+
return;
|
|
6228
|
+
}
|
|
6229
|
+
if (!doNotStore) {
|
|
6230
|
+
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectFilter`, JSON.stringify(this.state.filter));
|
|
6231
|
+
}
|
|
6232
|
+
const counter = { count: 0 };
|
|
6233
|
+
applyFilter(this.root, this.state.filter, this.props.lang, this.objects, undefined, counter, this.props.customFilter, this.props.types);
|
|
6234
|
+
if (counter.count < 500 && !this.state.expandAllVisible) {
|
|
6235
|
+
setTimeout(() => this.setState({ expandAllVisible: true }));
|
|
6236
|
+
}
|
|
6237
|
+
else if (counter.count >= 500 && this.state.expandAllVisible) {
|
|
6238
|
+
setTimeout(() => this.setState({ expandAllVisible: false }));
|
|
6239
|
+
}
|
|
6240
|
+
}
|
|
6129
6241
|
/**
|
|
6130
6242
|
* The rendering method of this component.
|
|
6131
6243
|
*/
|
|
@@ -6159,19 +6271,6 @@ export class ObjectBrowserClass extends Component {
|
|
|
6159
6271
|
};
|
|
6160
6272
|
this.styleTheme = this.props.themeType;
|
|
6161
6273
|
}
|
|
6162
|
-
// apply filter if changed
|
|
6163
|
-
const jsonFilter = JSON.stringify(this.state.filter);
|
|
6164
|
-
if (this.lastAppliedFilter !== jsonFilter && this.objects && this.root) {
|
|
6165
|
-
const counter = { count: 0 };
|
|
6166
|
-
applyFilter(this.root, this.state.filter, this.props.lang, this.objects, undefined, counter, this.props.customFilter, this.props.types);
|
|
6167
|
-
if (counter.count < 500 && !this.state.expandAllVisible) {
|
|
6168
|
-
setTimeout(() => this.setState({ expandAllVisible: true }));
|
|
6169
|
-
}
|
|
6170
|
-
else if (counter.count >= 500 && this.state.expandAllVisible) {
|
|
6171
|
-
setTimeout(() => this.setState({ expandAllVisible: false }));
|
|
6172
|
-
}
|
|
6173
|
-
this.lastAppliedFilter = jsonFilter;
|
|
6174
|
-
}
|
|
6175
6274
|
this.unsubscribeTimer = setTimeout(() => {
|
|
6176
6275
|
this.unsubscribeTimer = null;
|
|
6177
6276
|
this.checkUnsubscribes();
|