chuijs 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +113 -0
- package/README.md +43 -632
- package/framework/appLayout/default/chui_app_layout.js +314 -273
- package/framework/appLayout/default/global_style.css +93 -53
- package/framework/components/chui_accordion/accordion.js +29 -26
- package/framework/components/chui_accordion/styles.css +6 -5
- package/framework/components/chui_action_sheet/action_sheet.js +59 -33
- package/framework/components/chui_action_sheet/styles.css +2 -1
- package/framework/components/chui_affix/affix.js +11 -6
- package/framework/components/chui_alert/alert.js +23 -14
- package/framework/components/chui_avatar/avatar.js +23 -22
- package/framework/components/chui_avatar_group/avatar_group.js +21 -19
- package/framework/components/chui_backtop/backtop.js +35 -19
- package/framework/components/chui_badge/badge.js +15 -13
- package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
- package/framework/components/chui_button/button.js +42 -22
- package/framework/components/chui_button/styles.css +2 -2
- package/framework/components/chui_calendar/calendar.js +12 -10
- package/framework/components/chui_card/card.js +43 -23
- package/framework/components/chui_chat/chat.js +72 -33
- package/framework/components/chui_clipboard_history/clipboard_history.js +30 -21
- package/framework/components/chui_clipboard_history/styles.css +4 -2
- package/framework/components/chui_code/code.js +2 -2
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +47 -31
- package/framework/components/chui_code_editor/styles.css +3 -2
- package/framework/components/chui_command_palette/command_palette.js +60 -37
- package/framework/components/chui_console/console.js +5 -5
- package/framework/components/chui_console/styles.css +1 -1
- package/framework/components/chui_content_block/content_block.js +33 -19
- package/framework/components/chui_content_block/styles.css +2 -2
- package/framework/components/chui_context_menu/context_menu.js +9 -4
- package/framework/components/chui_custom_element/custom_element.js +22 -15
- package/framework/components/chui_data_grid/data_grid.js +396 -234
- package/framework/components/chui_data_grid/styles.css +10 -8
- package/framework/components/chui_descriptions/descriptions.js +34 -17
- package/framework/components/chui_details/details.js +32 -26
- package/framework/components/chui_details/styles.css +5 -4
- package/framework/components/chui_diff_viewer/diff_viewer.js +91 -66
- package/framework/components/chui_diff_viewer/styles.css +1 -1
- package/framework/components/chui_divider/divider.js +13 -11
- package/framework/components/chui_drawer/drawer.js +27 -25
- package/framework/components/chui_drop_zone/drop_zone.js +31 -21
- package/framework/components/chui_empty_state/empty_state.js +20 -15
- package/framework/components/chui_fieldset/fieldset.js +37 -20
- package/framework/components/chui_fieldset/styles.css +1 -1
- package/framework/components/chui_file_explorer/file_explorer.js +157 -86
- package/framework/components/chui_file_explorer/styles.css +2 -1
- package/framework/components/chui_form/form.js +31 -19
- package/framework/components/chui_form/styles.css +1 -1
- package/framework/components/chui_gantt/gantt.js +64 -40
- package/framework/components/chui_graphs/graphs.js +301 -200
- package/framework/components/chui_graphs/styles.css +1 -1
- package/framework/components/chui_hero/hero.js +40 -22
- package/framework/components/chui_html_block/html_block.js +6 -6
- package/framework/components/chui_html_block/styles.css +2 -2
- package/framework/components/chui_hx/hx.js +3 -3
- package/framework/components/chui_hx/styles.css +11 -4
- package/framework/components/chui_icons/icons.js +2109 -2109
- package/framework/components/chui_icons/styles.css +2 -2
- package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
- package/framework/components/chui_inputs/chui_check_box/styles.css +18 -18
- package/framework/components/chui_inputs/chui_chips/chips.js +50 -40
- package/framework/components/chui_inputs/chui_chips/styles.css +4 -2
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +36 -24
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +100 -82
- package/framework/components/chui_inputs/chui_combo_box/styles.css +14 -12
- package/framework/components/chui_inputs/chui_date/date.js +102 -66
- package/framework/components/chui_inputs/chui_date/styles.css +12 -11
- package/framework/components/chui_inputs/chui_date_range/date_range.js +40 -29
- package/framework/components/chui_inputs/chui_datetime/datetime.js +35 -27
- package/framework/components/chui_inputs/chui_email/email.js +43 -31
- package/framework/components/chui_inputs/chui_email/styles.css +5 -5
- package/framework/components/chui_inputs/chui_file/file.js +68 -41
- package/framework/components/chui_inputs/chui_file/styles.css +13 -12
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +61 -36
- package/framework/components/chui_inputs/chui_masked/masked.js +39 -28
- package/framework/components/chui_inputs/chui_mention/mention.js +77 -30
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +173 -153
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +9 -7
- package/framework/components/chui_inputs/chui_number/number.js +58 -41
- package/framework/components/chui_inputs/chui_number/styles.css +7 -7
- package/framework/components/chui_inputs/chui_otp/otp.js +38 -29
- package/framework/components/chui_inputs/chui_password/password.js +58 -36
- package/framework/components/chui_inputs/chui_password/styles.css +8 -8
- package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
- package/framework/components/chui_inputs/chui_radio_button/styles.css +20 -20
- package/framework/components/chui_inputs/chui_rating/rating.js +26 -22
- package/framework/components/chui_inputs/chui_select_box/select_box.js +102 -78
- package/framework/components/chui_inputs/chui_select_box/styles.css +11 -11
- package/framework/components/chui_inputs/chui_slider/slider.js +29 -26
- package/framework/components/chui_inputs/chui_slider/styles.css +2 -1
- package/framework/components/chui_inputs/chui_text/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text/text.js +65 -44
- package/framework/components/chui_inputs/chui_text_area/styles.css +6 -6
- package/framework/components/chui_inputs/chui_text_area/text_area.js +51 -28
- package/framework/components/chui_inputs/chui_time/styles.css +5 -3
- package/framework/components/chui_inputs/chui_time/time.js +38 -27
- package/framework/components/chui_inputs/chui_toggle/styles.css +3 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +53 -43
- package/framework/components/chui_json_viewer/json_viewer.js +52 -33
- package/framework/components/chui_json_viewer/styles.css +3 -2
- package/framework/components/chui_kanban/kanban.js +52 -34
- package/framework/components/chui_kbd/kbd.js +12 -10
- package/framework/components/chui_label/label.js +14 -12
- package/framework/components/chui_label/styles.css +2 -2
- package/framework/components/chui_link/link.js +27 -20
- package/framework/components/chui_list/list.js +31 -27
- package/framework/components/chui_list/styles.css +2 -1
- package/framework/components/chui_markdown_editor/markdown_editor.js +60 -44
- package/framework/components/chui_media/audio.js +326 -227
- package/framework/components/chui_media/audio_styles.css +40 -21
- package/framework/components/chui_media/image.js +70 -38
- package/framework/components/chui_media/image_compare.js +52 -21
- package/framework/components/chui_media/image_styles.css +3 -3
- package/framework/components/chui_media/video.js +155 -62
- package/framework/components/chui_media/video_styles.css +33 -16
- package/framework/components/chui_menu_bar/menu_bar.js +26 -24
- package/framework/components/chui_menu_bar/styles.css +4 -2
- package/framework/components/chui_modal/modal.js +44 -43
- package/framework/components/chui_modal/styles.css +3 -2
- package/framework/components/chui_notification/notification.js +50 -34
- package/framework/components/chui_notification/notification_download.js +31 -25
- package/framework/components/chui_notification/notification_download_progress.css +3 -2
- package/framework/components/chui_notification/notification_download_progress.js +47 -41
- package/framework/components/chui_notification/notification_update.js +23 -16
- package/framework/components/chui_notification/status_plate.js +2 -2
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +1 -1
- package/framework/components/chui_org_chart/org_chart.js +74 -35
- package/framework/components/chui_pagination/pagination.js +62 -27
- package/framework/components/chui_paragraph/paragraph.js +2 -2
- package/framework/components/chui_paragraph/styles.css +1 -1
- package/framework/components/chui_popover/popover.js +49 -28
- package/framework/components/chui_popups/popups.js +137 -108
- package/framework/components/chui_popups/styles.css +2 -2
- package/framework/components/chui_print_button/print_button.js +33 -23
- package/framework/components/chui_progress_bar/progress_bar.js +23 -15
- package/framework/components/chui_progress_bar/styles.css +2 -2
- package/framework/components/chui_progress_ring/progress_ring.js +17 -15
- package/framework/components/chui_qrcode/qrcode.js +75 -31
- package/framework/components/chui_query_builder/query_builder.js +216 -123
- package/framework/components/chui_radio_group/radio_group.js +36 -26
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +26 -16
- package/framework/components/chui_scheduler/scheduler.js +57 -35
- package/framework/components/chui_scheduler/styles.css +6 -2
- package/framework/components/chui_segmented_control/segmented_control.js +27 -21
- package/framework/components/chui_settings/settings.js +122 -48
- package/framework/components/chui_shortcut_help/shortcut_help.js +55 -32
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +33 -23
- package/framework/components/chui_skeleton/skeleton.js +29 -24
- package/framework/components/chui_slideshow/slideshow.js +60 -41
- package/framework/components/chui_slideshow/styles.css +18 -12
- package/framework/components/chui_spinner/spinner.js +8 -8
- package/framework/components/chui_spinner/styles.css +0 -1
- package/framework/components/chui_split_button/split_button.js +23 -18
- package/framework/components/chui_split_button/styles.css +1 -1
- package/framework/components/chui_splitter/splitter.js +35 -28
- package/framework/components/chui_statistic/statistic.js +65 -38
- package/framework/components/chui_status_bar/status_bar.js +11 -9
- package/framework/components/chui_stepper/stepper.js +27 -22
- package/framework/components/chui_sticky_bar/sticky_bar.js +9 -4
- package/framework/components/chui_sticky_bar/styles.css +3 -1
- package/framework/components/chui_tabs/chui_tabs.js +28 -22
- package/framework/components/chui_tabs/styles.css +3 -3
- package/framework/components/chui_text_editor/styles.css +20 -19
- package/framework/components/chui_text_editor/text_editor.js +85 -61
- package/framework/components/chui_text_editor/text_editor_panel.js +346 -284
- package/framework/components/chui_theme_toggle/theme_toggle.js +27 -22
- package/framework/components/chui_timeline/timeline.js +14 -12
- package/framework/components/chui_toast_queue/toast_queue.js +52 -46
- package/framework/components/chui_toolbar/toolbar.js +20 -13
- package/framework/components/chui_tooltip/tooltip.js +37 -24
- package/framework/components/chui_tour/styles.css +8 -3
- package/framework/components/chui_tour/tour.js +61 -27
- package/framework/components/chui_transfer/styles.css +2 -1
- package/framework/components/chui_transfer/transfer.js +75 -42
- package/framework/components/chui_tree_table/tree_table.js +43 -29
- package/framework/components/chui_tree_view/styles.css +4 -2
- package/framework/components/chui_tree_view/tree_view.js +142 -99
- package/framework/components/chui_watermark/watermark.js +24 -16
- package/framework/components/chui_webview/styles.css +2 -2
- package/framework/components/chui_webview/webview.js +62 -50
- package/framework/components/telegram_bot/chui_telegram_bot.js +71 -64
- package/framework/modules/chui_a11y/chui_a11y.js +77 -46
- package/framework/modules/chui_animations/animations.js +42 -42
- package/framework/modules/chui_animations/styles.css +1 -1
- package/framework/modules/chui_bridge/preload.js +56 -26
- package/framework/modules/chui_functions.js +52 -50
- package/framework/modules/chui_highlight/chui_highlight.js +25 -22
- package/framework/modules/chui_i18n/chui_i18n.js +9 -7
- package/framework/modules/chui_i18n/locales/a11y.js +5 -5
- package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
- package/framework/modules/chui_i18n/locales/calendar.js +3 -3
- package/framework/modules/chui_i18n/locales/common.js +3 -3
- package/framework/modules/chui_i18n/locales/data.js +36 -26
- package/framework/modules/chui_i18n/locales/editors.js +40 -13
- package/framework/modules/chui_i18n/locales/feedback.js +3 -3
- package/framework/modules/chui_i18n/locales/forms.js +8 -8
- package/framework/modules/chui_i18n/locales/graphics.js +8 -8
- package/framework/modules/chui_i18n/locales/media.js +4 -4
- package/framework/modules/chui_i18n/locales/navigation.js +8 -8
- package/framework/modules/chui_i18n/locales/validate.js +3 -3
- package/framework/modules/chui_json/chui_json.js +9 -9
- package/framework/modules/chui_layout/chui_layout.js +12 -10
- package/framework/modules/chui_logger/chui_logger.js +29 -25
- package/framework/modules/chui_page/page.js +33 -27
- package/framework/modules/chui_page/styles.css +3 -26
- package/framework/modules/chui_qr/chui_qr.js +158 -67
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +35 -24
- package/framework/modules/chui_scrollbar/styles.css +3 -1
- package/framework/modules/chui_services/chui_channels.js +76 -11
- package/framework/modules/chui_services/chui_services.js +39 -31
- package/framework/modules/chui_services/desktop.js +149 -30
- package/framework/modules/chui_sortable/chui_sortable.js +17 -12
- package/framework/modules/chui_validate/chui_validate.js +7 -4
- package/framework/tray_bar/chui_menu_items.js +136 -46
- package/index.d.ts +4814 -0
- package/index.js +449 -334
- package/package.json +79 -68
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const {Animation} = require(
|
|
2
|
-
const {Spinner} = require("../chui_spinner/spinner");
|
|
3
|
-
const {setStyles, getTime, optionOr} = require(
|
|
4
|
-
const {LAYOUT_ROLE, requireLayoutNode} = require(
|
|
5
|
-
const {Icons} = require("../chui_icons/icons");
|
|
1
|
+
const { Animation } = require("../../modules/chui_animations/animations");
|
|
2
|
+
const { Spinner } = require("../chui_spinner/spinner");
|
|
3
|
+
const { setStyles, getTime, optionOr } = require("../../modules/chui_functions");
|
|
4
|
+
const { LAYOUT_ROLE, requireLayoutNode } = require("../../modules/chui_layout/chui_layout");
|
|
5
|
+
const { Icons } = require("../chui_icons/icons");
|
|
6
6
|
// Плашка значка — общая на всё семейство карточек уведомлений
|
|
7
|
-
const {createStatusPlate} = require("./status_plate");
|
|
7
|
+
const { createStatusPlate } = require("./status_plate");
|
|
8
8
|
|
|
9
9
|
class UpdateNotification {
|
|
10
10
|
#id = require("randomstring").generate();
|
|
@@ -17,8 +17,10 @@ class UpdateNotification {
|
|
|
17
17
|
#update_notification_body = document.createElement("update_notification_body");
|
|
18
18
|
#update_notification_text = document.createElement("update_notification_text");
|
|
19
19
|
constructor(options = { title: String(), text: String(), spinner: Boolean() }) {
|
|
20
|
-
setStyles(__dirname + "/styles_update.css",
|
|
20
|
+
setStyles(__dirname + "/styles_update.css", "chUiJS_UpdateNotification");
|
|
21
21
|
this.#update_notification.id = this.#id;
|
|
22
|
+
// Карточка обновления живёт в ящике и меняется на месте — объявляем вежливо
|
|
23
|
+
this.#update_notification.setAttribute("role", "status");
|
|
22
24
|
// Пустая заготовка опции равносильна отсутствующей: пустое уведомление не собирается
|
|
23
25
|
const title = optionOr(options.title, undefined);
|
|
24
26
|
const text = optionOr(options.text, undefined);
|
|
@@ -36,10 +38,10 @@ class UpdateNotification {
|
|
|
36
38
|
}
|
|
37
39
|
this.#update_notification_date.innerHTML = getTime();
|
|
38
40
|
//
|
|
39
|
-
this.#update_notification_header.appendChild(this.#update_notification_title)
|
|
40
|
-
this.#update_notification_header.appendChild(this.#update_notification_date)
|
|
41
|
+
this.#update_notification_header.appendChild(this.#update_notification_title);
|
|
42
|
+
this.#update_notification_header.appendChild(this.#update_notification_date);
|
|
41
43
|
//
|
|
42
|
-
this.#update_notification_content.appendChild(this.#update_notification_header)
|
|
44
|
+
this.#update_notification_content.appendChild(this.#update_notification_header);
|
|
43
45
|
// Значок и спиннер делят одно место — плашку слева: карточка остаётся ровной,
|
|
44
46
|
// а текст не отъезжает вбок под вращающимся кольцом
|
|
45
47
|
this.#update_notification_icon = createStatusPlate(undefined, Icons.NOTIFICATION.SYSTEM_UPDATE);
|
|
@@ -50,17 +52,22 @@ class UpdateNotification {
|
|
|
50
52
|
this.#update_notification_icon.innerHTML = "";
|
|
51
53
|
this.#update_notification_icon.appendChild(new Spinner(Spinner.SIZE.V_SMALL, "0").set());
|
|
52
54
|
}
|
|
53
|
-
this.#update_notification_body.appendChild(this.#update_notification_text)
|
|
54
|
-
this.#update_notification_content.appendChild(this.#update_notification_body)
|
|
55
|
-
this.#update_notification.appendChild(this.#update_notification_icon)
|
|
56
|
-
this.#update_notification.appendChild(this.#update_notification_content)
|
|
55
|
+
this.#update_notification_body.appendChild(this.#update_notification_text);
|
|
56
|
+
this.#update_notification_content.appendChild(this.#update_notification_body);
|
|
57
|
+
this.#update_notification.appendChild(this.#update_notification_icon);
|
|
58
|
+
this.#update_notification.appendChild(this.#update_notification_content);
|
|
57
59
|
}
|
|
58
60
|
show(showOnSystem = Boolean()) {
|
|
59
61
|
const panel = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_PANEL, this.#update_notification);
|
|
60
62
|
panel.appendChild(this.#update_notification);
|
|
61
63
|
new Animation(this.#update_notification).slideRightIn();
|
|
62
64
|
//notification.addEventListener("click", () => this.hide(notification));
|
|
63
|
-
if (showOnSystem)
|
|
65
|
+
if (showOnSystem)
|
|
66
|
+
require("electron").ipcRenderer.send(
|
|
67
|
+
"show_system_notification",
|
|
68
|
+
this.#update_notification_title.innerText,
|
|
69
|
+
this.#update_notification_text.innerText
|
|
70
|
+
);
|
|
64
71
|
}
|
|
65
72
|
hide() {
|
|
66
73
|
const notification = this.#update_notification;
|
|
@@ -76,4 +83,4 @@ class UpdateNotification {
|
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
|
|
79
|
-
exports.UpdateNotification = UpdateNotification
|
|
86
|
+
exports.UpdateNotification = UpdateNotification;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const {setStyles} = require(
|
|
2
|
-
const {Icon, Icons} = require("../chui_icons/icons");
|
|
1
|
+
const { setStyles } = require("../../modules/chui_functions");
|
|
2
|
+
const { Icon, Icons } = require("../chui_icons/icons");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Плашка значка состояния: одно решение на всё семейство карточек уведомлений —
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const { setStyles } = require(
|
|
2
|
-
const { Avatar } = require(
|
|
3
|
-
const { makeKeyboardButton } = require(
|
|
4
|
-
const { Icon, Icons } = require(
|
|
5
|
-
const { I18n } = require(
|
|
1
|
+
const { setStyles } = require("../../modules/chui_functions");
|
|
2
|
+
const { Avatar } = require("../chui_avatar/avatar");
|
|
3
|
+
const { makeKeyboardButton } = require("../../modules/chui_a11y/chui_a11y");
|
|
4
|
+
const { Icon, Icons } = require("../chui_icons/icons");
|
|
5
|
+
const { I18n } = require("../../modules/chui_i18n/chui_i18n");
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Схема подчинения: карточки людей по уровням и связи «руководитель — подчинённый».
|
|
@@ -55,7 +55,7 @@ class OrgChart {
|
|
|
55
55
|
static STYLE = {
|
|
56
56
|
DEFAULT: "default",
|
|
57
57
|
ACCENT: "accent",
|
|
58
|
-
MUTED: "muted"
|
|
58
|
+
MUTED: "muted",
|
|
59
59
|
};
|
|
60
60
|
static DEFAULT_NODE_WIDTH = 176;
|
|
61
61
|
static DEFAULT_NODE_HEIGHT = 64;
|
|
@@ -86,11 +86,22 @@ class OrgChart {
|
|
|
86
86
|
#on_node_click = undefined;
|
|
87
87
|
#click_listeners = [];
|
|
88
88
|
|
|
89
|
-
constructor(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
constructor(
|
|
90
|
+
options = {
|
|
91
|
+
id: String(),
|
|
92
|
+
title: String(),
|
|
93
|
+
label: String(),
|
|
94
|
+
data: undefined,
|
|
95
|
+
height: String(),
|
|
96
|
+
nodeWidth: Number(),
|
|
97
|
+
nodeHeight: Number(),
|
|
98
|
+
gapX: Number(),
|
|
99
|
+
gapY: Number(),
|
|
100
|
+
collapsible: Boolean(),
|
|
101
|
+
emptyText: String(),
|
|
102
|
+
onNodeClick: undefined,
|
|
103
|
+
}
|
|
104
|
+
) {
|
|
94
105
|
setStyles(__dirname + "/styles.css", "ChUiJS_OrgChart");
|
|
95
106
|
OrgChart.#counter += 1;
|
|
96
107
|
this.#id = options.id === undefined ? `chui_org_chart_${OrgChart.#counter}` : options.id;
|
|
@@ -98,8 +109,10 @@ class OrgChart {
|
|
|
98
109
|
this.#label = options.label;
|
|
99
110
|
this.#empty_text = options.emptyText;
|
|
100
111
|
this.#on_node_click = options.onNodeClick;
|
|
101
|
-
if (options.nodeWidth !== undefined)
|
|
102
|
-
|
|
112
|
+
if (options.nodeWidth !== undefined)
|
|
113
|
+
this.#node_width = Math.max(80, Number(options.nodeWidth) || OrgChart.DEFAULT_NODE_WIDTH);
|
|
114
|
+
if (options.nodeHeight !== undefined)
|
|
115
|
+
this.#node_height = Math.max(40, Number(options.nodeHeight) || OrgChart.DEFAULT_NODE_HEIGHT);
|
|
103
116
|
if (options.gapX !== undefined) this.#gap_x = Number(options.gapX);
|
|
104
117
|
if (options.gapY !== undefined) this.#gap_y = Number(options.gapY);
|
|
105
118
|
if (options.collapsible !== undefined) this.#collapsible = options.collapsible !== false;
|
|
@@ -136,12 +149,22 @@ class OrgChart {
|
|
|
136
149
|
}
|
|
137
150
|
|
|
138
151
|
// GET
|
|
139
|
-
getId() {
|
|
140
|
-
|
|
152
|
+
getId() {
|
|
153
|
+
return this.#id;
|
|
154
|
+
}
|
|
155
|
+
getTitle() {
|
|
156
|
+
return this.#title.innerText;
|
|
157
|
+
}
|
|
141
158
|
/** Данные как передали: те же узлы (правьте их и зовите `setData()`) */
|
|
142
|
-
getData() {
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
getData() {
|
|
160
|
+
return this.#roots.length === 1 ? this.#roots[0] : [...this.#roots];
|
|
161
|
+
}
|
|
162
|
+
getSelected() {
|
|
163
|
+
return this.#selected;
|
|
164
|
+
}
|
|
165
|
+
getCanvas() {
|
|
166
|
+
return this.#canvas;
|
|
167
|
+
}
|
|
145
168
|
/** Видимые узлы по порядку обхода: `{id, title, position, level, expanded, hasChildren}` */
|
|
146
169
|
getItems() {
|
|
147
170
|
return this.#rows.map((row) => ({
|
|
@@ -150,7 +173,7 @@ class OrgChart {
|
|
|
150
173
|
position: row.node.position,
|
|
151
174
|
level: row.level,
|
|
152
175
|
expanded: row.expanded,
|
|
153
|
-
hasChildren: row.children.length > 0
|
|
176
|
+
hasChildren: row.children.length > 0,
|
|
154
177
|
}));
|
|
155
178
|
}
|
|
156
179
|
getNode(id = String()) {
|
|
@@ -181,7 +204,7 @@ class OrgChart {
|
|
|
181
204
|
}
|
|
182
205
|
/** Данные: один корень или массив корней; состояние свёрнутых веток сбрасывается */
|
|
183
206
|
setData(data = undefined) {
|
|
184
|
-
const roots = data === undefined || data === null ? [] :
|
|
207
|
+
const roots = data === undefined || data === null ? [] : Array.isArray(data) ? data : [data];
|
|
185
208
|
this.#roots = roots.filter((node) => node !== undefined && node !== null);
|
|
186
209
|
this.#expanded = new Map();
|
|
187
210
|
for (const node of this.#collect(this.#roots)) {
|
|
@@ -212,9 +235,11 @@ class OrgChart {
|
|
|
212
235
|
this.#expanded.set(String(id), want);
|
|
213
236
|
this.#render();
|
|
214
237
|
const count = this.#descendants(node);
|
|
215
|
-
this.#announce(
|
|
216
|
-
|
|
217
|
-
|
|
238
|
+
this.#announce(
|
|
239
|
+
want
|
|
240
|
+
? I18n.t("data.orgChartExpanded", { name: this.#nameOf(node), count: count })
|
|
241
|
+
: I18n.t("data.orgChartCollapsed", { name: this.#nameOf(node), count: count })
|
|
242
|
+
);
|
|
218
243
|
return this;
|
|
219
244
|
}
|
|
220
245
|
expandAll() {
|
|
@@ -231,7 +256,9 @@ class OrgChart {
|
|
|
231
256
|
this.#click_listeners.push(listener);
|
|
232
257
|
return this;
|
|
233
258
|
}
|
|
234
|
-
set() {
|
|
259
|
+
set() {
|
|
260
|
+
return this.#root;
|
|
261
|
+
}
|
|
235
262
|
|
|
236
263
|
// === РАСКЛАДКА ===
|
|
237
264
|
/** Все узлы дерева в порядке обхода (включая скрытые ветки) */
|
|
@@ -243,7 +270,9 @@ class OrgChart {
|
|
|
243
270
|
return found;
|
|
244
271
|
}
|
|
245
272
|
#childrenOf(node = {}) {
|
|
246
|
-
return Array.isArray(node.children)
|
|
273
|
+
return Array.isArray(node.children)
|
|
274
|
+
? node.children.filter((child) => child !== undefined && child !== null)
|
|
275
|
+
: [];
|
|
247
276
|
}
|
|
248
277
|
/** Ветка раскрыта: у несворачиваемой схемы всегда, иначе явное состояние или `collapsed` из данных */
|
|
249
278
|
#isExpanded(node = {}) {
|
|
@@ -261,7 +290,13 @@ class OrgChart {
|
|
|
261
290
|
let slot = 0;
|
|
262
291
|
const walk = (node, level, parent) => {
|
|
263
292
|
const children = this.#isExpanded(node) ? this.#childrenOf(node) : [];
|
|
264
|
-
const row = {
|
|
293
|
+
const row = {
|
|
294
|
+
node: node,
|
|
295
|
+
level: level,
|
|
296
|
+
parent: parent,
|
|
297
|
+
children: this.#childrenOf(node),
|
|
298
|
+
expanded: this.#isExpanded(node),
|
|
299
|
+
};
|
|
265
300
|
rows.push(row);
|
|
266
301
|
if (children.length === 0) {
|
|
267
302
|
row.slot = slot + 0.5;
|
|
@@ -274,7 +309,7 @@ class OrgChart {
|
|
|
274
309
|
return row;
|
|
275
310
|
};
|
|
276
311
|
for (const root of this.#roots) walk(root, 0, undefined);
|
|
277
|
-
return {rows: rows, slots: Math.max(1, slot)};
|
|
312
|
+
return { rows: rows, slots: Math.max(1, slot) };
|
|
278
313
|
}
|
|
279
314
|
#rowOf(id = undefined) {
|
|
280
315
|
if (id === undefined || id === null) return undefined;
|
|
@@ -367,7 +402,7 @@ class OrgChart {
|
|
|
367
402
|
}
|
|
368
403
|
/** Координаты узла в той же системе, что у связей: `x` — процент, `y` — пиксели */
|
|
369
404
|
#positionOf(row, step = this.#node_height + this.#gap_y) {
|
|
370
|
-
return {x: (row.slot / this.#slots) * 100, y: row.level * step};
|
|
405
|
+
return { x: (row.slot / this.#slots) * 100, y: row.level * step };
|
|
371
406
|
}
|
|
372
407
|
#renderNode(row, step = Number()) {
|
|
373
408
|
const position = this.#positionOf(row, step);
|
|
@@ -378,7 +413,8 @@ class OrgChart {
|
|
|
378
413
|
node.setAttribute("aria-level", String(row.level + 1));
|
|
379
414
|
node.setAttribute("aria-selected", String(row.node.id) === String(this.#selected) ? "true" : "false");
|
|
380
415
|
// Про раскрытие говорит только сворачиваемая схема: у несворачиваемой подчинённые всегда видны
|
|
381
|
-
if (row.children.length > 0 && this.#collapsible)
|
|
416
|
+
if (row.children.length > 0 && this.#collapsible)
|
|
417
|
+
node.setAttribute("aria-expanded", row.expanded ? "true" : "false");
|
|
382
418
|
// Остановку Tab расставит `#applyStop`, а `makeKeyboardButton` заполняет `tabindex`
|
|
383
419
|
// только если атрибута нет — поэтому он задаётся заранее
|
|
384
420
|
node.setAttribute("tabindex", "-1");
|
|
@@ -388,9 +424,9 @@ class OrgChart {
|
|
|
388
424
|
if (row.node.avatar !== undefined) {
|
|
389
425
|
const avatar = new Avatar({
|
|
390
426
|
name: row.node.title,
|
|
391
|
-
image: typeof row.node.avatar === "object" ? row.node.avatar : {path: row.node.avatar},
|
|
427
|
+
image: typeof row.node.avatar === "object" ? row.node.avatar : { path: row.node.avatar },
|
|
392
428
|
size: Avatar.SIZE.SMALL,
|
|
393
|
-
decorative: true
|
|
429
|
+
decorative: true,
|
|
394
430
|
});
|
|
395
431
|
node.appendChild(avatar.set());
|
|
396
432
|
}
|
|
@@ -414,7 +450,7 @@ class OrgChart {
|
|
|
414
450
|
if (row.children.length > 0) {
|
|
415
451
|
const count = document.createElement("chui_visually_hidden");
|
|
416
452
|
count.classList.add("chui_visually_hidden");
|
|
417
|
-
count.innerText = I18n.t("data.orgChartReports", {count: row.children.length});
|
|
453
|
+
count.innerText = I18n.t("data.orgChartReports", { count: row.children.length });
|
|
418
454
|
content.appendChild(count);
|
|
419
455
|
}
|
|
420
456
|
node.appendChild(content);
|
|
@@ -423,7 +459,10 @@ class OrgChart {
|
|
|
423
459
|
toggle.dataset.expanded = row.expanded ? "true" : "false";
|
|
424
460
|
toggle.dataset.id = String(row.node.id);
|
|
425
461
|
toggle.setAttribute("aria-hidden", "true");
|
|
426
|
-
toggle.innerHTML = new Icon(
|
|
462
|
+
toggle.innerHTML = new Icon(
|
|
463
|
+
row.expanded ? Icons.NAVIGATION.EXPAND_LESS : Icons.NAVIGATION.EXPAND_MORE,
|
|
464
|
+
"14px"
|
|
465
|
+
).getHTML();
|
|
427
466
|
node.appendChild(toggle);
|
|
428
467
|
}
|
|
429
468
|
this.#canvas.appendChild(node);
|
|
@@ -539,7 +578,7 @@ class OrgChart {
|
|
|
539
578
|
};
|
|
540
579
|
}
|
|
541
580
|
|
|
542
|
-
exports.OrgChart = OrgChart
|
|
581
|
+
exports.OrgChart = OrgChart;
|
|
543
582
|
|
|
544
583
|
// Описание узла собирает фабрика — как у ContextMenu и SplitButton
|
|
545
|
-
OrgChart.Node = (options = {}) => Object.assign({style: OrgChart.STYLE.DEFAULT}, options);
|
|
584
|
+
OrgChart.Node = (options = {}) => Object.assign({ style: OrgChart.STYLE.DEFAULT }, options);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const {setStyles, optionOr} = require("../../modules/chui_functions");
|
|
2
|
-
const {Icon, Icons} = require("../chui_icons/icons");
|
|
3
|
-
const {I18n} = require("../../modules/chui_i18n/chui_i18n");
|
|
1
|
+
const { setStyles, optionOr } = require("../../modules/chui_functions");
|
|
2
|
+
const { Icon, Icons } = require("../chui_icons/icons");
|
|
3
|
+
const { I18n } = require("../../modules/chui_i18n/chui_i18n");
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Постраничная навигация: номера страниц, «…» на пропусках и кнопки перехода.
|
|
@@ -25,7 +25,7 @@ const {I18n} = require("../../modules/chui_i18n/chui_i18n");
|
|
|
25
25
|
class Pagination {
|
|
26
26
|
static SIZE = {
|
|
27
27
|
SMALL: "small",
|
|
28
|
-
DEFAULT: "default"
|
|
28
|
+
DEFAULT: "default",
|
|
29
29
|
};
|
|
30
30
|
static #counter = 0;
|
|
31
31
|
|
|
@@ -40,18 +40,20 @@ class Pagination {
|
|
|
40
40
|
#listeners = [];
|
|
41
41
|
#on_change = undefined;
|
|
42
42
|
|
|
43
|
-
constructor(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
constructor(
|
|
44
|
+
options = {
|
|
45
|
+
id: String(),
|
|
46
|
+
pages: Number(),
|
|
47
|
+
page: Number(),
|
|
48
|
+
siblings: Number(),
|
|
49
|
+
edges: Number(),
|
|
50
|
+
jump: Boolean(),
|
|
51
|
+
size: String(),
|
|
52
|
+
label: String(),
|
|
53
|
+
onChange: undefined,
|
|
54
|
+
changeEvent: undefined,
|
|
55
|
+
}
|
|
56
|
+
) {
|
|
55
57
|
setStyles(__dirname + "/styles.css", "chUiJS_Pagination");
|
|
56
58
|
Pagination.#counter += 1;
|
|
57
59
|
this.#id = options.id === undefined ? `chui_pagination_${Pagination.#counter}` : options.id;
|
|
@@ -182,11 +184,13 @@ class Pagination {
|
|
|
182
184
|
for (let index = this.#page - siblings; index <= this.#page + siblings; index++) {
|
|
183
185
|
if (index >= 1 && index <= this.#pages) numbers.add(index);
|
|
184
186
|
}
|
|
185
|
-
const sorted = [...numbers]
|
|
187
|
+
const sorted = [...numbers]
|
|
188
|
+
.filter((number) => number >= 1 && number <= this.#pages)
|
|
189
|
+
.sort((first, second) => first - second);
|
|
186
190
|
const items = [];
|
|
187
191
|
let previous = 0;
|
|
188
192
|
for (const number of sorted) {
|
|
189
|
-
if (previous !== 0 && number - previous > 1) items.push({gap: true});
|
|
193
|
+
if (previous !== 0 && number - previous > 1) items.push({ gap: true });
|
|
190
194
|
items.push(number);
|
|
191
195
|
previous = number;
|
|
192
196
|
}
|
|
@@ -196,8 +200,23 @@ class Pagination {
|
|
|
196
200
|
#render() {
|
|
197
201
|
const focused = this.#focusedControl();
|
|
198
202
|
this.#list.innerHTML = "";
|
|
199
|
-
if (this.#jump)
|
|
200
|
-
|
|
203
|
+
if (this.#jump)
|
|
204
|
+
this.#list.appendChild(
|
|
205
|
+
this.#arrowButton(
|
|
206
|
+
"first",
|
|
207
|
+
I18n.t("navigation.firstPage"),
|
|
208
|
+
Icons.NAVIGATION.FIRST_PAGE,
|
|
209
|
+
this.#page === 1
|
|
210
|
+
)
|
|
211
|
+
);
|
|
212
|
+
this.#list.appendChild(
|
|
213
|
+
this.#arrowButton(
|
|
214
|
+
"prev",
|
|
215
|
+
I18n.t("navigation.previousPage"),
|
|
216
|
+
Icons.NAVIGATION.CHEVRON_LEFT,
|
|
217
|
+
this.#page === 1
|
|
218
|
+
)
|
|
219
|
+
);
|
|
201
220
|
for (const item of this.#window()) {
|
|
202
221
|
if (item.gap === true) {
|
|
203
222
|
const gap = document.createElement("chui_pagination_gap");
|
|
@@ -209,8 +228,23 @@ class Pagination {
|
|
|
209
228
|
}
|
|
210
229
|
this.#list.appendChild(this.#pageButton(item));
|
|
211
230
|
}
|
|
212
|
-
this.#list.appendChild(
|
|
213
|
-
|
|
231
|
+
this.#list.appendChild(
|
|
232
|
+
this.#arrowButton(
|
|
233
|
+
"next",
|
|
234
|
+
I18n.t("navigation.nextPage"),
|
|
235
|
+
Icons.NAVIGATION.CHEVRON_RIGHT,
|
|
236
|
+
this.#page === this.#pages
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
if (this.#jump)
|
|
240
|
+
this.#list.appendChild(
|
|
241
|
+
this.#arrowButton(
|
|
242
|
+
"last",
|
|
243
|
+
I18n.t("navigation.lastPage"),
|
|
244
|
+
Icons.NAVIGATION.LAST_PAGE,
|
|
245
|
+
this.#page === this.#pages
|
|
246
|
+
)
|
|
247
|
+
);
|
|
214
248
|
this.#restoreFocus(focused);
|
|
215
249
|
}
|
|
216
250
|
|
|
@@ -257,14 +291,15 @@ class Pagination {
|
|
|
257
291
|
#focusedControl() {
|
|
258
292
|
const active = document.activeElement;
|
|
259
293
|
if (active === null || active === undefined || !this.#list.contains(active)) return undefined;
|
|
260
|
-
return {role: active.dataset.role, page: active.dataset.page};
|
|
294
|
+
return { role: active.dataset.role, page: active.dataset.page };
|
|
261
295
|
}
|
|
262
296
|
|
|
263
297
|
#restoreFocus(control) {
|
|
264
298
|
if (control === undefined || control.role === undefined) return;
|
|
265
|
-
const selector =
|
|
266
|
-
|
|
267
|
-
|
|
299
|
+
const selector =
|
|
300
|
+
control.role === "page"
|
|
301
|
+
? `button[data-role="page"][data-page="${control.page}"]`
|
|
302
|
+
: `button[data-role="${control.role}"]`;
|
|
268
303
|
const node = this.#list.querySelector(selector);
|
|
269
304
|
// Номер мог уехать в «…» — тогда фокус остаётся там, где окажется ближайший контрол
|
|
270
305
|
if (node !== null) node.focus();
|
|
@@ -282,4 +317,4 @@ class Pagination {
|
|
|
282
317
|
static ICON_SIZE = "16px";
|
|
283
318
|
}
|
|
284
319
|
|
|
285
|
-
exports.Pagination = Pagination
|
|
320
|
+
exports.Pagination = Pagination;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class Paragraph {
|
|
2
2
|
#Paragraph = document.createElement(`p`);
|
|
3
3
|
constructor(text = String()) {
|
|
4
|
-
require(
|
|
4
|
+
require("../../modules/chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_Paragraph");
|
|
5
5
|
this.#Paragraph.innerText = text;
|
|
6
6
|
}
|
|
7
7
|
setText(text = String()) {
|
|
@@ -12,4 +12,4 @@ class Paragraph {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
exports.Paragraph = Paragraph
|
|
15
|
+
exports.Paragraph = Paragraph;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {setStyles, optionOr} = require("../../modules/chui_functions");
|
|
1
|
+
const { setStyles, optionOr } = require("../../modules/chui_functions");
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Поповер: панель у триггера с произвольным содержимым.
|
|
@@ -34,7 +34,7 @@ class Popover {
|
|
|
34
34
|
TOP: "top",
|
|
35
35
|
BOTTOM: "bottom",
|
|
36
36
|
LEFT: "left",
|
|
37
|
-
RIGHT: "right"
|
|
37
|
+
RIGHT: "right",
|
|
38
38
|
};
|
|
39
39
|
/** Зазор между триггером и панелью, px */
|
|
40
40
|
static GAP = 8;
|
|
@@ -54,17 +54,19 @@ class Popover {
|
|
|
54
54
|
#close_on_outside = true;
|
|
55
55
|
#destroyed = false;
|
|
56
56
|
|
|
57
|
-
constructor(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
constructor(
|
|
58
|
+
options = {
|
|
59
|
+
id: String(),
|
|
60
|
+
trigger: undefined,
|
|
61
|
+
content: undefined,
|
|
62
|
+
title: String(),
|
|
63
|
+
placement: String(),
|
|
64
|
+
label: String(),
|
|
65
|
+
onOpen: undefined,
|
|
66
|
+
onClose: undefined,
|
|
67
|
+
closeOnOutsideClick: Boolean(),
|
|
68
|
+
}
|
|
69
|
+
) {
|
|
68
70
|
setStyles(__dirname + "/styles.css", "chUiJS_Popover");
|
|
69
71
|
Popover.#counter += 1;
|
|
70
72
|
// Заготовка опции (`String()`) равносильна отсутствующей: иначе слой без аргументов
|
|
@@ -120,7 +122,8 @@ class Popover {
|
|
|
120
122
|
if (this.#header.id === "") this.#header.id = `${this.#id}_title`;
|
|
121
123
|
// Заголовок служит именем слоя, пока не задан свой label и пока он не пуст
|
|
122
124
|
const has_title = this.#header.innerText.trim() !== "";
|
|
123
|
-
if (has_title && this.#panel.getAttribute("aria-label") === null)
|
|
125
|
+
if (has_title && this.#panel.getAttribute("aria-label") === null)
|
|
126
|
+
this.#panel.setAttribute("aria-labelledby", this.#header.id);
|
|
124
127
|
else this.#panel.removeAttribute("aria-labelledby");
|
|
125
128
|
return this;
|
|
126
129
|
}
|
|
@@ -242,24 +245,42 @@ class Popover {
|
|
|
242
245
|
// Панель ставится по выбранной стороне; если не влезает — на противоположную, затем в окно
|
|
243
246
|
#place() {
|
|
244
247
|
const trigger = this.#trigger;
|
|
245
|
-
const rect =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
const rect =
|
|
249
|
+
trigger === undefined
|
|
250
|
+
? {
|
|
251
|
+
top: window.innerHeight / 2,
|
|
252
|
+
bottom: window.innerHeight / 2,
|
|
253
|
+
left: window.innerWidth / 2,
|
|
254
|
+
right: window.innerWidth / 2,
|
|
255
|
+
width: 0,
|
|
256
|
+
height: 0,
|
|
257
|
+
}
|
|
258
|
+
: trigger.getBoundingClientRect();
|
|
248
259
|
const width = this.#panel.offsetWidth;
|
|
249
260
|
const height = this.#panel.offsetHeight;
|
|
250
261
|
const gap = Popover.GAP;
|
|
251
262
|
const edge = Popover.EDGE;
|
|
252
263
|
let placement = this.#placement;
|
|
253
|
-
if (placement === Popover.PLACEMENT.BOTTOM && rect.bottom + height + gap > window.innerHeight - edge)
|
|
254
|
-
|
|
255
|
-
else if (placement === Popover.PLACEMENT.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
264
|
+
if (placement === Popover.PLACEMENT.BOTTOM && rect.bottom + height + gap > window.innerHeight - edge)
|
|
265
|
+
placement = Popover.PLACEMENT.TOP;
|
|
266
|
+
else if (placement === Popover.PLACEMENT.TOP && rect.top - height - gap < edge)
|
|
267
|
+
placement = Popover.PLACEMENT.BOTTOM;
|
|
268
|
+
else if (placement === Popover.PLACEMENT.RIGHT && rect.right + width + gap > window.innerWidth - edge)
|
|
269
|
+
placement = Popover.PLACEMENT.LEFT;
|
|
270
|
+
else if (placement === Popover.PLACEMENT.LEFT && rect.left - width - gap < edge)
|
|
271
|
+
placement = Popover.PLACEMENT.RIGHT;
|
|
272
|
+
let left =
|
|
273
|
+
placement === Popover.PLACEMENT.LEFT
|
|
274
|
+
? rect.left - width - gap
|
|
275
|
+
: placement === Popover.PLACEMENT.RIGHT
|
|
276
|
+
? rect.right + gap
|
|
277
|
+
: rect.left;
|
|
278
|
+
let top =
|
|
279
|
+
placement === Popover.PLACEMENT.TOP
|
|
280
|
+
? rect.top - height - gap
|
|
281
|
+
: placement === Popover.PLACEMENT.BOTTOM
|
|
282
|
+
? rect.bottom + gap
|
|
283
|
+
: rect.top;
|
|
263
284
|
left = Math.max(edge, Math.min(left, window.innerWidth - width - edge));
|
|
264
285
|
top = Math.max(edge, Math.min(top, window.innerHeight - height - edge));
|
|
265
286
|
this.#panel.dataset.placement = placement;
|
|
@@ -314,4 +335,4 @@ class Popover {
|
|
|
314
335
|
}
|
|
315
336
|
}
|
|
316
337
|
|
|
317
|
-
exports.Popover = Popover
|
|
338
|
+
exports.Popover = Popover;
|