@iobroker/json-config 8.3.13 → 8.4.1

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.
Files changed (153) hide show
  1. package/README.md +4 -0
  2. package/build/JsonConfigComponent/ConfigAccordion.d.ts +2 -2
  3. package/build/JsonConfigComponent/ConfigAccordion.js +21 -19
  4. package/build/JsonConfigComponent/ConfigAccordion.js.map +1 -1
  5. package/build/JsonConfigComponent/ConfigAlive.d.ts +3 -1
  6. package/build/JsonConfigComponent/ConfigAlive.js +22 -10
  7. package/build/JsonConfigComponent/ConfigAlive.js.map +1 -1
  8. package/build/JsonConfigComponent/ConfigAutocomplete.d.ts +1 -1
  9. package/build/JsonConfigComponent/ConfigAutocomplete.js +2 -2
  10. package/build/JsonConfigComponent/ConfigAutocomplete.js.map +1 -1
  11. package/build/JsonConfigComponent/ConfigAutocompleteSendTo.d.ts +1 -1
  12. package/build/JsonConfigComponent/ConfigAutocompleteSendTo.js +11 -3
  13. package/build/JsonConfigComponent/ConfigAutocompleteSendTo.js.map +1 -1
  14. package/build/JsonConfigComponent/ConfigCRON.d.ts +1 -1
  15. package/build/JsonConfigComponent/ConfigCRON.js +2 -2
  16. package/build/JsonConfigComponent/ConfigCRON.js.map +1 -1
  17. package/build/JsonConfigComponent/ConfigCertCollection.js +2 -2
  18. package/build/JsonConfigComponent/ConfigCertCollection.js.map +1 -1
  19. package/build/JsonConfigComponent/ConfigCertificateSelect.js +1 -1
  20. package/build/JsonConfigComponent/ConfigCertificateSelect.js.map +1 -1
  21. package/build/JsonConfigComponent/ConfigCertificates.js +2 -2
  22. package/build/JsonConfigComponent/ConfigCertificates.js.map +1 -1
  23. package/build/JsonConfigComponent/ConfigCheckDocker.js +1 -1
  24. package/build/JsonConfigComponent/ConfigCheckDocker.js.map +1 -1
  25. package/build/JsonConfigComponent/ConfigCheckLicense.d.ts +1 -1
  26. package/build/JsonConfigComponent/ConfigCheckLicense.js +7 -7
  27. package/build/JsonConfigComponent/ConfigCheckLicense.js.map +1 -1
  28. package/build/JsonConfigComponent/ConfigChip.d.ts +1 -1
  29. package/build/JsonConfigComponent/ConfigChip.js +2 -2
  30. package/build/JsonConfigComponent/ConfigChip.js.map +1 -1
  31. package/build/JsonConfigComponent/ConfigCoordinates.d.ts +1 -1
  32. package/build/JsonConfigComponent/ConfigCoordinates.js +3 -3
  33. package/build/JsonConfigComponent/ConfigCoordinates.js.map +1 -1
  34. package/build/JsonConfigComponent/ConfigDatePicker.d.ts +1 -1
  35. package/build/JsonConfigComponent/ConfigDatePicker.js +2 -2
  36. package/build/JsonConfigComponent/ConfigDatePicker.js.map +1 -1
  37. package/build/JsonConfigComponent/ConfigFile.d.ts +1 -1
  38. package/build/JsonConfigComponent/ConfigFile.js +2 -2
  39. package/build/JsonConfigComponent/ConfigFile.js.map +1 -1
  40. package/build/JsonConfigComponent/ConfigFileSelector.d.ts +1 -1
  41. package/build/JsonConfigComponent/ConfigFileSelector.js +2 -2
  42. package/build/JsonConfigComponent/ConfigFileSelector.js.map +1 -1
  43. package/build/JsonConfigComponent/ConfigFunc.d.ts +1 -1
  44. package/build/JsonConfigComponent/ConfigFunc.js +2 -2
  45. package/build/JsonConfigComponent/ConfigFunc.js.map +1 -1
  46. package/build/JsonConfigComponent/ConfigGeneric.d.ts +23 -7
  47. package/build/JsonConfigComponent/ConfigGeneric.js +178 -52
  48. package/build/JsonConfigComponent/ConfigGeneric.js.map +1 -1
  49. package/build/JsonConfigComponent/ConfigIFrame.d.ts +1 -1
  50. package/build/JsonConfigComponent/ConfigIFrame.js +2 -2
  51. package/build/JsonConfigComponent/ConfigIFrame.js.map +1 -1
  52. package/build/JsonConfigComponent/ConfigIFrameSendTo.d.ts +2 -2
  53. package/build/JsonConfigComponent/ConfigIFrameSendTo.js +15 -6
  54. package/build/JsonConfigComponent/ConfigIFrameSendTo.js.map +1 -1
  55. package/build/JsonConfigComponent/ConfigIP.d.ts +1 -1
  56. package/build/JsonConfigComponent/ConfigIP.js +2 -2
  57. package/build/JsonConfigComponent/ConfigIP.js.map +1 -1
  58. package/build/JsonConfigComponent/ConfigImageSendTo.d.ts +2 -2
  59. package/build/JsonConfigComponent/ConfigImageSendTo.js +14 -6
  60. package/build/JsonConfigComponent/ConfigImageSendTo.js.map +1 -1
  61. package/build/JsonConfigComponent/ConfigImageUpload.d.ts +1 -1
  62. package/build/JsonConfigComponent/ConfigImageUpload.js +2 -2
  63. package/build/JsonConfigComponent/ConfigImageUpload.js.map +1 -1
  64. package/build/JsonConfigComponent/ConfigInstanceSelect.d.ts +1 -1
  65. package/build/JsonConfigComponent/ConfigInstanceSelect.js +2 -2
  66. package/build/JsonConfigComponent/ConfigInstanceSelect.js.map +1 -1
  67. package/build/JsonConfigComponent/ConfigInterface.d.ts +1 -1
  68. package/build/JsonConfigComponent/ConfigInterface.js +5 -5
  69. package/build/JsonConfigComponent/ConfigInterface.js.map +1 -1
  70. package/build/JsonConfigComponent/ConfigJsonEditor.d.ts +1 -1
  71. package/build/JsonConfigComponent/ConfigJsonEditor.js +2 -2
  72. package/build/JsonConfigComponent/ConfigJsonEditor.js.map +1 -1
  73. package/build/JsonConfigComponent/ConfigLanguage.d.ts +1 -1
  74. package/build/JsonConfigComponent/ConfigLanguage.js +2 -2
  75. package/build/JsonConfigComponent/ConfigLanguage.js.map +1 -1
  76. package/build/JsonConfigComponent/ConfigLicense.d.ts +1 -1
  77. package/build/JsonConfigComponent/ConfigLicense.js +2 -2
  78. package/build/JsonConfigComponent/ConfigLicense.js.map +1 -1
  79. package/build/JsonConfigComponent/ConfigNumber.d.ts +1 -1
  80. package/build/JsonConfigComponent/ConfigNumber.js +2 -2
  81. package/build/JsonConfigComponent/ConfigNumber.js.map +1 -1
  82. package/build/JsonConfigComponent/ConfigOAuth2.js +1 -1
  83. package/build/JsonConfigComponent/ConfigOAuth2.js.map +1 -1
  84. package/build/JsonConfigComponent/ConfigObjectId.d.ts +1 -1
  85. package/build/JsonConfigComponent/ConfigObjectId.js +3 -3
  86. package/build/JsonConfigComponent/ConfigObjectId.js.map +1 -1
  87. package/build/JsonConfigComponent/ConfigPanel.d.ts +1 -1
  88. package/build/JsonConfigComponent/ConfigPanel.js +11 -8
  89. package/build/JsonConfigComponent/ConfigPanel.js.map +1 -1
  90. package/build/JsonConfigComponent/ConfigPassword.d.ts +1 -1
  91. package/build/JsonConfigComponent/ConfigPassword.js +2 -2
  92. package/build/JsonConfigComponent/ConfigPassword.js.map +1 -1
  93. package/build/JsonConfigComponent/ConfigPattern.d.ts +8 -1
  94. package/build/JsonConfigComponent/ConfigPattern.js +29 -3
  95. package/build/JsonConfigComponent/ConfigPattern.js.map +1 -1
  96. package/build/JsonConfigComponent/ConfigPort.js +2 -2
  97. package/build/JsonConfigComponent/ConfigPort.js.map +1 -1
  98. package/build/JsonConfigComponent/ConfigQrCode.js +1 -1
  99. package/build/JsonConfigComponent/ConfigQrCode.js.map +1 -1
  100. package/build/JsonConfigComponent/ConfigQrCodeSendTo.d.ts +1 -1
  101. package/build/JsonConfigComponent/ConfigQrCodeSendTo.js +22 -5
  102. package/build/JsonConfigComponent/ConfigQrCodeSendTo.js.map +1 -1
  103. package/build/JsonConfigComponent/ConfigRoom.d.ts +1 -1
  104. package/build/JsonConfigComponent/ConfigRoom.js +2 -2
  105. package/build/JsonConfigComponent/ConfigRoom.js.map +1 -1
  106. package/build/JsonConfigComponent/ConfigSelect.d.ts +13 -11
  107. package/build/JsonConfigComponent/ConfigSelect.js +35 -29
  108. package/build/JsonConfigComponent/ConfigSelect.js.map +1 -1
  109. package/build/JsonConfigComponent/ConfigSelectSendTo.d.ts +16 -11
  110. package/build/JsonConfigComponent/ConfigSelectSendTo.js +34 -23
  111. package/build/JsonConfigComponent/ConfigSelectSendTo.js.map +1 -1
  112. package/build/JsonConfigComponent/ConfigSendto.d.ts +1 -1
  113. package/build/JsonConfigComponent/ConfigSendto.js +17 -9
  114. package/build/JsonConfigComponent/ConfigSendto.js.map +1 -1
  115. package/build/JsonConfigComponent/ConfigSetState.js +2 -2
  116. package/build/JsonConfigComponent/ConfigSetState.js.map +1 -1
  117. package/build/JsonConfigComponent/ConfigSlider.d.ts +1 -1
  118. package/build/JsonConfigComponent/ConfigSlider.js +2 -2
  119. package/build/JsonConfigComponent/ConfigSlider.js.map +1 -1
  120. package/build/JsonConfigComponent/ConfigState.d.ts +2 -1
  121. package/build/JsonConfigComponent/ConfigState.js +32 -26
  122. package/build/JsonConfigComponent/ConfigState.js.map +1 -1
  123. package/build/JsonConfigComponent/ConfigTable.d.ts +1 -1
  124. package/build/JsonConfigComponent/ConfigTable.js +21 -19
  125. package/build/JsonConfigComponent/ConfigTable.js.map +1 -1
  126. package/build/JsonConfigComponent/ConfigTabs.d.ts +6 -0
  127. package/build/JsonConfigComponent/ConfigTabs.js +57 -21
  128. package/build/JsonConfigComponent/ConfigTabs.js.map +1 -1
  129. package/build/JsonConfigComponent/ConfigText.d.ts +1 -1
  130. package/build/JsonConfigComponent/ConfigText.js +2 -2
  131. package/build/JsonConfigComponent/ConfigText.js.map +1 -1
  132. package/build/JsonConfigComponent/ConfigTextSendTo.d.ts +1 -1
  133. package/build/JsonConfigComponent/ConfigTextSendTo.js +11 -3
  134. package/build/JsonConfigComponent/ConfigTextSendTo.js.map +1 -1
  135. package/build/JsonConfigComponent/ConfigTimePicker.d.ts +1 -1
  136. package/build/JsonConfigComponent/ConfigTimePicker.js +2 -2
  137. package/build/JsonConfigComponent/ConfigTimePicker.js.map +1 -1
  138. package/build/JsonConfigComponent/ConfigTopic.d.ts +1 -1
  139. package/build/JsonConfigComponent/ConfigTopic.js +2 -2
  140. package/build/JsonConfigComponent/ConfigTopic.js.map +1 -1
  141. package/build/JsonConfigComponent/ConfigUUID.js +2 -2
  142. package/build/JsonConfigComponent/ConfigUUID.js.map +1 -1
  143. package/build/JsonConfigComponent/ConfigUser.d.ts +1 -1
  144. package/build/JsonConfigComponent/ConfigUser.js +2 -2
  145. package/build/JsonConfigComponent/ConfigUser.js.map +1 -1
  146. package/build/JsonConfigComponent/ConfigYamlEditor.d.ts +1 -1
  147. package/build/JsonConfigComponent/ConfigYamlEditor.js +2 -2
  148. package/build/JsonConfigComponent/ConfigYamlEditor.js.map +1 -1
  149. package/build/JsonConfigComponent/index.d.ts +2 -0
  150. package/build/JsonConfigComponent/index.js +16 -1
  151. package/build/JsonConfigComponent/index.js.map +1 -1
  152. package/build/types.d.ts +1 -0
  153. package/package.json +1 -1
