chuijs 3.6.2 → 3.6.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.
Files changed (119) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1203 -162
  3. package/framework/appLayout/default/chui_app_layout.js +747 -747
  4. package/framework/appLayout/default/global_style.css +592 -568
  5. package/framework/appLayout/default/main_theme_style.css +118 -101
  6. package/framework/components/chui_accordion/accordion.js +63 -63
  7. package/framework/components/chui_accordion/styles.css +79 -75
  8. package/framework/components/chui_badge/badge.js +55 -55
  9. package/framework/components/chui_badge/styles.css +29 -29
  10. package/framework/components/chui_button/button.js +48 -48
  11. package/framework/components/chui_button/styles.css +75 -70
  12. package/framework/components/chui_calendar/calendar.js +97 -97
  13. package/framework/components/chui_card/card.js +87 -0
  14. package/framework/components/chui_card/styles.css +72 -0
  15. package/framework/components/chui_code/code.js +18 -18
  16. package/framework/components/chui_code/styles.css +9 -9
  17. package/framework/components/chui_console/console.js +27 -27
  18. package/framework/components/chui_console/styles.css +31 -31
  19. package/framework/components/chui_content_block/content_block.js +51 -51
  20. package/framework/components/chui_content_block/styles.css +2 -2
  21. package/framework/components/chui_context_menu/context_menu.js +230 -0
  22. package/framework/components/chui_context_menu/styles.css +136 -0
  23. package/framework/components/chui_custom_element/custom_element.js +24 -24
  24. package/framework/components/chui_details/details.js +85 -85
  25. package/framework/components/chui_details/styles.css +70 -66
  26. package/framework/components/chui_fieldset/fieldset.js +40 -40
  27. package/framework/components/chui_fieldset/styles.css +24 -24
  28. package/framework/components/chui_form/form.js +40 -40
  29. package/framework/components/chui_form/styles.css +21 -21
  30. package/framework/components/chui_graphs/graphs.js +234 -190
  31. package/framework/components/chui_graphs/styles.css +37 -32
  32. package/framework/components/chui_hero/hero.js +98 -0
  33. package/framework/components/chui_hero/styles.css +91 -0
  34. package/framework/components/chui_html_block/html_block.js +16 -16
  35. package/framework/components/chui_html_block/styles.css +5 -5
  36. package/framework/components/chui_hx/hx.js +15 -15
  37. package/framework/components/chui_hx/styles.css +38 -38
  38. package/framework/components/chui_icons/icons.js +2144 -2144
  39. package/framework/components/chui_icons/styles.css +13 -13
  40. package/framework/components/chui_inputs/chui_check_box/check_box.js +32 -32
  41. package/framework/components/chui_inputs/chui_check_box/styles.css +91 -86
  42. package/framework/components/chui_inputs/chui_combo_box/combo_box.js +166 -150
  43. package/framework/components/chui_inputs/chui_combo_box/styles.css +113 -107
  44. package/framework/components/chui_inputs/chui_date/date.js +177 -174
  45. package/framework/components/chui_inputs/chui_date/styles.css +163 -128
  46. package/framework/components/chui_inputs/chui_email/email.js +61 -61
  47. package/framework/components/chui_inputs/chui_email/styles.css +69 -71
  48. package/framework/components/chui_inputs/chui_file/file.js +76 -76
  49. package/framework/components/chui_inputs/chui_file/styles.css +99 -99
  50. package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +295 -295
  51. package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +212 -235
  52. package/framework/components/chui_inputs/chui_number/number.js +108 -108
  53. package/framework/components/chui_inputs/chui_number/styles.css +84 -84
  54. package/framework/components/chui_inputs/chui_password/password.js +99 -99
  55. package/framework/components/chui_inputs/chui_password/styles.css +97 -97
  56. package/framework/components/chui_inputs/chui_radio_button/radio_button.js +45 -45
  57. package/framework/components/chui_inputs/chui_radio_button/styles.css +76 -73
  58. package/framework/components/chui_inputs/chui_select_box/select_box.js +187 -170
  59. package/framework/components/chui_inputs/chui_select_box/styles.css +123 -117
  60. package/framework/components/chui_inputs/chui_text/styles.css +83 -84
  61. package/framework/components/chui_inputs/chui_text/text.js +91 -91
  62. package/framework/components/chui_inputs/chui_text_area/styles.css +57 -57
  63. package/framework/components/chui_inputs/chui_text_area/text_area.js +61 -61
  64. package/framework/components/chui_inputs/chui_toggle/styles.css +66 -61
  65. package/framework/components/chui_inputs/chui_toggle/toggle.js +36 -36
  66. package/framework/components/chui_label/label.js +54 -54
  67. package/framework/components/chui_label/styles.css +11 -11
  68. package/framework/components/chui_media/audio.js +908 -908
  69. package/framework/components/chui_media/audio_styles.css +458 -458
  70. package/framework/components/chui_media/image.js +105 -105
  71. package/framework/components/chui_media/image_styles.css +61 -61
  72. package/framework/components/chui_media/video.js +248 -248
  73. package/framework/components/chui_media/video_styles.css +160 -160
  74. package/framework/components/chui_menu_bar/menu_bar.js +66 -74
  75. package/framework/components/chui_menu_bar/styles.css +114 -76
  76. package/framework/components/chui_modal/modal.js +142 -135
  77. package/framework/components/chui_modal/styles.css +36 -36
  78. package/framework/components/chui_notification/notification.js +72 -72
  79. package/framework/components/chui_notification/notification_download.js +78 -78
  80. package/framework/components/chui_notification/notification_download_progress.css +119 -123
  81. package/framework/components/chui_notification/notification_download_progress.js +105 -105
  82. package/framework/components/chui_notification/notification_update.js +54 -54
  83. package/framework/components/chui_notification/styles.css +91 -91
  84. package/framework/components/chui_notification/styles_download.css +85 -85
  85. package/framework/components/chui_notification/styles_update.css +73 -73
  86. package/framework/components/chui_paragraph/paragraph.js +14 -14
  87. package/framework/components/chui_paragraph/styles.css +6 -6
  88. package/framework/components/chui_popups/popups.js +250 -250
  89. package/framework/components/chui_popups/styles.css +129 -115
  90. package/framework/components/chui_progress_bar/progress_bar.js +28 -28
  91. package/framework/components/chui_progress_bar/styles.css +28 -28
  92. package/framework/components/chui_radio_group/radio_group.js +57 -57
  93. package/framework/components/chui_radio_group/styles.css +3 -3
  94. package/framework/components/chui_slideshow/slideshow.js +75 -75
  95. package/framework/components/chui_slideshow/styles.css +94 -85
  96. package/framework/components/chui_spinner/spinner.js +45 -45
  97. package/framework/components/chui_spinner/styles.css +23 -23
  98. package/framework/components/chui_table/styles.css +42 -42
  99. package/framework/components/chui_table/table.js +234 -234
  100. package/framework/components/chui_tabs/chui_tabs.js +77 -77
  101. package/framework/components/chui_tabs/styles.css +54 -48
  102. package/framework/components/chui_text_editor/styles.css +217 -217
  103. package/framework/components/chui_text_editor/text_editor.js +144 -144
  104. package/framework/components/chui_text_editor/text_editor_panel.js +568 -568
  105. package/framework/components/chui_tree_view/styles.css +81 -75
  106. package/framework/components/chui_tree_view/tree_view.js +90 -90
  107. package/framework/components/chui_webview/styles.css +27 -27
  108. package/framework/components/chui_webview/webview.js +103 -103
  109. package/framework/components/telegram_bot/chui_telegram_bot.js +183 -183
  110. package/framework/modules/chui_animations/animations.js +121 -121
  111. package/framework/modules/chui_animations/styles.css +79 -79
  112. package/framework/modules/chui_fonts.js +7129 -6974
  113. package/framework/modules/chui_functions.js +106 -78
  114. package/framework/modules/chui_logger/chui_logger.js +53 -53
  115. package/framework/modules/chui_page/page.js +86 -86
  116. package/framework/modules/chui_page/styles.css +9 -9
  117. package/framework/tray_bar/chui_menu_items.js +48 -48
  118. package/index.js +570 -555
  119. package/package.json +51 -46
