@operato/data-grist 2.0.0-alpha.133 → 2.0.0-alpha.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/src/data-grid/data-grid-header.js +1 -1
  3. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  4. package/dist/src/data-grist.js +34 -36
  5. package/dist/src/data-grist.js.map +1 -1
  6. package/dist/src/filters/filter-styles.js +21 -11
  7. package/dist/src/filters/filter-styles.js.map +1 -1
  8. package/dist/src/filters/filters-form.d.ts +8 -2
  9. package/dist/src/filters/filters-form.js +128 -62
  10. package/dist/src/filters/filters-form.js.map +1 -1
  11. package/dist/src/personalizer/ox-grist-filter-personalizer.d.ts +8 -0
  12. package/dist/src/personalizer/ox-grist-filter-personalizer.js +177 -0
  13. package/dist/src/personalizer/ox-grist-filter-personalizer.js.map +1 -0
  14. package/dist/src/personalizer/ox-grist-personalizer.js +7 -1
  15. package/dist/src/personalizer/ox-grist-personalizer.js.map +1 -1
  16. package/dist/src/types.d.ts +11 -0
  17. package/dist/src/types.js.map +1 -1
  18. package/dist/stories/grid-setting.stories.d.ts +1 -0
  19. package/dist/stories/grid-setting.stories.js +21 -29
  20. package/dist/stories/grid-setting.stories.js.map +1 -1
  21. package/dist/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +6 -6
  23. package/src/data-grid/data-grid-header.ts +1 -1
  24. package/src/data-grist.ts +36 -38
  25. package/src/filters/filter-styles.ts +21 -11
  26. package/src/filters/filters-form.ts +196 -125
  27. package/src/personalizer/ox-grist-filter-personalizer.ts +191 -0
  28. package/src/personalizer/ox-grist-personalizer.ts +7 -1
  29. package/src/types.ts +12 -0
  30. package/stories/grid-setting.stories.ts +22 -29
@@ -1 +1 @@
1
- {"version":3,"file":"filter-styles.js","sourceRoot":"","sources":["../../../src/filters/filter-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmG9B,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport const FilterStyles = css`\n :host {\n --ox-filters-input-placeholder-color: var(--input-placeholder-color, var(--primary-color));\n\n --ox-filters-input-border: var(--input-border, 1px solid rgba(0, 0, 0, 0.2));\n --ox-filters-input-focus-border: var(--input-focus-border, 1px solid var(--primary-color));\n --ox-filters-input-font: var(--input-font, normal 14px var(--theme-font));\n --ox-filters-input-color: var(--input-color, var(--primary-text-color));\n --ox-filters-input-focus-color: var(--input-focus-color, var(--primary-color));\n --ox-filters-label-font: var(--label-font, normal 14px var(--theme-font));\n --ox-filters-label-color: var(--label-color, var(--primary-text-color));\n --ox-filters-input-background-color: transparent;\n\n --ox-filters-form-gap: var(--input-gap-vertical, 8px) var(--input-gap-horizontal, 16px);\n --ox-filters-input-padding: var(--input-padding, 6px 2px);\n\n --ox-select-padding: var(--ox-filters-input-padding);\n --ox-checkbox-background-color: var(--ox-filters-input-background-color, transparent);\n }\n\n label {\n font: var(--ox-filters-label-font);\n color: var(--ox-filters-label-color);\n }\n\n span {\n text-transform: capitalize;\n }\n\n input::placeholder {\n color: var(--ox-filters-input-placeholder-color);\n opacity: 0.6;\n }\n\n input {\n padding: var(--ox-filters-input-padding);\n }\n\n ox-select,\n input {\n border: none;\n border-bottom: var(--ox-filters-input-border);\n font: var(--ox-filters-input-font);\n color: var(--ox-filters-input-color);\n background-color: var(--ox-filters-input-background-color, transparent);\n }\n\n label > span + * {\n min-width: 120px;\n }\n\n ox-select:focus,\n input:focus {\n outline: none;\n border-bottom: var(--ox-filters-input-focus-border);\n color: var(--ox-filters-input-focus-color);\n }\n\n ox-select {\n min-width: 100px;\n max-width: 170px;\n }\n\n ox-input-barcode {\n min-width: 150px;\n }\n\n ox-input-search {\n max-width: 150px;\n }\n\n input[type='number'] {\n max-width: 90px;\n }\n\n input[type*='date'],\n input[type*='time'],\n input[type='week'],\n input[type='month'] {\n max-width: 170px;\n }\n\n @media only screen and (max-width: 460px) {\n :host {\n --ox-filters-form-label-font: bold 13px var(--theme-font);\n --ox-filters-input-font: normal 16px var(--theme-font);\n }\n\n input[from],\n input[to] {\n max-width: 44%;\n }\n\n input[type*='datetime'][from],\n input[type*='datetime'][to] {\n padding-right: var(--padding-narrow);\n min-width: 91%;\n }\n }\n`\n"]}
1
+ {"version":3,"file":"filter-styles.js","sourceRoot":"","sources":["../../../src/filters/filter-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6G9B,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport const FilterStyles = css`\n :host {\n --ox-filters-input-placeholder-color: var(--input-placeholder-color, var(--primary-color));\n\n --ox-filters-input-border: var(--input-border, 1px solid rgba(0, 0, 0, 0.2));\n --ox-filters-input-focus-border: var(--input-focus-border, 1px solid var(--primary-color));\n --ox-filters-input-font: var(--input-font, normal 14px var(--theme-font));\n --ox-filters-input-color: var(--input-color, var(--primary-text-color));\n --ox-filters-input-focus-color: var(--input-focus-color, var(--primary-color));\n --ox-filters-label-font: var(--label-font, normal 14px var(--theme-font));\n --ox-filters-label-color: var(--label-color, var(--primary-text-color));\n --ox-filters-input-background-color: transparent;\n\n --ox-filters-form-gap: var(--input-gap-vertical, 8px) var(--input-gap-horizontal, 16px);\n --ox-filters-input-padding: var(--input-padding, 6px 2px);\n\n --ox-select-padding: var(--ox-filters-input-padding);\n --ox-checkbox-background-color: var(--ox-filters-input-background-color, transparent);\n }\n\n label {\n font: var(--ox-filters-label-font);\n color: var(--ox-filters-label-color);\n }\n\n span {\n text-transform: capitalize;\n }\n\n input::placeholder {\n color: var(--ox-filters-input-placeholder-color);\n opacity: 0.6;\n }\n\n input {\n padding: var(--ox-filters-input-padding);\n }\n\n ox-select,\n input {\n border: none;\n border-bottom: var(--ox-filters-input-border);\n font: var(--ox-filters-input-font);\n color: var(--ox-filters-input-color);\n background-color: var(--ox-filters-input-background-color, transparent);\n }\n\n ox-select:focus,\n input:focus {\n outline: none;\n border-bottom: var(--ox-filters-input-focus-border);\n color: var(--ox-filters-input-focus-color);\n }\n\n ox-select {\n min-width: 100px;\n max-width: 170px;\n }\n\n ox-input-barcode {\n min-width: 150px;\n }\n\n ox-input-search {\n max-width: 150px;\n }\n\n input[type='number'] {\n max-width: 90px;\n }\n\n input[type*='date'],\n input[type*='time'],\n input[type='week'],\n input[type='month'] {\n max-width: 170px;\n }\n\n @media only screen and (max-width: 460px) {\n :host {\n --ox-filters-form-label-font: bold 13px var(--theme-font);\n --ox-filters-input-font: normal 16px var(--theme-font);\n }\n\n ox-input-barcode {\n max-width: unset;\n flex: 1;\n }\n\n ox-input-search {\n max-width: unset;\n }\n\n ox-select {\n max-width: unset;\n }\n\n ox-checkbox {\n max-width: unset;\n }\n\n input[type='number'] {\n max-width: unset;\n }\n\n input {\n flex: 1;\n }\n }\n`\n"]}
@@ -3,7 +3,9 @@ import '@operato/input/ox-select.js';
3
3
  import '@operato/popup/ox-popup-list.js';