@@ -24,8 +24,11 @@ export default class ConfigGeneric extends Component {
24
24
  sendToTimeout;
25
25
  noPlaceRequired;
26
26
  reportedHidden = false;
27
+ calculateTimeout = null;
28
+ AsyncFunction;
27
29
  constructor(props) {
28
30
  super(props);
31
+ this.AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
29
32
  // @ts-expect-error of course, as we just
30
33
  this.state = {
31
34
  confirmDialog: false,
@@ -35,24 +38,30 @@ export default class ConfigGeneric extends Component {
35
38
  confirmCallback: null,
36
39
  };
37
40
  this.isError = {};
41
+ this.lang = I18n.getLanguage();
42
+ // Initialize literal defaults synchronously so the first render has them.
43
+ // defaultFunc is evaluated asynchronously in componentDidMount.
38
44
  if (props.schema) {
39
45
  if (props.custom) {
40
- this.defaultValue = props.schema.defaultFunc
41
- ? this.executeCustom(props.schema.defaultFunc, props.data, props.customObj, props.oContext.instanceObj, props.arrayIndex, props.globalData)
42
- : props.schema.default;
46
+ if (!props.schema.defaultFunc) {
47
+ this.defaultValue = props.schema.default;
48
+ }
43
49
  }
44
- else if (props.schema.type !== 'state') {
45
- this.defaultValue = props.schema.defaultFunc
46
- ? this.execute(props.schema.defaultFunc, props.schema.default, props.data, props.arrayIndex, props.globalData)
47
- : props.schema.default;
50
+ else if (props.schema.type !== 'state' && !props.schema.defaultFunc) {
51
+ this.defaultValue = props.schema.default;
48
52
  }
49
53
  }
50
- this.lang = I18n.getLanguage();
51
54
  }
52
- componentDidMount() {
53
- if (this.props.oContext.registerOnForceUpdate) {
54
- this.props.oContext.registerOnForceUpdate(this.props.attr, this.onUpdate);
55
+ async componentDidMount() {
56
+ if (this.props.schema?.defaultFunc) {
57
+ if (this.props.custom) {
58
+ this.defaultValue = await this.executeCustom(this.props.schema.defaultFunc, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData);
59
+ }
60
+ else if (this.props.schema.type !== 'state') {
61
+ this.defaultValue = await this.execute(this.props.schema.defaultFunc, this.props.schema.default, this.props.data, this.props.arrayIndex, this.props.globalData);
62
+ }
55
63
  }
64
+ this.props.oContext.registerOnForceUpdate?.(this.props.attr, this.onUpdate);
56
65
  const LIKE_SELECT = ['select', 'autocomplete', 'autocompleteSendTo'];
57
66
  // init default value
58
67
  if (this.defaultValue !== undefined) {
@@ -71,15 +80,15 @@ export default class ConfigGeneric extends Component {
71
80
  }
72
81
  }
73
82
  else if (this.props.schema.defaultSendTo) {
74
- this.sendTo();
83
+ this.sendTo().catch(e => console.error(e));
75
84
  }
76
85
  }
77
- sendTo() {
86
+ async sendTo() {
78
87
  if (this.props.alive) {
79
88
  this.defaultSendToDone = true;
80
89
  let data = this.props.schema.data;
81
90
  if (data === undefined && this.props.schema.jsonData) {
82
- const dataStr = this.getPattern(this.props.schema.jsonData, null, true);
91
+ const dataStr = await this.getPatternAsync(this.props.schema.jsonData, null, true);
83
92
  try {
84
93
  data = JSON.parse(dataStr);
85
94
  }
@@ -96,8 +105,18 @@ export default class ConfigGeneric extends Component {
96
105
  if (data === undefined) {
97
106
  data = null;
98
107
  }
108
+ const instance = await this.getPatternAsync(this.props.schema.instance ||
109
+ `${this.props.oContext.adapterName}.${this.props.oContext.instance}`);
110
+ // Check that instance is alive
111
+ if (instance !== `${this.props.oContext.adapterName}.${this.props.oContext.instance}`) {
112
+ const alive = await this.props.oContext.socket.getState(`system.adapter.${instance}.alive`);
113
+ if (!alive?.val) {
114
+ window.alert(I18n.t('ra_Instance %s is not alive', instance));
115
+ return;
116
+ }
117
+ }
99
118
  void this.props.oContext.socket
100
- .sendTo(`${this.props.oContext.adapterName}.${this.props.oContext.instance}`, this.props.schema.defaultSendTo, data)
119
+ .sendTo(instance, this.props.schema.defaultSendTo, data)
101
120
  .then((value) => {
102
121
  if (value !== null && value !== undefined) {
103
122
  if (this.props.custom) {
@@ -126,6 +145,10 @@ export default class ConfigGeneric extends Component {
126
145
  clearTimeout(this.sendToTimeout);
127
146
  this.sendToTimeout = null;
128
147
  }
148
+ if (this.calculateTimeout) {
149
+ clearTimeout(this.calculateTimeout);
150
+ this.calculateTimeout = null;
151
+ }
129
152
  }
130
153
  onUpdate = (data) => {
131
154
  const value = ConfigGeneric.getValue(data || this.props.data, this.props.attr) || '';
@@ -351,12 +374,12 @@ export default class ConfigGeneric extends Component {
351
374
  * @param newValue new value of the attribute
352
375
  * @param cb optional callback function, else returns a Promise
353
376
  */
354
- onChange(attr, newValue, cb) {
377
+ async onChange(attr, newValue, cb) {
355
378
  // Do not use here deep copy, as it is not JsonConfig
356
379
  const data = JSON.parse(JSON.stringify(this.props.data));
357
380
  ConfigGeneric.setValue(data, attr, newValue);
358
381
  if (this.props.schema.confirm &&
359
- this.execute(this.props.schema.confirm.condition, false, data, this.props.arrayIndex, this.props.globalData)) {
382
+ (await this.execute(this.props.schema.confirm.condition, false, data, this.props.arrayIndex, this.props.globalData))) {
360
383
  return new Promise(resolve => {
361
384
  this.setState({
362
385
  confirmDialog: true,
@@ -379,7 +402,7 @@ export default class ConfigGeneric extends Component {
379
402
  const dep = this.props.schema.confirmDependsOn[z];
380
403
  if (dep.confirm) {
381
404
  const val = ConfigGeneric.getValue(data, dep.attr);
382
- if (this.execute(dep.confirm.condition, false, data, this.props.arrayIndex, this.props.globalData)) {
405
+ if (await this.execute(dep.confirm.condition, false, data, this.props.arrayIndex, this.props.globalData)) {
383
406
  return new Promise(resolve => {
384
407
  this.setState({
385
408
  confirmDialog: true,
@@ -409,10 +432,10 @@ export default class ConfigGeneric extends Component {
409
432
  const val = ConfigGeneric.getValue(data, dep.attr);
410
433
  let _newValue;
411
434
  if (this.props.custom) {
412
- _newValue = this.executeCustom(dep.onChange.calculateFunc, data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData);
435
+ _newValue = await this.executeCustom(dep.onChange.calculateFunc, data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData);
413
436
  }
414
437
  else {
415
- _newValue = this.execute(dep.onChange.calculateFunc, val, data, this.props.arrayIndex, this.props.globalData);
438
+ _newValue = await this.execute(dep.onChange.calculateFunc, val, data, this.props.arrayIndex, this.props.globalData);
416
439
  }
417
440
  if (_newValue !== val) {
418
441
  ConfigGeneric.setValue(data, dep.attr, _newValue);
@@ -448,8 +471,8 @@ export default class ConfigGeneric extends Component {
448
471
  if (this.props.schema.onChange && !this.props.schema.onChange.ignoreOwnChanges) {
449
472
  const val = ConfigGeneric.getValue(data, this.props.attr);
450
473
  const newValue_ = this.props.custom
451
- ? this.executeCustom(this.props.schema.onChange.calculateFunc, data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
452
- : this.execute(this.props.schema.onChange.calculateFunc, val, data, this.props.arrayIndex, this.props.globalData);
474
+ ? await this.executeCustom(this.props.schema.onChange.calculateFunc, data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
475
+ : await this.execute(this.props.schema.onChange.calculateFunc, val, data, this.props.arrayIndex, this.props.globalData);
453
476
  if (newValue_ !== val) {
454
477
  ConfigGeneric.setValue(data, this.props.attr, newValue_);
455
478
  }
@@ -465,14 +488,22 @@ export default class ConfigGeneric extends Component {
465
488
  if (changed.length) {
466
489
  this.props.oContext.forceUpdate(changed, data);
467
490
  }
468
- if (cb) {
469
- cb();
470
- }
491
+ cb?.();
471
492
  });
472
493
  }
473
494
  return Promise.resolve();
474
495
  }
475
- execute(func, defaultValue, data, arrayIndex, globalData) {
496
+ /** Ensure that every bare getObject( call is preceded by "await". */
497
+ static ensureAwaitGetObject(code) {
498
+ return code.replace(/(?<![\w$.])getObject\(/g, (match, offset) => {
499
+ const before = code.slice(Math.max(0, offset - 10), offset);
500
+ if (/await\s+$/.test(before)) {
501
+ return match;
502
+ }
503
+ return `await ${match}`;
504
+ });
505
+ }
506
+ async execute(func, defaultValue, data, arrayIndex, globalData) {
476
507
  let fun;
477
508
  if (isObject(func)) {
478
509
  fun = func.func;
@@ -486,16 +517,20 @@ export default class ConfigGeneric extends Component {
486
517
  if (!fun) {
487
518
  return defaultValue;
488
519
  }
520
+ if (fun.includes('getObject(')) {
521
+ // ensure, that await is placed in front of getObject
522
+ fun = ConfigGeneric.ensureAwaitGetObject(fun);
523
+ }
489
524
  try {
490
- const f = new Function('data', 'originalData', '_system', '_alive', '_common', '_socket', '_instance', 'arrayIndex', 'globalData', '_changed', fun.includes('return') ? fun : `return ${fun}`);
491
- return f(data || this.props.data, this.props.originalData, this.props.oContext.systemConfig, this.props.alive, this.props.common, this.props.oContext.socket, this.props.oContext.instance, arrayIndex, globalData, this.props.changed);
525
+ const f = new this.AsyncFunction('data', 'originalData', '_system', '_alive', '_common', '_socket', '_instance', 'arrayIndex', 'globalData', '_changed', '_href', 'getObject', fun.includes('return') ? fun : `return ${fun}`);
526
+ return await f(data || this.props.data, this.props.originalData, this.props.oContext.systemConfig, this.props.alive, this.props.common, this.props.oContext.socket, this.props.oContext.instance, arrayIndex, globalData, this.props.changed, window.location.href, this.getObject);
492
527
  }
493
528
  catch (e) {
494
529
  console.error(`Cannot execute ${JSON.stringify(func)}: ${e}`);
495
530
  return defaultValue;
496
531
  }
497
532
  }
498
- executeCustom(func, data, customObj, instanceObj, arrayIndex, globalData) {
533
+ async executeCustom(func, data, customObj, instanceObj, arrayIndex, globalData) {
499
534
  let fun;
500
535
  if (isObject(func)) {
501
536
  fun = func.func;
@@ -509,30 +544,34 @@ export default class ConfigGeneric extends Component {
509
544
  if (!fun) {
510
545
  return null;
511
546
  }
547
+ if (fun.includes('getObject(')) {
548
+ // ensure, that await is placed in front of getObject
549
+ fun = ConfigGeneric.ensureAwaitGetObject(fun);
550
+ }
512
551
  try {
513
- const f = new Function('data', 'originalData', '_system', 'instanceObj', 'customObj', '_socket', 'arrayIndex', 'globalData', '_changed', fun.includes('return') ? fun : `return ${fun}`);
514
- return f(data || this.props.data, this.props.originalData, this.props.oContext.systemConfig, instanceObj, customObj, this.props.oContext.socket, arrayIndex, globalData, this.props.changed);
552
+ const f = new this.AsyncFunction('data', 'originalData', '_system', 'instanceObj', 'customObj', '_socket', 'arrayIndex', 'globalData', '_changed', '_href', 'getObject', fun.includes('return') ? fun : `return ${fun}`);
553
+ return await f(data || this.props.data, this.props.originalData, this.props.oContext.systemConfig, instanceObj, customObj, this.props.oContext.socket, arrayIndex, globalData, this.props.changed, window.location.href, this.getObject);
515
554
  }
516
555
  catch (e) {
517
556
  console.error(`Cannot execute ${fun}: ${e}`);
518
557
  return null;
519
558
  }
520
559
  }
521
- calculate(schema) {
560
+ async calculate(schema) {
522
561
  let error;
523
562
  let disabled;
524
563
  let hidden;
525
564
  let defaultValue;
526
565
  if (this.props.custom) {
527
566
  error = schema.validator
528
- ? !this.executeCustom(schema.validator, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
567
+ ? !(await this.executeCustom(schema.validator, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData))
529
568
  : false;
530
569
  if (schema.disabled === true) {
531
570
  disabled = true;
532
571
  }
533
572
  else {
534
573
  disabled = schema.disabled
535
- ? this.executeCustom(schema.disabled, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
574
+ ? (await this.executeCustom(schema.disabled, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData))
536
575
  : false;
537
576
  }
538
577
  if (schema.hidden === true) {
@@ -540,23 +579,23 @@ export default class ConfigGeneric extends Component {
540
579
  }
541
580
  else {
542
581
  hidden = schema.hidden
543
- ? this.executeCustom(schema.hidden, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
582
+ ? (await this.executeCustom(schema.hidden, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData))
544
583
  : false;
545
584
  }
546
585
  defaultValue = schema.defaultFunc
547
- ? this.executeCustom(schema.defaultFunc, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
586
+ ? await this.executeCustom(schema.defaultFunc, this.props.data, this.props.customObj, this.props.oContext.instanceObj, this.props.arrayIndex, this.props.globalData)
548
587
  : schema.default;
549
588
  }
550
589
  else {
551
590
  error = schema.validator
552
- ? !this.execute(schema.validator, false, this.props.data, this.props.arrayIndex, this.props.globalData)
591
+ ? !(await this.execute(schema.validator, false, this.props.data, this.props.arrayIndex, this.props.globalData))
553
592
  : false;
554
593
  if (schema.disabled === true) {
555
594
  disabled = true;
556
595
  }
557
596
  else {
558
597
  disabled = schema.disabled
559
- ? this.execute(schema.disabled, false, this.props.data, this.props.arrayIndex, this.props.globalData)
598
+ ? (await this.execute(schema.disabled, false, this.props.data, this.props.arrayIndex, this.props.globalData))
560
599
  : false;
561
600
  }
562
601
  if (schema.hidden === true) {
@@ -564,11 +603,11 @@ export default class ConfigGeneric extends Component {
564
603
  }
565
604
  else {
566
605
  hidden = schema.hidden
567
- ? this.execute(schema.hidden, false, this.props.data, this.props.arrayIndex, this.props.globalData)
606
+ ? (await this.execute(schema.hidden, false, this.props.data, this.props.arrayIndex, this.props.globalData))
568
607
  : false;
569
608
  }
570
609
  defaultValue = schema.defaultFunc
571
- ? this.execute(schema.defaultFunc, schema.default, this.props.data, this.props.arrayIndex, this.props.globalData)
610
+ ? await this.execute(schema.defaultFunc, schema.default, this.props.data, this.props.arrayIndex, this.props.globalData)
572
611
  : schema.default;
573
612
  }
574
613
  return {
@@ -629,6 +668,60 @@ export default class ConfigGeneric extends Component {
629
668
  });
630
669
  return str;
631
670
  }
671
+ /** This function is used in pattern */
672
+ getObject = async (id) => {
673
+ try {
674
+ const obj = await this.props.oContext.getCachedObject(id);
675
+ return obj || null;
676
+ }
677
+ catch (e) {
678
+ console.error(e);
679
+ return null;
680
+ }
681
+ };
682
+ async getPatternAsync(pattern, data, noTranslation) {
683
+ data ||= this.props.data;
684
+ if (!pattern) {
685
+ return '';
686
+ }
687
+ let patternStr;
688
+ if (typeof pattern === 'object') {
689
+ if (pattern.func) {
690
+ patternStr = pattern.func;
691
+ }
692
+ else {
693
+ console.log(`Object must be stringified: ${JSON.stringify(pattern)}`);
694
+ patternStr = JSON.stringify(pattern);
695
+ }
696
+ }
697
+ else {
698
+ patternStr = pattern;
699
+ }
700
+ if (patternStr.includes('getObject(')) {
701
+ // ensure, that await is placed in front of getObject
702
+ patternStr = ConfigGeneric.ensureAwaitGetObject(patternStr);
703
+ }
704
+ try {
705
+ if (this.props.custom) {
706
+ const f = new this.AsyncFunction('data', 'originalData', 'arrayIndex', 'globalData', '_system', 'instanceObj', 'customObj', '_socket', '_changed', '_href', 'getObject', `return \`${ConfigGeneric.escapeString(patternStr, data)}\``);
707
+ const text = await f(data, this.props.originalData, this.props.arrayIndex, this.props.globalData, this.props.oContext.systemConfig, this.props.oContext.instanceObj, this.props.customObj, this.props.oContext.socket, this.props.changed, window.location.href, this.getObject);
708
+ if (noTranslation) {
709
+ return text;
710
+ }
711
+ return I18n.t(text);
712
+ }
713
+ const f = new this.AsyncFunction('data', 'originalData', 'arrayIndex', 'globalData', '_system', '_alive', '_common', '_socket', '_changed', '_href', 'getObject', `return \`${ConfigGeneric.escapeString(patternStr, data)}\``);
714
+ const text = await f(data, this.props.originalData, this.props.arrayIndex, this.props.globalData, this.props.oContext.systemConfig, this.props.alive, this.props.common, this.props.oContext.socket, this.props.changed, window.location.href, this.getObject);
715
+ if (noTranslation) {
716
+ return text;
717
+ }
718
+ return I18n.t(text);
719
+ }
720
+ catch (e) {
721
+ console.error(`Cannot execute ${patternStr}: ${e}`);
722
+ return patternStr;
723
+ }
724
+ }
632
725
  getPattern(pattern, data, noTranslation) {
633
726
  data ||= this.props.data;
634
727
  if (!pattern) {
@@ -647,13 +740,21 @@ export default class ConfigGeneric extends Component {
647
740
  else {
648
741
  patternStr = pattern;
649
742
  }
743
+ if (patternStr.includes('getObject(')) {
744
+ // ensure, that await is placed in front of getObject
745
+ console.log(`It is not possible to use getObject function in text patterns: ${patternStr}`);
746
+ }
650
747
  try {
651
748
  if (this.props.custom) {
652
- const f = new Function('data', 'originalData', 'arrayIndex', 'globalData', '_system', 'instanceObj', 'customObj', '_socket', '_changed', '_href', `return \`${ConfigGeneric.escapeString(patternStr, data)}\``);
653
- return f(data, this.props.originalData, this.props.arrayIndex, this.props.globalData, this.props.oContext.systemConfig, this.props.oContext.instanceObj, this.props.customObj, this.props.oContext.socket, this.props.changed, window.location.href);
749
+ const f = new this.AsyncFunction('data', 'originalData', 'arrayIndex', 'globalData', '_system', 'instanceObj', 'customObj', '_socket', '_changed', '_href', 'getObject', `return \`${ConfigGeneric.escapeString(patternStr, data)}\``);
750
+ const text = f(data, this.props.originalData, this.props.arrayIndex, this.props.globalData, this.props.oContext.systemConfig, this.props.oContext.instanceObj, this.props.customObj, this.props.oContext.socket, this.props.changed, window.location.href, this.getObject);
751
+ if (noTranslation) {
752
+ return text;
753
+ }
754
+ return I18n.t(text);
654
755
  }
655
- const f = new Function('data', 'originalData', 'arrayIndex', 'globalData', '_system', '_alive', '_common', '_socket', '_changed', '_href', `return \`${ConfigGeneric.escapeString(patternStr, data)}\``);
656
- const text = f(data, this.props.originalData, this.props.arrayIndex, this.props.globalData, this.props.oContext.systemConfig, this.props.alive, this.props.common, this.props.oContext.socket, this.props.changed, window.location.href);
756
+ const f = new this.AsyncFunction('data', 'originalData', 'arrayIndex', 'globalData', '_system', '_alive', '_common', '_socket', '_changed', '_href', 'getObject', `return \`${ConfigGeneric.escapeString(patternStr, data)}\``);
757
+ const text = f(data, this.props.originalData, this.props.arrayIndex, this.props.globalData, this.props.oContext.systemConfig, this.props.alive, this.props.common, this.props.oContext.socket, this.props.changed, window.location.href, this.getObject);
657
758
  if (noTranslation) {
658
759
  return text;
659
760
  }
@@ -664,6 +765,28 @@ export default class ConfigGeneric extends Component {
664
765
  return patternStr;
665
766
  }
666
767
  }
768
+ updateCalculatedValues() {
769
+ if (this.calculateTimeout) {
770
+ clearTimeout(this.calculateTimeout);
771
+ }
772
+ this.calculateTimeout = setTimeout(async () => {
773
+ this.calculateTimeout = null;
774
+ const schema = this.props.schema;
775
+ if (!schema) {
776
+ return null;
777
+ }
778
+ const { error, disabled, hidden, defaultValue } = await this.calculate(schema);
779
+ if (!this.state.calculatedValues ||
780
+ this.state.calculatedValues.error !== error ||
781
+ this.state.calculatedValues.disabled !== disabled ||
782
+ this.state.calculatedValues.hidden !== hidden ||
783
+ this.state.calculatedValues.defaultValue !== defaultValue) {
784
+ this.setState({
785
+ calculatedValues: { error, disabled, hidden, defaultValue },
786
+ });
787
+ }
788
+ }, 50);
789
+ }
667
790
  render() {
668
791
  const schema = this.props.schema;
669
792
  if (!schema) {
@@ -674,13 +797,16 @@ export default class ConfigGeneric extends Component {
674
797
  return null;
675
798
  }
676
799
  if (this.props.alive && this.defaultSendToDone === false) {
677
- this.sendToTimeout = setTimeout(() => {
800
+ this.sendToTimeout = setTimeout(async () => {
678
801
  this.sendToTimeout = null;
679
- this.sendTo();
802
+ await this.sendTo();
680
803
  }, 200);
681
804
  }
682
- const { error, disabled, hidden, defaultValue } = this.calculate(schema);
683
- if (hidden) {
805
+ this.updateCalculatedValues();
806
+ if (!this.state.calculatedValues) {
807
+ return null;
808
+ }
809
+ if (this.state.calculatedValues.hidden) {
684
810
  // Remove all errors if an element is hidden
685
811
  if (Object.keys(this.isError).length) {
686
812
  setTimeout(isError => Object.keys(isError).forEach(attr => this.props.onError(attr)), 100, JSON.parse(JSON.stringify(this.isError)));
@@ -719,18 +845,18 @@ export default class ConfigGeneric extends Component {
719
845
  }
720
846
  // Add error
721
847
  if (schema.validatorNoSaveOnError) {
722
- if (error && !Object.keys(this.isError).length) {
848
+ if (this.state.calculatedValues.error && !Object.keys(this.isError).length) {
723
849
  this.isError = {
724
850
  [this.props.attr]: schema.validatorErrorText ? I18n.t(schema.validatorErrorText) : true,
725
851
  };
726
852
  setTimeout(isError => Object.keys(isError).forEach(attr => this.props.onError(attr, isError[attr])), 100, JSON.parse(JSON.stringify(this.isError)));
727
853
  }
728
- else if (!error && Object.keys(this.isError).length) {
854
+ else if (!this.state.calculatedValues.error && Object.keys(this.isError).length) {
729
855
  setTimeout(isError => Object.keys(isError).forEach(attr => this.props.onError(attr)), 100, JSON.parse(JSON.stringify(this.isError)));
730
856
  this.isError = {};
731
857
  }
732
858
  }
733
- const renderedItem = this.renderItem(error, disabled || this.props.commandRunning || this.props.disabled, defaultValue);
859
+ const renderedItem = this.renderItem(this.state.calculatedValues.error, this.state.calculatedValues.disabled || this.props.commandRunning || this.props.disabled, this.state.calculatedValues.defaultValue);
734
860
  if (this.noPlaceRequired) {
735
861
  return renderedItem;
736
862
  }
@@ -749,7 +875,7 @@ export default class ConfigGeneric extends Component {
749
875
  } }, this.props.schema.defaultSendTo && this.props.schema.button ? (React.createElement(Grid2, { container: true, style: { width: '100%' } },
750
876
  React.createElement(Grid2, { flex: 1 }, renderedItem),
751
877
  React.createElement(Grid2, null,
752
- React.createElement(Button, { disabled: disabled, variant: "outlined", onClick: () => this.sendTo(), title: this.props.schema.buttonTooltip
878
+ React.createElement(Button, { disabled: this.state.calculatedValues.disabled, variant: "outlined", onClick: () => this.sendTo(), title: this.props.schema.buttonTooltip
753
879
  ? this.getText(this.props.schema.buttonTooltip, this.props.schema.buttonTooltipNoTranslation)
754
880
  : I18n.t('ra_Request data by instance') }, this.getText(this.props.schema.button))))) : (renderedItem)));
755
881
  if (schema.newLine) {