@compas-oscd/open-scd 0.34.16 → 0.34.18
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/dist/WizardDivider.d.ts +8 -8
- package/dist/WizardDivider.js +26 -26
- package/dist/Wizarding.js +36 -36
- package/dist/Wizarding.js.map +1 -1
- package/dist/action-icon.d.ts +25 -25
- package/dist/action-icon.js +51 -51
- package/dist/action-pane.d.ts +25 -25
- package/dist/action-pane.js +86 -86
- package/dist/addons/Editor.d.ts +25 -25
- package/dist/addons/Editor.js +105 -105
- package/dist/addons/Editor.js.map +1 -1
- package/dist/addons/History.d.ts +86 -93
- package/dist/addons/History.js +301 -302
- package/dist/addons/History.js.map +1 -1
- package/dist/addons/Layout.d.ts +96 -96
- package/dist/addons/Layout.js +448 -448
- package/dist/addons/Layout.js.map +1 -1
- package/dist/addons/Settings.d.ts +68 -68
- package/dist/addons/Settings.js +272 -272
- package/dist/addons/Settings.js.map +1 -1
- package/dist/addons/Waiter.d.ts +14 -14
- package/dist/addons/Waiter.js +40 -40
- package/dist/addons/Waiter.js.map +1 -1
- package/dist/addons/Wizards.d.ts +15 -15
- package/dist/addons/Wizards.js +46 -46
- package/dist/addons/editor/edit-action-to-v1-converter.d.ts +3 -3
- package/dist/addons/editor/edit-action-to-v1-converter.js +95 -95
- package/dist/addons/editor/edit-action-to-v1-converter.js.map +1 -1
- package/dist/addons/editor/edit-v1-to-v2-converter.d.ts +2 -2
- package/dist/addons/editor/edit-v1-to-v2-converter.js +36 -36
- package/dist/addons/editor/edit-v1-to-v2-converter.js.map +1 -1
- package/dist/addons/history/get-log-text.d.ts +5 -5
- package/dist/addons/history/get-log-text.js +25 -25
- package/dist/addons/history/get-log-text.js.map +1 -1
- package/dist/addons/menu-tabs/menu-tabs.d.ts +22 -22
- package/dist/addons/menu-tabs/menu-tabs.js +59 -59
- package/dist/addons/plugin-manager/custom-plugin-dialog.d.ts +28 -28
- package/dist/addons/plugin-manager/custom-plugin-dialog.js +71 -71
- package/dist/addons/plugin-manager/plugin-manager.d.ts +20 -20
- package/dist/addons/plugin-manager/plugin-manager.js +77 -77
- package/dist/core/api/api.js +7 -0
- package/dist/core/api/api.js.map +1 -0
- package/dist/core/api/editor/subject.js +22 -0
- package/dist/core/api/editor/subject.js.map +1 -0
- package/dist/core/api/editor/xml-editor.js +82 -0
- package/dist/core/api/editor/xml-editor.js.map +1 -0
- package/dist/core/api/plugin-state-api.js +27 -0
- package/dist/core/api/plugin-state-api.js.map +1 -0
- package/dist/core/foundation/cyrb64.js +26 -0
- package/dist/core/foundation/cyrb64.js.map +1 -0
- package/dist/core/foundation/deprecated/edit-event.js +44 -0
- package/dist/core/foundation/deprecated/edit-event.js.map +1 -0
- package/dist/core/foundation/deprecated/editor.js +94 -0
- package/dist/core/foundation/deprecated/editor.js.map +1 -0
- package/dist/core/foundation/deprecated/history.js +17 -0
- package/dist/core/foundation/deprecated/history.js.map +1 -0
- package/dist/core/foundation/deprecated/open-event.js +9 -0
- package/dist/core/foundation/deprecated/open-event.js.map +1 -0
- package/dist/core/foundation/deprecated/settings.js +19 -0
- package/dist/core/foundation/deprecated/settings.js.map +1 -0
- package/dist/core/foundation/deprecated/validation.js +8 -0
- package/dist/core/foundation/deprecated/validation.js.map +1 -0
- package/dist/core/foundation/deprecated/waiter.js +12 -0
- package/dist/core/foundation/deprecated/waiter.js.map +1 -0
- package/dist/core/foundation/edit-completed-event.js +11 -0
- package/dist/core/foundation/edit-completed-event.js.map +1 -0
- package/dist/core/foundation/edit-event.js +8 -0
- package/dist/core/foundation/edit-event.js.map +1 -0
- package/dist/core/foundation/edit.js +31 -0
- package/dist/core/foundation/edit.js.map +1 -0
- package/dist/core/foundation/handle-edit.js +151 -0
- package/dist/core/foundation/handle-edit.js.map +1 -0
- package/dist/core/foundation/open-event.js +8 -0
- package/dist/core/foundation/open-event.js.map +1 -0
- package/dist/core/foundation/plugin.js +2 -0
- package/dist/core/foundation/plugin.js.map +1 -0
- package/dist/core/foundation.js +14 -0
- package/dist/core/foundation.js.map +1 -0
- package/dist/core/locales.js +21 -0
- package/dist/core/locales.js.map +1 -0
- package/dist/filtered-list.d.ts +27 -27
- package/dist/filtered-list.js +118 -118
- package/dist/finder-list.d.ts +37 -37
- package/dist/finder-list.js +153 -153
- package/dist/foundation/compare.d.ts +79 -79
- package/dist/foundation/compare.js +216 -216
- package/dist/foundation/dai.d.ts +30 -30
- package/dist/foundation/dai.js +126 -126
- package/dist/foundation/generators.d.ts +13 -13
- package/dist/foundation/generators.js +66 -66
- package/dist/foundation/ied.d.ts +22 -22
- package/dist/foundation/ied.js +83 -83
- package/dist/foundation/ied.js.map +1 -1
- package/dist/foundation/nsd.d.ts +4 -4
- package/dist/foundation/nsd.js +12 -12
- package/dist/foundation/nsdoc.d.ts +14 -14
- package/dist/foundation/nsdoc.js +178 -178
- package/dist/foundation/scl.d.ts +1 -1
- package/dist/foundation/scl.js +63 -63
- package/dist/foundation.d.ts +230 -230
- package/dist/foundation.js +1921 -1921
- package/dist/foundation.js.map +1 -1
- package/dist/icons/compare.d.ts +3 -3
- package/dist/icons/compare.js +4 -4
- package/dist/icons/icons.d.ts +41 -41
- package/dist/icons/icons.js +92 -92
- package/dist/icons/ied-icons.d.ts +3 -3
- package/dist/icons/ied-icons.js +4 -4
- package/dist/icons/lnode.d.ts +16 -16
- package/dist/icons/lnode.js +17 -17
- package/dist/open-scd.d.ts +131 -131
- package/dist/open-scd.js +438 -438
- package/dist/open-scd.js.map +1 -1
- package/dist/openscd/src/WizardDivider.js +37 -0
- package/dist/openscd/src/WizardDivider.js.map +1 -0
- package/dist/openscd/src/Wizarding.js +38 -0
- package/dist/openscd/src/Wizarding.js.map +1 -0
- package/dist/openscd/src/action-icon.js +220 -0
- package/dist/openscd/src/action-icon.js.map +1 -0
- package/dist/openscd/src/action-pane.js +176 -0
- package/dist/openscd/src/action-pane.js.map +1 -0
- package/dist/openscd/src/addons/Editor.js +106 -0
- package/dist/openscd/src/addons/Editor.js.map +1 -0
- package/dist/openscd/src/addons/History.js +490 -0
- package/dist/openscd/src/addons/History.js.map +1 -0
- package/dist/openscd/src/addons/Layout.js +619 -0
- package/dist/openscd/src/addons/Layout.js.map +1 -0
- package/dist/openscd/src/addons/Settings.js +465 -0
- package/dist/openscd/src/addons/Settings.js.map +1 -0
- package/dist/openscd/src/addons/Waiter.js +45 -0
- package/dist/openscd/src/addons/Waiter.js.map +1 -0
- package/dist/openscd/src/addons/Wizards.js +48 -0
- package/dist/openscd/src/addons/Wizards.js.map +1 -0
- package/dist/openscd/src/addons/editor/edit-action-to-v1-converter.js +96 -0
- package/dist/openscd/src/addons/editor/edit-action-to-v1-converter.js.map +1 -0
- package/dist/openscd/src/addons/editor/edit-v1-to-v2-converter.js +37 -0
- package/dist/openscd/src/addons/editor/edit-v1-to-v2-converter.js.map +1 -0
- package/dist/openscd/src/addons/history/get-log-text.js +26 -0
- package/dist/openscd/src/addons/history/get-log-text.js.map +1 -0
- package/dist/openscd/src/addons/menu-tabs/menu-tabs.js +74 -0
- package/dist/openscd/src/addons/menu-tabs/menu-tabs.js.map +1 -0
- package/dist/openscd/src/addons/plugin-manager/custom-plugin-dialog.js +177 -0
- package/dist/openscd/src/addons/plugin-manager/custom-plugin-dialog.js.map +1 -0
- package/dist/openscd/src/addons/plugin-manager/plugin-manager.js +165 -0
- package/dist/openscd/src/addons/plugin-manager/plugin-manager.js.map +1 -0
- package/dist/openscd/src/filtered-list.js +168 -0
- package/dist/openscd/src/filtered-list.js.map +1 -0
- package/dist/openscd/src/finder-list.js +207 -0
- package/dist/openscd/src/finder-list.js.map +1 -0
- package/dist/openscd/src/foundation/compare.js +273 -0
- package/dist/openscd/src/foundation/compare.js.map +1 -0
- package/dist/openscd/src/foundation/dai.js +127 -0
- package/dist/openscd/src/foundation/dai.js.map +1 -0
- package/dist/openscd/src/foundation/generators.js +67 -0
- package/dist/openscd/src/foundation/generators.js.map +1 -0
- package/dist/openscd/src/foundation/ied.js +84 -0
- package/dist/openscd/src/foundation/ied.js.map +1 -0
- package/dist/openscd/src/foundation/nsd.js +13 -0
- package/dist/openscd/src/foundation/nsd.js.map +1 -0
- package/dist/openscd/src/foundation/nsdoc.js +180 -0
- package/dist/openscd/src/foundation/nsdoc.js.map +1 -0
- package/dist/openscd/src/foundation/scl.js +64 -0
- package/dist/openscd/src/foundation/scl.js.map +1 -0
- package/dist/openscd/src/foundation.js +1922 -0
- package/dist/openscd/src/foundation.js.map +1 -0
- package/dist/openscd/src/icons/compare.js +11 -0
- package/dist/openscd/src/icons/compare.js.map +1 -0
- package/dist/openscd/src/icons/icons.js +611 -0
- package/dist/openscd/src/icons/icons.js.map +1 -0
- package/dist/openscd/src/icons/ied-icons.js +11 -0
- package/dist/openscd/src/icons/ied-icons.js.map +1 -0
- package/dist/openscd/src/icons/lnode.js +50 -0
- package/dist/openscd/src/icons/lnode.js.map +1 -0
- package/dist/openscd/src/open-scd.js +483 -0
- package/dist/openscd/src/open-scd.js.map +1 -0
- package/dist/openscd/src/oscd-filter-button.js +89 -0
- package/dist/openscd/src/oscd-filter-button.js.map +1 -0
- package/dist/openscd/src/plain-compare-list.js +132 -0
- package/dist/openscd/src/plain-compare-list.js.map +1 -0
- package/dist/openscd/src/plugin-tag.js +23 -0
- package/dist/openscd/src/plugin-tag.js.map +1 -0
- package/dist/openscd/src/plugin.events.js +12 -0
- package/dist/openscd/src/plugin.events.js.map +1 -0
- package/dist/openscd/src/plugin.js +2 -0
- package/dist/openscd/src/plugin.js.map +1 -0
- package/dist/openscd/src/plugins.js +256 -0
- package/dist/openscd/src/plugins.js.map +1 -0
- package/dist/openscd/src/schemas.js +9325 -0
- package/dist/openscd/src/schemas.js.map +1 -0
- package/dist/openscd/src/themes.js +122 -0
- package/dist/openscd/src/themes.js.map +1 -0
- package/dist/openscd/src/translations/de.js +954 -0
- package/dist/openscd/src/translations/de.js.map +1 -0
- package/dist/openscd/src/translations/en.js +950 -0
- package/dist/openscd/src/translations/en.js.map +1 -0
- package/dist/openscd/src/translations/loader.js +10 -0
- package/dist/openscd/src/translations/loader.js.map +1 -0
- package/dist/openscd/src/wizard-checkbox.js +152 -0
- package/dist/openscd/src/wizard-checkbox.js.map +1 -0
- package/dist/openscd/src/wizard-dialog.js +374 -0
- package/dist/openscd/src/wizard-dialog.js.map +1 -0
- package/dist/openscd/src/wizard-select.js +115 -0
- package/dist/openscd/src/wizard-select.js.map +1 -0
- package/dist/openscd/src/wizard-textfield.js +191 -0
- package/dist/openscd/src/wizard-textfield.js.map +1 -0
- package/dist/openscd/src/wizards.js +196 -0
- package/dist/openscd/src/wizards.js.map +1 -0
- package/dist/oscd-filter-button.d.ts +27 -27
- package/dist/oscd-filter-button.js +59 -59
- package/dist/plain-compare-list.d.ts +36 -36
- package/dist/plain-compare-list.js +70 -70
- package/dist/plugin-tag.d.ts +6 -6
- package/dist/plugin-tag.js +22 -22
- package/dist/plugin.d.ts +23 -23
- package/dist/plugin.events.d.ts +15 -15
- package/dist/plugin.events.js +11 -11
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +255 -255
- package/dist/schemas.d.ts +58 -58
- package/dist/schemas.js +59 -59
- package/dist/themes.d.ts +3 -3
- package/dist/themes.js +13 -13
- package/dist/themes.js.map +1 -1
- package/dist/translations/de.d.ts +2 -2
- package/dist/translations/de.js +952 -952
- package/dist/translations/en.d.ts +963 -963
- package/dist/translations/en.js +948 -948
- package/dist/translations/loader.d.ts +12 -12
- package/dist/translations/loader.js +9 -9
- package/dist/translations/loader.js.map +1 -1
- package/dist/wizard-checkbox.d.ts +37 -37
- package/dist/wizard-checkbox.js +130 -130
- package/dist/wizard-dialog.d.ts +45 -45
- package/dist/wizard-dialog.js +235 -235
- package/dist/wizard-dialog.js.map +1 -1
- package/dist/wizard-select.d.ts +31 -31
- package/dist/wizard-select.js +102 -102
- package/dist/wizard-textfield.d.ts +50 -50
- package/dist/wizard-textfield.js +162 -162
- package/dist/wizards.d.ts +23 -23
- package/dist/wizards.js +148 -148
- package/dist/wizards.js.map +1 -1
- package/dist/xml/src/foundation.js +67 -0
- package/dist/xml/src/foundation.js.map +1 -0
- package/dist/xml/src/index.js +2 -0
- package/dist/xml/src/index.js.map +1 -0
- package/package.json +29 -127
- package/dist/Wizarding.d.ts +0 -10
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement, html, LitElement, property, query, css } from 'lit-element';
|
|
3
|
+
import { get } from 'lit-translate';
|
|
4
|
+
import '@material/mwc-dialog';
|
|
5
|
+
import '@material/mwc-list';
|
|
6
|
+
import { newResetPluginsEvent, newSetPluginsEvent, pluginIcons } from '../../open-scd.js';
|
|
7
|
+
let OscdPluginManager = class OscdPluginManager extends LitElement {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
/** The plugins to render the layout. */
|
|
11
|
+
this.plugins = [];
|
|
12
|
+
}
|
|
13
|
+
render() {
|
|
14
|
+
return html `
|
|
15
|
+
<mwc-dialog
|
|
16
|
+
stacked
|
|
17
|
+
id="plugin-manager-root"
|
|
18
|
+
heading="${get('plugins.heading')}"
|
|
19
|
+
>
|
|
20
|
+
<mwc-list
|
|
21
|
+
id="pluginList"
|
|
22
|
+
multi
|
|
23
|
+
@selected=${(e) => {
|
|
24
|
+
const selectedPlugins = this.pluginList.items
|
|
25
|
+
.filter((item, index) => e.detail.index.has(index))
|
|
26
|
+
// @ts-expect-error: we add plugin to the list item
|
|
27
|
+
.map(item => item.plugin);
|
|
28
|
+
this.dispatchEvent(newSetPluginsEvent(selectedPlugins));
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<mwc-list-item graphic="avatar" noninteractive>
|
|
32
|
+
<strong>${get(`plugins.editor`)}</strong>
|
|
33
|
+
<mwc-icon slot="graphic" class="inverted">
|
|
34
|
+
${pluginIcons['editor']}
|
|
35
|
+
</mwc-icon>
|
|
36
|
+
</mwc-list-item>
|
|
37
|
+
|
|
38
|
+
<li divider role="separator"></li>
|
|
39
|
+
|
|
40
|
+
${this.generateEditorListItems()}
|
|
41
|
+
|
|
42
|
+
<mwc-list-item graphic="avatar" noninteractive>
|
|
43
|
+
<strong>${get(`plugins.menu`)}</strong>
|
|
44
|
+
<mwc-icon slot="graphic" class="inverted">
|
|
45
|
+
<strong>${pluginIcons['menu']}</strong></mwc-icon>
|
|
46
|
+
</mwc-list-item>
|
|
47
|
+
<li divider role="separator"></li>
|
|
48
|
+
|
|
49
|
+
${this.generateMenuListItems('top')}
|
|
50
|
+
|
|
51
|
+
<li divider role="separator" inset></li>
|
|
52
|
+
|
|
53
|
+
${this.generateValidatorListItems()}
|
|
54
|
+
|
|
55
|
+
<li divider role="separator" inset></li>
|
|
56
|
+
|
|
57
|
+
${this.generateMenuListItems('middle')}
|
|
58
|
+
|
|
59
|
+
<li divider role="separator" inset></li>
|
|
60
|
+
|
|
61
|
+
${this.generateMenuListItems('bottom')}
|
|
62
|
+
|
|
63
|
+
</mwc-list>
|
|
64
|
+
<mwc-button
|
|
65
|
+
slot="secondaryAction"
|
|
66
|
+
icon="refresh"
|
|
67
|
+
label="${get('reset')}"
|
|
68
|
+
@click=${async () => {
|
|
69
|
+
this.dispatchEvent(newResetPluginsEvent());
|
|
70
|
+
this.requestUpdate();
|
|
71
|
+
}}
|
|
72
|
+
style="--mdc-theme-primary: var(--mdc-theme-error)"
|
|
73
|
+
>
|
|
74
|
+
</mwc-button>
|
|
75
|
+
<mwc-button
|
|
76
|
+
slot="secondaryAction"
|
|
77
|
+
icon=""
|
|
78
|
+
label="${get('close')}"
|
|
79
|
+
dialogAction="close">
|
|
80
|
+
</mwc-button>
|
|
81
|
+
<mwc-button
|
|
82
|
+
outlined
|
|
83
|
+
trailingIcon
|
|
84
|
+
slot="primaryAction"
|
|
85
|
+
icon="library_add"
|
|
86
|
+
label="${get('plugins.add.heading')}…"
|
|
87
|
+
@click=${() => this.dispatchOpenCustomPluginDialogEvent()}>
|
|
88
|
+
</mwc-button>
|
|
89
|
+
</mwc-dialog>
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
show() {
|
|
93
|
+
this.root.show();
|
|
94
|
+
}
|
|
95
|
+
generateEditorListItems() {
|
|
96
|
+
return this.plugins
|
|
97
|
+
.filter(p => p.kind === 'editor')
|
|
98
|
+
.map(this.renderPluginListItem);
|
|
99
|
+
}
|
|
100
|
+
generateMenuListItems(position) {
|
|
101
|
+
return this.plugins
|
|
102
|
+
.filter(p => p.kind === 'menu' && p.position === position)
|
|
103
|
+
.map(this.renderPluginListItem);
|
|
104
|
+
}
|
|
105
|
+
generateValidatorListItems() {
|
|
106
|
+
return this.plugins
|
|
107
|
+
.filter(p => p.kind === 'validator')
|
|
108
|
+
.map(this.renderPluginListItem);
|
|
109
|
+
}
|
|
110
|
+
dispatchOpenCustomPluginDialogEvent() {
|
|
111
|
+
const event = new CustomEvent('open-plugin-download', {
|
|
112
|
+
bubbles: true,
|
|
113
|
+
composed: true,
|
|
114
|
+
});
|
|
115
|
+
this.dispatchEvent(event);
|
|
116
|
+
}
|
|
117
|
+
renderPluginListItem(plugin) {
|
|
118
|
+
if (!plugin) {
|
|
119
|
+
return html ``;
|
|
120
|
+
}
|
|
121
|
+
return html `
|
|
122
|
+
<mwc-check-list-item
|
|
123
|
+
class="${plugin.official ? 'official' : 'external'}"
|
|
124
|
+
value="${plugin.src}"
|
|
125
|
+
.plugin=${plugin}
|
|
126
|
+
?selected=${plugin.active}
|
|
127
|
+
@request-selected=${(e) => {
|
|
128
|
+
if (e.detail.source !== 'interaction') {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
e.stopPropagation();
|
|
131
|
+
e.stopImmediatePropagation();
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}}
|
|
135
|
+
hasMeta
|
|
136
|
+
left
|
|
137
|
+
>
|
|
138
|
+
<mwc-icon slot="meta">
|
|
139
|
+
${plugin.icon || pluginIcons[plugin.kind]}
|
|
140
|
+
</mwc-icon>
|
|
141
|
+
${plugin.name}
|
|
142
|
+
</mwc-check-list-item>
|
|
143
|
+
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
OscdPluginManager.styles = css `
|
|
148
|
+
mwc-dialog {
|
|
149
|
+
--mdc-dialog-max-width: 98vw;
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
__decorate([
|
|
153
|
+
property({ type: Array })
|
|
154
|
+
], OscdPluginManager.prototype, "plugins", void 0);
|
|
155
|
+
__decorate([
|
|
156
|
+
query('#plugin-manager-root')
|
|
157
|
+
], OscdPluginManager.prototype, "root", void 0);
|
|
158
|
+
__decorate([
|
|
159
|
+
query('#pluginList')
|
|
160
|
+
], OscdPluginManager.prototype, "pluginList", void 0);
|
|
161
|
+
OscdPluginManager = __decorate([
|
|
162
|
+
customElement('oscd-plugin-manager')
|
|
163
|
+
], OscdPluginManager);
|
|
164
|
+
export { OscdPluginManager };
|
|
165
|
+
//# sourceMappingURL=plugin-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-manager.js","sourceRoot":"","sources":["../../../../../src/addons/plugin-manager/plugin-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n customElement,\n html,\n LitElement,\n property,\n query,\n TemplateResult,\n css\n} from 'lit-element';\nimport { get } from 'lit-translate';\n\nimport type { ActionDetail } from '@material/mwc-list';\nimport type { MultiSelectedEvent } from '@material/mwc-list/mwc-list-foundation.js';\nimport type { Dialog } from '@material/mwc-dialog';\nimport '@material/mwc-dialog';\nimport '@material/mwc-list';\nimport type {List} from '@material/mwc-list';\n\nimport {\n newResetPluginsEvent,\n newSetPluginsEvent,\n pluginIcons\n} from '../../open-scd.js';\n\nimport {\n MenuPosition,\n Plugin,\n} from \"../../plugin.js\";\n\n@customElement('oscd-plugin-manager')\nexport class OscdPluginManager extends LitElement {\n\n /** The plugins to render the layout. */\n @property({ type: Array }) plugins: Plugin[] = [];\n @query('#plugin-manager-root') root!: Dialog\n @query('#pluginList') pluginList!: List\n\n render(): TemplateResult {\n return html`\n <mwc-dialog\n stacked\n id=\"plugin-manager-root\"\n heading=\"${get('plugins.heading')}\"\n >\n <mwc-list\n id=\"pluginList\"\n multi\n @selected=${(e: MultiSelectedEvent) => {\n const selectedPlugins = this.pluginList.items\n .filter((item, index) => e.detail.index.has(index))\n // @ts-expect-error: we add plugin to the list item\n .map(item => item.plugin) as Plugin[]\n\n this.dispatchEvent(newSetPluginsEvent(selectedPlugins))\n }}\n >\n <mwc-list-item graphic=\"avatar\" noninteractive>\n <strong>${get(`plugins.editor`)}</strong>\n <mwc-icon slot=\"graphic\" class=\"inverted\">\n ${pluginIcons['editor']}\n </mwc-icon>\n </mwc-list-item>\n\n <li divider role=\"separator\"></li>\n\n ${this.generateEditorListItems()}\n\n <mwc-list-item graphic=\"avatar\" noninteractive>\n <strong>${get(`plugins.menu`)}</strong>\n <mwc-icon slot=\"graphic\" class=\"inverted\">\n <strong>${pluginIcons['menu']}</strong></mwc-icon>\n </mwc-list-item>\n <li divider role=\"separator\"></li>\n\n ${this.generateMenuListItems('top')}\n\n <li divider role=\"separator\" inset></li>\n\n ${this.generateValidatorListItems()}\n\n <li divider role=\"separator\" inset></li>\n\n ${this.generateMenuListItems('middle')}\n\n <li divider role=\"separator\" inset></li>\n\n ${this.generateMenuListItems('bottom')}\n\n </mwc-list>\n <mwc-button\n slot=\"secondaryAction\"\n icon=\"refresh\"\n label=\"${get('reset')}\"\n @click=${async () => {\n this.dispatchEvent(newResetPluginsEvent());\n this.requestUpdate();\n }}\n style=\"--mdc-theme-primary: var(--mdc-theme-error)\"\n >\n </mwc-button>\n <mwc-button\n slot=\"secondaryAction\"\n icon=\"\"\n label=\"${get('close')}\"\n dialogAction=\"close\">\n </mwc-button>\n <mwc-button\n outlined\n trailingIcon\n slot=\"primaryAction\"\n icon=\"library_add\"\n label=\"${get('plugins.add.heading')}…\"\n @click=${() => this.dispatchOpenCustomPluginDialogEvent()}>\n </mwc-button>\n </mwc-dialog>\n `;\n }\n\n static styles = css`\n mwc-dialog {\n --mdc-dialog-max-width: 98vw;\n }\n `\n\n public show(){\n this.root.show()\n }\n\n\n private generateEditorListItems(): TemplateResult[] {\n return this.plugins\n .filter(p => p.kind === 'editor')\n .map(this.renderPluginListItem)\n }\n\n private generateMenuListItems(position: MenuPosition): TemplateResult[] {\n return this.plugins\n .filter(p => p.kind === 'menu' && p.position === position)\n .map(this.renderPluginListItem)\n }\n\n private generateValidatorListItems(): TemplateResult[] {\n return this.plugins\n .filter(p => p.kind === 'validator')\n .map(this.renderPluginListItem)\n }\n\n private dispatchOpenCustomPluginDialogEvent(): void {\n const event = new CustomEvent('open-plugin-download', {\n bubbles: true,\n composed: true,\n });\n\n this.dispatchEvent(event);\n }\n\n private renderPluginListItem(plugin?: Plugin): TemplateResult {\n if(!plugin){ return html`` }\n\n return html`\n <mwc-check-list-item\n class=\"${plugin.official ? 'official' : 'external'}\"\n value=\"${plugin.src}\"\n .plugin=${plugin}\n ?selected=${plugin.active}\n @request-selected=${(e: CustomEvent<{source: string}>) => {\n if(e.detail.source !== 'interaction'){\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n return false;\n }\n }}\n hasMeta\n left\n >\n <mwc-icon slot=\"meta\">\n ${plugin.icon || pluginIcons[plugin.kind]}\n </mwc-icon>\n ${plugin.name}\n </mwc-check-list-item>\n\n `;\n }\n\n}\n"]}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, customElement, html, property, query, state, unsafeCSS, } from 'lit-element';
|
|
3
|
+
import { get } from 'lit-translate';
|
|
4
|
+
import '@material/mwc-checkbox';
|
|
5
|
+
import '@material/mwc-formfield';
|
|
6
|
+
import '@material/mwc-textfield';
|
|
7
|
+
import { CheckListItem } from '@material/mwc-list/mwc-check-list-item';
|
|
8
|
+
import { List } from '@material/mwc-list';
|
|
9
|
+
import { ListBase } from '@material/mwc-list/mwc-list-base';
|
|
10
|
+
function slotItem(item) {
|
|
11
|
+
if (!item.closest('filtered-list') || !item.parentElement)
|
|
12
|
+
return item;
|
|
13
|
+
if (item.parentElement instanceof FilteredList)
|
|
14
|
+
return item;
|
|
15
|
+
return slotItem(item.parentElement);
|
|
16
|
+
}
|
|
17
|
+
function hideFiltered(item, searchText) {
|
|
18
|
+
const itemInnerText = item.innerText + '\n';
|
|
19
|
+
const childInnerText = Array.from(item.children)
|
|
20
|
+
.map(child => child.innerText)
|
|
21
|
+
.join('\n');
|
|
22
|
+
const value = item.value;
|
|
23
|
+
const filterTarget = (itemInnerText +
|
|
24
|
+
childInnerText +
|
|
25
|
+
value).toUpperCase();
|
|
26
|
+
const terms = searchText
|
|
27
|
+
.toUpperCase()
|
|
28
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
29
|
+
.trim()
|
|
30
|
+
.split(/\s+/g);
|
|
31
|
+
(terms.length === 1 && terms[0] === '') ||
|
|
32
|
+
terms.every(term => {
|
|
33
|
+
// regexp escape
|
|
34
|
+
const reTerm = new RegExp(`*${term}*`.replace(/\*/g, '.*').replace(/\?/g, '.{1}'), 'i');
|
|
35
|
+
return reTerm.test(filterTarget);
|
|
36
|
+
})
|
|
37
|
+
? slotItem(item).classList.remove('hidden')
|
|
38
|
+
: slotItem(item).classList.add('hidden');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A mwc-list with mwc-textfield that filters the list items for given or separated terms
|
|
42
|
+
*/
|
|
43
|
+
let FilteredList = class FilteredList extends ListBase {
|
|
44
|
+
get existCheckListItem() {
|
|
45
|
+
return this.items.some(item => item instanceof CheckListItem);
|
|
46
|
+
}
|
|
47
|
+
get isAllSelected() {
|
|
48
|
+
return this.items
|
|
49
|
+
.filter(item => !item.disabled)
|
|
50
|
+
.filter(item => item instanceof CheckListItem)
|
|
51
|
+
.every(checkItem => checkItem.selected);
|
|
52
|
+
}
|
|
53
|
+
get isSomeSelected() {
|
|
54
|
+
return this.items
|
|
55
|
+
.filter(item => !item.disabled)
|
|
56
|
+
.filter(item => item instanceof CheckListItem)
|
|
57
|
+
.some(checkItem => checkItem.selected);
|
|
58
|
+
}
|
|
59
|
+
onCheckAll() {
|
|
60
|
+
const select = !this.isAllSelected;
|
|
61
|
+
this.items
|
|
62
|
+
.filter(item => !item.disabled && !item.classList.contains('hidden'))
|
|
63
|
+
.forEach(item => (item.selected = select));
|
|
64
|
+
}
|
|
65
|
+
onFilterInput() {
|
|
66
|
+
Array.from(this.querySelectorAll('mwc-list-item, mwc-check-list-item, mwc-radio-list-item')).forEach(item => hideFiltered(item, this.searchField.value));
|
|
67
|
+
}
|
|
68
|
+
onListItemConnected(e) {
|
|
69
|
+
super.onListItemConnected(e);
|
|
70
|
+
this.requestUpdate();
|
|
71
|
+
}
|
|
72
|
+
update(changedProperties) {
|
|
73
|
+
super.update(changedProperties);
|
|
74
|
+
// regenerate filtering of text
|
|
75
|
+
this.onFilterInput();
|
|
76
|
+
}
|
|
77
|
+
constructor() {
|
|
78
|
+
super();
|
|
79
|
+
/** Whether the check all option (checkbox next to search text field) is activated */
|
|
80
|
+
this.disableCheckAll = false;
|
|
81
|
+
this.addEventListener('selected', () => {
|
|
82
|
+
this.requestUpdate();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
renderCheckAll() {
|
|
86
|
+
return this.existCheckListItem && !this.disableCheckAll
|
|
87
|
+
? html `<mwc-formfield class="checkall"
|
|
88
|
+
><mwc-checkbox
|
|
89
|
+
?indeterminate=${!this.isAllSelected && this.isSomeSelected}
|
|
90
|
+
?checked=${this.isAllSelected}
|
|
91
|
+
@change=${() => {
|
|
92
|
+
this.onCheckAll();
|
|
93
|
+
}}
|
|
94
|
+
></mwc-checkbox
|
|
95
|
+
></mwc-formfield>`
|
|
96
|
+
: html ``;
|
|
97
|
+
}
|
|
98
|
+
render() {
|
|
99
|
+
return html `<div id="tfcontainer">
|
|
100
|
+
<abbr title="${this.searchFieldLabel ?? get('filter')}"
|
|
101
|
+
><mwc-textfield
|
|
102
|
+
label="${this.searchFieldLabel ?? ''}"
|
|
103
|
+
iconTrailing="search"
|
|
104
|
+
outlined
|
|
105
|
+
@input=${() => this.onFilterInput()}
|
|
106
|
+
></mwc-textfield
|
|
107
|
+
></abbr>
|
|
108
|
+
${this.renderCheckAll()}
|
|
109
|
+
</div>
|
|
110
|
+
${super.render()}`;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
FilteredList.styles = css `
|
|
114
|
+
${unsafeCSS(List.styles)}
|
|
115
|
+
|
|
116
|
+
#tfcontainer {
|
|
117
|
+
display: flex;
|
|
118
|
+
flex: auto;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
::slotted(.hidden) {
|
|
122
|
+
display: none;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
abbr {
|
|
126
|
+
display: flex;
|
|
127
|
+
flex: auto;
|
|
128
|
+
margin: 8px;
|
|
129
|
+
text-decoration: none;
|
|
130
|
+
border-bottom: none;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
mwc-textfield {
|
|
134
|
+
width: 100%;
|
|
135
|
+
--mdc-shape-small: 28px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
mwc-formfield.checkall {
|
|
139
|
+
padding-right: 8px;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.mdc-list {
|
|
143
|
+
padding-inline-start: 0px;
|
|
144
|
+
}
|
|
145
|
+
`;
|
|
146
|
+
__decorate([
|
|
147
|
+
property({ type: String })
|
|
148
|
+
], FilteredList.prototype, "searchFieldLabel", void 0);
|
|
149
|
+
__decorate([
|
|
150
|
+
property({ type: Boolean })
|
|
151
|
+
], FilteredList.prototype, "disableCheckAll", void 0);
|
|
152
|
+
__decorate([
|
|
153
|
+
state()
|
|
154
|
+
], FilteredList.prototype, "existCheckListItem", null);
|
|
155
|
+
__decorate([
|
|
156
|
+
state()
|
|
157
|
+
], FilteredList.prototype, "isAllSelected", null);
|
|
158
|
+
__decorate([
|
|
159
|
+
state()
|
|
160
|
+
], FilteredList.prototype, "isSomeSelected", null);
|
|
161
|
+
__decorate([
|
|
162
|
+
query('mwc-textfield')
|
|
163
|
+
], FilteredList.prototype, "searchField", void 0);
|
|
164
|
+
FilteredList = __decorate([
|
|
165
|
+
customElement('filtered-list')
|
|
166
|
+
], FilteredList);
|
|
167
|
+
export { FilteredList };
|
|
168
|
+
//# sourceMappingURL=filtered-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filtered-list.js","sourceRoot":"","sources":["../../../src/filtered-list.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n customElement,\n html,\n property,\n query,\n state,\n TemplateResult,\n unsafeCSS,\n} from 'lit-element';\nimport { get } from 'lit-translate';\n\nimport '@material/mwc-checkbox';\nimport '@material/mwc-formfield';\nimport '@material/mwc-textfield';\nimport { CheckListItem } from '@material/mwc-list/mwc-check-list-item';\nimport { List } from '@material/mwc-list';\nimport { ListBase } from '@material/mwc-list/mwc-list-base';\nimport { ListItemBase } from '@material/mwc-list/mwc-list-item-base';\nimport { TextField } from '@material/mwc-textfield';\n\nfunction slotItem(item: Element): Element {\n if (!item.closest('filtered-list') || !item.parentElement) return item;\n if (item.parentElement instanceof FilteredList) return item;\n return slotItem(item.parentElement);\n}\n\nfunction hideFiltered(item: ListItemBase, searchText: string): void {\n const itemInnerText = item.innerText + '\\n';\n const childInnerText = Array.from(item.children)\n .map(child => (<HTMLElement>child).innerText)\n .join('\\n');\n const value = item.value;\n\n const filterTarget: string = (\n itemInnerText +\n childInnerText +\n value\n ).toUpperCase();\n\n const terms: string[] = searchText\n .toUpperCase()\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .trim()\n .split(/\\s+/g);\n\n (terms.length === 1 && terms[0] === '') ||\n terms.every(term => {\n // regexp escape\n const reTerm = new RegExp(\n `*${term}*`.replace(/\\*/g, '.*').replace(/\\?/g, '.{1}'),\n 'i'\n );\n return reTerm.test(filterTarget);\n })\n ? slotItem(item).classList.remove('hidden')\n : slotItem(item).classList.add('hidden');\n}\n\n/**\n * A mwc-list with mwc-textfield that filters the list items for given or separated terms\n */\n@customElement('filtered-list')\nexport class FilteredList extends ListBase {\n /** search mwc-textfield label property */\n @property({ type: String })\n searchFieldLabel?: string;\n /** Whether the check all option (checkbox next to search text field) is activated */\n @property({ type: Boolean })\n disableCheckAll = false;\n\n @state()\n private get existCheckListItem(): boolean {\n return this.items.some(item => item instanceof CheckListItem);\n }\n\n @state()\n private get isAllSelected(): boolean {\n return this.items\n .filter(item => !item.disabled)\n .filter(item => item instanceof CheckListItem)\n .every(checkItem => checkItem.selected);\n }\n\n @state()\n private get isSomeSelected(): boolean {\n return this.items\n .filter(item => !item.disabled)\n .filter(item => item instanceof CheckListItem)\n .some(checkItem => checkItem.selected);\n }\n\n @query('mwc-textfield') searchField!: TextField;\n\n private onCheckAll(): void {\n const select = !this.isAllSelected;\n this.items\n .filter(item => !item.disabled && !item.classList.contains('hidden'))\n .forEach(item => (item.selected = select));\n }\n\n onFilterInput(): void {\n Array.from(\n this.querySelectorAll(\n 'mwc-list-item, mwc-check-list-item, mwc-radio-list-item'\n )\n ).forEach(item =>\n hideFiltered(item as ListItemBase, this.searchField.value)\n );\n }\n\n protected onListItemConnected(e: CustomEvent): void {\n super.onListItemConnected(e);\n this.requestUpdate();\n }\n\n protected update(\n changedProperties: Map<string | number | symbol, unknown>\n ): void {\n super.update(changedProperties);\n // regenerate filtering of text\n this.onFilterInput();\n }\n\n constructor() {\n super();\n this.addEventListener('selected', () => {\n this.requestUpdate();\n });\n }\n\n private renderCheckAll(): TemplateResult {\n return this.existCheckListItem && !this.disableCheckAll\n ? html`<mwc-formfield class=\"checkall\"\n ><mwc-checkbox\n ?indeterminate=${!this.isAllSelected && this.isSomeSelected}\n ?checked=${this.isAllSelected}\n @change=${() => {\n this.onCheckAll();\n }}\n ></mwc-checkbox\n ></mwc-formfield>`\n : html``;\n }\n\n render(): TemplateResult {\n return html`<div id=\"tfcontainer\">\n <abbr title=\"${this.searchFieldLabel ?? get('filter')}\"\n ><mwc-textfield\n label=\"${this.searchFieldLabel ?? ''}\"\n iconTrailing=\"search\"\n outlined\n @input=${() => this.onFilterInput()}\n ></mwc-textfield\n ></abbr>\n ${this.renderCheckAll()}\n </div>\n ${super.render()}`;\n }\n\n static styles = css`\n ${unsafeCSS(List.styles)}\n\n #tfcontainer {\n display: flex;\n flex: auto;\n }\n\n ::slotted(.hidden) {\n display: none;\n }\n\n abbr {\n display: flex;\n flex: auto;\n margin: 8px;\n text-decoration: none;\n border-bottom: none;\n }\n\n mwc-textfield {\n width: 100%;\n --mdc-shape-small: 28px;\n }\n\n mwc-formfield.checkall {\n padding-right: 8px;\n }\n\n .mdc-list {\n padding-inline-start: 0px;\n }\n `;\n}\n"]}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, customElement, html, LitElement, property, query, } from 'lit-element';
|
|
3
|
+
import { until } from 'lit-html/directives/until';
|
|
4
|
+
import { get } from 'lit-translate';
|
|
5
|
+
import '@material/mwc-icon';
|
|
6
|
+
import '@material/mwc-list';
|
|
7
|
+
import '@material/mwc-list/mwc-list-item';
|
|
8
|
+
import './filtered-list.js';
|
|
9
|
+
import { depth } from './foundation.js';
|
|
10
|
+
import { ifDefined } from 'lit-html/directives/if-defined';
|
|
11
|
+
const waitingList = html `<div class="column">
|
|
12
|
+
<mwc-list
|
|
13
|
+
><mwc-list-item noninteractive hasMeta
|
|
14
|
+
>${get('loading')}<mwc-icon slot="meta">pending</mwc-icon></mwc-list-item
|
|
15
|
+
></mwc-list
|
|
16
|
+
>
|
|
17
|
+
</div>`;
|
|
18
|
+
let FinderList = class FinderList extends LitElement {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.selection = {};
|
|
22
|
+
this.multi = false;
|
|
23
|
+
this.read = async (path) => {
|
|
24
|
+
return {
|
|
25
|
+
path,
|
|
26
|
+
header: html `<h2>${'/' + path.join('/')}</h2>`,
|
|
27
|
+
entries: [],
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
this.loaded = Promise.resolve();
|
|
31
|
+
}
|
|
32
|
+
get depth() {
|
|
33
|
+
return depth(this.selection);
|
|
34
|
+
}
|
|
35
|
+
get paths() {
|
|
36
|
+
return this.getPaths();
|
|
37
|
+
}
|
|
38
|
+
set paths(paths) {
|
|
39
|
+
const selection = {};
|
|
40
|
+
for (const path of paths) {
|
|
41
|
+
let i = selection;
|
|
42
|
+
for (const name of path) {
|
|
43
|
+
if (!Object.prototype.hasOwnProperty.call(i, name))
|
|
44
|
+
i[name] = {};
|
|
45
|
+
i = i[name];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
this.selection = selection;
|
|
49
|
+
}
|
|
50
|
+
get path() {
|
|
51
|
+
return this.paths[0] ?? [];
|
|
52
|
+
}
|
|
53
|
+
set path(path) {
|
|
54
|
+
this.paths = [path];
|
|
55
|
+
}
|
|
56
|
+
getTitle(path) {
|
|
57
|
+
return path.join('/');
|
|
58
|
+
}
|
|
59
|
+
getDisplayString(entry, path) {
|
|
60
|
+
return entry;
|
|
61
|
+
}
|
|
62
|
+
getPaths(depth) {
|
|
63
|
+
let paths = Object.keys(this.selection).map(key => [key]);
|
|
64
|
+
let i = depth ?? this.depth - 1;
|
|
65
|
+
while (i-- > 0) {
|
|
66
|
+
paths = paths.flatMap(path => {
|
|
67
|
+
let dir = this.selection;
|
|
68
|
+
for (const entry of path)
|
|
69
|
+
dir = dir[entry]; // recursive descent
|
|
70
|
+
const newPaths = Object.keys(dir).map(entry => path.concat(entry));
|
|
71
|
+
return newPaths.length === 0 ? [path] : newPaths;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return depth === undefined
|
|
75
|
+
? paths
|
|
76
|
+
: paths.filter(path => path.length > depth);
|
|
77
|
+
}
|
|
78
|
+
multiSelect(event, path, clicked) {
|
|
79
|
+
let dir = this.selection;
|
|
80
|
+
for (const entry of path)
|
|
81
|
+
dir = dir[entry]; // recursive descent
|
|
82
|
+
if (dir && dir[clicked])
|
|
83
|
+
delete dir[clicked];
|
|
84
|
+
// deselect if selected
|
|
85
|
+
else
|
|
86
|
+
dir[clicked] = {}; // select otherwise
|
|
87
|
+
}
|
|
88
|
+
singleSelect(event, path, clicked) {
|
|
89
|
+
if (this.path[path.length] === clicked)
|
|
90
|
+
this.path = path;
|
|
91
|
+
// deselect if selected
|
|
92
|
+
else
|
|
93
|
+
this.path = path.concat(clicked); // select otherwise
|
|
94
|
+
}
|
|
95
|
+
async select(event, path) {
|
|
96
|
+
const clicked = event.target.selected.value;
|
|
97
|
+
if (this.multi)
|
|
98
|
+
this.multiSelect(event, path, clicked);
|
|
99
|
+
else
|
|
100
|
+
this.singleSelect(event, path, clicked);
|
|
101
|
+
this.requestUpdate();
|
|
102
|
+
await this.updateComplete;
|
|
103
|
+
await new Promise(resolve => setTimeout(resolve, 250));
|
|
104
|
+
this.container.scrollLeft = 1000 * this.depth;
|
|
105
|
+
}
|
|
106
|
+
renderDirectory(path, entries) {
|
|
107
|
+
return html `<filtered-list
|
|
108
|
+
@selected=${(e) => this.select(e, path)}
|
|
109
|
+
searchFieldLabel="${this.getTitle(path)}"
|
|
110
|
+
>
|
|
111
|
+
${entries.map(entry => html `<mwc-list-item
|
|
112
|
+
value="${entry}"
|
|
113
|
+
?activated=${this.getPaths(path.length)
|
|
114
|
+
.map(p => JSON.stringify(p))
|
|
115
|
+
.includes(JSON.stringify(path.concat(entry)))}
|
|
116
|
+
>${this.getDisplayString(entry, path)}</mwc-list-item
|
|
117
|
+
>`)}
|
|
118
|
+
</filtered-list>`;
|
|
119
|
+
}
|
|
120
|
+
async renderColumn(column) {
|
|
121
|
+
const paths = this.getPaths(column);
|
|
122
|
+
const dirs = paths.map(path => this.read(path));
|
|
123
|
+
const lists = [];
|
|
124
|
+
for await (const { header, entries, path } of dirs) {
|
|
125
|
+
if (header || entries.length > 0)
|
|
126
|
+
lists.push(html `${ifDefined(header)} ${this.renderDirectory(path, entries)}`);
|
|
127
|
+
}
|
|
128
|
+
if (lists.length === 0)
|
|
129
|
+
return html ``;
|
|
130
|
+
return html `<div class="column">${lists}</div>`;
|
|
131
|
+
}
|
|
132
|
+
render() {
|
|
133
|
+
const columns = new Array(this.depth)
|
|
134
|
+
.fill(0)
|
|
135
|
+
.map((_, index) => this.renderColumn(index));
|
|
136
|
+
this.loaded = Promise.allSettled(columns).then();
|
|
137
|
+
return html `<div class="pane">
|
|
138
|
+
${columns.map(column => until(column, waitingList))}
|
|
139
|
+
</div>`;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
FinderList.styles = css `
|
|
143
|
+
div.pane {
|
|
144
|
+
display: flex;
|
|
145
|
+
flex-direction: row;
|
|
146
|
+
overflow: auto;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
h2 {
|
|
150
|
+
color: var(--mdc-theme-primary);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
section {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-direction: column;
|
|
156
|
+
width: max-content;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
section > mwc-list {
|
|
160
|
+
margin-top: 76px;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
a {
|
|
164
|
+
font-weight: 600;
|
|
165
|
+
font-variant: small-caps;
|
|
166
|
+
text-transform: lowercase;
|
|
167
|
+
text-decoration: none;
|
|
168
|
+
color: var(--mdc-theme-primary);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
a:link {
|
|
172
|
+
color: var(--mdc-theme-error);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
a:visited {
|
|
176
|
+
color: var(--mdc-theme-secondary);
|
|
177
|
+
}
|
|
178
|
+
`;
|
|
179
|
+
__decorate([
|
|
180
|
+
property({ type: Object })
|
|
181
|
+
], FinderList.prototype, "selection", void 0);
|
|
182
|
+
__decorate([
|
|
183
|
+
property({ type: Boolean })
|
|
184
|
+
], FinderList.prototype, "multi", void 0);
|
|
185
|
+
__decorate([
|
|
186
|
+
property({ type: Number })
|
|
187
|
+
], FinderList.prototype, "depth", null);
|
|
188
|
+
__decorate([
|
|
189
|
+
property({ type: Array })
|
|
190
|
+
], FinderList.prototype, "paths", null);
|
|
191
|
+
__decorate([
|
|
192
|
+
property({ type: Array })
|
|
193
|
+
], FinderList.prototype, "path", null);
|
|
194
|
+
__decorate([
|
|
195
|
+
property({ attribute: false })
|
|
196
|
+
], FinderList.prototype, "read", void 0);
|
|
197
|
+
__decorate([
|
|
198
|
+
property({ attribute: false })
|
|
199
|
+
], FinderList.prototype, "loaded", void 0);
|
|
200
|
+
__decorate([
|
|
201
|
+
query('div')
|
|
202
|
+
], FinderList.prototype, "container", void 0);
|
|
203
|
+
FinderList = __decorate([
|
|
204
|
+
customElement('finder-list')
|
|
205
|
+
], FinderList);
|
|
206
|
+
export { FinderList };
|
|
207
|
+
//# sourceMappingURL=finder-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finder-list.js","sourceRoot":"","sources":["../../../src/finder-list.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n customElement,\n html,\n LitElement,\n property,\n query,\n TemplateResult,\n} from 'lit-element';\nimport { until } from 'lit-html/directives/until';\nimport { get } from 'lit-translate';\n\nimport '@material/mwc-icon';\nimport '@material/mwc-list';\nimport '@material/mwc-list/mwc-list-item';\nimport { List } from '@material/mwc-list';\nimport { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation';\nimport { ListItem } from '@material/mwc-list/mwc-list-item';\n\nimport './filtered-list.js';\nimport { depth } from './foundation.js';\nimport { ifDefined } from 'lit-html/directives/if-defined';\n\nexport type Selection = { [name: string]: Selection };\n\nexport type Path = string[];\nexport interface Directory {\n path: Path;\n header?: TemplateResult;\n entries: string[];\n}\n\nconst waitingList = html`<div class=\"column\">\n <mwc-list\n ><mwc-list-item noninteractive hasMeta\n >${get('loading')}<mwc-icon slot=\"meta\">pending</mwc-icon></mwc-list-item\n ></mwc-list\n >\n</div>`;\n\n@customElement('finder-list')\nexport class FinderList extends LitElement {\n @property({ type: Object })\n selection: Selection = {};\n\n @property({ type: Boolean })\n multi = false;\n\n @property({ type: Number })\n get depth(): number {\n return depth(this.selection);\n }\n\n @property({ type: Array })\n get paths(): Path[] {\n return this.getPaths();\n }\n set paths(paths: Path[]) {\n const selection: Selection = {};\n for (const path of paths) {\n let i = selection;\n for (const name of path) {\n if (!Object.prototype.hasOwnProperty.call(i, name)) i[name] = {};\n i = i[name];\n }\n }\n this.selection = selection;\n }\n\n @property({ type: Array })\n get path(): Path {\n return this.paths[0] ?? [];\n }\n set path(path: Path) {\n this.paths = [path];\n }\n\n @property({ attribute: false })\n read: (path: Path) => Promise<Directory> = async path => {\n return {\n path,\n header: html`<h2>${'/' + path.join('/')}</h2>`,\n entries: [],\n };\n };\n\n @property({ attribute: false })\n loaded: Promise<void> = Promise.resolve();\n\n getTitle(path: string[]): string {\n return path.join('/');\n }\n\n getDisplayString(entry: string, path: string[]): string {\n return entry;\n }\n\n @query('div')\n container!: Element;\n\n private getPaths(depth?: number): Path[] {\n let paths: Path[] = Object.keys(this.selection).map(key => [key]);\n\n let i = depth ?? this.depth - 1;\n while (i-- > 0) {\n paths = paths.flatMap(path => {\n let dir = this.selection;\n for (const entry of path) dir = dir[entry]; // recursive descent\n const newPaths = Object.keys(dir).map(entry => path.concat(entry));\n return newPaths.length === 0 ? [path] : newPaths;\n });\n }\n\n return depth === undefined\n ? paths\n : paths.filter(path => path.length > depth);\n }\n\n multiSelect(event: SingleSelectedEvent, path: Path, clicked: string): void {\n let dir = this.selection;\n for (const entry of path) dir = dir[entry]; // recursive descent\n\n if (dir && dir[clicked]) delete dir[clicked];\n // deselect if selected\n else dir[clicked] = {}; // select otherwise\n }\n\n singleSelect(event: SingleSelectedEvent, path: Path, clicked: string): void {\n if (this.path[path.length] === clicked) this.path = path;\n // deselect if selected\n else this.path = path.concat(clicked); // select otherwise\n }\n\n async select(event: SingleSelectedEvent, path: Path): Promise<void> {\n const clicked = (<ListItem>(<List>event.target).selected).value;\n\n if (this.multi) this.multiSelect(event, path, clicked);\n else this.singleSelect(event, path, clicked);\n\n this.requestUpdate();\n await this.updateComplete;\n await new Promise(resolve => setTimeout(resolve, 250));\n this.container.scrollLeft = 1000 * this.depth;\n }\n\n renderDirectory(path: Path, entries: string[]): TemplateResult {\n return html`<filtered-list\n @selected=${(e: SingleSelectedEvent) => this.select(e, path)}\n searchFieldLabel=\"${this.getTitle(path)}\"\n >\n ${entries.map(\n entry =>\n html`<mwc-list-item\n value=\"${entry}\"\n ?activated=${this.getPaths(path.length)\n .map(p => JSON.stringify(p))\n .includes(JSON.stringify(path.concat(entry)))}\n >${this.getDisplayString(entry, path)}</mwc-list-item\n >`\n )}\n </filtered-list>`;\n }\n\n async renderColumn(column: number): Promise<TemplateResult> {\n const paths = this.getPaths(column);\n\n const dirs = paths.map(path => this.read(path));\n const lists: TemplateResult[] = [];\n\n for await (const { header, entries, path } of dirs) {\n if (header || entries.length > 0)\n lists.push(\n html`${ifDefined(header)} ${this.renderDirectory(path, entries)}`\n );\n }\n\n if (lists.length === 0) return html``;\n return html`<div class=\"column\">${lists}</div>`;\n }\n\n render(): TemplateResult {\n const columns = new Array(this.depth)\n .fill(0)\n .map((_, index) => this.renderColumn(index));\n this.loaded = Promise.allSettled(columns).then();\n return html`<div class=\"pane\">\n ${columns.map(column => until(column, waitingList))}\n </div>`;\n }\n\n static styles = css`\n div.pane {\n display: flex;\n flex-direction: row;\n overflow: auto;\n }\n\n h2 {\n color: var(--mdc-theme-primary);\n }\n\n section {\n display: flex;\n flex-direction: column;\n width: max-content;\n }\n\n section > mwc-list {\n margin-top: 76px;\n }\n\n a {\n font-weight: 600;\n font-variant: small-caps;\n text-transform: lowercase;\n text-decoration: none;\n color: var(--mdc-theme-primary);\n }\n\n a:link {\n color: var(--mdc-theme-error);\n }\n\n a:visited {\n color: var(--mdc-theme-secondary);\n }\n `;\n}\n"]}
|