@things-factory/setting-ui 8.0.37 → 9.0.0-9.0.0-beta.59.0

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.
@@ -1,47 +0,0 @@
1
- import { html, css } from 'lit'
2
- import { customElement, property, query, state } from 'lit/decorators.js'
3
- import { connect } from 'pwa-helpers/connect-mixin.js'
4
-
5
- import { store, PageView } from '@operato/shell'
6
- import { i18next, localize } from '@operato/i18n'
7
-
8
- @customElement('setting-page')
9
- export class SettingPage extends connect(store)(localize(i18next)(PageView)) {
10
- static styles = [
11
- css`
12
- :host {
13
- overflow-y: auto;
14
- background-color: var(--md-sys-color-background);
15
- }
16
- div {
17
- margin: var(--setting-icon-margin);
18
- height: var(--setting-icon-height);
19
- background: url(/assets/images/icon-setting.png) center top no-repeat;
20
- background-size: contain;
21
- }
22
- `
23
- ]
24
-
25
- @state() private _settings: any[] = []
26
-
27
- render() {
28
- var _sortedSettings = this._settings.sort((a, b) => {
29
- return a.seq - b.seq
30
- })
31
-
32
- return html`
33
- <div class="page-icon"></div>
34
- ${_sortedSettings.map(setting => html` ${setting.template} `)}
35
- `
36
- }
37
-
38
- stateChanged(state) {
39
- this._settings = state.setting.settings
40
- }
41
-
42
- get context() {
43
- return {
44
- title: i18next.t('title.setting')
45
- }
46
- }
47
- }
package/client/route.ts DELETED
@@ -1,15 +0,0 @@
1
- export default function route(page) {
2
- switch (page) {
3
- case 'setting':
4
- import('./pages/setting')
5
- return page
6
-
7
- case 'settings':
8
- import('./pages/setting-list')
9
- return page
10
-
11
- case 'partner_settings':
12
- import('./pages/partner-setting-list')
13
- return page
14
- }
15
- }
@@ -1,50 +0,0 @@
1
- import { clientSettingStore } from '@operato/shell'
2
-
3
- var prefersColorSchemeMedia
4
-
5
- function getPrefersColorSchemeMedia() {
6
- if (!prefersColorSchemeMedia) {
7
- prefersColorSchemeMedia = window.matchMedia('(prefers-color-scheme: dark)')
8
- }
9
- return prefersColorSchemeMedia
10
- }
11
-
12
- async function onPreferColorSchemeChanged() {
13
- const themeMode = ((await clientSettingStore.get('theme'))?.value || {}).mode || 'light'
14
-
15
- if (themeMode !== 'auto') {
16
- getPrefersColorSchemeMedia().removeEventListener('change', onPreferColorSchemeChanged)
17
-
18
- return
19
- }
20
-
21
- if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
22
- document.body.classList.add('dark')
23
- document.body.classList.remove('light')
24
- } else {
25
- document.body.classList.add('light')
26
- document.body.classList.remove('dark')
27
- }
28
- }
29
-
30
- export function setThemeMode(mode) {
31
- getPrefersColorSchemeMedia().removeEventListener('change', onPreferColorSchemeChanged)
32
-
33
- if (mode === 'dark') {
34
- document.body.classList.add('dark')
35
- document.body.classList.remove('light')
36
- } else if (mode === 'light') {
37
- document.body.classList.add('light')
38
- document.body.classList.remove('dark')
39
- } else {
40
- if (getPrefersColorSchemeMedia().matches) {
41
- document.body.classList.add('dark')
42
- document.body.classList.remove('light')
43
- } else {
44
- document.body.classList.add('light')
45
- document.body.classList.remove('dark')
46
- }
47
-
48
- getPrefersColorSchemeMedia().addEventListener('change', onPreferColorSchemeChanged)
49
- }
50
- }
@@ -1,49 +0,0 @@
1
- import '@things-factory/setting-base'
2
- import '@operato/i18n/ox-i18n.js'
3
-
4
- import { store } from '@operato/shell'
5
-
6
- import { html, css, LitElement } from 'lit'
7
- import { customElement, property, query, queryAll, state } from 'lit/decorators.js'
8
- import { connect } from 'pwa-helpers/connect-mixin'
9
-
10
- @customElement('domain-switch-let')
11
- export class DomainSwitchLet extends connect(store)(LitElement) {
12
- static styles = [
13
- css`
14
- select {
15
- border: var(--input-field-border);
16
- padding: var(--input-padding);
17
- border-radius: var(--border-radius);
18
- font: var(--input-font);
19
- }
20
- `
21
- ]
22
-
23
- @state() domains: any[] = []
24
- @state() domain: any
25
-
26
- render() {
27
- return html`
28
- <setting-let>
29
- <ox-i18n slot="title" msgid="title.switch domain"></ox-i18n>
30
-
31
- <select slot="content" @change=${e => (window.location.pathname = '/auth/checkin/' + e.target.value)}>
32
- <option value="">&nbsp</option>
33
- ${this.domains.map(
34
- option => html`
35
- <option value=${option.subdomain} ?selected=${this.domain?.subdomain == option.subdomain}>
36
- ${option.name}
37
- </option>
38
- `
39
- )}
40
- </select>
41
- </setting-let>
42
- `
43
- }
44
-
45
- stateChanged(state) {
46
- this.domains = state.app.domains
47
- this.domain = state.app.domain
48
- }
49
- }
@@ -1,208 +0,0 @@
1
- import '@material/web/textfield/filled-text-field.js'
2
- import '@things-factory/setting-base'
3
- import '@operato/i18n/ox-i18n.js'
4
-
5
- import gql from 'graphql-tag'
6
- import { html, css, LitElement, PropertyValueMap } from 'lit'
7
- import { customElement, property, query, queryAll, state } from 'lit/decorators.js'
8
-
9
- import { i18next } from '@operato/i18n'
10
- import { client } from '@operato/graphql'
11
-
12
- @customElement('secure-iplist-setting-let')
13
- export class SecureIPListSettingLet extends LitElement {
14
- static styles = [
15
- css`
16
- div[slot='content'] {
17
- display: flex;
18
- flex-direction: column;
19
- gap: 6px;
20
- }
21
-
22
- ul {
23
- flex: 1;
24
- background-color: var(--md-sys-color-surface);
25
- overflow: auto;
26
- display: grid;
27
- grid-template-columns: 1fr 1fr;
28
- margin: 0;
29
- padding: var(--spacing-medium);
30
- list-style: none;
31
- border: 1px dashed var(--md-sys-color-outline);
32
- border-width: 1px 0;
33
- }
34
-
35
- [hidden] {
36
- display: none;
37
- }
38
-
39
- @media screen and (max-width: 480px) {
40
- ul {
41
- grid-template-columns: 1fr;
42
- }
43
- }
44
- `
45
- ]
46
-
47
- @property({ type: Object }) value?: {
48
- blacklist?: string[]
49
- whitelist?: string[]
50
- protectedlist?: string[]
51
- privileges?: any[]
52
- }
53
-
54
- @state() private allPrivileges: {
55
- privilege: string
56
- category: string
57
- description: string
58
- }[] = []
59
-
60
- @query('[name="whitelist"]') whitelist
61
- @query('[name="blacklist"]') blacklist
62
- @query('[name="protectedlist"]') protectedlist
63
- @queryAll('ul[privileges] input[type=checkbox]:checked') protectedPrivileges
64
-
65
- render() {
66
- const { whitelist = [], blacklist = [], protectedlist = [], privileges = [] } = this.value || {}
67
-
68
- return html`
69
- <setting-let>
70
- <ox-title-with-help slot="title" topic="setting/secure-ip-list" msgid="title.secure-ip-list"
71
- >secure IP list</ox-title-with-help
72
- >
73
-
74
- <div slot="content" @change=${() => this.onSave()}>
75
- <md-filled-text-field
76
- type="text"
77
- name="whitelist"
78
- .label=${String(i18next.t('label.whitelist'))}
79
- icon="health_and_safety"
80
- value=${whitelist.join(', ')}
81
- supporting-text=${String(i18next.t('text.supporting text for whitelist'))}
82
- hidden
83
- >
84
- <md-icon slot="leading-icon">health_and_safety</md-icon>
85
- </md-filled-text-field>
86
-
87
- <md-filled-text-field
88
- type="text"
89
- name="blacklist"
90
- .label=${String(i18next.t('label.blacklist'))}
91
- value=${blacklist.join(', ')}
92
- supporting-text=${String(i18next.t('text.supporting text for blacklist'))}
93
- >
94
- <md-icon slot="leading-icon">block</md-icon>
95
- </md-filled-text-field>
96
-
97
- <md-filled-text-field
98
- type="text"
99
- name="protectedlist"
100
- .label=${String(i18next.t('label.protectedlist'))}
101
- value=${protectedlist.join(', ')}
102
- supporting-text=${String(i18next.t('text.supporting text for protected ip-list'))}
103
- >
104
- <md-icon slot="leading-icon">security</md-icon>
105
- </md-filled-text-field>
106
-
107
- <div>
108
- <h3><ox-i18n msgid="title.protected-privileges"></ox-i18n></h3>
109
- <div>
110
- <input id="checkAll" type="checkbox" @change=${e => this.oncheckAll(e)} />
111
- <label for="checkAll">Check all</label>
112
- </div>
113
-
114
- <ul privileges>
115
- ${this.allPrivileges.map(privilege => {
116
- const id = `${privilege.category}-${privilege.privilege}`
117
- return html`
118
- <li>
119
- <input
120
- type="checkbox"
121
- id=${id}
122
- .checked=${!!privileges.find(
123
- p => p.privilege == privilege.privilege && p.category == privilege.category
124
- )}
125
- .data-privilege=${privilege}
126
- />
127
- <label for="${id}">${privilege.description}</label>
128
- </li>
129
- `
130
- })}
131
- </ul>
132
- </div>
133
- </div>
134
- </setting-let>
135
- `
136
- }
137
-
138
- async firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): Promise<void> {
139
- var { data } = await client.query({
140
- query: gql`
141
- query {
142
- privileges {
143
- items {
144
- privilege
145
- category
146
- description
147
- }
148
- total
149
- }
150
- }
151
- `
152
- })
153
-
154
- this.allPrivileges = data?.privileges.items || []
155
-
156
- var { data } = await client.query({
157
- query: gql`
158
- query {
159
- secureIPList
160
- }
161
- `
162
- })
163
-
164
- this.value = data ? data.secureIPList : {}
165
- }
166
-
167
- checkAll(checked) {
168
- Array.from(this.renderRoot.querySelectorAll('ul[privileges] input[type=checkbox]')).forEach(
169
- checkbox => ((checkbox as HTMLInputElement).checked = checked)
170
- )
171
- }
172
-
173
- oncheckAll(e) {
174
- this.checkAll(e.target.checked)
175
- }
176
-
177
- async onSave() {
178
- const whitelist = !this.whitelist.value ? [] : this.whitelist.value.split(',').map(ip => ip.trim())
179
- const blacklist = !this.blacklist.value ? [] : this.blacklist.value.split(',').map(ip => ip.trim())
180
- const protectedlist = !this.protectedlist.value ? [] : this.protectedlist.value.split(',').map(ip => ip.trim())
181
- const privileges = Array.from(this.protectedPrivileges)
182
- .map((e: any) => e['data-privilege'])
183
- .map((priv: any) => {
184
- const { description, ...others } = priv
185
- return others
186
- })
187
-
188
- const iplist = {
189
- whitelist,
190
- blacklist,
191
- protectedlist,
192
- privileges
193
- }
194
-
195
- const { data } = await client.query({
196
- query: gql`
197
- mutation ($iplist: Object!) {
198
- updateSecureIPList(iplist: $iplist)
199
- }
200
- `,
201
- variables: {
202
- iplist
203
- }
204
- })
205
-
206
- this.value = data ? data.updateSecureIPList : {}
207
- }
208
- }
@@ -1,80 +0,0 @@
1
- import '@operato/i18n/ox-i18n.js'
2
- import '@material/web/radio/radio.js'
3
-
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, property } from 'lit/decorators.js'
6
-
7
- import { i18next, localize } from '@operato/i18n'
8
- import { clientSettingStore } from '@operato/shell'
9
- import { MdRadio } from '@material/web/radio/radio.js'
10
- import { setThemeMode } from '../set-theme-mode.js'
11
-
12
- @customElement('theme-mode-setting-let')
13
- export class ThemeModeSettingLet extends localize(i18next)(LitElement) {
14
- static styles = [
15
- css`
16
- label {
17
- display: flex;
18
- gap: 10px;
19
- align-items: center;
20
-
21
- font: var(--label-font);
22
- color: var(--md-sys-color-on-surface);
23
- text-transform: var(--label-text-transform);
24
- }
25
-
26
- div[slot='content'] {
27
- display: flex;
28
- gap: 10px;
29
- }
30
- `
31
- ]
32
-
33
- @property({ type: String, attribute: 'theme-mode' }) themeMode: 'dark' | 'light' | 'auto' = 'light'
34
-
35
- render() {
36
- const themeMode = this.themeMode
37
-
38
- return html`
39
- <setting-let>
40
- <ox-i18n slot="title" msgid="title.theme setting"></ox-i18n>
41
-
42
- <div slot="content" @change=${(e: Event) => this.onChangeThemeMode(e)}>
43
- <md-radio id="dark-mode" name="theme-mode" value="dark" ?checked=${themeMode == 'dark'}></md-radio>
44
- <label for="dark-mode">dark mode</label>
45
-
46
- <md-radio id="light-mode" name="theme-mode" value="light" ?checked=${themeMode == 'light'}></md-radio>
47
- <label for="light-mode">light mode</label>
48
-
49
- <md-radio id="auto-mode" name="theme-mode" value="auto" ?checked=${themeMode == 'auto'}></md-radio>
50
- <label for="auto-mode">auto mode</label>
51
- </div>
52
- </setting-let>
53
- `
54
- }
55
-
56
- async firstUpdated() {
57
- this.themeMode = ((await clientSettingStore.get('theme'))?.value || {}).mode || 'light'
58
- }
59
-
60
- async onChangeThemeMode(e: Event) {
61
- const target = e.target as MdRadio
62
- const value = target.value
63
- const mode = (this.querySelector('md-radio[checked]') as MdRadio)?.value || value
64
-
65
- if (mode) {
66
- try {
67
- await clientSettingStore.put({
68
- key: 'theme',
69
- value: {
70
- mode
71
- }
72
- })
73
-
74
- setThemeMode(mode)
75
- } catch (e) {
76
- console.error(e)
77
- }
78
- }
79
- }
80
- }
@@ -1,32 +0,0 @@
1
- body {
2
- --setting-background: var(--md-sys-color-background);
3
-
4
- --setting-let-background: var(--md-sys-color-on-primary);
5
- --setting-let-margin: var(--margin-wide);
6
- --setting-let-border-radius: var(--border-radius);
7
- --setting-let-border: var(--border-dim-color);
8
-
9
- --setting-title-font: var(--subtitle-font);
10
- --setting-title-color: var(--subtitle-text-color);
11
-
12
- --setting-content-padding: var(--padding-wide);
13
- --setting-content-font: normal 0.9em var(--theme-font);
14
- --setting-content-color: var(--md-sys-color-secondary);
15
-
16
- --setting-info-content-padding: 10px 15px;
17
- --setting-info-background-color: #f0f0f0;
18
- --setting-info-font: normal 14px/14px var(--theme-font);
19
- --setting-info-color: #666;
20
- --setting-info-appname-color: var(--md-sys-color-primary);
21
-
22
- --setting-icon-height: 170px;
23
- --setting-icon-margin: 40px 0 5px 0;
24
- }
25
- @media screen and (max-width: 460px) {
26
- body {
27
- --setting-let-margin: var(--margin-default);
28
- --setting-content-padding: var(--padding-default);
29
- --setting-icon-height: 140px;
30
- --setting-icon-margin: var(--margin-wide) 0;
31
- }
32
- }
@@ -1,3 +0,0 @@
1
- import '@material/web/icon/icon.js';
2
- import '@things-factory/form-ui';
3
- import '@operato/data-grist';
@@ -1,142 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import '@material/web/icon/icon.js';
3
- import '@things-factory/form-ui';
4
- import '@operato/data-grist';
5
- import { i18next } from '@operato/i18n';
6
- import { client, gqlContext } from '@operato/graphql';
7
- import { isMobileDevice } from '@operato/utils';
8
- import { CommonGristStyles, CommonHeaderStyles } from '@operato/styles';
9
- import gql from 'graphql-tag';
10
- import { css, html, LitElement } from 'lit';
11
- import { customElement, query, state } from 'lit/decorators.js';
12
- let PartnerSelector = class PartnerSelector extends LitElement {
13
- constructor() {
14
- super(...arguments);
15
- this.mode = isMobileDevice() ? 'LIST' : 'GRID';
16
- }
17
- render() {
18
- return html `
19
- <ox-grist .mode=${this.mode} auto-fetch .config=${this.config} .fetchHandler=${this.fetchHandler.bind(this)}>
20
- <div slot="headroom" class="header">
21
- <div class="filters">
22
- <ox-filters-form></ox-filters-form>
23
- </div>
24
- </div>
25
- </ox-grist>
26
-
27
- <div class="footer">
28
- <div filler></div>
29
- <button @click=${this.select.bind(this)} done>
30
- <md-icon>select_check_box</md-icon>${i18next.t('button.select')}
31
- </button>
32
- </div>
33
- `;
34
- }
35
- firstUpdated() {
36
- this.config = {
37
- list: { fields: ['name', 'description'] },
38
- rows: { selectable: { multiple: true }, appendable: false, handlers: { click: 'select-row-toggle' } },
39
- columns: [
40
- { type: 'gutter', gutterName: 'sequence' },
41
- { type: 'gutter', gutterName: 'row-selector', multiple: false },
42
- {
43
- type: 'string',
44
- name: 'name',
45
- header: i18next.t('field.name'),
46
- record: { editable: false, align: 'left' },
47
- sortable: true,
48
- filter: 'search',
49
- width: 100
50
- },
51
- {
52
- type: 'string',
53
- name: 'description',
54
- header: i18next.t('field.description'),
55
- record: { editable: false, align: 'left' },
56
- sortable: true,
57
- filter: 'search',
58
- width: 200
59
- }
60
- ]
61
- };
62
- }
63
- async fetchHandler({ filters, page, limit, sorters = [] }) {
64
- const pagination = { page, limit };
65
- const sortings = sorters;
66
- const response = await client.query({
67
- query: gql `
68
- query searchCustomers($filters: [Filter!]!, $pagination: Pagination!, $sortings: [Sorting!]!) {
69
- searchCustomers(filters: $filters, pagination: $pagination, sortings: $sortings) {
70
- items {
71
- id
72
- name
73
- description
74
- }
75
- total
76
- }
77
- }
78
- `,
79
- variables: { filters, pagination, sortings },
80
- context: gqlContext()
81
- });
82
- return {
83
- records: response.data.searchCustomers.items || [],
84
- total: response.data.searchCustomers.total || 0
85
- };
86
- }
87
- select() {
88
- const selectedItems = this.dataGrist.selected;
89
- if (!selectedItems.length) {
90
- this.showToast(i18next.t('text.nothing_selected'));
91
- return;
92
- }
93
- history.back();
94
- this.dispatchEvent(new CustomEvent('select', {
95
- detail: selectedItems[0]
96
- }));
97
- }
98
- showToast(message) {
99
- document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }));
100
- }
101
- };
102
- PartnerSelector.styles = [
103
- CommonGristStyles,
104
- CommonHeaderStyles,
105
- css `
106
- :host {
107
- display: flex;
108
- flex-direction: column;
109
- overflow: hidden;
110
- background-color: var(--md-sys-color-surface);
111
- }
112
-
113
- ox-grist {
114
- overflow-y: auto;
115
- flex: 1;
116
- }
117
-
118
- ox-filters-form {
119
- flex: 1;
120
- }
121
- `
122
- ];
123
- __decorate([
124
- state(),
125
- __metadata("design:type", Object)
126
- ], PartnerSelector.prototype, "config", void 0);
127
- __decorate([
128
- state(),
129
- __metadata("design:type", Object)
130
- ], PartnerSelector.prototype, "data", void 0);
131
- __decorate([
132
- state(),
133
- __metadata("design:type", String)
134
- ], PartnerSelector.prototype, "mode", void 0);
135
- __decorate([
136
- query('ox-grist'),
137
- __metadata("design:type", Object)
138
- ], PartnerSelector.prototype, "dataGrist", void 0);
139
- PartnerSelector = __decorate([
140
- customElement('partner-selector')
141
- ], PartnerSelector);
142
- //# sourceMappingURL=partner-selector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"partner-selector.js","sourceRoot":"","sources":["../../client/components/partner-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@things-factory/form-ui'\nimport '@operato/data-grist'\n\nimport { i18next } from '@operato/i18n'\nimport { client, gqlContext } from '@operato/graphql'\nimport { isMobileDevice } from '@operato/utils'\nimport { CommonGristStyles, CommonHeaderStyles } from '@operato/styles'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\nimport { FetchOption } from '@operato/data-grist'\n\n@customElement('partner-selector')\nclass PartnerSelector extends LitElement {\n static styles = [\n CommonGristStyles,\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background-color: var(--md-sys-color-surface);\n }\n\n ox-grist {\n overflow-y: auto;\n flex: 1;\n }\n\n ox-filters-form {\n flex: 1;\n }\n `\n ]\n\n @state() private config: any\n @state() private data: any\n @state() private mode: string = isMobileDevice() ? 'LIST' : 'GRID'\n\n @query('ox-grist') private dataGrist: any\n\n render() {\n return html`\n <ox-grist .mode=${this.mode} auto-fetch .config=${this.config} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form></ox-filters-form>\n </div>\n </div>\n </ox-grist>\n\n <div class=\"footer\">\n <div filler></div>\n <button @click=${this.select.bind(this)} done>\n <md-icon>select_check_box</md-icon>${i18next.t('button.select')}\n </button>\n </div>\n `\n }\n\n firstUpdated() {\n this.config = {\n list: { fields: ['name', 'description'] },\n rows: { selectable: { multiple: true }, appendable: false, handlers: { click: 'select-row-toggle' } },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: false },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: { editable: false, align: 'left' },\n sortable: true,\n filter: 'search',\n width: 100\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: { editable: false, align: 'left' },\n sortable: true,\n filter: 'search',\n width: 200\n }\n ]\n }\n }\n\n async fetchHandler({ filters, page, limit, sorters = [] }: FetchOption) {\n const pagination = { page, limit }\n const sortings = sorters\n\n const response = await client.query({\n query: gql`\n query searchCustomers($filters: [Filter!]!, $pagination: Pagination!, $sortings: [Sorting!]!) {\n searchCustomers(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n }\n total\n }\n }\n `,\n variables: { filters, pagination, sortings },\n context: gqlContext()\n })\n\n return {\n records: response.data.searchCustomers.items || [],\n total: response.data.searchCustomers.total || 0\n }\n }\n\n select() {\n const selectedItems = this.dataGrist.selected\n if (!selectedItems.length) {\n this.showToast(i18next.t('text.nothing_selected'))\n return\n }\n\n history.back()\n\n this.dispatchEvent(\n new CustomEvent('select', {\n detail: selectedItems[0]\n })\n )\n }\n\n showToast(message) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))\n }\n}\n"]}