4
4
  import '@operato/input/ox-input-search.js';
5
5
  import { LitElement, PropertyValues, TemplateResult } from 'lit';
6
- import { ColumnConfig, FilterOperator, FilterValue, GristConfig } from '../types';
6
+ import { PagePreferenceProvider } from '@operato/p13n';
7
+ import { FilterPreference } from '../types.js';
8
+ import { ColumnConfig, FilterOperator, FilterValue, GristConfig, PersonalGristPreference } from '../types';
7
9
  export type QueryFilterRangeValue = [from: number, to: number];
8
10
  export type QueryFilter = {
9
11
  name: string;
@@ -16,6 +18,9 @@ export declare class OxFiltersForm extends LitElement {
16
18
  withoutSearch: boolean;
17
19
  autofocus: boolean;
18
20
  empty: boolean;
21
+ personalConfigProvider?: PagePreferenceProvider;
22
+ personalConfig?: PersonalGristPreference;
23
+ personalFilters?: FilterPreference[];
19
24
  config: GristConfig;
20
25
  filterColumns: ColumnConfig[];
21
26
  searchColumns: ColumnConfig[];
@@ -24,8 +29,9 @@ export declare class OxFiltersForm extends LitElement {
24
29
  private objectValue?;
25
30
  connectedCallback(): void;
26
31
  buildDefaultValue(operator: FilterOperator, defaultValue: any): any;
27
- updated(changes: PropertyValues<this>): void;
32
+ updated(changes: PropertyValues<this>): Promise<void>;
28
33
  render(): TemplateResult;
34
+ applyUpdatedConfiguration(): void;
29
35
  getQueryFilters(): Promise<QueryFilter[]>;
30
36
  setInputValue(name: string, value: any): void;
31
37
  getInputValue(name: string): any;
@@ -24,6 +24,7 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
24
24
  const grist = this.closest('ox-grist');
25
25
  if (grist) {
26
26
  this.config = grist.compiledConfig;
27
+ this.personalConfigProvider = grist.personalConfigProvider;
27
28
  grist.addEventListener('config-change', (e) => {
28
29
  this.config = e.detail;
29
30
  });
@@ -76,38 +77,12 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
76
77
  return getDefaultValue(defaultValue, this);
77
78
  }
78
79
  }
79
- updated(changes) {
80
- var _a;
81
- if (changes.has('config')) {
82
- const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter);
83
- this.filterColumns = filters.filter((columnConfig) => {
84
- const filter = columnConfig.filter;
85
- return filter.operator !== 'search';
86
- });
87
- this.searchColumns = filters.filter(columnConfig => {
88
- const filter = columnConfig.filter;
89
- return filter.operator === 'search';
90
- });
91
- const grist = this.closest('ox-grist');
92
- this.value = ((grist === null || grist === void 0 ? void 0 : grist.filters) || []).map(filter => {
93
- return {
94
- ...filter,
95
- value: this.buildDefaultValue(filter.operator, filter.value)
96
- };
97
- });
98
- this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0;
99
- this.autoUpdateTargetsOnChange = {};
100
- (_a = this.filterColumns) === null || _a === void 0 ? void 0 : _a.filter(({ filter }) => {
101
- return typeof filter == 'object' && filter.boundTo && filter.boundTo.length > 0;
102
- }).map(({ name, filter }) => {
103
- const boundTo = filter.boundTo;
104
- boundTo.forEach(to => {
105
- const origin = this.autoUpdateTargetsOnChange[to] || [];
106
- if (name && !origin.includes(name)) {
107
- this.autoUpdateTargetsOnChange[to] = [...origin, name];
108
- }
109
- });
110
- });
80
+ async updated(changes) {
81
+ if (changes.has('personalConfigProvider') && this.personalConfigProvider) {
82
+ this.personalConfig = await this.personalConfigProvider.load();
83
+ }
84
+ else if (changes.has('config') || changes.has('personalConfig')) {
85
+ this.applyUpdatedConfiguration();
111
86
  }
112
87
  }
113
88
  render() {
@@ -124,15 +99,17 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
124
99
  grist && grist.fetch();
125
100
  }}
126
101
  >
127
- ${this.searchColumns.length === 0 || this.withoutSearch
128
- ? html ``
129
- : html `
130
- <ox-input-search name="search" .value=${searchValue} ?autofocus=${this.autofocus}></ox-input-search>
131
- `}
132
- ${this.filterColumns.map((column) => {
102
+ ${this.filterColumns
103
+ .filter(column => !column.filter.hidden)
104
+ .map((column) => {
133
105
  var _a, _b, _c;
134
106
  const { name, header, label, filter } = column;
135
107
  const type = filter.type;
108
+ if (type == 'search') {
109
+ return html `
110
+ <ox-input-search name="search" .value=${searchValue} ?autofocus=${this.autofocus}></ox-input-search>
111
+ `;
112
+ }
136
113
  const operator = filter.operator;
137
114
  const filterLabel = filter.label;
138
115
  const labelText = filterLabel !== undefined
@@ -152,17 +129,17 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
152
129
  ? renderer(column, value, this)
153
130
  : type !== 'select' && labelText
154
131
  ? html `<label filter-title ?between=${operator === 'between'}
155
- ><span>${labelText}</span> ${renderer(column, value, this)}
156
- </label> `
132
+ ><span>${labelText}</span> ${renderer(column, value, this)}
133
+ </label> `
157
134
  : type !== 'select' && !labelText
158
135
  ? renderer(column, value, this)
159
136
  : operator === 'in'
160
137
  ? html `
161
- <ox-select
162
- name=${name}
163
- placeholder=${labelText}
164
- .value=${value}
165
- @change=${(e) => {
138
+ <ox-select
139
+ name=${name}
140
+ placeholder=${labelText}
141
+ .value=${value}
142
+ @change=${(e) => {
166
143
  var _a;
167
144
  return (_a = e.target) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new CustomEvent('filter-change', {
168
145
  detail: {
@@ -172,18 +149,18 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
172
149
  }
173
150
  }));
174
151
  }}
175
- >
176
- <ox-popup-list multiple attr-selected="checked" with-search>
177
- ${renderer(column, value, this)}
178
- </ox-popup-list>
179
- </ox-select>
180
- `
152
+ >
153
+ <ox-popup-list multiple attr-selected="checked" with-search>
154
+ ${renderer(column, value, this)}
155
+ </ox-popup-list>
156
+ </ox-select>
157
+ `
181
158
  : html `
182
- <ox-select
183
- name=${name}
184
- placeholder=${labelText}
185
- .value=${value}
186
- @change=${(e) => {
159
+ <ox-select
160
+ name=${name}
161
+ placeholder=${labelText}
162
+ .value=${value}
163
+ @change=${(e) => {
187
164
  var _a;
188
165
  return (_a = e.target) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new CustomEvent('filter-change', {
189
166
  detail: {
@@ -193,14 +170,92 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
193
170
  }
194
171
  }));
195
172
  }}
196
- >
197
- <ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>
198
- </ox-select>
199
- `;
173
+ >
174
+ <ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>
175
+ </ox-select>
176
+ `;
200
177
  })}
201
178
  </form>
179
+ <slot name="setting"></slot>
202
180
  `;
203
181
  }
182
+ applyUpdatedConfiguration() {
183
+ var _a;
184
+ const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter);
185
+ this.filterColumns = filters.filter((columnConfig) => {
186
+ const filter = columnConfig.filter;
187
+ return filter.operator !== 'search';
188
+ });
189
+ this.searchColumns = filters.filter(columnConfig => {
190
+ const filter = columnConfig.filter;
191
+ return filter.operator === 'search';
192
+ });
193
+ if (this.searchColumns.length > 0) {
194
+ this.filterColumns.unshift({ name: 'search', filter: { type: 'search' } });
195
+ }
196
+ if (!this.personalConfig) {
197
+ this.personalFilters = this.filterColumns.map(column => {
198
+ return { name: column.name };
199
+ });
200
+ }
201
+ else {
202
+ const { filters: personalFilters = [] } = this.personalConfig;
203
+ if (personalFilters) {
204
+ const xfilters = this.filterColumns.map(column => {
205
+ return personalFilters.find(pFilter => pFilter.name == column.name) || { name: column.name };
206
+ });
207
+ function reorderList(a, b) {
208
+ // 결과 배열 초기화, a 배열 길이만큼 undefined로 채움
209
+ const result = new Array(a.length);
210
+ // b 배열에 없는 아이템은 원래 위치로 채움
211
+ a.forEach((item, index) => {
212
+ if (!item.name || !b.find(bi => bi.name == item.name)) {
213
+ result[index] = item;
214
+ }
215
+ });
216
+ b.forEach(item => {
217
+ const ai = a.find(ai => ai.name == item.name);
218
+ if (ai) {
219
+ result[result.findIndex(slot => slot === undefined)] = ai;
220
+ }
221
+ });
222
+ return result;
223
+ }
224
+ // 배열 재정렬 실행
225
+ this.personalFilters = reorderList(xfilters, personalFilters);
226
+ this.filterColumns = this.personalFilters
227
+ .map(filter => {
228
+ const column = this.filterColumns.find(column => column.name == filter.name);
229
+ if (column === null || column === void 0 ? void 0 : column.filter) {
230
+ ;
231
+ column.filter.hidden = filter.hidden;
232
+ }
233
+ return column;
234
+ })
235
+ .filter(Boolean);
236
+ }
237
+ }
238
+ const grist = this.closest('ox-grist');
239
+ this.value = ((grist === null || grist === void 0 ? void 0 : grist.filters) || []).map(filter => {
240
+ return {
241
+ ...filter,
242
+ value: this.buildDefaultValue(filter.operator, filter.value)
243
+ };
244
+ });
245
+ this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0;
246
+ this.autoUpdateTargetsOnChange = {};
247
+ (_a = this.filterColumns) === null || _a === void 0 ? void 0 : _a.filter(({ filter }) => {
248
+ return typeof filter == 'object' && filter.boundTo && filter.boundTo.length > 0;
249
+ }).map(({ name, filter }) => {
250
+ const boundTo = filter.boundTo;
251
+ boundTo.forEach(to => {
252
+ const origin = this.autoUpdateTargetsOnChange[to] || [];
253
+ if (name && !origin.includes(name)) {
254
+ this.autoUpdateTargetsOnChange[to] = [...origin, name];
255
+ }
256
+ });
257
+ });
258
+ }
204
259
  async getQueryFilters() {
205
260
  var _a;
206
261
  const form = await this.form;
@@ -209,6 +264,7 @@ let OxFiltersForm = class OxFiltersForm extends LitElement {
209
264
  const formData = new FormData(form);
210
265
  const search = (_a = formData.get('search')) === null || _a === void 0 ? void 0 : _a.toString();
211
266
  var filters = this.filterColumns
267
+ .filter(column => column.name !== 'search' && !column.filter.hidden)
212
268
  .map((column) => {
213
269
  const { name, type, filter } = column;
214
270
  const operator = filter.operator;
@@ -320,8 +376,9 @@ OxFiltersForm.styles = [
320
376
  }
321
377
 
322
378
  @media only screen and (max-width: 460px) {
323
- label[between] {
324
- display: block;
379
+ form {
380
+ flex-direction: column;
381
+ flex-flow: column;
325
382
  }
326
383
  }
327
384
  `
@@ -338,6 +395,15 @@ __decorate([
338
395
  __decorate([
339
396
  property({ type: Boolean, attribute: 'empty', reflect: true })
340
397
  ], OxFiltersForm.prototype, "empty", void 0);
398
+ __decorate([
399
+ state()
400
+ ], OxFiltersForm.prototype, "personalConfigProvider", void 0);
401
+ __decorate([
402
+ state()
403
+ ], OxFiltersForm.prototype, "personalConfig", void 0);
404
+ __decorate([
405
+ state()
406
+ ], OxFiltersForm.prototype, "personalFilters", void 0);
341
407
  __decorate([
342
408
  state()
343
409
  ], OxFiltersForm.prototype, "config", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"filters-form.js","sourceRoot":"","sources":["../../../src/filters/filters-form.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/input/ox-checkbox.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/popup/ox-popup-list.js'\nimport '@operato/input/ox-input-search.js'\n\nimport { css, html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { customElement, property, queryAsync, state } from 'lit/decorators.js'\n\nimport { getDefaultValue } from '@operato/time-calculator'\n\nimport { FilterConfigObject } from '..'\nimport { DataGrist } from '../data-grist'\nimport { ColumnConfig, FilterOperator, FilterValue, GristConfig } from '../types'\nimport { FilterStyles } from './filter-styles'\nimport { getFilterRenderer } from './registry'\n\nexport type QueryFilterRangeValue = [from: number, to: number]\n\nexport type QueryFilter = {\n name: string\n operator: FilterOperator\n value: any\n}\n\n@customElement('ox-filters-form')\nexport class OxFiltersForm extends LitElement {\n static styles = [\n FilterStyles,\n css`\n :host {\n display: flex;\n }\n\n form {\n flex: 1;\n\n display: flex;\n flex-flow: row wrap;\n gap: var(--ox-filters-form-gap);\n }\n\n form > * {\n display: flex;\n align-items: center;\n gap: var(--input-intra-gap, 7px);\n }\n\n label span {\n display: block;\n }\n\n @media only screen and (max-width: 460px) {\n label[between] {\n display: block;\n }\n }\n `\n ]\n\n @property({ type: Array }) value: FilterValue[] = []\n @property({ type: Boolean, attribute: 'without-search' }) withoutSearch: boolean = false\n @property({ type: Boolean, attribute: 'autofocus' }) autofocus: boolean = true\n @property({ type: Boolean, attribute: 'empty', reflect: true }) empty: boolean = true\n\n @state() config!: GristConfig\n @state() filterColumns: ColumnConfig[] = []\n @state() searchColumns: ColumnConfig[] = []\n\n @queryAsync('form') form!: HTMLFormElement\n\n private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}\n private objectValue?: object\n\n connectedCallback(): void {\n super.connectedCallback()\n\n const grist = this.closest('ox-grist') as DataGrist\n\n if (grist) {\n this.config = grist.compiledConfig\n\n grist.addEventListener('config-change', (e: Event) => {\n this.config = (e as CustomEvent).detail\n })\n\n grist.addEventListener('fetch-params-change', (e: Event) => {\n const { filters, from } = (e as CustomEvent).detail || {}\n if (from === 'filters-form') {\n return\n }\n\n this.value = filters\n })\n\n this.renderRoot.addEventListener('change', async (e: Event) => {\n const { target, detail: value } = e as CustomEvent\n const name = (target as HTMLInputElement).name\n const { filter } = this.filterColumns.find(filter => filter.name == name) || {}\n\n if (this.autoUpdateTargetsOnChange[name]) {\n /* 일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함. */\n ;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {\n const target = this.renderRoot.querySelector(`[name='${name}']`)\n if (target) {\n ;(target as HTMLInputElement).value = ''\n }\n })\n\n await this.updateObjectValues()\n this.requestUpdate()\n }\n\n const onchange = typeof filter == 'object' ? filter.onchange : null\n const keepGoing = onchange ? await onchange.call(null, value ?? (target as HTMLInputElement).value, this) : true\n\n keepGoing &&\n this.dispatchEvent(\n new CustomEvent('fetch-params-change', {\n bubbles: true,\n composed: true,\n detail: {\n filters: await this.getQueryFilters(),\n from: 'filters-form'\n }\n })\n )\n })\n }\n }\n\n buildDefaultValue(operator: FilterOperator, defaultValue: any) {\n if (defaultValue === undefined) {\n return\n }\n if (operator == 'between') {\n return (defaultValue as Array<any>).map(v => getDefaultValue(v, this))\n } else {\n return getDefaultValue(defaultValue, this)\n }\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('config')) {\n const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter)\n this.filterColumns = filters.filter((columnConfig: ColumnConfig) => {\n const filter = columnConfig.filter as FilterConfigObject\n return filter!.operator !== 'search'\n })\n this.searchColumns = filters.filter(columnConfig => {\n const filter = columnConfig.filter as FilterConfigObject\n return filter!.operator === 'search'\n })\n\n const grist = this.closest('ox-grist') as DataGrist\n\n this.value = (grist?.filters || []).map(filter => {\n return {\n ...filter,\n value: this.buildDefaultValue(filter!.operator, filter!.value)\n }\n })\n\n this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0\n\n this.autoUpdateTargetsOnChange = {}\n this.filterColumns\n ?.filter(({ filter }) => {\n return typeof filter == 'object' && filter.boundTo && filter.boundTo.length > 0\n })\n .map(({ name, filter }) => {\n const boundTo = (filter as FilterConfigObject).boundTo\n\n boundTo!.forEach(to => {\n const origin = this.autoUpdateTargetsOnChange[to] || []\n if (name && !origin.includes(name)) {\n this.autoUpdateTargetsOnChange[to] = [...origin, name]\n }\n })\n })\n }\n }\n\n render(): TemplateResult {\n const searchValue =\n (this.value?.find(filter => filter.operator === 'search')?.value as string)?.match(/^\\%(.*)\\%$/)?.[1] || ''\n\n return this.empty\n ? html``\n : html`\n <form\n @submit=${(e: Event) => {\n e.stopPropagation()\n e.preventDefault()\n\n const grist = this.closest('ox-grist') as DataGrist\n\n grist && grist.fetch()\n }}\n >\n ${this.searchColumns.length === 0 || this.withoutSearch\n ? html``\n : html`\n <ox-input-search name=\"search\" .value=${searchValue} ?autofocus=${this.autofocus}></ox-input-search>\n `}\n ${this.filterColumns.map((column: ColumnConfig) => {\n const { name, header, label, filter } = column\n\n const type = (filter as FilterConfigObject).type\n const operator = (filter as FilterConfigObject).operator\n const filterLabel = (filter as FilterConfigObject).label\n\n const labelText =\n filterLabel !== undefined\n ? filterLabel\n : typeof label === 'object' && label.renderer\n ? label.renderer(column)\n : header.renderer(column) || name\n\n const idx = operator === 'between' ? 1 : 0\n const renderer = getFilterRenderer(\n operator === 'like' || operator === 'i_like' || operator === 'i_nlike' || operator === 'nlike'\n ? 'text'\n : type\n )[idx]\n const value =\n this.value?.find(filter => filter.name == name)?.value ??\n this.buildDefaultValue(operator!, (filter as FilterConfigObject)?.value)\n\n if (!renderer) {\n return html``\n }\n\n return type === 'boolean' || type === 'checkbox'\n ? renderer(column, value, this)\n : type !== 'select' && labelText\n ? html`<label filter-title ?between=${operator === 'between'}\n ><span>${labelText}</span> ${renderer(column, value, this)}\n </label> `\n : type !== 'select' && !labelText\n ? renderer(column, value, this)\n : operator === 'in'\n ? html`\n <ox-select\n name=${name}\n placeholder=${labelText}\n .value=${value}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list multiple attr-selected=\"checked\" with-search>\n ${renderer(column, value, this)}\n </ox-popup-list>\n </ox-select>\n `\n : html`\n <ox-select\n name=${name}\n placeholder=${labelText}\n .value=${value}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>\n </ox-select>\n `\n })}\n </form>\n `\n }\n\n async getQueryFilters(): Promise<QueryFilter[]> {\n const form = await this.form\n if (!form) return []\n\n const formData = new FormData(form)\n const search: string | undefined = formData.get('search')?.toString()\n\n var filters = this.filterColumns\n .map((column: ColumnConfig) => {\n const { name, type, filter } = column\n const operator = (filter as FilterConfigObject).operator\n\n var value = formData.getAll(name)\n if (value.length == 0) {\n return\n }\n\n if (-1 === value.findIndex(v => v !== '')) {\n return\n }\n\n const filterValue = value.map(v => {\n const value = v.toString()\n\n /* TODO registry에서 타입별로 parsing 방법을 지정할 수 있도록 해야한다. */\n switch (type) {\n case 'integer':\n case 'float':\n case 'number':\n case 'progress':\n case 'checkbox':\n case 'boolean':\n return !value ? undefined : JSON.parse(value)\n default:\n return value\n }\n })\n\n return {\n name,\n operator,\n value: filterValue.length === 1 ? filterValue[0] : filterValue\n }\n })\n .filter(result => result !== undefined) as QueryFilter[]\n\n if (search) {\n filters = filters.concat(\n this.searchColumns.map((column: ColumnConfig) => {\n const { name } = column\n\n return {\n name,\n operator: 'search',\n value: `%${search}%`\n }\n })\n )\n }\n\n return filters\n }\n\n public setInputValue(name: string, value: any) {\n const input = this.renderRoot.querySelector(`form [name=\"${name}\"]`) as HTMLInputElement\n if (input) {\n input.value = value\n input.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n public getInputValue(name: string): any {\n const input = this.renderRoot.querySelector(`form [name=\"${name}\"]`) as HTMLInputElement\n return input?.value\n }\n\n private async updateObjectValues() {\n const form = await this.form\n if (!form) return []\n\n const formData = new FormData(form)\n\n const object = {} as any\n formData.forEach((value, key) => {\n const prev = object[key]\n\n if (key in object) {\n object[key] = prev instanceof Array ? [...prev, value] : [prev, value]\n } else {\n object[key] = value\n }\n })\n\n this.objectValue = object\n }\n\n public getFormObjectValue() {\n return this.objectValue\n }\n\n reset() {\n this.form\n .then((form: HTMLFormElement) => {\n form.reset()\n })\n .catch((error: any) => {\n console.error('Error resetting the form:', error)\n })\n }\n}\n"]}
1
+ {"version":3,"file":"filters-form.js","sourceRoot":"","sources":["../../../src/filters/filters-form.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/input/ox-checkbox.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/popup/ox-popup-list.js'\nimport '@operato/input/ox-input-search.js'\n\nimport { css, html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { customElement, property, queryAsync, state } from 'lit/decorators.js'\n\nimport { PagePreferenceProvider } from '@operato/p13n'\nimport { getDefaultValue } from '@operato/time-calculator'\n\nimport { FilterConfigObject, FilterPreference } from '../types.js'\nimport { DataGrist } from '../data-grist'\nimport { ColumnConfig, FilterOperator, FilterValue, GristConfig, PersonalGristPreference } from '../types'\nimport { FilterStyles } from './filter-styles'\nimport { getFilterRenderer } from './registry'\n\nexport type QueryFilterRangeValue = [from: number, to: number]\n\nexport type QueryFilter = {\n name: string\n operator: FilterOperator\n value: any\n}\n\n@customElement('ox-filters-form')\nexport class OxFiltersForm extends LitElement {\n static styles = [\n FilterStyles,\n css`\n :host {\n display: flex;\n }\n\n form {\n flex: 1;\n\n display: flex;\n flex-flow: row wrap;\n gap: var(--ox-filters-form-gap);\n }\n\n form > * {\n display: flex;\n align-items: center;\n gap: var(--input-intra-gap, 7px);\n }\n\n label span {\n display: block;\n }\n\n @media only screen and (max-width: 460px) {\n form {\n flex-direction: column;\n flex-flow: column;\n }\n }\n `\n ]\n\n @property({ type: Array }) value: FilterValue[] = []\n @property({ type: Boolean, attribute: 'without-search' }) withoutSearch: boolean = false\n @property({ type: Boolean, attribute: 'autofocus' }) autofocus: boolean = true\n @property({ type: Boolean, attribute: 'empty', reflect: true }) empty: boolean = true\n\n @state() personalConfigProvider?: PagePreferenceProvider\n @state() personalConfig?: PersonalGristPreference\n @state() personalFilters?: FilterPreference[]\n\n @state() config!: GristConfig\n @state() filterColumns: ColumnConfig[] = []\n @state() searchColumns: ColumnConfig[] = []\n\n @queryAsync('form') form!: HTMLFormElement\n\n private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}\n private objectValue?: object\n\n connectedCallback(): void {\n super.connectedCallback()\n\n const grist = this.closest('ox-grist') as DataGrist\n\n if (grist) {\n this.config = grist.compiledConfig\n this.personalConfigProvider = grist.personalConfigProvider\n\n grist.addEventListener('config-change', (e: Event) => {\n this.config = (e as CustomEvent).detail\n })\n\n grist.addEventListener('fetch-params-change', (e: Event) => {\n const { filters, from } = (e as CustomEvent).detail || {}\n if (from === 'filters-form') {\n return\n }\n\n this.value = filters\n })\n\n this.renderRoot.addEventListener('change', async (e: Event) => {\n const { target, detail: value } = e as CustomEvent\n const name = (target as HTMLInputElement).name\n const { filter } = this.filterColumns.find(filter => filter.name == name) || {}\n\n if (this.autoUpdateTargetsOnChange[name]) {\n /* 일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함. */\n ;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {\n const target = this.renderRoot.querySelector(`[name='${name}']`)\n if (target) {\n ;(target as HTMLInputElement).value = ''\n }\n })\n\n await this.updateObjectValues()\n this.requestUpdate()\n }\n\n const onchange = typeof filter == 'object' ? filter.onchange : null\n const keepGoing = onchange ? await onchange.call(null, value ?? (target as HTMLInputElement).value, this) : true\n\n keepGoing &&\n this.dispatchEvent(\n new CustomEvent('fetch-params-change', {\n bubbles: true,\n composed: true,\n detail: {\n filters: await this.getQueryFilters(),\n from: 'filters-form'\n }\n })\n )\n })\n }\n }\n\n buildDefaultValue(operator: FilterOperator, defaultValue: any) {\n if (defaultValue === undefined) {\n return\n }\n if (operator == 'between') {\n return (defaultValue as Array<any>).map(v => getDefaultValue(v, this))\n } else {\n return getDefaultValue(defaultValue, this)\n }\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('personalConfigProvider') && this.personalConfigProvider) {\n this.personalConfig = await this.personalConfigProvider.load()\n } else if (changes.has('config') || changes.has('personalConfig')) {\n this.applyUpdatedConfiguration()\n }\n }\n\n render(): TemplateResult {\n const searchValue =\n (this.value?.find(filter => filter.operator === 'search')?.value as string)?.match(/^\\%(.*)\\%$/)?.[1] || ''\n\n return this.empty\n ? html``\n : html`\n <form\n @submit=${(e: Event) => {\n e.stopPropagation()\n e.preventDefault()\n\n const grist = this.closest('ox-grist') as DataGrist\n\n grist && grist.fetch()\n }}\n >\n ${this.filterColumns\n .filter(column => !(column.filter as FilterConfigObject).hidden)\n .map((column: ColumnConfig) => {\n const { name, header, label, filter } = column\n\n const type = (filter as FilterConfigObject).type\n\n if (type == 'search') {\n return html`\n <ox-input-search name=\"search\" .value=${searchValue} ?autofocus=${this.autofocus}></ox-input-search>\n `\n }\n\n const operator = (filter as FilterConfigObject).operator\n const filterLabel = (filter as FilterConfigObject).label\n\n const labelText =\n filterLabel !== undefined\n ? filterLabel\n : typeof label === 'object' && label.renderer\n ? label.renderer(column)\n : header.renderer(column) || name\n\n const idx = operator === 'between' ? 1 : 0\n const renderer = getFilterRenderer(\n operator === 'like' || operator === 'i_like' || operator === 'i_nlike' || operator === 'nlike'\n ? 'text'\n : type\n )[idx]\n const value =\n this.value?.find(filter => filter.name == name)?.value ??\n this.buildDefaultValue(operator!, (filter as FilterConfigObject)?.value)\n\n if (!renderer) {\n return html``\n }\n\n return type === 'boolean' || type === 'checkbox'\n ? renderer(column, value, this)\n : type !== 'select' && labelText\n ? html`<label filter-title ?between=${operator === 'between'}\n ><span>${labelText}</span> ${renderer(column, value, this)}\n </label> `\n : type !== 'select' && !labelText\n ? renderer(column, value, this)\n : operator === 'in'\n ? html`\n <ox-select\n name=${name}\n placeholder=${labelText}\n .value=${value}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list multiple attr-selected=\"checked\" with-search>\n ${renderer(column, value, this)}\n </ox-popup-list>\n </ox-select>\n `\n : html`\n <ox-select\n name=${name}\n placeholder=${labelText}\n .value=${value}\n @change=${(e: CustomEvent) =>\n e.target?.dispatchEvent(\n new CustomEvent('filter-change', {\n detail: {\n name,\n operator,\n value: e.detail\n }\n })\n )}\n >\n <ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>\n </ox-select>\n `\n })}\n </form>\n <slot name=\"setting\"></slot>\n `\n }\n\n applyUpdatedConfiguration() {\n const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter)\n this.filterColumns = filters.filter((columnConfig: ColumnConfig) => {\n const filter = columnConfig.filter as FilterConfigObject\n return filter!.operator !== 'search'\n })\n this.searchColumns = filters.filter(columnConfig => {\n const filter = columnConfig.filter as FilterConfigObject\n return filter!.operator === 'search'\n })\n\n if (this.searchColumns.length > 0) {\n this.filterColumns.unshift({ name: 'search', filter: { type: 'search' } } as any)\n }\n\n if (!this.personalConfig) {\n this.personalFilters = this.filterColumns.map(column => {\n return { name: column.name }\n })\n } else {\n const { filters: personalFilters = [] } = this.personalConfig\n\n if (personalFilters) {\n const xfilters = this.filterColumns.map(column => {\n return personalFilters.find(pFilter => pFilter.name == column.name) || { name: column.name }\n })\n\n function reorderList(a: FilterPreference[], b: FilterPreference[]): FilterPreference[] {\n // 결과 배열 초기화, a 배열 길이만큼 undefined로 채움\n const result = new Array(a.length)\n\n // b 배열에 없는 아이템은 원래 위치로 채움\n a.forEach((item, index) => {\n if (!item.name || !b.find(bi => bi.name == item.name)) {\n result[index] = item\n }\n })\n\n b.forEach(item => {\n const ai = a.find(ai => ai.name == item.name)\n if (ai) {\n result[result.findIndex(slot => slot === undefined)] = ai\n }\n })\n\n return result\n }\n\n // 배열 재정렬 실행\n this.personalFilters = reorderList(xfilters as any, personalFilters as any) as FilterPreference[]\n\n this.filterColumns = this.personalFilters\n .map(filter => {\n const column = this.filterColumns.find(column => column.name == filter.name)\n if (column?.filter) {\n ;(column.filter as FilterConfigObject)!.hidden = filter.hidden\n }\n return column\n })\n .filter(Boolean) as ColumnConfig[]\n }\n }\n\n const grist = this.closest('ox-grist') as DataGrist\n\n this.value = (grist?.filters || []).map(filter => {\n return {\n ...filter,\n value: this.buildDefaultValue(filter!.operator, filter!.value)\n }\n })\n\n this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0\n\n this.autoUpdateTargetsOnChange = {}\n this.filterColumns\n ?.filter(({ filter }) => {\n return typeof filter == 'object' && filter.boundTo && filter.boundTo.length > 0\n })\n .map(({ name, filter }) => {\n const boundTo = (filter as FilterConfigObject).boundTo\n\n boundTo!.forEach(to => {\n const origin = this.autoUpdateTargetsOnChange[to] || []\n if (name && !origin.includes(name)) {\n this.autoUpdateTargetsOnChange[to] = [...origin, name]\n }\n })\n })\n }\n\n async getQueryFilters(): Promise<QueryFilter[]> {\n const form = await this.form\n if (!form) return []\n\n const formData = new FormData(form)\n const search: string | undefined = formData.get('search')?.toString()\n\n var filters = this.filterColumns\n .filter(column => column.name !== 'search' && !(column.filter as FilterConfigObject)!.hidden)\n .map((column: ColumnConfig) => {\n const { name, type, filter } = column\n const operator = (filter as FilterConfigObject).operator\n\n var value = formData.getAll(name)\n if (value.length == 0) {\n return\n }\n\n if (-1 === value.findIndex(v => v !== '')) {\n return\n }\n\n const filterValue = value.map(v => {\n const value = v.toString()\n\n /* TODO registry에서 타입별로 parsing 방법을 지정할 수 있도록 해야한다. */\n switch (type) {\n case 'integer':\n case 'float':\n case 'number':\n case 'progress':\n case 'checkbox':\n case 'boolean':\n return !value ? undefined : JSON.parse(value)\n default:\n return value\n }\n })\n\n return {\n name,\n operator,\n value: filterValue.length === 1 ? filterValue[0] : filterValue\n }\n })\n .filter(result => result !== undefined) as QueryFilter[]\n\n if (search) {\n filters = filters.concat(\n this.searchColumns.map((column: ColumnConfig) => {\n const { name } = column\n\n return {\n name,\n operator: 'search',\n value: `%${search}%`\n }\n })\n )\n }\n\n return filters\n }\n\n public setInputValue(name: string, value: any) {\n const input = this.renderRoot.querySelector(`form [name=\"${name}\"]`) as HTMLInputElement\n if (input) {\n input.value = value\n input.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n public getInputValue(name: string): any {\n const input = this.renderRoot.querySelector(`form [name=\"${name}\"]`) as HTMLInputElement\n return input?.value\n }\n\n private async updateObjectValues() {\n const form = await this.form\n if (!form) return []\n\n const formData = new FormData(form)\n\n const object = {} as any\n formData.forEach((value, key) => {\n const prev = object[key]\n\n if (key in object) {\n object[key] = prev instanceof Array ? [...prev, value] : [prev, value]\n } else {\n object[key] = value\n }\n })\n\n this.objectValue = object\n }\n\n public getFormObjectValue() {\n return this.objectValue\n }\n\n reset() {\n this.form\n .then((form: HTMLFormElement) => {\n form.reset()\n })\n .catch((error: any) => {\n console.error('Error resetting the form:', error)\n })\n }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import '@material/web/button/outlined-button.js';
2
+ import { LitElement } from 'lit';
3
+ export declare class OxGristFilterPersonalizer extends LitElement {
4
+ static styles: import("lit").CSSResult[];
5
+ debug: boolean;
6
+ private preference?;
7
+ render(): import("lit-html").TemplateResult<1>;
8
+ }
@@ -0,0 +1,177 @@
1
+ import { __decorate } from "tslib";
2
+ import '@material/web/button/outlined-button.js';
3
+ import { css, html, LitElement } from 'lit';
4
+ import { customElement, property, state } from 'lit/decorators.js';
5
+ import { i18next } from '@operato/i18n';
6
+ import { OxPopupList } from '@operato/popup';
7
+ let OxGristFilterPersonalizer = class OxGristFilterPersonalizer extends LitElement {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.debug = false;
11
+ }
12
+ render() {
13
+ return html `
14
+ <md-icon
15
+ @click=${async (e) => {
16
+ var _a;
17
+ const form = this.closest('ox-filters-form');
18
+ const { filterColumns, personalFilters = [] } = form;
19
+ const queryFilters = await form.getQueryFilters();
20
+ this.preference = {
21
+ filters: (personalFilters.map((filter) => {
22
+ var _a;
23
+ const originFilterColumn = filter.name == 'search'
24
+ ? { filter: { name: 'search' } }
25
+ : filterColumns.find(f => f.name == filter.name);
26
+ if (!originFilterColumn) {
27
+ /* 원래 filters 설정에 있는 것들 만을 유지한다. */
28
+ return;
29
+ }
30
+ const { value } = originFilterColumn.filter;
31
+ return {
32
+ name: filter.name,
33
+ hidden: filter.hidden,
34
+ /* 만약, filters에 기본값이 이미 설정되어 있다면, 그대로 유지한다. */
35
+ value: value !== null && value !== void 0 ? value : (_a = queryFilters.find(f => f.name == filter.name)) === null || _a === void 0 ? void 0 : _a.value
36
+ };
37
+ }) || []).filter(Boolean)
38
+ };
39
+ const template = html `
40
+ <div class="personalizer-header" slot="header">
41
+ <md-icon
42
+ style="margin-left: auto;"
43
+ @click=${async (e) => {
44
+ if (form.personalConfigProvider) {
45
+ form.personalConfig = await form.personalConfigProvider.save(this.preference);
46
+ }
47
+ popup.close();
48
+ }}
49
+ title=${String(i18next.t('button.save'))}
50
+ >keep</md-icon
51
+ ><md-icon
52
+ @click=${async (e) => {
53
+ if (form.personalConfigProvider) {
54
+ form.personalConfig = this.preference = {};
55
+ await form.personalConfigProvider.reset();
56
+ }
57
+ popup.close();
58
+ }}
59
+ title=${String(i18next.t('button.delete'))}
60
+ >keep_off</md-icon
61
+ ><md-icon @click=${async (e) => popup.close()} title=${String(i18next.t('button.close'))}
62
+ >close</md-icon
63
+ >
64
+ </div>
65
+
66
+ ${(_a = this.preference) === null || _a === void 0 ? void 0 : _a.filters.map(filter => html `
67
+ <ox-checkbox label="checkbox" ?checked=${!filter.hidden} value=${filter.name} option
68
+ >${filter.name}<span style="position: absolute; right: 10px; cursor: move;" handle
69
+ >☰</span
70
+ ></ox-checkbox
71
+ >
72
+ `)}
73
+ `;
74
+ const popup = OxPopupList.open({
75
+ template,
76
+ multiple: true,
77
+ sortable: true,
78
+ debug: this.debug,
79
+ attrSelected: 'checked',
80
+ top: e.pageY,
81
+ left: e.pageX,
82
+ styles: css `
83
+ :host {
84
+ width: 240px;
85
+ max-height: 300px;
86
+ overflow: auto;
87
+ }
88
+
89
+ ::slotted(.personalizer-header) {
90
+ --md-icon-size: 1.4em;
91
+
92
+ display: flex;
93
+ flex-direction: row;
94
+ align-items: center;
95
+ text-transform: capitalize;
96
+ box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3);
97
+ }
98
+
99
+ ::slotted([option]) {
100
+ position: relative;
101
+ user-select: none;
102
+ }
103
+ `
104
+ });
105
+ popup.onselect = (e) => {
106
+ var _a;
107
+ const selected = e.detail;
108
+ const pconfig = { ...form.personalConfig };
109
+ const pfilters = (_a = this.preference) === null || _a === void 0 ? void 0 : _a.filters;
110
+ pconfig.filters = pfilters.map(filter => {
111
+ return {
112
+ name: filter.name,
113
+ hidden: selected.indexOf(filter.name) == -1,
114
+ value: filter.value
115
+ };
116
+ });
117
+ form.personalConfig = this.preference = pconfig;
118
+ form.applyUpdatedConfiguration();
119
+ };
120
+ popup.addEventListener('sorted', (e) => {
121
+ var _a;
122
+ const sorted = e.detail;
123
+ const pconfig = { ...form.personalConfig };
124
+ const pfilters = (_a = this.preference) === null || _a === void 0 ? void 0 : _a.filters;
125
+ pconfig.filters = sorted
126
+ .map(element => {
127
+ const name = element.value;
128
+ return pfilters.find(filter => filter.name == name);
129
+ })
130
+ .filter(Boolean);
131
+ form.personalConfig = this.preference = pconfig;
132
+ form.applyUpdatedConfiguration();
133
+ });
134
+ }}
135
+ >settings<md-ripple></md-ripple
136
+ ></md-icon>
137
+ `;
138
+ }
139
+ };
140
+ OxGristFilterPersonalizer.styles = [
141
+ css `
142
+ md-icon {
143
+ --md-icon-size: 16px;
144
+ width: 36px;
145
+ height: 36px;
146
+ color: var(--md-sys-color-secondary-container);
147
+ cursor: pointer;
148
+
149
+ display: flex;
150
+ place-content: center;
151
+ place-items: center;
152
+ position: relative;
153
+
154
+ &:hover {
155
+ color: var(--md-sys-color-primary-container);
156
+ }
157
+ }
158
+
159
+ md-ripple {
160
+ border-radius: 50%;
161
+ inset: unset;
162
+ height: 36px;
163
+ width: 36px;
164
+ }
165
+ `
166
+ ];
167
+ __decorate([
168
+ property({ type: Boolean, attribute: true })
169
+ ], OxGristFilterPersonalizer.prototype, "debug", void 0);
170
+ __decorate([
171
+ state()
172
+ ], OxGristFilterPersonalizer.prototype, "preference", void 0);
173
+ OxGristFilterPersonalizer = __decorate([
174
+ customElement('ox-grist-filter-personalizer')
175
+ ], OxGristFilterPersonalizer);
176
+ export { OxGristFilterPersonalizer };
177
+ //# sourceMappingURL=ox-grist-filter-personalizer.js.map