@flexem/fc-gui 3.0.0-alpha.18 → 3.0.0-alpha.181

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 (194) hide show
  1. package/CHANGELOG.md +419 -1
  2. package/assets/img/black_first_page.png +0 -0
  3. package/assets/img/black_last_page.png +0 -0
  4. package/assets/img/black_next_page.png +0 -0
  5. package/assets/img/black_previous_page.png +0 -0
  6. package/assets/img/exclamation-outline-circle.png +0 -0
  7. package/bundles/@flexem/fc-gui.umd.js +37413 -32291
  8. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  9. package/bundles/@flexem/fc-gui.umd.min.js +5 -5
  10. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  11. package/communication/variable/variable-communicator.d.ts +5 -0
  12. package/communication/variable/variable-state-enum.d.ts +1 -0
  13. package/communication/variable/variable-state-enum.js +1 -0
  14. package/communication/variable/variable-state-enum.metadata.json +1 -1
  15. package/communication/variable/variable-value.d.ts +4 -1
  16. package/communication/variable/variable-value.js +4 -1
  17. package/communication/variable/variable-value.metadata.json +1 -1
  18. package/config/alarm/alarm.store.d.ts +6 -0
  19. package/config/alarm/alarm.store.js +0 -0
  20. package/config/alarm/alarm.store.metadata.json +1 -0
  21. package/config/alarm/get-alarms-args.d.ts +12 -0
  22. package/config/alarm/get-alarms-args.js +13 -0
  23. package/config/alarm/get-alarms-args.metadata.json +1 -0
  24. package/config/alarm/index.d.ts +2 -0
  25. package/config/alarm/index.js +1 -0
  26. package/config/alarm/index.metadata.json +1 -0
  27. package/config/config-store.d.ts +2 -0
  28. package/config/gui-feature-config.d.ts +3 -0
  29. package/config/gui-feature-config.js +3 -0
  30. package/config/gui-feature-config.metadata.json +1 -0
  31. package/config/index.d.ts +2 -0
  32. package/config/index.js +2 -0
  33. package/config/index.metadata.json +1 -1
  34. package/config/variable/variable-store.d.ts +1 -0
  35. package/elements/air-quality/air-quality-element.js +3 -4
  36. package/elements/alarm/alarm-element.d.ts +89 -0
  37. package/elements/alarm/alarm-element.js +739 -0
  38. package/elements/alarm/alarm-element.metadata.json +1 -0
  39. package/elements/bar-graph-element.d.ts +10 -2
  40. package/elements/bar-graph-element.js +135 -5
  41. package/elements/bar-graph-element.metadata.json +1 -1
  42. package/elements/base/readable-element.d.ts +6 -1
  43. package/elements/base/readable-element.js +69 -2
  44. package/elements/base/readable-element.metadata.json +1 -1
  45. package/elements/base/state-control-element.d.ts +13 -1
  46. package/elements/base/state-control-element.js +42 -8
  47. package/elements/base/state-control-element.metadata.json +1 -1
  48. package/elements/character-display/character-display-element.d.ts +9 -0
  49. package/elements/character-display/character-display-element.js +18 -2
  50. package/elements/character-display/character-display-element.metadata.json +1 -1
  51. package/elements/datetime-display/datetime-display-element.d.ts +1 -0
  52. package/elements/datetime-display/datetime-display-element.js +10 -2
  53. package/elements/datetime-display/datetime-display-element.metadata.json +1 -1
  54. package/elements/datetime-display/time-zone-select-json.d.ts +8 -0
  55. package/elements/datetime-display/time-zone-select-json.js +558 -0
  56. package/elements/historical-curve/historical-curve.element.d.ts +45 -3
  57. package/elements/historical-curve/historical-curve.element.js +722 -45
  58. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  59. package/elements/main-element.d.ts +1 -0
  60. package/elements/main-element.js +71 -9
  61. package/elements/main-element.metadata.json +1 -1
  62. package/elements/meter-element.d.ts +7 -1
  63. package/elements/meter-element.js +76 -7
  64. package/elements/meter-element.metadata.json +1 -1
  65. package/elements/numerical-display/numerical-display-element.d.ts +31 -3
  66. package/elements/numerical-display/numerical-display-element.js +160 -12
  67. package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
  68. package/elements/per-view-variable-communicator.d.ts +4 -0
  69. package/elements/per-view-variable-communicator.js +21 -1
  70. package/elements/per-view-variable-communicator.metadata.json +1 -1
  71. package/elements/ring-graph/ring-graph-element.d.ts +13 -1
  72. package/elements/ring-graph/ring-graph-element.js +164 -3
  73. package/elements/ring-graph/ring-graph-element.metadata.json +1 -1
  74. package/elements/scroll-alarm/scroll-alarm-element.d.ts +79 -0
  75. package/elements/scroll-alarm/scroll-alarm-element.js +845 -0
  76. package/elements/scroll-alarm/scroll-alarm-element.metadata.json +1 -0
  77. package/elements/shared/graph/graph-state-element.d.ts +1 -0
  78. package/elements/shared/graph/graph-state-element.js +30 -1
  79. package/elements/shared/graph/graph-state-element.metadata.json +1 -1
  80. package/elements/shared/text/text-element.d.ts +14 -0
  81. package/elements/shared/text/text-element.js +42 -4
  82. package/elements/shared/text/text-element.metadata.json +1 -1
  83. package/elements/shared/text/text-state-element.d.ts +39 -2
  84. package/elements/shared/text/text-state-element.js +242 -67
  85. package/elements/shared/text/text-state-element.metadata.json +1 -1
  86. package/elements/static-elements/hyperlink-element.d.ts +28 -2
  87. package/elements/static-elements/hyperlink-element.js +153 -4
  88. package/elements/static-elements/hyperlink-element.metadata.json +1 -1
  89. package/elements/static-elements/text-element.d.ts +28 -2
  90. package/elements/static-elements/text-element.js +162 -12
  91. package/elements/static-elements/text-element.metadata.json +1 -1
  92. package/elements/switch-indicator-light/bit-indicator-light-operator.d.ts +1 -0
  93. package/elements/switch-indicator-light/bit-indicator-light-operator.js +10 -3
  94. package/elements/switch-indicator-light/bit-indicator-light-operator.metadata.json +1 -1
  95. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +20 -2
  96. package/elements/switch-indicator-light/switch-indicator-light-element.js +85 -12
  97. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  98. package/elements/switch-indicator-light/word-indicator-light-operator.d.ts +1 -0
  99. package/elements/switch-indicator-light/word-indicator-light-operator.js +10 -3
  100. package/elements/switch-indicator-light/word-indicator-light-operator.metadata.json +1 -1
  101. package/elements/video/video-element.d.ts +10 -0
  102. package/elements/video/video-element.js +139 -21
  103. package/elements/video/video-element.metadata.json +1 -1
  104. package/elements/view-operation/view-operation.element.d.ts +28 -2
  105. package/elements/view-operation/view-operation.element.js +165 -5
  106. package/elements/view-operation/view-operation.element.metadata.json +1 -1
  107. package/elements/weather/weater-element.js +0 -1
  108. package/gui/gui-context.d.ts +25 -2
  109. package/gui/gui-host.d.ts +1 -1
  110. package/gui/gui-view.d.ts +19 -2
  111. package/gui/gui-view.js +147 -12
  112. package/gui/gui-view.metadata.json +1 -1
  113. package/gui/gui.component.d.ts +3 -0
  114. package/gui/gui.component.js +15 -2
  115. package/gui/gui.component.metadata.json +1 -1
  116. package/localization/localization.service.d.ts +11 -0
  117. package/localization/localization.service.js +16 -5
  118. package/localization/localization.service.metadata.json +1 -1
  119. package/localization/localization.service.zh_CN.js +12 -1
  120. package/localization/localization.service.zh_CN.metadata.json +1 -1
  121. package/modal/write-character/write-character-modal.component.d.ts +3 -2
  122. package/modal/write-character/write-character-modal.component.html +4 -4
  123. package/modal/write-character/write-character-modal.component.js +7 -5
  124. package/modal/write-character/write-character-modal.component.less +15 -0
  125. package/modal/write-character/write-character-modal.component.metadata.json +1 -1
  126. package/modal/write-value/write-value-modal-args.d.ts +5 -1
  127. package/modal/write-value/write-value-modal-args.js +3 -1
  128. package/modal/write-value/write-value-modal-args.metadata.json +1 -1
  129. package/modal/write-value/write-value-modal.component.d.ts +15 -8
  130. package/modal/write-value/write-value-modal.component.html +10 -5
  131. package/modal/write-value/write-value-modal.component.js +99 -21
  132. package/modal/write-value/write-value-modal.component.less +16 -1
  133. package/modal/write-value/write-value-modal.component.metadata.json +1 -1
  134. package/model/alarm/alarm.model.d.ts +14 -0
  135. package/model/alarm/alarm.model.js +0 -0
  136. package/model/alarm/alarm.model.metadata.json +1 -0
  137. package/model/bar-graph/bar-graph.d.ts +4 -0
  138. package/model/base/font-setting-model.d.ts +22 -1
  139. package/model/base/font-setting-model.metadata.json +1 -1
  140. package/model/base/readable-model.d.ts +4 -0
  141. package/model/character-display/character-display.d.ts +1 -0
  142. package/model/datetime-display/datetime-display.d.ts +1 -0
  143. package/model/historical-curve/historical-curve-axis-settings.d.ts +11 -0
  144. package/model/historical-curve/historical-curve-axis-settings.js +5 -0
  145. package/model/historical-curve/historical-curve-axis-settings.metadata.json +1 -1
  146. package/model/historical-curve/historical-curve-chanel.model.d.ts +8 -0
  147. package/model/historical-curve/historical-curve.display-settings.d.ts +1 -0
  148. package/model/meter/meter.d.ts +4 -0
  149. package/model/numerical-display/numerical-display.d.ts +1 -0
  150. package/model/numerical-display/numerical-operation.d.ts +10 -2
  151. package/model/ring-graph/ring-graph.model.d.ts +8 -0
  152. package/model/scroll-alarm/scroll-alarm.model.d.ts +21 -0
  153. package/model/scroll-alarm/scroll-alarm.model.js +0 -0
  154. package/model/scroll-alarm/scroll-alarm.model.metadata.json +1 -0
  155. package/model/settings/popup/view-popup-location-type.d.ts +2 -1
  156. package/model/settings/popup/view-popup-location-type.js +1 -0
  157. package/model/settings/popup/view-popup-location-type.metadata.json +1 -1
  158. package/model/shared/state/state.d.ts +1 -0
  159. package/model/shared/state/state.js +1 -0
  160. package/model/shared/state/state.metadata.json +1 -1
  161. package/model/shared/text/font.d.ts +1 -1
  162. package/model/shared/text/text.d.ts +3 -0
  163. package/model/switch-indicator-light/switch-indicator-light.d.ts +3 -0
  164. package/model/view-operation/view-operation-element.model.d.ts +7 -1
  165. package/package.json +1 -1
  166. package/public_api.js +1 -0
  167. package/remote/communication/variable/remote-variable-communicator.d.ts +30 -0
  168. package/remote/communication/variable/remote-variable-communicator.js +193 -3
  169. package/remote/communication/variable/remote-variable-communicator.metadata.json +1 -1
  170. package/remote/communication/variable/remote-variable-protocol.d.ts +8 -0
  171. package/service/index.d.ts +4 -0
  172. package/service/index.js +1 -0
  173. package/service/index.metadata.json +1 -1
  174. package/service/language.service.d.ts +37 -0
  175. package/service/language.service.js +0 -0
  176. package/service/language.service.metadata.json +1 -0
  177. package/service/released-variable/index.d.ts +1 -0
  178. package/service/released-variable/index.js +0 -0
  179. package/service/released-variable/index.metadata.json +1 -0
  180. package/service/released-variable/released-variable.service.d.ts +4 -0
  181. package/service/released-variable/released-variable.service.js +0 -0
  182. package/service/released-variable/released-variable.service.metadata.json +1 -0
  183. package/service/system-text-library.service.d.ts +77 -0
  184. package/service/system-text-library.service.js +29 -0
  185. package/service/system-text-library.service.metadata.json +1 -0
  186. package/service/text-library.service.d.ts +49 -0
  187. package/service/text-library.service.js +0 -0
  188. package/service/text-library.service.metadata.json +1 -0
  189. package/shared/gui-consts.d.ts +2 -0
  190. package/shared/gui-consts.js +3 -1
  191. package/shared/gui-consts.metadata.json +1 -1
  192. package/utils/data-type/fbox-data-type.service.js +40 -0
  193. package/utils/numerical-operation.service.js +28 -4
  194. package/view/popup-view.service.d.ts +1 -1