@@ -1,748 +1,748 @@
1
- const {Animation} = require('../../modules/chui_animations/animations');
2
- const {Icon, Icons} = require('../../components/chui_icons/icons');
3
- const {Button} = require("../../components/chui_button/button");
4
- // НАСТРОЙКИ
5
- const {Dialog} = require("../../components/chui_modal/modal");
6
- const {Label} = require("../../components/chui_label/label");
7
- const {ContentBlock} = require("../../components/chui_content_block/content_block");
8
- const {Popup} = require("../../components/chui_popups/popups");
9
- const {UpdateNotification} = require("../../components/chui_notification/notification_update");
10
- const {ipcRenderer} = require("electron");
11
- const chui_functions = require('../../modules/chui_functions');
12
- const {DownloadNotification} = require("../../components/chui_notification/notification_download");
13
- const {Log} = require("../../../framework/modules/chui_logger/chui_logger");
14
- const fs = require("fs");
15
-
16
- class Events {
17
- #route_event = undefined;
18
- constructor() {}
19
- route(page) {
20
- this.#route_event = new CustomEvent("route_event_"+page.constructor.name, {
21
- bubbles: true,
22
- detail: {
23
- class: page.constructor.name,
24
- title: page.getTitle(),
25
- page: page
26
- },
27
- });
28
- document.dispatchEvent(this.#route_event)
29
- }
30
- }
31
-
32
- class Route extends Events {
33
- constructor() {
34
- super();
35
- }
36
- go(page) {
37
- let header_toolbar = document.getElementById("header_toolbar");
38
- let page_name = document.getElementById("page_name");
39
- let center = document.getElementById("center");
40
- //
41
- header_toolbar.innerHTML = ''
42
- page_name.innerHTML = page.getTitle();
43
- center.innerHTML = '';
44
- center.appendChild(page.render());
45
- const _page = document.getElementsByTagName('page')[0];
46
- new Animation(_page).fadeIn();
47
- _page.addEventListener('animationend', () => {
48
- center.removeAttribute('style');
49
- });
50
- if (page.getMenuBar() !== undefined) {
51
- new Animation(page.getMenuBar()).fadeIn();
52
- header_toolbar.appendChild(page.getMenuBar());
53
- center.classList.add("header_padding", "test_scroll_track");
54
- } else {
55
- center.classList.remove("header_padding", "test_scroll_track");
56
- }
57
-
58
- this.route(page)
59
- }
60
- }
61
-
62
- class WindowControls {
63
- // Управление кнопками
64
- #box = document.createElement("wc_box")
65
- #close = document.createElement("wc_close")
66
- #maximize = document.createElement("wc_maximize")
67
- #minimize = document.createElement("wc_minimize")
68
- constructor() {
69
- this.#close.innerHTML = new Icon(Icons.NAVIGATION.CLOSE, "16px").getHTML();
70
- this.#maximize.innerHTML = new Icon(Icons.CONTENT.ADD, "16px").getHTML();
71
- this.#minimize.innerHTML = new Icon(Icons.CONTENT.REMOVE, "16px").getHTML();
72
- this.#close.addEventListener("click", () => {
73
- let r_window = require("@electron/remote").BrowserWindow.getFocusedWindow();
74
- r_window.close();
75
- })
76
- this.#maximize.addEventListener("click", () => {
77
- let r_window = require("@electron/remote").BrowserWindow.getFocusedWindow();
78
- r_window.isMaximized() ? r_window.unmaximize() : r_window.maximize();
79
- })
80
- this.#minimize.addEventListener("click", () => {
81
- let r_window = require("@electron/remote").BrowserWindow.getFocusedWindow();
82
- r_window.minimize();
83
- })
84
- }
85
- set(pos_bool = Boolean()) {
86
- if (pos_bool) {
87
- this.#box.appendChild(this.#close)
88
- this.#box.appendChild(this.#maximize)
89
- this.#box.appendChild(this.#minimize)
90
- } else {
91
- this.#box.appendChild(this.#minimize)
92
- this.#box.appendChild(this.#maximize)
93
- this.#box.appendChild(this.#close)
94
- }
95
- ipcRenderer.on("chui_resizable_false", (e) => this.#maximize.remove())
96
- return this.#box;
97
- }
98
- }
99
-
100
- class Header {
101
- #wc_box = new WindowControls();
102
- #header = document.createElement("header");
103
- #header_main = document.createElement("header_main");
104
- #header_toolbar = document.createElement("header_toolbar");
105
- #header_left_box = document.createElement("header_left_box");
106
- #header_right_box = document.createElement("header_right_box");
107
- constructor() {
108
- this.#header.id = "header";
109
- this.#header_main.id = "header_main";
110
- this.#header_toolbar.id = "header_toolbar";
111
- this.#header_main.appendChild(this.#header_left_box);
112
- this.#header_main.appendChild(this.#header_right_box);
113
- this.#header_main.appendChild(this.#wc_box.set(false));
114
- this.#header.appendChild(this.#header_main)
115
- this.#header.appendChild(this.#header_toolbar)
116
- }
117
- addWC(boolean = Boolean()) {
118
- this.#header_main.insertBefore(this.#wc_box.set(boolean), this.#header_main.firstChild);
119
- }
120
- addToLeftBeforeTittle(...components) {
121
- for (let component of components) this.#header_left_box.insertBefore(component, this.#header_left_box.firstChild);
122
- }
123
- addToLeft(...components) {
124
- for (let component of components) {
125
- this.#header_left_box.appendChild(component)
126
- }
127
- }
128
- addToRight(...components) {
129
- for (let component of components) this.#header_right_box.insertBefore(component, this.#header_right_box.firstChild);
130
- }
131
- removeToRight(...components) {
132
- for (let component of components) this.#header_right_box.removeChild(component);
133
- }
134
- set() {
135
- return this.#header;
136
- }
137
- }
138
-
139
- class Center {
140
- #center = document.createElement('center');
141
- constructor() {
142
- this.#center.id = "center";
143
- }
144
- set() {
145
- return this.#center;
146
- }
147
- }
148
-
149
- class AppMenu {
150
- #routeList = [];
151
- #appMenu = document.createElement('app_menu');
152
- #appMenuWidth = 400;
153
- #appMenuWidthTest = 425;
154
- #routeViews = document.createElement('route_views');
155
- #appMenuButton = document.createElement('app_menu_button');
156
- // Блок поиска
157
- #app_menu_search_main = document.createElement("app_menu_search_main");
158
- #app_menu_search_input = document.createElement("input");
159
- // ===
160
- #auto_close = false;
161
- constructor(header, center) {
162
- this.#appMenu.style.top = `calc(${header.set().style.height})`;
163
- this.#appMenu.style.width = `${this.#appMenuWidth}px`;
164
- this.#appMenu.style.left = `calc(-${this.#appMenuWidthTest}px)`;
165
- this.#appMenu.style.height = `calc(100% - ${header.set().style.height})`;
166
- //
167
- this.#appMenuButton.id = "appMenuButton"
168
- this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
169
- this.#appMenuButton.addEventListener("click", () => {
170
- if (this.#appMenuButton.classList.contains("app_menu_button_active")) {
171
- this.#appMenu.style.transform = `translateX(-${this.#appMenuWidth}px)`;
172
- this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
173
- } else {
174
- this.#appMenu.style.transform = `translateX(${this.#appMenuWidthTest}px)`;
175
- this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU_OPEN, "var(--header_icon_size)").getHTML();
176
- }
177
- this.#appMenuButton.classList.toggle("app_menu_button_active")
178
- })
179
- header.set().addEventListener('click', (e) => {
180
- if (e.target !== this.#appMenuButton) {
181
- this.#appMenu.style.transform = `translateX(-${this.#appMenuWidth}px)`;
182
- this.#appMenuButton.classList.remove("app_menu_button_active")
183
- this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
184
- }
185
- })
186
- center.addEventListener('click', (e) => {
187
- if (!this.#appMenu.contains(e.target)) {
188
- if (this.#appMenu.style.transform === `translateX(${this.#appMenuWidthTest}px)`) {
189
- this.#appMenu.style.transform = `translateX(-${this.#appMenuWidthTest}px)`;
190
- this.#appMenuButton.classList.toggle("app_menu_button_active")
191
- this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
192
- }
193
- }
194
- })
195
- let page_name = document.createElement('page_name');
196
- page_name.id = "page_name"
197
- header.addToLeft(this.#appMenuButton, page_name);
198
- this.#appMenu.appendChild(this.#routeViews)
199
- }
200
- enableSearchInput() {
201
- this.#app_menu_search_input.classList.add("app_menu_search_input")
202
- this.#app_menu_search_input.placeholder = "Поиск..."
203
- this.#app_menu_search_input.addEventListener('focus', () => {
204
- this.#app_menu_search_input.style.border = '1px solid var(--blue_prime_background)';
205
- })
206
- this.#app_menu_search_input.addEventListener('blur', () => {
207
- this.#app_menu_search_input.removeAttribute("style");
208
- })
209
- this.#app_menu_search_input.addEventListener("input", (evt) => {
210
- for (let item of this.#routeViews.children) {
211
- let text1 = item.children.item(0).textContent.toLowerCase();
212
- let text2 = evt.target.value.toLowerCase();
213
- if (!text1.includes(text2)) {
214
- item.style.display = "none"
215
- } else {
216
- item.removeAttribute("style")
217
- }
218
- }
219
- })
220
- this.#app_menu_search_main.appendChild(this.#app_menu_search_input)
221
- this.#appMenu.insertBefore(this.#app_menu_search_main, this.#routeViews)
222
- }
223
- go(page) {
224
- let header_toolbar = document.getElementById("header_toolbar");
225
- let page_name = document.getElementById("page_name");
226
- let center = document.getElementById("center");
227
- //
228
- header_toolbar.innerHTML = ''
229
- page_name.innerHTML = page.getTitle();
230
- center.innerHTML = '';
231
- center.appendChild(page.render());
232
- const _page = document.getElementsByTagName('page')[0];
233
- new Animation(_page).fadeIn();
234
- _page.addEventListener('animationend', () => {
235
- center.removeAttribute('style');
236
- });
237
- if (page.getMenuBar() !== undefined) {
238
- new Animation(page.getMenuBar()).fadeIn();
239
- header_toolbar.appendChild(page.getMenuBar());
240
- center.classList.add("header_padding", "test_scroll_track");
241
- } else {
242
- center.classList.remove("header_padding", "test_scroll_track");
243
- }
244
- }
245
- setRouteTest(page) {
246
- this.#routeList.push(page);
247
- let test = this.#routeList.filter(route => route.getTitle().includes(page.getTitle()));
248
- if (test.length === 1) {
249
- let button_route = document.createElement('route');
250
- let icon_menu = document.createElement('route_icon');
251
- icon_menu.innerHTML = page.getIcon();
252
- let title_menu = document.createElement('route_title');
253
- title_menu.innerHTML = page.getTitle();
254
- if (page.getMain()) {
255
- this.go(page);
256
- button_route.classList.add("route_active");
257
- }
258
- button_route.addEventListener('click', () => {
259
- const eventAwesome = new CustomEvent("route_event_"+page.constructor.name, {
260
- bubbles: true,
261
- detail: {
262
- class: page.constructor.name,
263
- title: page.getTitle(),
264
- page: page
265
- },
266
- });
267
- document.dispatchEvent(eventAwesome)
268
-
269
- if (!button_route.classList.contains('route_active')) {
270
- for (let act of document.getElementsByTagName('route')) act.classList.remove('route_active');
271
- this.go(page);
272
- button_route.classList.add("route_active");
273
- if (this.#auto_close) {
274
- if (this.#appMenu.style.transform === `translateX(${this.#appMenuWidth + 25}px)`) {
275
- this.#appMenu.style.transform = `translateX(-${this.#appMenuWidth + 25}px)`;
276
- this.#appMenuButton.classList.toggle("app_menu_button_active");
277
- this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
278
- }
279
- }
280
- }
281
- });
282
- if (page.getIcon() !== undefined) {
283
- button_route.appendChild(icon_menu)
284
- }
285
- button_route.appendChild(title_menu)
286
- this.#routeViews.appendChild(button_route)
287
- } else {
288
- Log
289
- Log.error(`Страница "${page.getTitle()}" уже добавлена в меню`)
290
- }
291
- }
292
- setAutoClose() {
293
- this.#auto_close = true;
294
- }
295
- getMenu() {
296
- return this.#appMenu;
297
- }
298
- }
299
-
300
- class NotificationBox {
301
- #notification_box = document.createElement('notification_box');
302
- #notification_box_main = document.createElement("notification_box_main");
303
- #notification_box_controls = document.createElement("notification_box_controls");
304
- #notification_box_width = 400;
305
- #notification_box_width_test = 425;
306
- #notification_button = document.createElement('notification_button');
307
- constructor(header, center) {
308
- let remove_button = new Button({
309
- icon: Icons.ACTIONS.DELETE,
310
- clickEvent: async () => {
311
- let box = document.getElementById("chui_notification_box");
312
- for (let child of box.children) {
313
- child.style.transform = "translateX(100%)"
314
- child.style.opacity = "0"
315
- setTimeout(async () => {
316
- await child.remove()
317
- }, 300)
318
- }
319
- }
320
- });
321
- this.#notification_box_controls.appendChild(remove_button.set())
322
- this.#notification_box.appendChild(this.#notification_box_main)
323
- this.#notification_box.appendChild(this.#notification_box_controls)
324
- this.#notification_box_main.id = 'chui_notification_box';
325
- this.#notification_box.style.top = `calc(${header.set().style.height})`;
326
- this.#notification_box.style.width = `${this.#notification_box_width}px`;
327
- this.#notification_box.style.right = `calc(-${this.#notification_box_width_test}px)`;
328
- this.#notification_box.style.height = `calc(100% - ${header.set().style.height})`;
329
- this.#notification_button.addEventListener("click", () => {
330
- if (this.#notification_button.classList.contains("notification_button_active")) {
331
- this.#notification_box.style.transform = `translateX(${this.#notification_box_width}px)`;
332
- } else {
333
- this.#notification_box.style.transform = `translateX(-${this.#notification_box_width_test}px)`;
334
- }
335
- this.#notification_button.classList.toggle("notification_button_active")
336
- })
337
- this.#notification_button.innerHTML = new Icon(Icons.SOCIAL.NOTIFICATIONS, "var(--header_icon_size)").getHTML();
338
- header.set().addEventListener('click', (e) => {
339
- if (e.target !== this.#notification_button) {
340
- this.#notification_box.style.transform = `translateX(${this.#notification_box_width}px)`;
341
- this.#notification_button.classList.remove("notification_button_active")
342
- }
343
- })
344
- center.addEventListener('click', (e) => {
345
- if (!this.#notification_box.contains(e.target)) {
346
- if (this.#notification_box.style.transform === `translateX(-${this.#notification_box_width_test}px)`) {
347
- this.#notification_box.style.transform = `translateX(${this.#notification_box_width_test}px)`;
348
- this.#notification_button.classList.toggle("notification_button_active")
349
- }
350
- }
351
- })
352
- center.onscroll = () => {
353
- if (center.scrollTop > 15) {
354
- header.set().style.backgroundColor = 'var(--header_background)'
355
- header.set().style.boxShadow = "var(--box_shadow_main)"
356
- //header.set().style.borderBottom = "1px solid var(--border_color)"
357
- } else {
358
- header.set().removeAttribute('style')
359
- }
360
- };
361
- header.addToRight(this.#notification_button)
362
- }
363
- getBox() {
364
- return this.#notification_box;
365
- }
366
- }
367
-
368
- class AppLayout {
369
- #header = new Header();
370
- #center = new Center().set();
371
- #appMenu = new AppMenu(this.#header, this.#center);
372
- #notificationBox = new NotificationBox(this.#header, this.#center);
373
- #notificationPanel = document.createElement('notification_panel');
374
- constructor() {
375
- require('../../modules/chui_fonts').install();
376
- // Глобальные стили
377
- chui_functions.setStyles(__dirname + `/global_style.css`, 'chUiJS_Global_App')
378
- chui_functions.setStyles(__dirname + `/main_theme_style.css`, 'chUiJS_Main_Theme')
379
- //if (process.platform !== "darwin") document.body.style.border = "1px solid var(--border_color)";
380
- // ===
381
-
382
- document.body.appendChild(this.#header.set())
383
- document.body.appendChild(this.#center)
384
- document.body.appendChild(this.#appMenu.getMenu())
385
- document.body.appendChild(this.#notificationBox.getBox())
386
- document.body.appendChild(this.#notificationPanel)
387
-
388
- // ЗАГРУЗКА ОБЬЕКТОВ
389
- ipcRenderer.on("sendNotificationDownload", (e, text, body) => {
390
- let downloadNotificationLoad = new DownloadNotification({ title: text, text: body });
391
- downloadNotificationLoad.show();
392
- ipcRenderer.on("sendNotificationDownloadUpdate", (e, title, text) => downloadNotificationLoad.update(title, text));
393
- ipcRenderer.on("sendNotificationDownloadComplete", () => downloadNotificationLoad.done());
394
- ipcRenderer.on("sendNotificationDownloadError", () => downloadNotificationLoad.error());
395
- })
396
- //
397
- ipcRenderer.on("sendNotificationUpdateLoad", async (e, text, body) => {
398
- let updateNotificationLoad = new UpdateNotification({ title: text, text: body, spinner: true });
399
- updateNotificationLoad.show(true);
400
- ipcRenderer.on("sendNotificationUpdateLoadClose", () => updateNotificationLoad.hide());
401
- })
402
- ipcRenderer.on("sendNotificationUpdate", async (e, text, body) => {
403
- let updateNotification = new UpdateNotification({ title: text, text: body, spinner: false });
404
- updateNotification.show(true);
405
- ipcRenderer.on("sendNotificationUpdateClose", () => updateNotification.hide());
406
- })
407
- let popup = new Popup();
408
- ipcRenderer.once("checkUpdatesTrue", async (e, check, version) => {
409
- if (check) {
410
- let confirm_res = await popup.confirm({
411
- title: `Доступна новая версия ${version}`, message: 'Установить сейчас?',
412
- cancelText: 'Отмена', okText: 'Установить'
413
- });
414
- e.sender.send("updateInstallConfirm", confirm_res)
415
- }
416
- })
417
- }
418
- setWindowControlsLeft() {
419
- this.#header.addWC(true);
420
- }
421
- setSearchToAppMenu() {
422
- this.#appMenu.enableSearchInput();
423
- }
424
- setAutoCloseRouteMenu() {
425
- this.#appMenu.setAutoClose();
426
- }
427
- setRoute(page) {
428
- this.#appMenu.setRouteTest(page);
429
- }
430
- addToHeaderRight(headerRight = []) {
431
- this.#header.addToRight(...headerRight);
432
- }
433
- removeToHeaderRight(headerRight = []) {
434
- this.#header.removeToRight(...headerRight);
435
- }
436
- addToHeaderLeft(headerLeft = []) {
437
- this.#header.addToLeft(...headerLeft);
438
- }
439
- addToHeaderLeftBeforeTitle(headerLeft = []) {
440
- this.#header.addToLeftBeforeTittle(...headerLeft);
441
- }
442
- disableAppMenu() {
443
- document.getElementById("appMenuButton").remove()
444
- document.getElementById("page_name").style.marginLeft = "8px"
445
- }
446
- setScript(pathToJS = String(), id = String()) {
447
- let data = fs.readFileSync(pathToJS, 'utf8');
448
- let script = document.createElement('script');
449
- script.innerHTML = String(data);
450
- script.setAttribute('id', id);
451
- if (document.getElementById(id) == null) document.body.appendChild(script);
452
- }
453
- static TABS(options = {
454
- width: String(),
455
- default: Number(),
456
- tabs: []
457
- }) { return new HeaderTabs(options).set(); }
458
- static BUTTON(options = {
459
- title: String(),
460
- icon: undefined,
461
- reverse: Boolean(),
462
- clickEvent: () => {}
463
- }) { return new HeaderButton(options).set(); }
464
- static USER_PROFILE(options = {
465
- username: String(),
466
- image: { noImage: Boolean(), imageLink: String(), imageBase64: String() },
467
- items: []
468
- }) { return new UserProfile(options).set(); }
469
- static USER_PROFILE_ITEM(options = {
470
- title: String(),
471
- icon: undefined,
472
- clickEvent: () => {}
473
- }) { return new UserDDItem(options).set(); }
474
- static DIALOG(options = {
475
- title: String(),
476
- icon: undefined,
477
- reverse: Boolean(),
478
- dialogOptions: {
479
- title: String(),
480
- closeOutSideClick: Boolean(),
481
- style: {
482
- width: String(),
483
- height: String(),
484
- direction: String(),
485
- wrap: String(),
486
- align: String(),
487
- justify: String(),
488
- },
489
- components: []
490
- }
491
- }) { return new HeaderDialog(options).set(); }
492
- }
493
-
494
- class HeaderTabs {
495
- #id_list = require("randomstring").generate();
496
- #header_tabs_list = undefined;
497
- #header_tabs = document.createElement('header_tabs');
498
- constructor(options = { width: String(), default: Number(), tabs: [] }) {
499
- this.#header_tabs_list = options.tabs;
500
- this.#header_tabs.id = this.#id_list;
501
- for (let item of this.#header_tabs_list) {
502
- this.#header_tabs.appendChild(item);
503
- item.addEventListener('click', (event) => {
504
- if (event.target.tagName === "HEADER_BUTTON_ICON" || event.target.tagName === "HEADER_BUTTON_TITLE") {
505
- this.#setActive(event.target.parentNode)
506
- } else {
507
- this.#setActive(event.target)
508
- }
509
- })
510
- }
511
- if (options.width !== undefined) this.#header_tabs.style.width = options.width;
512
- for (let item of this.#header_tabs_list) {
513
- if (this.#header_tabs_list.indexOf(item) === options.default) {
514
- setTimeout(() => {
515
- item.click()
516
- //this.#setActive(item)
517
- }, 250)
518
- }
519
- }
520
- }
521
- set() {
522
- return this.#header_tabs;
523
- }
524
- #setActive(target) {
525
- if (target.getAttribute("active") === null) {
526
- document.getElementById(this.#id_list).childNodes.forEach(child => {
527
- child.removeAttribute("active");
528
- child.classList.remove("header_tab_active")
529
- })
530
- target.setAttribute("active", true);
531
- target.classList.add("header_tab_active")
532
- }
533
- }
534
- }
535
-
536
- class UserProfile {
537
- #user_main = document.createElement("user_main");
538
- #user_button = document.createElement("user_button");
539
- #user_dropdown = document.createElement("user_dropdown");
540
- //
541
- #user_dd_image_main = document.createElement("user_dd_image_main");
542
- #user_dd_image = document.createElement("user_dd_image");
543
- //
544
- constructor(options = {
545
- username: String(),
546
- image: { noImage: Boolean(), imageLink: String(), imageBase64: String() },
547
- items: []
548
- }) {
549
- this.#user_button.innerText = options.username;
550
- this.#user_main.appendChild(this.#user_button)
551
- this.#user_main.appendChild(this.#user_dropdown)
552
- this.#user_button.addEventListener("click", () => {
553
- if (this.#user_dropdown.style.display === "flex") {
554
- this.#user_button.classList.remove("user_button");
555
- new Animation(this.#user_dropdown).fadeOut();
556
- } else {
557
- this.#user_button.classList.add("user_button");
558
- new Animation(this.#user_dropdown).fadeIn();
559
- }
560
- })
561
- window.addEventListener('click', (event) => {
562
- if (event.target.parentNode !== this.#user_main) {
563
- this.#user_button.classList.remove("user_button");
564
- new Animation(this.#user_dropdown).fadeOut();
565
- }
566
- });
567
- //
568
- if (options.image !== undefined) {
569
- if (!options.image.noImage) {
570
- let new_name = ""
571
- for (let item of options.username.split(" ")) new_name += item.charAt(0);
572
- this.#user_dd_image.innerText = new_name;
573
- this.#user_dd_image_main.appendChild(this.#user_dd_image);
574
- this.#user_dropdown.appendChild(this.#user_dd_image_main);
575
- }
576
- }
577
- //
578
- for (let item of options.items) this.#user_dropdown.appendChild(item);
579
- }
580
-
581
- set() {
582
- return this.#user_main;
583
- }
584
- }
585
-
586
- class UserDDItem {
587
- #user_item = document.createElement("user_item");
588
-
589
- constructor(options = {
590
- title: String(),
591
- icon: undefined,
592
- clickEvent: () => {}
593
- }) {
594
- if (options.title !== undefined && options.icon !== undefined) this.#user_item.innerHTML = options.title + options.icon;
595
- if (options.title !== undefined) this.#user_item.innerText = options.title;
596
- if (options.icon !== undefined) this.#user_item.innerHTML = options.icon;
597
- this.#user_item.addEventListener("click", options.clickEvent)
598
- }
599
-
600
- set() {
601
- return this.#user_item;
602
- }
603
- }
604
-
605
- class HeaderDialog {
606
- #header_button = document.createElement("header_button");
607
- #header_button_title = document.createElement("header_button_title");
608
- #header_button_icon = document.createElement("header_button_icon");
609
- constructor(options = {
610
- title: String(),
611
- icon: undefined,
612
- reverse: Boolean(),
613
- dialogOptions: {
614
- title: String(),
615
- closeOutSideClick: Boolean(),
616
- style: {
617
- width: String(),
618
- height: String(),
619
- direction: String(),
620
- wrap: String(),
621
- align: String(),
622
- justify: String(),
623
- },
624
- components: []
625
- }
626
- }) {
627
- let dialog = new Dialog({
628
- width: options.dialogOptions.style.width,
629
- height: options.dialogOptions.style.height,
630
- closeOutSideClick: options.dialogOptions.closeOutSideClick
631
- })
632
- // HEADER
633
- let header_dialog = new ContentBlock({
634
- direction: "row",
635
- wrap: "nowrap",
636
- align: "center",
637
- justify: "space-between",
638
- disableMarginChild: true
639
- });
640
- header_dialog.setWidth("-webkit-fill-available");
641
- header_dialog.setPadding("0px 0px 0px 10px");
642
- let title = new Label({
643
- markdownText: `**${options.dialogOptions.title}**`,
644
- textAlign: "center",
645
- wordBreak: "normal",
646
- width: "max-content",
647
- fontSize: "14pt"
648
- })
649
- let close_button = new Button({
650
- icon: Icons.NAVIGATION.CLOSE,
651
- reverse: true,
652
- clickEvent: () => dialog.close()
653
- });
654
- header_dialog.add(title, close_button);
655
- dialog.addToHeader(header_dialog);
656
- // BODY
657
- let body_dialog = new ContentBlock({
658
- direction: options.dialogOptions.style.direction,
659
- wrap: options.dialogOptions.style.wrap,
660
- align: options.dialogOptions.style.align,
661
- justify: options.dialogOptions.style.justify
662
- });
663
- body_dialog.setWidth("-webkit-fill-available");
664
- body_dialog.add(...options.dialogOptions.components)
665
- dialog.addToBody(body_dialog);
666
- // FOOTER
667
-
668
- //
669
- document.body.appendChild(dialog.set());
670
- //center.appendChild(dialog.set());
671
- if (options.title !== undefined && options.icon !== undefined) {
672
- if (options.reverse) {
673
- this.#header_button_title.innerText = options.title;
674
- this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
675
- this.#header_button_icon.style.marginRight = "6px";
676
- this.#header_button.appendChild(this.#header_button_icon)
677
- this.#header_button.appendChild(this.#header_button_title)
678
- } else {
679
- this.#header_button_title.innerText = options.title;
680
- this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
681
- this.#header_button_icon.style.marginLeft = "6px";
682
- this.#header_button.appendChild(this.#header_button_title)
683
- this.#header_button.appendChild(this.#header_button_icon)
684
- }
685
- } else if (options.title !== undefined && options.icon === undefined) {
686
- this.#header_button_title.innerText = options.title;
687
- this.#header_button.appendChild(this.#header_button_title)
688
- } else if (options.title === undefined && options.icon !== undefined) {
689
- this.#header_button.style.padding = "8px"
690
- this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
691
- this.#header_button.appendChild(this.#header_button_icon)
692
- }
693
- this.#header_button.addEventListener("click", () => dialog.open());
694
- }
695
-
696
- set() {
697
- return this.#header_button;
698
- }
699
- }
700
-
701
- class HeaderButton {
702
- #header_button = document.createElement("header_button");
703
- #header_button_title = document.createElement("header_button_title");
704
- #header_button_icon = document.createElement("header_button_icon");
705
-
706
- constructor(options = {
707
- title: String(),
708
- icon: undefined,
709
- reverse: Boolean(),
710
- clickEvent: () => {
711
- }
712
- }) {
713
- if (options.title !== undefined && options.icon !== undefined) {
714
- if (options.reverse) {
715
- this.#header_button_title.innerText = options.title;
716
- this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
717
- this.#header_button_icon.style.marginRight = "6px";
718
- this.#header_button.appendChild(this.#header_button_icon)
719
- this.#header_button.appendChild(this.#header_button_title)
720
- } else {
721
- this.#header_button_title.innerText = options.title;
722
- this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
723
- this.#header_button_icon.style.marginLeft = "6px";
724
- this.#header_button.appendChild(this.#header_button_title)
725
- this.#header_button.appendChild(this.#header_button_icon)
726
- }
727
- } else if (options.title !== undefined && options.icon === undefined) {
728
- this.#header_button_title.innerText = options.title;
729
- this.#header_button.appendChild(this.#header_button_title)
730
- } else if (options.title === undefined && options.icon !== undefined) {
731
- this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
732
- this.#header_button.appendChild(this.#header_button_icon)
733
- }
734
- this.#header_button.addEventListener("click", options.clickEvent);
735
- }
736
-
737
- set() {
738
- return this.#header_button;
739
- }
740
- }
741
-
742
- const removeEvents = (event) => {
743
- event.target.remove();
744
- event.target.removeEventListener('animationend', removeEvents);
745
- }
746
-
747
- exports.AppLayout = AppLayout
1
+ const {Animation} = require('../../modules/chui_animations/animations');
2
+ const {Icon, Icons} = require('../../components/chui_icons/icons');
3
+ const {Button} = require("../../components/chui_button/button");
4
+ // НАСТРОЙКИ
5
+ const {Dialog} = require("../../components/chui_modal/modal");
6
+ const {Label} = require("../../components/chui_label/label");
7
+ const {ContentBlock} = require("../../components/chui_content_block/content_block");
8
+ const {Popup} = require("../../components/chui_popups/popups");
9
+ const {UpdateNotification} = require("../../components/chui_notification/notification_update");
10
+ const {ipcRenderer} = require("electron");
11
+ const chui_functions = require('../../modules/chui_functions');
12
+ const {DownloadNotification} = require("../../components/chui_notification/notification_download");
13
+ const {Log} = require("../../../framework/modules/chui_logger/chui_logger");
14
+ const fs = require("fs");
15
+
16
+ class Events {
17
+ #route_event = undefined;
18
+ constructor() {}
19
+ route(page) {
20
+ this.#route_event = new CustomEvent("route_event_"+page.constructor.name, {
21
+ bubbles: true,
22
+ detail: {
23
+ class: page.constructor.name,
24
+ title: page.getTitle(),
25
+ page: page
26
+ },
27
+ });
28
+ document.dispatchEvent(this.#route_event)
29
+ }
30
+ }
31
+
32
+ class Route extends Events {
33
+ constructor() {
34
+ super();
35
+ }
36
+ go(page) {
37
+ let header_toolbar = document.getElementById("header_toolbar");
38
+ let page_name = document.getElementById("page_name");
39
+ let center = document.getElementById("center");
40
+ //
41
+ header_toolbar.innerHTML = ''
42
+ page_name.innerHTML = page.getTitle();
43
+ center.innerHTML = '';
44
+ center.appendChild(page.render());
45
+ const _page = document.getElementsByTagName('page')[0];
46
+ new Animation(_page).fadeIn();
47
+ _page.addEventListener('animationend', () => {
48
+ center.removeAttribute('style');
49
+ });
50
+ if (page.getMenuBar() !== undefined) {
51
+ new Animation(page.getMenuBar()).fadeIn();
52
+ header_toolbar.appendChild(page.getMenuBar());
53
+ center.classList.add("header_padding", "test_scroll_track");
54
+ } else {
55
+ center.classList.remove("header_padding", "test_scroll_track");
56
+ }
57
+
58
+ this.route(page)
59
+ }
60
+ }
61
+
62
+ class WindowControls {
63
+ // Управление кнопками
64
+ #box = document.createElement("wc_box")
65
+ #close = document.createElement("wc_close")
66
+ #maximize = document.createElement("wc_maximize")
67
+ #minimize = document.createElement("wc_minimize")
68
+ constructor() {
69
+ this.#close.innerHTML = new Icon(Icons.NAVIGATION.CLOSE, "16px").getHTML();
70
+ this.#maximize.innerHTML = new Icon(Icons.CONTENT.ADD, "16px").getHTML();
71
+ this.#minimize.innerHTML = new Icon(Icons.CONTENT.REMOVE, "16px").getHTML();
72
+ this.#close.addEventListener("click", () => {
73
+ let r_window = require("@electron/remote").BrowserWindow.getFocusedWindow();
74
+ r_window.close();
75
+ })
76
+ this.#maximize.addEventListener("click", () => {
77
+ let r_window = require("@electron/remote").BrowserWindow.getFocusedWindow();
78
+ r_window.isMaximized() ? r_window.unmaximize() : r_window.maximize();
79
+ })
80
+ this.#minimize.addEventListener("click", () => {
81
+ let r_window = require("@electron/remote").BrowserWindow.getFocusedWindow();
82
+ r_window.minimize();
83
+ })
84
+ }
85
+ set(pos_bool = Boolean()) {
86
+ if (pos_bool) {
87
+ this.#box.appendChild(this.#close)
88
+ this.#box.appendChild(this.#maximize)
89
+ this.#box.appendChild(this.#minimize)
90
+ } else {
91
+ this.#box.appendChild(this.#minimize)
92
+ this.#box.appendChild(this.#maximize)
93
+ this.#box.appendChild(this.#close)
94
+ }
95
+ ipcRenderer.on("chui_resizable_false", (e) => this.#maximize.remove())
96
+ return this.#box;
97
+ }
98
+ }
99
+
100
+ class Header {
101
+ #wc_box = new WindowControls();
102
+ #header = document.createElement("header");
103
+ #header_main = document.createElement("header_main");
104
+ #header_toolbar = document.createElement("header_toolbar");
105
+ #header_left_box = document.createElement("header_left_box");
106
+ #header_right_box = document.createElement("header_right_box");
107
+ constructor() {
108
+ this.#header.id = "header";
109
+ this.#header_main.id = "header_main";
110
+ this.#header_toolbar.id = "header_toolbar";
111
+ this.#header_main.appendChild(this.#header_left_box);
112
+ this.#header_main.appendChild(this.#header_right_box);
113
+ this.#header_main.appendChild(this.#wc_box.set(false));
114
+ this.#header.appendChild(this.#header_main)
115
+ this.#header.appendChild(this.#header_toolbar)
116
+ }
117
+ addWC(boolean = Boolean()) {
118
+ this.#header_main.insertBefore(this.#wc_box.set(boolean), this.#header_main.firstChild);
119
+ }
120
+ addToLeftBeforeTittle(...components) {
121
+ for (let component of components) this.#header_left_box.insertBefore(component, this.#header_left_box.firstChild);
122
+ }
123
+ addToLeft(...components) {
124
+ for (let component of components) {
125
+ this.#header_left_box.appendChild(component)
126
+ }
127
+ }
128
+ addToRight(...components) {
129
+ for (let component of components) this.#header_right_box.insertBefore(component, this.#header_right_box.firstChild);
130
+ }
131
+ removeToRight(...components) {
132
+ for (let component of components) this.#header_right_box.removeChild(component);
133
+ }
134
+ set() {
135
+ return this.#header;
136
+ }
137
+ }
138
+
139
+ class Center {
140
+ #center = document.createElement('center');
141
+ constructor() {
142
+ this.#center.id = "center";
143
+ }
144
+ set() {
145
+ return this.#center;
146
+ }
147
+ }
148
+
149
+ class AppMenu {
150
+ #routeList = [];
151
+ #appMenu = document.createElement('app_menu');
152
+ #appMenuWidth = 400;
153
+ #appMenuOffset = 25;
154
+ get #appMenuSlide() { return this.#appMenuWidth + this.#appMenuOffset; }
155
+ #routeViews = document.createElement('route_views');
156
+ #appMenuButton = document.createElement('app_menu_button');
157
+ // Блок поиска
158
+ #app_menu_search_main = document.createElement("app_menu_search_main");
159
+ #app_menu_search_input = document.createElement("input");
160
+ // ===
161
+ #auto_close = false;
162
+ constructor(header, center) {
163
+ this.#appMenu.style.top = `calc(${header.set().style.height})`;
164
+ this.#appMenu.style.width = `${this.#appMenuWidth}px`;
165
+ this.#appMenu.style.left = `calc(-${this.#appMenuSlide}px)`;
166
+ this.#appMenu.style.height = `calc(100% - ${header.set().style.height})`;
167
+ //
168
+ this.#appMenuButton.id = "appMenuButton"
169
+ this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
170
+ this.#appMenuButton.addEventListener("click", () => {
171
+ if (this.#appMenuButton.classList.contains("app_menu_button_active")) {
172
+ this.#appMenu.style.transform = `translateX(-${this.#appMenuSlide}px)`;
173
+ this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
174
+ } else {
175
+ this.#appMenu.style.transform = `translateX(${this.#appMenuSlide}px)`;
176
+ this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU_OPEN, "var(--header_icon_size)").getHTML();
177
+ }
178
+ this.#appMenuButton.classList.toggle("app_menu_button_active")
179
+ })
180
+ header.set().addEventListener('click', (e) => {
181
+ if (e.target !== this.#appMenuButton) {
182
+ this.#appMenu.style.transform = `translateX(-${this.#appMenuSlide}px)`;
183
+ this.#appMenuButton.classList.remove("app_menu_button_active")
184
+ this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
185
+ }
186
+ })
187
+ center.addEventListener('click', (e) => {
188
+ if (!this.#appMenu.contains(e.target)) {
189
+ if (this.#appMenu.style.transform === `translateX(${this.#appMenuSlide}px)`) {
190
+ this.#appMenu.style.transform = `translateX(-${this.#appMenuSlide}px)`;
191
+ this.#appMenuButton.classList.toggle("app_menu_button_active")
192
+ this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
193
+ }
194
+ }
195
+ })
196
+ let page_name = document.createElement('page_name');
197
+ page_name.id = "page_name"
198
+ header.addToLeft(this.#appMenuButton, page_name);
199
+ this.#appMenu.appendChild(this.#routeViews)
200
+ }
201
+ enableSearchInput() {
202
+ this.#app_menu_search_input.classList.add("app_menu_search_input")
203
+ this.#app_menu_search_input.placeholder = "Поиск..."
204
+ this.#app_menu_search_input.addEventListener('focus', () => {
205
+ this.#app_menu_search_input.style.border = '1px solid var(--blue_prime_background)';
206
+ })
207
+ this.#app_menu_search_input.addEventListener('blur', () => {
208
+ this.#app_menu_search_input.removeAttribute("style");
209
+ })
210
+ this.#app_menu_search_input.addEventListener("input", (evt) => {
211
+ for (let item of this.#routeViews.children) {
212
+ let text1 = item.children.item(0).textContent.toLowerCase();
213
+ let text2 = evt.target.value.toLowerCase();
214
+ if (!text1.includes(text2)) {
215
+ item.style.display = "none"
216
+ } else {
217
+ item.removeAttribute("style")
218
+ }
219
+ }
220
+ })
221
+ this.#app_menu_search_main.appendChild(this.#app_menu_search_input)
222
+ this.#appMenu.insertBefore(this.#app_menu_search_main, this.#routeViews)
223
+ }
224
+ go(page) {
225
+ let header_toolbar = document.getElementById("header_toolbar");
226
+ let page_name = document.getElementById("page_name");
227
+ let center = document.getElementById("center");
228
+ //
229
+ header_toolbar.innerHTML = ''
230
+ page_name.innerHTML = page.getTitle();
231
+ center.innerHTML = '';
232
+ center.appendChild(page.render());
233
+ const _page = document.getElementsByTagName('page')[0];
234
+ new Animation(_page).fadeIn();
235
+ _page.addEventListener('animationend', () => {
236
+ center.removeAttribute('style');
237
+ });
238
+ if (page.getMenuBar() !== undefined) {
239
+ new Animation(page.getMenuBar()).fadeIn();
240
+ header_toolbar.appendChild(page.getMenuBar());
241
+ center.classList.add("header_padding", "test_scroll_track");
242
+ } else {
243
+ center.classList.remove("header_padding", "test_scroll_track");
244
+ }
245
+ }
246
+ setRouteTest(page) {
247
+ this.#routeList.push(page);
248
+ let test = this.#routeList.filter(route => route.getTitle().includes(page.getTitle()));
249
+ if (test.length === 1) {
250
+ let button_route = document.createElement('route');
251
+ let icon_menu = document.createElement('route_icon');
252
+ icon_menu.innerHTML = page.getIcon();
253
+ let title_menu = document.createElement('route_title');
254
+ title_menu.innerHTML = page.getTitle();
255
+ if (page.getMain()) {
256
+ this.go(page);
257
+ button_route.classList.add("route_active");
258
+ }
259
+ button_route.addEventListener('click', () => {
260
+ const eventAwesome = new CustomEvent("route_event_"+page.constructor.name, {
261
+ bubbles: true,
262
+ detail: {
263
+ class: page.constructor.name,
264
+ title: page.getTitle(),
265
+ page: page
266
+ },
267
+ });
268
+ document.dispatchEvent(eventAwesome)
269
+
270
+ if (!button_route.classList.contains('route_active')) {
271
+ for (let act of document.getElementsByTagName('route')) act.classList.remove('route_active');
272
+ this.go(page);
273
+ button_route.classList.add("route_active");
274
+ if (this.#auto_close) {
275
+ if (this.#appMenu.style.transform === `translateX(${this.#appMenuSlide}px)`) {
276
+ this.#appMenu.style.transform = `translateX(-${this.#appMenuSlide}px)`;
277
+ this.#appMenuButton.classList.toggle("app_menu_button_active");
278
+ this.#appMenuButton.innerHTML = new Icon(Icons.NAVIGATION.MENU, "var(--header_icon_size)").getHTML();
279
+ }
280
+ }
281
+ }
282
+ });
283
+ if (page.getIcon() !== undefined) {
284
+ button_route.appendChild(icon_menu)
285
+ }
286
+ button_route.appendChild(title_menu)
287
+ this.#routeViews.appendChild(button_route)
288
+ } else {
289
+ Log.error(`Страница "${page.getTitle()}" уже добавлена в меню`)
290
+ }
291
+ }
292
+ setAutoClose() {
293
+ this.#auto_close = true;
294
+ }
295
+ getMenu() {
296
+ return this.#appMenu;
297
+ }
298
+ }
299
+
300
+ class NotificationBox {
301
+ #notification_box = document.createElement('notification_box');
302
+ #notification_box_main = document.createElement("notification_box_main");
303
+ #notification_box_controls = document.createElement("notification_box_controls");
304
+ #notification_box_width = 400;
305
+ #notification_box_width_test = 425;
306
+ #notification_button = document.createElement('notification_button');
307
+ constructor(header, center) {
308
+ let remove_button = new Button({
309
+ icon: Icons.ACTIONS.DELETE,
310
+ clickEvent: async () => {
311
+ let box = document.getElementById("chui_notification_box");
312
+ for (let child of box.children) {
313
+ child.style.transform = "translateX(100%)"
314
+ child.style.opacity = "0"
315
+ setTimeout(async () => {
316
+ await child.remove()
317
+ }, 300)
318
+ }
319
+ }
320
+ });
321
+ this.#notification_box_controls.appendChild(remove_button.set())
322
+ this.#notification_box.appendChild(this.#notification_box_main)
323
+ this.#notification_box.appendChild(this.#notification_box_controls)
324
+ this.#notification_box_main.id = 'chui_notification_box';
325
+ this.#notification_box.style.top = `calc(${header.set().style.height})`;
326
+ this.#notification_box.style.width = `${this.#notification_box_width}px`;
327
+ this.#notification_box.style.right = `calc(-${this.#notification_box_width_test}px)`;
328
+ this.#notification_box.style.height = `calc(100% - ${header.set().style.height})`;
329
+ this.#notification_button.addEventListener("click", () => {
330
+ if (this.#notification_button.classList.contains("notification_button_active")) {
331
+ this.#notification_box.style.transform = `translateX(${this.#notification_box_width}px)`;
332
+ } else {
333
+ this.#notification_box.style.transform = `translateX(-${this.#notification_box_width_test}px)`;
334
+ }
335
+ this.#notification_button.classList.toggle("notification_button_active")
336
+ })
337
+ this.#notification_button.innerHTML = new Icon(Icons.SOCIAL.NOTIFICATIONS, "var(--header_icon_size)").getHTML();
338
+ header.set().addEventListener('click', (e) => {
339
+ if (e.target !== this.#notification_button) {
340
+ this.#notification_box.style.transform = `translateX(${this.#notification_box_width}px)`;
341
+ this.#notification_button.classList.remove("notification_button_active")
342
+ }
343
+ })
344
+ center.addEventListener('click', (e) => {
345
+ if (!this.#notification_box.contains(e.target)) {
346
+ if (this.#notification_box.style.transform === `translateX(-${this.#notification_box_width_test}px)`) {
347
+ this.#notification_box.style.transform = `translateX(${this.#notification_box_width_test}px)`;
348
+ this.#notification_button.classList.toggle("notification_button_active")
349
+ }
350
+ }
351
+ })
352
+ center.onscroll = () => {
353
+ if (center.scrollTop > 15) {
354
+ header.set().style.backgroundColor = 'var(--header_background)'
355
+ header.set().style.boxShadow = "var(--box_shadow_main)"
356
+ //header.set().style.borderBottom = "1px solid var(--border_color)"
357
+ } else {
358
+ header.set().removeAttribute('style')
359
+ }
360
+ };
361
+ header.addToRight(this.#notification_button)
362
+ }
363
+ getBox() {
364
+ return this.#notification_box;
365
+ }
366
+ }
367
+
368
+ class AppLayout {
369
+ #header = new Header();
370
+ #center = new Center().set();
371
+ #appMenu = new AppMenu(this.#header, this.#center);
372
+ #notificationBox = new NotificationBox(this.#header, this.#center);
373
+ #notificationPanel = document.createElement('notification_panel');
374
+ constructor() {
375
+ require('../../modules/chui_fonts').install();
376
+ // Глобальные стили
377
+ chui_functions.setStyles(__dirname + `/global_style.css`, 'chUiJS_Global_App')
378
+ chui_functions.setStyles(__dirname + `/main_theme_style.css`, 'chUiJS_Main_Theme')
379
+ //if (process.platform !== "darwin") document.body.style.border = "1px solid var(--border_color)";
380
+ // ===
381
+
382
+ document.body.appendChild(this.#header.set())
383
+ document.body.appendChild(this.#center)
384
+ document.body.appendChild(this.#appMenu.getMenu())
385
+ document.body.appendChild(this.#notificationBox.getBox())
386
+ document.body.appendChild(this.#notificationPanel)
387
+
388
+ // ЗАГРУЗКА ОБЬЕКТОВ
389
+ ipcRenderer.on("sendNotificationDownload", (e, text, body) => {
390
+ let downloadNotificationLoad = new DownloadNotification({ title: text, text: body });
391
+ downloadNotificationLoad.show();
392
+ ipcRenderer.on("sendNotificationDownloadUpdate", (e, title, text) => downloadNotificationLoad.update(title, text));
393
+ ipcRenderer.on("sendNotificationDownloadComplete", () => downloadNotificationLoad.done());
394
+ ipcRenderer.on("sendNotificationDownloadError", () => downloadNotificationLoad.error());
395
+ })
396
+ //
397
+ ipcRenderer.on("sendNotificationUpdateLoad", async (e, text, body) => {
398
+ let updateNotificationLoad = new UpdateNotification({ title: text, text: body, spinner: true });
399
+ updateNotificationLoad.show(true);
400
+ ipcRenderer.on("sendNotificationUpdateLoadClose", () => updateNotificationLoad.hide());
401
+ })
402
+ ipcRenderer.on("sendNotificationUpdate", async (e, text, body) => {
403
+ let updateNotification = new UpdateNotification({ title: text, text: body, spinner: false });
404
+ updateNotification.show(true);
405
+ ipcRenderer.on("sendNotificationUpdateClose", () => updateNotification.hide());
406
+ })
407
+ let popup = new Popup();
408
+ ipcRenderer.once("checkUpdatesTrue", async (e, check, version) => {
409
+ if (check) {
410
+ let confirm_res = await popup.confirm({
411
+ title: `Доступна новая версия ${version}`, message: 'Установить сейчас?',
412
+ cancelText: 'Отмена', okText: 'Установить'
413
+ });
414
+ e.sender.send("updateInstallConfirm", confirm_res)
415
+ }
416
+ })
417
+ }
418
+ setWindowControlsLeft() {
419
+ this.#header.addWC(true);
420
+ }
421
+ setSearchToAppMenu() {
422
+ this.#appMenu.enableSearchInput();
423
+ }
424
+ setAutoCloseRouteMenu() {
425
+ this.#appMenu.setAutoClose();
426
+ }
427
+ setRoute(page) {
428
+ this.#appMenu.setRouteTest(page);
429
+ }
430
+ addToHeaderRight(headerRight = []) {
431
+ this.#header.addToRight(...headerRight);
432
+ }
433
+ removeToHeaderRight(headerRight = []) {
434
+ this.#header.removeToRight(...headerRight);
435
+ }
436
+ addToHeaderLeft(headerLeft = []) {
437
+ this.#header.addToLeft(...headerLeft);
438
+ }
439
+ addToHeaderLeftBeforeTitle(headerLeft = []) {
440
+ this.#header.addToLeftBeforeTittle(...headerLeft);
441
+ }
442
+ disableAppMenu() {
443
+ document.getElementById("appMenuButton").remove()
444
+ document.getElementById("page_name").style.marginLeft = "8px"
445
+ }
446
+ setScript(pathToJS = String(), id = String()) {
447
+ let data = fs.readFileSync(pathToJS, 'utf8');
448
+ let script = document.createElement('script');
449
+ script.innerHTML = String(data);
450
+ script.setAttribute('id', id);
451
+ if (document.getElementById(id) == null) document.body.appendChild(script);
452
+ }
453
+ static TABS(options = {
454
+ width: String(),
455
+ default: Number(),
456
+ tabs: []
457
+ }) { return new HeaderTabs(options).set(); }
458
+ static BUTTON(options = {
459
+ title: String(),
460
+ icon: undefined,
461
+ reverse: Boolean(),
462
+ clickEvent: () => {}
463
+ }) { return new HeaderButton(options).set(); }
464
+ static USER_PROFILE(options = {
465
+ username: String(),
466
+ image: { noImage: Boolean(), imageLink: String(), imageBase64: String() },
467
+ items: []
468
+ }) { return new UserProfile(options).set(); }
469
+ static USER_PROFILE_ITEM(options = {
470
+ title: String(),
471
+ icon: undefined,
472
+ clickEvent: () => {}
473
+ }) { return new UserDDItem(options).set(); }
474
+ static DIALOG(options = {
475
+ title: String(),
476
+ icon: undefined,
477
+ reverse: Boolean(),
478
+ dialogOptions: {
479
+ title: String(),
480
+ closeOutSideClick: Boolean(),
481
+ style: {
482
+ width: String(),
483
+ height: String(),
484
+ direction: String(),
485
+ wrap: String(),
486
+ align: String(),
487
+ justify: String(),
488
+ },
489
+ components: []
490
+ }
491
+ }) { return new HeaderDialog(options).set(); }
492
+ }
493
+
494
+ class HeaderTabs {
495
+ #id_list = require("randomstring").generate();
496
+ #header_tabs_list = undefined;
497
+ #header_tabs = document.createElement('header_tabs');
498
+ constructor(options = { width: String(), default: Number(), tabs: [] }) {
499
+ this.#header_tabs_list = options.tabs;
500
+ this.#header_tabs.id = this.#id_list;
501
+ for (let item of this.#header_tabs_list) {
502
+ this.#header_tabs.appendChild(item);
503
+ item.addEventListener('click', (event) => {
504
+ if (event.target.tagName === "HEADER_BUTTON_ICON" || event.target.tagName === "HEADER_BUTTON_TITLE") {
505
+ this.#setActive(event.target.parentNode)
506
+ } else {
507
+ this.#setActive(event.target)
508
+ }
509
+ })
510
+ }
511
+ if (options.width !== undefined) this.#header_tabs.style.width = options.width;
512
+ for (let item of this.#header_tabs_list) {
513
+ if (this.#header_tabs_list.indexOf(item) === options.default) {
514
+ setTimeout(() => {
515
+ item.click()
516
+ //this.#setActive(item)
517
+ }, 250)
518
+ }
519
+ }
520
+ }
521
+ set() {
522
+ return this.#header_tabs;
523
+ }
524
+ #setActive(target) {
525
+ if (target.getAttribute("active") === null) {
526
+ document.getElementById(this.#id_list).childNodes.forEach(child => {
527
+ child.removeAttribute("active");
528
+ child.classList.remove("header_tab_active")
529
+ })
530
+ target.setAttribute("active", true);
531
+ target.classList.add("header_tab_active")
532
+ }
533
+ }
534
+ }
535
+
536
+ class UserProfile {
537
+ #user_main = document.createElement("user_main");
538
+ #user_button = document.createElement("user_button");
539
+ #user_dropdown = document.createElement("user_dropdown");
540
+ //
541
+ #user_dd_image_main = document.createElement("user_dd_image_main");
542
+ #user_dd_image = document.createElement("user_dd_image");
543
+ //
544
+ constructor(options = {
545
+ username: String(),
546
+ image: { noImage: Boolean(), imageLink: String(), imageBase64: String() },
547
+ items: []
548
+ }) {
549
+ this.#user_button.innerText = options.username;
550
+ this.#user_main.appendChild(this.#user_button)
551
+ this.#user_main.appendChild(this.#user_dropdown)
552
+ this.#user_button.addEventListener("click", () => {
553
+ if (this.#user_dropdown.style.display === "flex") {
554
+ this.#user_button.classList.remove("user_button");
555
+ new Animation(this.#user_dropdown).fadeOut();
556
+ } else {
557
+ this.#user_button.classList.add("user_button");
558
+ new Animation(this.#user_dropdown).fadeIn();
559
+ }
560
+ })
561
+ window.addEventListener('click', (event) => {
562
+ if (event.target.parentNode !== this.#user_main) {
563
+ this.#user_button.classList.remove("user_button");
564
+ new Animation(this.#user_dropdown).fadeOut();
565
+ }
566
+ });
567
+ //
568
+ if (options.image !== undefined) {
569
+ if (!options.image.noImage) {
570
+ let new_name = ""
571
+ for (let item of options.username.split(" ")) new_name += item.charAt(0);
572
+ this.#user_dd_image.innerText = new_name;
573
+ this.#user_dd_image_main.appendChild(this.#user_dd_image);
574
+ this.#user_dropdown.appendChild(this.#user_dd_image_main);
575
+ }
576
+ }
577
+ //
578
+ for (let item of options.items) this.#user_dropdown.appendChild(item);
579
+ }
580
+
581
+ set() {
582
+ return this.#user_main;
583
+ }
584
+ }
585
+
586
+ class UserDDItem {
587
+ #user_item = document.createElement("user_item");
588
+
589
+ constructor(options = {
590
+ title: String(),
591
+ icon: undefined,
592
+ clickEvent: () => {}
593
+ }) {
594
+ if (options.title !== undefined && options.icon !== undefined) this.#user_item.innerHTML = options.title + options.icon;
595
+ if (options.title !== undefined) this.#user_item.innerText = options.title;
596
+ if (options.icon !== undefined) this.#user_item.innerHTML = options.icon;
597
+ this.#user_item.addEventListener("click", options.clickEvent)
598
+ }
599
+
600
+ set() {
601
+ return this.#user_item;
602
+ }
603
+ }
604
+
605
+ class HeaderDialog {
606
+ #header_button = document.createElement("header_button");
607
+ #header_button_title = document.createElement("header_button_title");
608
+ #header_button_icon = document.createElement("header_button_icon");
609
+ constructor(options = {
610
+ title: String(),
611
+ icon: undefined,
612
+ reverse: Boolean(),
613
+ dialogOptions: {
614
+ title: String(),
615
+ closeOutSideClick: Boolean(),
616
+ style: {
617
+ width: String(),
618
+ height: String(),
619
+ direction: String(),
620
+ wrap: String(),
621
+ align: String(),
622
+ justify: String(),
623
+ },
624
+ components: []
625
+ }
626
+ }) {
627
+ let dialog = new Dialog({
628
+ width: options.dialogOptions.style.width,
629
+ height: options.dialogOptions.style.height,
630
+ closeOutSideClick: options.dialogOptions.closeOutSideClick
631
+ })
632
+ // HEADER
633
+ let header_dialog = new ContentBlock({
634
+ direction: "row",
635
+ wrap: "nowrap",
636
+ align: "center",
637
+ justify: "space-between",
638
+ disableMarginChild: true
639
+ });
640
+ header_dialog.setWidth("-webkit-fill-available");
641
+ header_dialog.setPadding("0px 0px 0px 10px");
642
+ let title = new Label({
643
+ markdownText: `**${options.dialogOptions.title}**`,
644
+ textAlign: "center",
645
+ wordBreak: "normal",
646
+ width: "max-content",
647
+ fontSize: "14pt"
648
+ })
649
+ let close_button = new Button({
650
+ icon: Icons.NAVIGATION.CLOSE,
651
+ reverse: true,
652
+ clickEvent: () => dialog.close()
653
+ });
654
+ header_dialog.add(title, close_button);
655
+ dialog.addToHeader(header_dialog);
656
+ // BODY
657
+ let body_dialog = new ContentBlock({
658
+ direction: options.dialogOptions.style.direction,
659
+ wrap: options.dialogOptions.style.wrap,
660
+ align: options.dialogOptions.style.align,
661
+ justify: options.dialogOptions.style.justify
662
+ });
663
+ body_dialog.setWidth("-webkit-fill-available");
664
+ body_dialog.add(...options.dialogOptions.components)
665
+ dialog.addToBody(body_dialog);
666
+ // FOOTER
667
+
668
+ //
669
+ document.body.appendChild(dialog.set());
670
+ //center.appendChild(dialog.set());
671
+ if (options.title !== undefined && options.icon !== undefined) {
672
+ if (options.reverse) {
673
+ this.#header_button_title.innerText = options.title;
674
+ this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
675
+ this.#header_button_icon.style.marginRight = "6px";
676
+ this.#header_button.appendChild(this.#header_button_icon)
677
+ this.#header_button.appendChild(this.#header_button_title)
678
+ } else {
679
+ this.#header_button_title.innerText = options.title;
680
+ this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
681
+ this.#header_button_icon.style.marginLeft = "6px";
682
+ this.#header_button.appendChild(this.#header_button_title)
683
+ this.#header_button.appendChild(this.#header_button_icon)
684
+ }
685
+ } else if (options.title !== undefined && options.icon === undefined) {
686
+ this.#header_button_title.innerText = options.title;
687
+ this.#header_button.appendChild(this.#header_button_title)
688
+ } else if (options.title === undefined && options.icon !== undefined) {
689
+ this.#header_button.style.padding = "8px"
690
+ this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
691
+ this.#header_button.appendChild(this.#header_button_icon)
692
+ }
693
+ this.#header_button.addEventListener("click", () => dialog.open());
694
+ }
695
+
696
+ set() {
697
+ return this.#header_button;
698
+ }
699
+ }
700
+
701
+ class HeaderButton {
702
+ #header_button = document.createElement("header_button");
703
+ #header_button_title = document.createElement("header_button_title");
704
+ #header_button_icon = document.createElement("header_button_icon");
705
+
706
+ constructor(options = {
707
+ title: String(),
708
+ icon: undefined,
709
+ reverse: Boolean(),
710
+ clickEvent: () => {
711
+ }
712
+ }) {
713
+ if (options.title !== undefined && options.icon !== undefined) {
714
+ if (options.reverse) {
715
+ this.#header_button_title.innerText = options.title;
716
+ this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
717
+ this.#header_button_icon.style.marginRight = "6px";
718
+ this.#header_button.appendChild(this.#header_button_icon)
719
+ this.#header_button.appendChild(this.#header_button_title)
720
+ } else {
721
+ this.#header_button_title.innerText = options.title;
722
+ this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
723
+ this.#header_button_icon.style.marginLeft = "6px";
724
+ this.#header_button.appendChild(this.#header_button_title)
725
+ this.#header_button.appendChild(this.#header_button_icon)
726
+ }
727
+ } else if (options.title !== undefined && options.icon === undefined) {
728
+ this.#header_button_title.innerText = options.title;
729
+ this.#header_button.appendChild(this.#header_button_title)
730
+ } else if (options.title === undefined && options.icon !== undefined) {
731
+ this.#header_button_icon.innerHTML = new Icon(options.icon, "var(--header_icon_size)").getHTML();
732
+ this.#header_button.appendChild(this.#header_button_icon)
733
+ }
734
+ this.#header_button.addEventListener("click", options.clickEvent);
735
+ }
736
+
737
+ set() {
738
+ return this.#header_button;
739
+ }
740
+ }
741
+
742
+ const removeEvents = (event) => {
743
+ event.target.remove();
744
+ event.target.removeEventListener('animationend', removeEvents);
745
+ }
746
+
747
+ exports.AppLayout = AppLayout
748
748
  exports.Route = Route