@@ -0,0 +1,739 @@
1
+ import * as d3 from 'd3';
2
+ import { SYSTEM_TEXT_LIBRARY_TYPES, ALARM_TABLE_HEADER_KEYS, TIME_PERIOD_KEYS } from '../../service';
3
+ import { ConditionalDisplayElement } from '../base/conditional-display-element';
4
+ import { GetAlarmsArgs } from '../../config';
5
+ import * as moment from 'moment';
6
+ import { LOGGER_SERVICE_TOKEN } from '../../logger';
7
+ var AlaertElementStatus;
8
+ (function (AlaertElementStatus) {
9
+ AlaertElementStatus[AlaertElementStatus["Normal"] = 0] = "Normal";
10
+ AlaertElementStatus[AlaertElementStatus["Loading"] = 1] = "Loading"; // 加载中
11
+ })(AlaertElementStatus || (AlaertElementStatus = {}));
12
+ export class AlarmElement extends ConditionalDisplayElement {
13
+ constructor(element, injector, permissionChecker, variableCommunicator, variableStore, alarmsStore, signalRAppId, systemTextLibraryService, languageService, guiContext) {
14
+ var _a;
15
+ super(element, permissionChecker, variableCommunicator, variableStore, signalRAppId);
16
+ this.alarmsStore = alarmsStore;
17
+ this.systemTextLibraryService = systemTextLibraryService;
18
+ this.languageService = languageService;
19
+ this.guiContext = guiContext;
20
+ this.elementStatus = AlaertElementStatus.Loading;
21
+ this.displayOption = {
22
+ dataLimit: 500,
23
+ dataZoomHeight: 32,
24
+ marginLeft: 1,
25
+ marginRight: 20,
26
+ mobileMinWidth: 450,
27
+ operationAreaHeight: 32,
28
+ operationAreaMarginTop: 10,
29
+ operationSelectFontSize: '16px',
30
+ operationButtonWidth: 24,
31
+ operationButtonHeight: 24,
32
+ operationButtonMargin: 4
33
+ };
34
+ this.alarmNames = [];
35
+ this.alarmList = [];
36
+ this.currentAlarmList = [];
37
+ this.page = 0;
38
+ this.totalCount = 0;
39
+ this.pageSize = 5;
40
+ this.maxVisibleRows = 15;
41
+ this.rowHeight = 0;
42
+ this.isDisposed = false;
43
+ this.handleScrollMouseEnter = () => {
44
+ clearInterval(this.scrollIntervalId);
45
+ };
46
+ this.handleScrollMouseLeave = () => {
47
+ this.startAutoScroll();
48
+ };
49
+ this.rootElement.selectAll('*').remove();
50
+ this.setStatusAsLoading();
51
+ this.logger = injector.get(LOGGER_SERVICE_TOKEN);
52
+ this.variableCommunicator = variableCommunicator;
53
+ this.pageSize = this.model.generalSetting.pageSize;
54
+ localStorage.setItem('simulate-time', moment().valueOf() + '');
55
+ // 订阅语种变化事件
56
+ this.subscribeLanguageChange();
57
+ if (this.model.filterSetting) {
58
+ this.alarmNames = this.model.filterSetting.detailsData.map(item => item.name);
59
+ this.currentTimePeriod = (_a = this.model.filterSetting) === null || _a === void 0 ? void 0 : _a.displayPeriod;
60
+ this.updateQueryTimeRange();
61
+ if (this.model.filterSetting.alarmType) {
62
+ this.refreshIntervalId = setInterval(() => {
63
+ if (this.model.generalSetting.autoScroll) {
64
+ // 开启滚动时,仅更新数据不重渲染,保持滚动进度
65
+ this.refreshCurrentPageData();
66
+ }
67
+ else {
68
+ // 未开启滚动时,返回第一页
69
+ this.loadFirstPage();
70
+ }
71
+ this.logger.debug(`[GUI]Refresh Alarm Table:${d3.time.format('%x %X')(new Date())}`);
72
+ }, this.model.filterSetting.refreshCycle * 60 * 1000);
73
+ }
74
+ else {
75
+ variableCommunicator.subscribeUserDeviceAlarms(signalRAppId).subscribe(alarms => {
76
+ alarms.forEach(alarm => {
77
+ if (this.alarmNames.indexOf(alarm.name) !== -1) {
78
+ if (this.model.generalSetting.autoScroll) {
79
+ // 开启滚动时,刷新当前页并保持滚动进度
80
+ this.refreshCurrentPageData();
81
+ }
82
+ else {
83
+ // 未开启滚动时,刷新当前页(原有逻辑)
84
+ this.getAlarmData();
85
+ }
86
+ return;
87
+ }
88
+ });
89
+ });
90
+ }
91
+ this.getAlarmData();
92
+ }
93
+ else {
94
+ this.totalCount = 0;
95
+ this.alarmList = [];
96
+ this.renderElement();
97
+ }
98
+ }
99
+ dispose() {
100
+ this.isDisposed = true;
101
+ clearInterval(this.refreshIntervalId);
102
+ clearInterval(this.scrollIntervalId);
103
+ clearTimeout(this.getAlarmDataId);
104
+ this.unbindScrollHoverEvents();
105
+ // 取消语种变化订阅
106
+ if (this.languageChangeSubscription) {
107
+ this.languageChangeSubscription.unsubscribe();
108
+ this.languageChangeSubscription = undefined;
109
+ }
110
+ this.logger.debug(`[GUI]Dispose Alarm Table Refresh Interval:${d3.time.format('%x %X')(new Date())}`);
111
+ }
112
+ /**
113
+ * 订阅语种变化事件
114
+ */
115
+ subscribeLanguageChange() {
116
+ if (this.guiContext && this.guiContext.languageChanged$) {
117
+ this.languageChangeSubscription = this.guiContext.languageChanged$.subscribe(() => {
118
+ // 只更新文案,不重新查询数据
119
+ this.updateLanguageTexts();
120
+ });
121
+ }
122
+ }
123
+ /**
124
+ * 更新语种相关的文案(表头和时间段选择器)
125
+ */
126
+ updateLanguageTexts() {
127
+ var _a;
128
+ // 更新表头文本
129
+ const headerCells = this.$element.find('table th');
130
+ for (let col = 0; col < 4 && col < headerCells.length; col++) {
131
+ headerCells.eq(col).text(this.getHeaderTextByColumn(col));
132
+ }
133
+ // 更新时间段选择器选项
134
+ if ((_a = this.model.filterSetting) === null || _a === void 0 ? void 0 : _a.alarmType) {
135
+ const selectElement = this.rootElement.select('select');
136
+ if (!selectElement.empty()) {
137
+ // 重新生成时间段数据
138
+ const updatedTimePeriods = this.getValidTimePeriods();
139
+ this.timePeriods = updatedTimePeriods;
140
+ // 更新选项文本
141
+ const options = selectElement.selectAll('option');
142
+ options.each(function (_d, i) {
143
+ if (i < updatedTimePeriods.length) {
144
+ d3.select(this).text(updatedTimePeriods[i].name);
145
+ }
146
+ });
147
+ }
148
+ }
149
+ }
150
+ /**
151
+ * 获取当前语种的 culture 代码
152
+ */
153
+ getCurrentCulture() {
154
+ var _a, _b, _c, _e, _f, _g;
155
+ // 获取当前语种ID
156
+ const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
157
+ // 确定要使用的语种代码(culture)
158
+ const defaultLanguage = ((_e = this.languageService) === null || _e === void 0 ? void 0 : _e.getDefaultLanguage()) || 'zh-CN';
159
+ if (currentLanguageId === null || currentLanguageId === undefined) {
160
+ // 设备未设置当前语种,使用默认语种
161
+ return defaultLanguage;
162
+ }
163
+ else {
164
+ // 设备已设置当前语种,获取对应的语种代码
165
+ const currentLanguage = (_g = (_f = this.guiContext) === null || _f === void 0 ? void 0 : _f.getLanguageCultureById) === null || _g === void 0 ? void 0 : _g.call(_f, currentLanguageId);
166
+ if (currentLanguage) {
167
+ return currentLanguage;
168
+ }
169
+ else {
170
+ // 无法获取语种代码,使用默认语种
171
+ return defaultLanguage;
172
+ }
173
+ }
174
+ }
175
+ /**
176
+ * 根据列索引获取表头翻译(从系统文本库获取多语种翻译)
177
+ * 固定4项表头,按列索引顺序:告警名称、告警内容、告警等级、时间
178
+ */
179
+ getHeaderTextByColumn(columnIndex) {
180
+ if (columnIndex < 0 || columnIndex > 3) {
181
+ return '';
182
+ }
183
+ const currentCulture = this.getCurrentCulture();
184
+ const systemType = SYSTEM_TEXT_LIBRARY_TYPES.COMPONENT_BUILTIN;
185
+ const headerKeys = [
186
+ ALARM_TABLE_HEADER_KEYS.ALARM_NAME,
187
+ ALARM_TABLE_HEADER_KEYS.ALARM_MESSAGE,
188
+ ALARM_TABLE_HEADER_KEYS.ALARM_LEVEL,
189
+ ALARM_TABLE_HEADER_KEYS.TIME
190
+ ];
191
+ // 尝试从系统文本库获取翻译
192
+ if (this.systemTextLibraryService) {
193
+ const translation = this.systemTextLibraryService.getSystemTextValue(systemType, headerKeys[columnIndex], currentCulture);
194
+ if (translation) {
195
+ return translation;
196
+ }
197
+ }
198
+ return '';
199
+ }
200
+ getValidTimePeriods() {
201
+ const timePeriods = new Array();
202
+ timePeriods.push({ key: 6, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_MINUTES) });
203
+ timePeriods.push({ key: 1, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_HOUR) });
204
+ timePeriods.push({ key: 7, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_EIGHT_HOURS) });
205
+ timePeriods.push({ key: 2, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_TWENTY_FOUR_HOURS) });
206
+ timePeriods.push({ key: 3, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_SEVEN_DAYS) });
207
+ timePeriods.push({ key: 4, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_DAYS) });
208
+ timePeriods.push({ key: 5, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_YEAR) });
209
+ return timePeriods;
210
+ }
211
+ /**
212
+ * 获取时间段文案(从系统文本库获取多语种翻译)
213
+ */
214
+ getTimePeriodText(textKey) {
215
+ const currentCulture = this.getCurrentCulture();
216
+ const systemType = SYSTEM_TEXT_LIBRARY_TYPES.COMPONENT_BUILTIN;
217
+ if (this.systemTextLibraryService) {
218
+ const translation = this.systemTextLibraryService.getSystemTextValue(systemType, textKey, currentCulture);
219
+ if (translation) {
220
+ return translation;
221
+ }
222
+ }
223
+ return '';
224
+ }
225
+ getAlarmData() {
226
+ clearInterval(this.scrollIntervalId);
227
+ this.unbindScrollHoverEvents();
228
+ this.rootElement.selectAll('*').remove();
229
+ this.setStatusAsLoading();
230
+ clearTimeout(this.getAlarmDataId);
231
+ this.getAlarmDataId = setTimeout(() => {
232
+ if (this.isDisposed)
233
+ return;
234
+ this.timePeriods = this.getValidTimePeriods();
235
+ if (this.model.filterSetting.alarmType) {
236
+ this.updateQueryTimeRange();
237
+ const input = new GetAlarmsArgs(this.alarmNames, this.startTime, this.endTime, this.pageSize, this.page * this.pageSize);
238
+ this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
239
+ if (this.isDisposed)
240
+ return;
241
+ if (!result.error) {
242
+ this.totalCount = result.totalCount;
243
+ this.alarmList = result.items.map(item => [
244
+ item.name,
245
+ item.message,
246
+ item.alarmLevel,
247
+ item.triggeredTime.format('YYYY-MM-DD HH:mm:ss')
248
+ ]);
249
+ this.renderElement();
250
+ }
251
+ });
252
+ }
253
+ else {
254
+ const input = new GetAlarmsArgs(this.alarmNames, undefined, undefined, this.pageSize, this.page * this.pageSize);
255
+ this.alarmsStore.getCurrentAlarms(input).subscribe(result => {
256
+ if (this.isDisposed)
257
+ return;
258
+ if (!result.error) {
259
+ this.totalCount = result.totalCount;
260
+ this.currentAlarmList = result.items;
261
+ if (!result.items.length && result.totalCount) {
262
+ this.page = 0;
263
+ this.getAlarmData();
264
+ return;
265
+ }
266
+ this.alarmList = this.currentAlarmList.map(item => [
267
+ item.name,
268
+ item.message,
269
+ item.alarmLevel,
270
+ item.triggeredTime.format('YYYY-MM-DD HH:mm:ss')
271
+ ]);
272
+ this.renderElement();
273
+ }
274
+ });
275
+ }
276
+ }, 500);
277
+ }
278
+ refreshCurrentPageData() {
279
+ var _a;
280
+ if (this.isDisposed)
281
+ return;
282
+ const currentScrollTop = ((_a = this.scrollContainer) === null || _a === void 0 ? void 0 : _a.scrollTop) || 0;
283
+ if (this.model.filterSetting.alarmType) {
284
+ this.updateQueryTimeRange();
285
+ const input = new GetAlarmsArgs(this.alarmNames, this.startTime, this.endTime, this.pageSize, this.page * this.pageSize);
286
+ this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
287
+ if (this.isDisposed)
288
+ return;
289
+ if (!result.error) {
290
+ this.totalCount = result.totalCount;
291
+ this.alarmList = result.items.map(item => [
292
+ item.name,
293
+ item.message,
294
+ item.alarmLevel,
295
+ item.triggeredTime.format('YYYY-MM-DD HH:mm:ss')
296
+ ]);
297
+ this.updateTableContent();
298
+ if (this.scrollContainer) {
299
+ this.scrollContainer.scrollTop = currentScrollTop;
300
+ }
301
+ }
302
+ });
303
+ }
304
+ else {
305
+ const input = new GetAlarmsArgs(this.alarmNames, undefined, undefined, this.pageSize, this.page * this.pageSize);
306
+ this.alarmsStore.getCurrentAlarms(input).subscribe(result => {
307
+ if (this.isDisposed)
308
+ return;
309
+ if (!result.error) {
310
+ this.totalCount = result.totalCount;
311
+ this.currentAlarmList = result.items;
312
+ if (!result.items.length && result.totalCount) {
313
+ this.page = 0;
314
+ this.refreshCurrentPageData();
315
+ return;
316
+ }
317
+ this.alarmList = this.currentAlarmList.map(item => [
318
+ item.name,
319
+ item.message,
320
+ item.alarmLevel,
321
+ item.triggeredTime.format('YYYY-MM-DD HH:mm:ss')
322
+ ]);
323
+ this.updateTableContent();
324
+ if (this.scrollContainer) {
325
+ this.scrollContainer.scrollTop = currentScrollTop;
326
+ }
327
+ }
328
+ });
329
+ }
330
+ }
331
+ updateTableContent() {
332
+ if (!this.element)
333
+ return;
334
+ const useScroll = this.pageSize > this.maxVisibleRows;
335
+ const dataRowHeight = this.model.heights[1] || this.model.heights[0];
336
+ // 查找表格主体
337
+ let tbody;
338
+ if (useScroll) {
339
+ const bodyContainer = this.element.querySelector('div > div:nth-child(2)');
340
+ if (!bodyContainer)
341
+ return;
342
+ const bodyTable = bodyContainer.querySelector('table');
343
+ if (!bodyTable)
344
+ return;
345
+ tbody = bodyTable;
346
+ }
347
+ else {
348
+ const table = this.element.querySelector('table');
349
+ if (!table)
350
+ return;
351
+ tbody = table;
352
+ }
353
+ // 清除现有数据行(保留表头)
354
+ const rows = Array.from(tbody.querySelectorAll('tr'));
355
+ rows.forEach((row, index) => {
356
+ if (index > 0 || useScroll) { // 对于 scrollable 模式,表头在另一个 table,所以这里全部清除
357
+ row.remove();
358
+ }
359
+ });
360
+ // 重新生成数据行
361
+ for (let row = 0; row < this.pageSize; row++) {
362
+ const rowHeight = useScroll ? dataRowHeight : this.model.heights[row + 1];
363
+ tbody.appendChild(this.buildDataRow(row, rowHeight));
364
+ }
365
+ }
366
+ getIconScale() {
367
+ const initSize = this.model.initSize;
368
+ if (!initSize || !initSize.width || !initSize.height) {
369
+ return 1;
370
+ }
371
+ const scaleX = this.model.size.width / initSize.width;
372
+ const scaleY = this.model.size.height / initSize.height;
373
+ return Math.min(scaleX, scaleY);
374
+ }
375
+ renderElement() {
376
+ const elementHeight = this.model.size.height;
377
+ this.element = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
378
+ this.element.setAttribute('width', this.model.size.width.toString());
379
+ this.element.setAttribute('height', elementHeight.toString());
380
+ this.$element.append(this.element);
381
+ const scale = this.getIconScale();
382
+ // 表格与底部操作区之间的预留高度,需要与操作区渲染时使用的同一个 scale 保持一致,
383
+ // 否则表格按未缩放高度占满后,缩放后的操作区会超出元件整体高度
384
+ const operationAreaReservedHeight = 39 * scale;
385
+ const useScroll = this.pageSize > this.maxVisibleRows;
386
+ if (useScroll) {
387
+ this.renderScrollableTable(elementHeight, operationAreaReservedHeight);
388
+ }
389
+ else {
390
+ this.renderPlainTable(elementHeight, operationAreaReservedHeight);
391
+ }
392
+ this.renderOperationArea(this.model.size.width, elementHeight - operationAreaReservedHeight, scale);
393
+ }
394
+ buildHeaderRow() {
395
+ const tr = document.createElement('tr');
396
+ let fontString = '';
397
+ if (this.model.generalSetting.headerFont.isItalic) {
398
+ fontString += 'italic ';
399
+ }
400
+ if (this.model.generalSetting.headerFont.isBold) {
401
+ fontString += 'bold ';
402
+ }
403
+ fontString += this.model.generalSetting.headerFont.fontSize + ' ' + this.model.generalSetting.headerFont.fontFamily;
404
+ tr.style.cssText = `height: ${this.model.heights[0]}px;
405
+ background: ${this.model.generalSetting.headerFillColor};
406
+ color: ${this.model.generalSetting.headerFont.color};
407
+ font: ${fontString};
408
+ text-align: ${this.model.generalSetting.headerFont.textAlign};
409
+ ${this.model.generalSetting.headerFont.isUnderline ? 'text-decoration: underline' : ''};
410
+ vertical-align: middle;`;
411
+ for (let col = 0; col < 4; col++) {
412
+ const th = document.createElement('th');
413
+ th.innerHTML = this.getHeaderTextByColumn(col);
414
+ th.style.cssText = `width: ${this.model.widths[col] / this.model.size.width * 100}%;
415
+ border-style: solid;
416
+ border-color: ${this.model.generalSetting.splitLine};
417
+ border-left-width: ${!col || this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;`;
418
+ tr.appendChild(th);
419
+ }
420
+ return tr;
421
+ }
422
+ buildDataRow(row, rowHeight) {
423
+ const levelColors = ['#3695FF', '#FFE900', '#FFA800', '#E84F4F'];
424
+ const tr = document.createElement('tr');
425
+ tr.style.cssText = `height: ${rowHeight}px;
426
+ background: ${this.model.generalSetting.tableFillColor};
427
+ font: ${this.model.generalSetting.fontStyle};
428
+ color: ${this.model.generalSetting.fontColor};
429
+ text-align: ${this.model.generalSetting.textAlign};
430
+ vertical-align: middle;`;
431
+ for (let col = 0; col < 4; col++) {
432
+ const td = document.createElement('td');
433
+ td.style.cssText = `width: ${this.model.widths[col] / this.model.size.width * 100}%;
434
+ border-style: solid;
435
+ border-color: ${this.model.generalSetting.splitLine};
436
+ border-top-width: ${this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;
437
+ border-left-width: ${!col || this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;`;
438
+ if (this.alarmList[row]) {
439
+ if (col !== 2) {
440
+ td.innerHTML = this.alarmList[row][col];
441
+ td.style.cssText += `${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
442
+ }
443
+ else {
444
+ const alarmLevel = document.createElement('div');
445
+ let alarmHeight = parseInt(this.model.generalSetting.fontSize) + 15;
446
+ if (alarmHeight > rowHeight)
447
+ alarmHeight = rowHeight;
448
+ let margin = '0 15px';
449
+ if (this.model.generalSetting.textAlign === 'left') {
450
+ margin = '0 30px 0 0';
451
+ }
452
+ else if (this.model.generalSetting.textAlign === 'right') {
453
+ margin = '0 0 0 30px';
454
+ }
455
+ alarmLevel.style.cssText = `margin: ${margin};
456
+ border-radius: 5px;
457
+ background: ${levelColors[this.alarmList[row][col]]};
458
+ color: #ffffff;
459
+ width: ${this.model.widths[col] - 30}px;
460
+ height: ${alarmHeight}px;
461
+ max-height: ${rowHeight}px;
462
+ display: flex;
463
+ justify-content: center;
464
+ align-items: center;
465
+ ${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
466
+ alarmLevel.innerHTML = this.model.levelText[this.alarmList[row][col]];
467
+ td.appendChild(alarmLevel);
468
+ }
469
+ }
470
+ else if (col === 2) {
471
+ const alarmLevel = document.createElement('div');
472
+ let margin = '0 15px';
473
+ if (this.model.generalSetting.textAlign === 'left') {
474
+ margin = '0 30px 0 0';
475
+ }
476
+ else if (this.model.generalSetting.textAlign === 'right') {
477
+ margin = '0 0 0 30px';
478
+ }
479
+ alarmLevel.style.cssText = `margin: ${margin};
480
+ width: ${this.model.widths[col] - 30}px;`;
481
+ td.appendChild(alarmLevel);
482
+ }
483
+ tr.appendChild(td);
484
+ }
485
+ return tr;
486
+ }
487
+ renderPlainTable(elementHeight, operationAreaReservedHeight) {
488
+ this.scrollContainer = null;
489
+ const table = document.createElement('table');
490
+ table.style.cssText = `border: 2px solid ${this.model.generalSetting.stroke};
491
+ height: ${elementHeight - operationAreaReservedHeight}px;`;
492
+ table.appendChild(this.buildHeaderRow());
493
+ for (let row = 0; row < this.pageSize; row++) {
494
+ table.appendChild(this.buildDataRow(row, this.model.heights[row + 1]));
495
+ }
496
+ this.element.appendChild(table);
497
+ this.hoverTarget = table;
498
+ this.bindScrollHoverEvents();
499
+ this.startAutoScroll();
500
+ }
501
+ renderScrollableTable(elementHeight, operationAreaReservedHeight) {
502
+ const dataRowHeight = this.model.heights[1] || this.model.heights[0];
503
+ this.rowHeight = dataRowHeight;
504
+ const wrapper = document.createElement('div');
505
+ wrapper.style.cssText = `display: flex;
506
+ flex-direction: column;
507
+ box-sizing: border-box;
508
+ border: 2px solid ${this.model.generalSetting.stroke};
509
+ height: ${elementHeight - operationAreaReservedHeight}px;
510
+ overflow: hidden;`;
511
+ const headerWrapper = document.createElement('div');
512
+ headerWrapper.style.cssText = 'flex: none; box-sizing: border-box; overflow: hidden;';
513
+ const headerTable = document.createElement('table');
514
+ headerTable.style.cssText = 'width: 100%; table-layout: fixed;';
515
+ headerTable.appendChild(this.buildHeaderRow());
516
+ headerWrapper.appendChild(headerTable);
517
+ const bodyContainer = document.createElement('div');
518
+ bodyContainer.style.cssText = `flex: none;
519
+ overflow-y: auto;
520
+ overflow-x: hidden;
521
+ height: ${dataRowHeight * this.maxVisibleRows}px;`;
522
+ const bodyTable = document.createElement('table');
523
+ bodyTable.style.cssText = 'width: 100%; table-layout: fixed;';
524
+ for (let row = 0; row < this.pageSize; row++) {
525
+ bodyTable.appendChild(this.buildDataRow(row, dataRowHeight));
526
+ }
527
+ bodyContainer.appendChild(bodyTable);
528
+ wrapper.appendChild(headerWrapper);
529
+ wrapper.appendChild(bodyContainer);
530
+ this.element.appendChild(wrapper);
531
+ this.scrollContainer = bodyContainer;
532
+ requestAnimationFrame(() => {
533
+ const scrollbarWidth = bodyContainer.offsetWidth - bodyContainer.clientWidth;
534
+ if (scrollbarWidth > 0) {
535
+ headerWrapper.style.paddingRight = scrollbarWidth + 'px';
536
+ }
537
+ });
538
+ this.hoverTarget = bodyContainer;
539
+ this.bindScrollHoverEvents();
540
+ this.startAutoScroll();
541
+ }
542
+ bindScrollHoverEvents() {
543
+ if (!this.hoverTarget)
544
+ return;
545
+ this.hoverTarget.addEventListener('mouseenter', this.handleScrollMouseEnter);
546
+ this.hoverTarget.addEventListener('mouseleave', this.handleScrollMouseLeave);
547
+ }
548
+ unbindScrollHoverEvents() {
549
+ if (!this.hoverTarget)
550
+ return;
551
+ this.hoverTarget.removeEventListener('mouseenter', this.handleScrollMouseEnter);
552
+ this.hoverTarget.removeEventListener('mouseleave', this.handleScrollMouseLeave);
553
+ this.hoverTarget = null;
554
+ }
555
+ startAutoScroll() {
556
+ clearInterval(this.scrollIntervalId);
557
+ if (!this.model.generalSetting.autoScroll)
558
+ return;
559
+ const totalPages = Math.max(1, Math.ceil(this.totalCount / this.pageSize));
560
+ if (totalPages <= 1 && !this.scrollContainer)
561
+ return;
562
+ const duration = (this.model.generalSetting.scrollDuration || 10) * 1000;
563
+ this.scrollIntervalId = setInterval(() => this.scrollOneRow(), duration);
564
+ }
565
+ scrollOneRow() {
566
+ const el = this.scrollContainer;
567
+ if (!el) {
568
+ this.autoNextPage();
569
+ return;
570
+ }
571
+ const maxScrollTop = el.scrollHeight - el.clientHeight;
572
+ if (maxScrollTop <= 1 || el.scrollTop >= maxScrollTop - 1) {
573
+ this.autoNextPage();
574
+ return;
575
+ }
576
+ el.scrollTop = Math.min(el.scrollTop + this.rowHeight, maxScrollTop);
577
+ }
578
+ autoNextPage() {
579
+ const totalPages = Math.max(1, Math.ceil(this.totalCount / this.pageSize));
580
+ if (totalPages <= 1)
581
+ return;
582
+ const lastPage = totalPages - 1;
583
+ this.page = this.page < lastPage ? this.page + 1 : 0;
584
+ this.getAlarmData();
585
+ }
586
+ renderOperationArea(chartWidth, chartHeight, scale = 1) {
587
+ var _a;
588
+ const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop * scale})`)
589
+ .append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight * scale).attr('fill', 'none')
590
+ .append('xhtml:div').style('height', (this.displayOption.operationAreaHeight * scale - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
591
+ if ((_a = this.model.filterSetting) === null || _a === void 0 ? void 0 : _a.alarmType) {
592
+ const selectElement = operationArea.append('select').style('margin-left', (this.displayOption.marginLeft * scale) + 'px')
593
+ .style('font-size', (parseFloat(this.displayOption.operationSelectFontSize) * scale) + 'px').on('change', () => {
594
+ const displayTimePeriod = this.rootElement.select('select').property('value');
595
+ this.updateTimeRange(displayTimePeriod);
596
+ this.getAlarmData();
597
+ });
598
+ const options = selectElement.selectAll('option').data(this.timePeriods).enter().append('option');
599
+ options.text(d => d.name).attr('value', d => d.key).property('selected', d => d.key === Number(this.currentTimePeriod));
600
+ }
601
+ const buttonWidth = (this.displayOption.operationButtonWidth * scale) + 'px', buttonHeight = (this.displayOption.operationButtonHeight * scale) + 'px';
602
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
603
+ .style('float', 'right').style('background-image', 'url(assets/img/last_page.svg)')
604
+ .style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
605
+ .style('background-color', 'inherit')
606
+ .on('click', () => { this.loadLastPage(); });
607
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
608
+ .style('float', 'right').style('background-image', 'url(assets/img/next_page.svg)')
609
+ .style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
610
+ .style('margin', `0 ${this.displayOption.operationButtonMargin * scale}px 0 0`)
611
+ .style('background-color', 'inherit')
612
+ .on('click', () => { this.loadNextPage(); });
613
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
614
+ .style('float', 'right').style('background-image', 'url(assets/img/previous_page.svg)')
615
+ .style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
616
+ .style('margin', `0 ${this.displayOption.operationButtonMargin * scale}px 0 0`)
617
+ .style('background-color', 'inherit')
618
+ .on('click', () => { this.loadPreviousPage(); });
619
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
620
+ .style('float', 'right').style('background-image', 'url(assets/img/first_page.svg)')
621
+ .style('background-size', 'contain').style('background-repeat', 'no-repeat').style('background-position', 'center')
622
+ .style('margin', `0 ${this.displayOption.operationButtonMargin * scale}px 0 0`)
623
+ .style('background-color', 'inherit')
624
+ .on('click', () => { this.loadFirstPage(); });
625
+ this.setStatusAsNormal();
626
+ }
627
+ updateTimeRange(timePeriodType) {
628
+ this.currentTimePeriod = +timePeriodType;
629
+ this.updateQueryTimeRange();
630
+ }
631
+ updateQueryTimeRange() {
632
+ this.endTime = moment();
633
+ switch (this.currentTimePeriod) {
634
+ case 1:
635
+ this.startTime = moment().subtract(1, 'hours');
636
+ break;
637
+ case 3:
638
+ this.startTime = moment().subtract(7, 'days');
639
+ break;
640
+ case 4:
641
+ this.startTime = moment().subtract(30, 'days');
642
+ break;
643
+ case 5:
644
+ this.startTime = moment().subtract(1, 'years');
645
+ break;
646
+ case 6:
647
+ this.startTime = moment().subtract(30, 'minutes');
648
+ break;
649
+ case 7:
650
+ this.startTime = moment().subtract(8, 'hours');
651
+ break;
652
+ default:
653
+ this.startTime = moment().subtract(1, 'days');
654
+ }
655
+ }
656
+ loadFirstPage() {
657
+ if (this.page > 0) {
658
+ this.page = 0;
659
+ this.getAlarmData();
660
+ }
661
+ }
662
+ loadNextPage() {
663
+ let last_page = Math.ceil(this.totalCount / this.pageSize);
664
+ if (last_page)
665
+ last_page--;
666
+ if (this.page < last_page) {
667
+ this.page++;
668
+ this.getAlarmData();
669
+ }
670
+ }
671
+ loadPreviousPage() {
672
+ if (this.page > 0) {
673
+ this.page--;
674
+ this.getAlarmData();
675
+ }
676
+ }
677
+ loadLastPage() {
678
+ let last_page = Math.ceil(this.totalCount / this.pageSize);
679
+ if (last_page)
680
+ last_page--;
681
+ if (this.page !== last_page) {
682
+ this.page = last_page;
683
+ this.getAlarmData();
684
+ }
685
+ }
686
+ setStatusAsNormal() {
687
+ this.elementStatus = AlaertElementStatus.Normal;
688
+ this.clearStatus();
689
+ }
690
+ setStatusAsLoading() {
691
+ this.elementStatus = AlaertElementStatus.Loading;
692
+ this.renderStatus('assets/img/loading.svg', '#226abc');
693
+ }
694
+ renderStatus(icon, stroke) {
695
+ if (this.elementStatus === AlaertElementStatus.Normal) {
696
+ this.clearStatus();
697
+ return;
698
+ }
699
+ this.rootElement.append('rect').attr('id', 'StateFrame').attr('fill', 'transparent')
700
+ .attr('width', this.model.size.width)
701
+ .attr('height', this.model.size.height);
702
+ const document = this.$element[0].ownerDocument;
703
+ const currentRect = this.$element.find('rect#StateFrame').first();
704
+ if (!currentRect.length) {
705
+ return;
706
+ }
707
+ this.$element.find('image#StateImage').remove();
708
+ const imgObj = document.createElementNS('http://www.w3.org/2000/svg', 'image');
709
+ if (imgObj) {
710
+ let x = Number(currentRect[0].getAttribute('width')) - 20;
711
+ const currentRectX = currentRect[0].getAttribute('x');
712
+ if (currentRectX !== null) {
713
+ x += Number(currentRectX);
714
+ }
715
+ currentRect[0].setAttribute('stroke', stroke);
716
+ currentRect[0].setAttribute('stroke-opacity', '0.5');
717
+ imgObj.href.baseVal = icon;
718
+ imgObj.setAttributeNS(null, 'id', 'StateImage');
719
+ imgObj.setAttributeNS(null, 'x', x.toString());
720
+ imgObj.setAttributeNS(null, 'y', '0');
721
+ imgObj.setAttributeNS(null, 'height', '20px');
722
+ imgObj.setAttributeNS(null, 'width', '20px');
723
+ const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');
724
+ imgObj.appendChild(titleElement);
725
+ this.$element.append(imgObj);
726
+ }
727
+ }
728
+ clearStatus() {
729
+ const currentRect = this.$element.find('rect#StateFrame').first();
730
+ if (!currentRect.length) {
731
+ return;
732
+ }
733
+ const stroke = currentRect[0].getAttribute('stroke');
734
+ if (stroke) {
735
+ currentRect[0].removeAttribute('stroke');
736
+ }
737
+ this.$element.find('image#StateImage').remove();
738
+ }
739
+ }