@operato/data-grist 2.0.0-alpha.99 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +441 -0
- package/demo/data-grist-test.html +1 -1
- package/demo/index.html +1 -1
- package/dist/src/data-card/data-card-field.js +2 -2
- package/dist/src/data-card/data-card-field.js.map +1 -1
- package/dist/src/data-card/data-card-gutter-menu.js +5 -5
- package/dist/src/data-card/data-card-gutter-menu.js.map +1 -1
- package/dist/src/data-card/data-card-gutter.js +6 -6
- package/dist/src/data-card/data-card-gutter.js.map +1 -1
- package/dist/src/data-card/data-card.js +7 -9
- package/dist/src/data-card/data-card.js.map +1 -1
- package/dist/src/data-card/record-card.js +9 -10
- package/dist/src/data-card/record-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-accum-field.js +12 -5
- package/dist/src/data-grid/data-grid-accum-field.js.map +1 -1
- package/dist/src/data-grid/data-grid-body-style.js +12 -0
- package/dist/src/data-grid/data-grid-body-style.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +0 -1
- package/dist/src/data-grid/data-grid-body.js +14 -21
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-field.js +8 -2
- package/dist/src/data-grid/data-grid-field.js.map +1 -1
- package/dist/src/data-grid/data-grid-footer.js +4 -2
- package/dist/src/data-grid/data-grid-footer.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.js +9 -6
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.js +23 -1
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js +3 -0
- package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js.map +1 -1
- package/dist/src/data-grist.d.ts +10 -2
- package/dist/src/data-grist.js +71 -8
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/data-list-field.js +5 -5
- package/dist/src/data-list/data-list-field.js.map +1 -1
- package/dist/src/data-list/data-list-gutter.js +3 -3
- package/dist/src/data-list/data-list-gutter.js.map +1 -1
- package/dist/src/data-list/data-list.js +4 -4
- package/dist/src/data-list/data-list.js.map +1 -1
- package/dist/src/data-list/record-partial.js +9 -10
- package/dist/src/data-list/record-partial.js.map +1 -1
- package/dist/src/data-manipulator.d.ts +1 -1
- package/dist/src/data-manipulator.js +5 -5
- package/dist/src/data-manipulator.js.map +1 -1
- package/dist/src/data-report/data-report-field.js +2 -1
- package/dist/src/data-report/data-report-field.js.map +1 -1
- package/dist/src/data-report/data-report-header.js +2 -2
- package/dist/src/data-report/data-report-header.js.map +1 -1
- package/dist/src/editors/ox-grist-editor-select.js +37 -25
- package/dist/src/editors/ox-grist-editor-select.js.map +1 -1
- package/dist/src/editors/ox-input-tree.js +8 -8
- package/dist/src/editors/ox-input-tree.js.map +1 -1
- package/dist/src/filters/filter-input-barcode.js +1 -0
- package/dist/src/filters/filter-input-barcode.js.map +1 -1
- package/dist/src/filters/filter-select.js +30 -16
- package/dist/src/filters/filter-select.js.map +1 -1
- package/dist/src/filters/filter-styles.js +46 -31
- package/dist/src/filters/filter-styles.js.map +1 -1
- package/dist/src/filters/filters-form.d.ts +15 -4
- package/dist/src/filters/filters-form.js +205 -70
- package/dist/src/filters/filters-form.js.map +1 -1
- package/dist/src/gutters/gutter-dirty.js +2 -2
- package/dist/src/gutters/gutter-dirty.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/personalizer/index.d.ts +1 -0
- package/dist/src/personalizer/index.js +2 -0
- package/dist/src/personalizer/index.js.map +1 -0
- package/dist/src/personalizer/ox-grist-filter-personalizer.d.ts +8 -0
- package/dist/src/personalizer/ox-grist-filter-personalizer.js +177 -0
- package/dist/src/personalizer/ox-grist-filter-personalizer.js.map +1 -0
- package/dist/src/personalizer/ox-grist-personalizer.d.ts +8 -0
- package/dist/src/personalizer/ox-grist-personalizer.js +178 -0
- package/dist/src/personalizer/ox-grist-personalizer.js.map +1 -0
- package/dist/src/record-view/record-creator.js +2 -2
- package/dist/src/record-view/record-creator.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-select.js +34 -4
- package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-tree.js +8 -8
- package/dist/src/renderers/ox-grist-renderer-tree.js.map +1 -1
- package/dist/src/sorters/sorters-control.js +3 -3
- package/dist/src/sorters/sorters-control.js.map +1 -1
- package/dist/src/types.d.ts +41 -2
- package/dist/src/types.js.map +1 -1
- package/dist/stories/{accumulator.stories.d.ts → accumulator-format.stories.d.ts} +9 -0
- package/dist/stories/{accumulator.stories.js → accumulator-format.stories.js} +24 -12
- package/dist/stories/accumulator-format.stories.js.map +1 -0
- package/dist/stories/barcode-input-filter.stories.d.ts +5 -0
- package/dist/stories/barcode-input-filter.stories.js +29 -5
- package/dist/stories/barcode-input-filter.stories.js.map +1 -1
- package/dist/stories/bounded-select-filters.stories.d.ts +30 -0
- package/dist/stories/bounded-select-filters.stories.js +288 -0
- package/dist/stories/bounded-select-filters.stories.js.map +1 -0
- package/dist/stories/bounded-select-record.stories.d.ts +30 -0
- package/dist/stories/bounded-select-record.stories.js +291 -0
- package/dist/stories/bounded-select-record.stories.js.map +1 -0
- package/dist/stories/click-event.stories.d.ts +41 -0
- package/dist/stories/click-event.stories.js +234 -0
- package/dist/stories/click-event.stories.js.map +1 -0
- package/dist/stories/creatable-only-column.stories.d.ts +5 -0
- package/dist/stories/creatable-only-column.stories.js +46 -21
- package/dist/stories/creatable-only-column.stories.js.map +1 -1
- package/dist/stories/default-filters.stories.d.ts +5 -0
- package/dist/stories/default-filters.stories.js +84 -17
- package/dist/stories/default-filters.stories.js.map +1 -1
- package/dist/stories/dynamic-editable.stories.d.ts +5 -0
- package/dist/stories/dynamic-editable.stories.js +44 -21
- package/dist/stories/dynamic-editable.stories.js.map +1 -1
- package/dist/stories/empty-sorters.stories.d.ts +7 -1
- package/dist/stories/empty-sorters.stories.js +41 -17
- package/dist/stories/empty-sorters.stories.js.map +1 -1
- package/dist/stories/explicit-fetch.stories.d.ts +5 -0
- package/dist/stories/explicit-fetch.stories.js +40 -17
- package/dist/stories/explicit-fetch.stories.js.map +1 -1
- package/dist/stories/fixed-column.stories.d.ts +5 -0
- package/dist/stories/fixed-column.stories.js +53 -30
- package/dist/stories/fixed-column.stories.js.map +1 -1
- package/dist/stories/grid-setting.stories.d.ts +20 -4
- package/dist/stories/grid-setting.stories.js +96 -51
- package/dist/stories/grid-setting.stories.js.map +1 -1
- package/dist/stories/grist-modes.stories.d.ts +8 -2
- package/dist/stories/grist-modes.stories.js +58 -35
- package/dist/stories/grist-modes.stories.js.map +1 -1
- package/dist/stories/group-header.stories.d.ts +5 -0
- package/dist/stories/group-header.stories.js +53 -30
- package/dist/stories/group-header.stories.js.map +1 -1
- package/dist/stories/textarea.stories.d.ts +8 -2
- package/dist/stories/textarea.stories.js +37 -13
- package/dist/stories/textarea.stories.js.map +1 -1
- package/dist/stories/tree-column-with-checkbox.stories.d.ts +5 -0
- package/dist/stories/tree-column-with-checkbox.stories.js +44 -21
- package/dist/stories/tree-column-with-checkbox.stories.js.map +1 -1
- package/dist/stories/tree-column.stories.d.ts +5 -0
- package/dist/stories/tree-column.stories.js +44 -21
- package/dist/stories/tree-column.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/default-value/value-generator/date-generator.md +29 -0
- package/docs/default-value/value-generator/hour-time-generator.md +33 -0
- package/docs/default-value/value-generator/minute-time-generator.md +33 -0
- package/docs/default-value/value-generator/month-date-generator.md +2 -0
- package/docs/default-value/value-generator/now-generator.md +29 -0
- package/docs/default-value/value-generator/time-generator.md +31 -0
- package/docs/default-value/value-generator/today-generator.md +29 -0
- package/docs/default-value/value-generator/week-date-generator.md +31 -0
- package/docs/default-value/value-generator/year-date-generator.md +31 -0
- package/package.json +15 -10
- package/src/data-card/data-card-field.ts +2 -2
- package/src/data-card/data-card-gutter-menu.ts +5 -5
- package/src/data-card/data-card-gutter.ts +6 -6
- package/src/data-card/data-card.ts +7 -9
- package/src/data-card/record-card.ts +9 -10
- package/src/data-grid/data-grid-accum-field.ts +11 -5
- package/src/data-grid/data-grid-body-style.ts +12 -0
- package/src/data-grid/data-grid-body.ts +16 -29
- package/src/data-grid/data-grid-field.ts +7 -2
- package/src/data-grid/data-grid-footer.ts +4 -2
- package/src/data-grid/data-grid-header.ts +8 -6
- package/src/data-grid/data-grid.ts +23 -1
- package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +4 -0
- package/src/data-grist.ts +88 -8
- package/src/data-list/data-list-field.ts +5 -5
- package/src/data-list/data-list-gutter.ts +3 -3
- package/src/data-list/data-list.ts +4 -4
- package/src/data-list/record-partial.ts +9 -10
- package/src/data-manipulator.ts +5 -5
- package/src/data-report/data-report-field.ts +2 -1
- package/src/data-report/data-report-header.ts +2 -2
- package/src/editors/ox-grist-editor-select.ts +41 -28
- package/src/editors/ox-input-tree.ts +8 -8
- package/src/filters/filter-input-barcode.ts +1 -0
- package/src/filters/filter-select.ts +41 -28
- package/src/filters/filter-styles.ts +46 -31
- package/src/filters/filters-form.ts +273 -119
- package/src/gutters/gutter-dirty.ts +2 -2
- package/src/index.ts +1 -0
- package/src/personalizer/index.ts +1 -0
- package/src/personalizer/ox-grist-filter-personalizer.ts +191 -0
- package/src/personalizer/ox-grist-personalizer.ts +192 -0
- package/src/record-view/record-creator.ts +2 -2
- package/src/renderers/ox-grist-renderer-select.ts +41 -6
- package/src/renderers/ox-grist-renderer-tree.ts +8 -8
- package/src/sorters/sorters-control.ts +3 -3
- package/src/types.ts +53 -2
- package/stories/{accumulator.stories.ts → accumulator-format.stories.ts} +33 -12
- package/stories/barcode-input-filter.stories.ts +31 -6
- package/stories/bounded-select-filters.stories.ts +339 -0
- package/stories/bounded-select-record.stories.ts +342 -0
- package/stories/click-event.stories.ts +269 -0
- package/stories/creatable-only-column.stories.ts +54 -28
- package/stories/default-filters.stories.ts +92 -24
- package/stories/dynamic-editable.stories.ts +52 -28
- package/stories/empty-sorters.stories.ts +51 -25
- package/stories/explicit-fetch.stories.ts +48 -24
- package/stories/fixed-column.stories.ts +62 -39
- package/stories/grid-setting.stories.ts +120 -63
- package/stories/grist-modes.stories.ts +74 -46
- package/stories/group-header.stories.ts +61 -39
- package/stories/textarea.stories.ts +49 -17
- package/stories/tree-column-with-checkbox.stories.ts +52 -28
- package/stories/tree-column.stories.ts +52 -28
- package/themes/dark-hc.css +151 -0
- package/themes/dark-mc.css +151 -0
- package/themes/dark.css +151 -0
- package/themes/grist-theme.css +103 -100
- package/themes/light-hc.css +151 -0
- package/themes/light-mc.css +151 -0
- package/themes/light.css +151 -0
- package/themes/md-typescale-styles.css +100 -0
- package/themes/spacing.css +43 -0
- package/themes/state-color.css +6 -0
- package/dist/stories/accumulator.stories.js.map +0 -1
- package/themes/app-theme.css +0 -145
- package/themes/form-theme.css +0 -75
- package/themes/oops-theme.css +0 -26
- package/themes/report-theme.css +0 -47
@@ -5,12 +5,14 @@ import '@operato/input/ox-input-search.js'
|
|
5
5
|
|
6
6
|
import { css, html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'
|
7
7
|
import { customElement, property, queryAsync, state } from 'lit/decorators.js'
|
8
|
+
import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
|
8
9
|
|
10
|
+
import { PagePreferenceProvider } from '@operato/p13n'
|
9
11
|
import { getDefaultValue } from '@operato/time-calculator'
|
10
12
|
|
11
|
-
import { FilterConfigObject } from '
|
13
|
+
import { FilterConfigObject, FilterPreference } from '../types.js'
|
12
14
|
import { DataGrist } from '../data-grist'
|
13
|
-
import { ColumnConfig, FilterOperator, FilterValue, GristConfig } from '../types'
|
15
|
+
import { ColumnConfig, FilterOperator, FilterValue, GristConfig, PersonalGristPreference } from '../types'
|
14
16
|
import { FilterStyles } from './filter-styles'
|
15
17
|
import { getFilterRenderer } from './registry'
|
16
18
|
|
@@ -23,12 +25,14 @@ export type QueryFilter = {
|
|
23
25
|
}
|
24
26
|
|
25
27
|
@customElement('ox-filters-form')
|
26
|
-
export class
|
28
|
+
export class OxFiltersForm extends LitElement {
|
27
29
|
static styles = [
|
30
|
+
MDTypeScaleStyles,
|
28
31
|
FilterStyles,
|
29
32
|
css`
|
30
33
|
:host {
|
31
34
|
display: flex;
|
35
|
+
padding: var(--spacing-small);
|
32
36
|
}
|
33
37
|
|
34
38
|
form {
|
@@ -50,8 +54,9 @@ export class FiltersForm extends LitElement {
|
|
50
54
|
}
|
51
55
|
|
52
56
|
@media only screen and (max-width: 460px) {
|
53
|
-
|
54
|
-
|
57
|
+
form {
|
58
|
+
flex-direction: column;
|
59
|
+
flex-flow: column;
|
55
60
|
}
|
56
61
|
}
|
57
62
|
`
|
@@ -62,12 +67,19 @@ export class FiltersForm extends LitElement {
|
|
62
67
|
@property({ type: Boolean, attribute: 'autofocus' }) autofocus: boolean = true
|
63
68
|
@property({ type: Boolean, attribute: 'empty', reflect: true }) empty: boolean = true
|
64
69
|
|
70
|
+
@state() personalConfigProvider?: PagePreferenceProvider
|
71
|
+
@state() personalConfig?: PersonalGristPreference
|
72
|
+
@state() personalFilters?: FilterPreference[]
|
73
|
+
|
65
74
|
@state() config!: GristConfig
|
66
75
|
@state() filterColumns: ColumnConfig[] = []
|
67
76
|
@state() searchColumns: ColumnConfig[] = []
|
68
77
|
|
69
78
|
@queryAsync('form') form!: HTMLFormElement
|
70
79
|
|
80
|
+
private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}
|
81
|
+
private objectValue?: object
|
82
|
+
|
71
83
|
connectedCallback(): void {
|
72
84
|
super.connectedCallback()
|
73
85
|
|
@@ -75,6 +87,7 @@ export class FiltersForm extends LitElement {
|
|
75
87
|
|
76
88
|
if (grist) {
|
77
89
|
this.config = grist.compiledConfig
|
90
|
+
this.personalConfigProvider = grist.personalConfigProvider
|
78
91
|
|
79
92
|
grist.addEventListener('config-change', (e: Event) => {
|
80
93
|
this.config = (e as CustomEvent).detail
|
@@ -90,21 +103,42 @@ export class FiltersForm extends LitElement {
|
|
90
103
|
})
|
91
104
|
|
92
105
|
this.renderRoot.addEventListener('change', async (e: Event) => {
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
106
|
+
const { target, detail: value } = e as CustomEvent
|
107
|
+
const name = (target as HTMLInputElement).name
|
108
|
+
const { filter } = this.filterColumns.find(filter => filter.name == name) || {}
|
109
|
+
|
110
|
+
if (this.autoUpdateTargetsOnChange[name]) {
|
111
|
+
/* 일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함. */
|
112
|
+
;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {
|
113
|
+
const target = this.renderRoot.querySelector(`[name='${name}']`)
|
114
|
+
if (target) {
|
115
|
+
;(target as HTMLInputElement).value = ''
|
100
116
|
}
|
101
117
|
})
|
102
|
-
|
118
|
+
|
119
|
+
await this.updateObjectValues()
|
120
|
+
this.requestUpdate()
|
121
|
+
}
|
122
|
+
|
123
|
+
const onchange = typeof filter == 'object' ? filter.onchange : null
|
124
|
+
const keepGoing = onchange ? await onchange.call(null, value ?? (target as HTMLInputElement).value, this) : true
|
125
|
+
|
126
|
+
keepGoing &&
|
127
|
+
this.dispatchEvent(
|
128
|
+
new CustomEvent('fetch-params-change', {
|
129
|
+
bubbles: true,
|
130
|
+
composed: true,
|
131
|
+
detail: {
|
132
|
+
filters: await this.getQueryFilters(),
|
133
|
+
from: 'filters-form'
|
134
|
+
}
|
135
|
+
})
|
136
|
+
)
|
103
137
|
})
|
104
138
|
}
|
105
139
|
}
|
106
140
|
|
107
|
-
buildDefaultValue(operator:
|
141
|
+
buildDefaultValue(operator: FilterOperator, defaultValue: any) {
|
108
142
|
if (defaultValue === undefined) {
|
109
143
|
return
|
110
144
|
}
|
@@ -115,28 +149,11 @@ export class FiltersForm extends LitElement {
|
|
115
149
|
}
|
116
150
|
}
|
117
151
|
|
118
|
-
updated(changes: PropertyValues<this>) {
|
119
|
-
if (changes.has('
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
return filter!.operator !== 'search'
|
124
|
-
})
|
125
|
-
this.searchColumns = filters.filter(columnConfig => {
|
126
|
-
const filter = columnConfig.filter as FilterConfigObject
|
127
|
-
return filter!.operator === 'search'
|
128
|
-
})
|
129
|
-
|
130
|
-
const grist = this.closest('ox-grist') as DataGrist
|
131
|
-
|
132
|
-
this.value = (grist?.filters || []).map(filter => {
|
133
|
-
return {
|
134
|
-
...filter,
|
135
|
-
value: this.buildDefaultValue(filter!.operator, filter!.value)
|
136
|
-
}
|
137
|
-
})
|
138
|
-
|
139
|
-
this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0
|
152
|
+
async updated(changes: PropertyValues<this>) {
|
153
|
+
if (changes.has('personalConfigProvider') && this.personalConfigProvider) {
|
154
|
+
this.personalConfig = await this.personalConfigProvider.load()
|
155
|
+
} else if (changes.has('config') || changes.has('personalConfig')) {
|
156
|
+
this.applyUpdatedConfiguration()
|
140
157
|
}
|
141
158
|
}
|
142
159
|
|
@@ -148,6 +165,7 @@ export class FiltersForm extends LitElement {
|
|
148
165
|
? html``
|
149
166
|
: html`
|
150
167
|
<form
|
168
|
+
class="md-typescale-body-medium-prominent"
|
151
169
|
@submit=${(e: Event) => {
|
152
170
|
e.stopPropagation()
|
153
171
|
e.preventDefault()
|
@@ -157,93 +175,194 @@ export class FiltersForm extends LitElement {
|
|
157
175
|
grist && grist.fetch()
|
158
176
|
}}
|
159
177
|
>
|
160
|
-
${this.
|
161
|
-
|
162
|
-
:
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
: type !== 'select' &&
|
200
|
-
?
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
178
|
+
${this.filterColumns
|
179
|
+
.filter(column => !(column.filter as FilterConfigObject).hidden)
|
180
|
+
.map((column: ColumnConfig) => {
|
181
|
+
const { name, header, label, filter } = column
|
182
|
+
|
183
|
+
const type = (filter as FilterConfigObject).type
|
184
|
+
|
185
|
+
if (type == 'search') {
|
186
|
+
return html`
|
187
|
+
<ox-input-search name="search" .value=${searchValue} ?autofocus=${this.autofocus}></ox-input-search>
|
188
|
+
`
|
189
|
+
}
|
190
|
+
|
191
|
+
const operator = (filter as FilterConfigObject).operator
|
192
|
+
const filterLabel = (filter as FilterConfigObject).label
|
193
|
+
|
194
|
+
const labelText =
|
195
|
+
filterLabel !== undefined
|
196
|
+
? filterLabel
|
197
|
+
: typeof label === 'object' && label.renderer
|
198
|
+
? label.renderer(column)
|
199
|
+
: header.renderer(column) || name
|
200
|
+
|
201
|
+
const idx = operator === 'between' ? 1 : 0
|
202
|
+
const renderer = getFilterRenderer(
|
203
|
+
operator === 'like' || operator === 'i_like' || operator === 'i_nlike' || operator === 'nlike'
|
204
|
+
? 'text'
|
205
|
+
: type
|
206
|
+
)[idx]
|
207
|
+
const value =
|
208
|
+
this.value?.find(filter => filter.name == name)?.value ??
|
209
|
+
this.buildDefaultValue(operator!, (filter as FilterConfigObject)?.value)
|
210
|
+
|
211
|
+
if (!renderer) {
|
212
|
+
return html``
|
213
|
+
}
|
214
|
+
|
215
|
+
return type === 'boolean' || type === 'checkbox'
|
216
|
+
? renderer(column, value, this)
|
217
|
+
: type !== 'select' && labelText
|
218
|
+
? html`<label filter-title ?between=${operator === 'between'}
|
219
|
+
><span>${labelText}</span> ${renderer(column, value, this)}
|
220
|
+
</label> `
|
221
|
+
: type !== 'select' && !labelText
|
222
|
+
? renderer(column, value, this)
|
223
|
+
: operator === 'in'
|
224
|
+
? html`
|
225
|
+
<ox-select
|
226
|
+
name=${name}
|
227
|
+
placeholder=${labelText}
|
228
|
+
.value=${value}
|
229
|
+
@change=${(e: CustomEvent) =>
|
230
|
+
e.target?.dispatchEvent(
|
231
|
+
new CustomEvent('filter-change', {
|
232
|
+
detail: {
|
233
|
+
name,
|
234
|
+
operator,
|
235
|
+
value: e.detail
|
236
|
+
}
|
237
|
+
})
|
238
|
+
)}
|
239
|
+
>
|
240
|
+
<ox-popup-list multiple attr-selected="checked" with-search>
|
241
|
+
${renderer(column, value, this)}
|
242
|
+
</ox-popup-list>
|
243
|
+
</ox-select>
|
244
|
+
`
|
245
|
+
: html`
|
246
|
+
<ox-select
|
247
|
+
name=${name}
|
248
|
+
placeholder=${labelText}
|
249
|
+
.value=${value}
|
250
|
+
@change=${(e: CustomEvent) =>
|
251
|
+
e.target?.dispatchEvent(
|
252
|
+
new CustomEvent('filter-change', {
|
253
|
+
detail: {
|
254
|
+
name,
|
255
|
+
operator,
|
256
|
+
value: e.detail
|
257
|
+
}
|
258
|
+
})
|
259
|
+
)}
|
260
|
+
>
|
261
|
+
<ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>
|
262
|
+
</ox-select>
|
263
|
+
`
|
264
|
+
})}
|
243
265
|
</form>
|
266
|
+
<slot name="setting"></slot>
|
244
267
|
`
|
245
268
|
}
|
246
269
|
|
270
|
+
applyUpdatedConfiguration() {
|
271
|
+
if (!this.config) {
|
272
|
+
return
|
273
|
+
}
|
274
|
+
|
275
|
+
const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter)
|
276
|
+
|
277
|
+
this.filterColumns = filters.filter((columnConfig: ColumnConfig) => {
|
278
|
+
const filter = columnConfig.filter as FilterConfigObject
|
279
|
+
return filter!.operator !== 'search'
|
280
|
+
})
|
281
|
+
this.searchColumns = filters.filter(columnConfig => {
|
282
|
+
const filter = columnConfig.filter as FilterConfigObject
|
283
|
+
return filter!.operator === 'search'
|
284
|
+
})
|
285
|
+
|
286
|
+
if (this.searchColumns.length > 0 && !this.withoutSearch) {
|
287
|
+
this.filterColumns.unshift({ name: 'search', filter: { type: 'search' } } as any)
|
288
|
+
}
|
289
|
+
|
290
|
+
if (!this.personalConfig) {
|
291
|
+
this.personalFilters = this.filterColumns.map(column => {
|
292
|
+
return { name: column.name }
|
293
|
+
})
|
294
|
+
} else {
|
295
|
+
const { filters: personalFilters = [] } = this.personalConfig
|
296
|
+
|
297
|
+
if (personalFilters) {
|
298
|
+
const xfilters = this.filterColumns.map(column => {
|
299
|
+
return personalFilters.find(pFilter => pFilter.name == column.name) || { name: column.name }
|
300
|
+
})
|
301
|
+
|
302
|
+
function reorderList(a: FilterPreference[], b: FilterPreference[]): FilterPreference[] {
|
303
|
+
// 결과 배열 초기화, a 배열 길이만큼 undefined로 채움
|
304
|
+
const result = new Array(a.length)
|
305
|
+
|
306
|
+
// b 배열에 없는 아이템은 원래 위치로 채움
|
307
|
+
a.forEach((item, index) => {
|
308
|
+
if (!item.name || !b.find(bi => bi.name == item.name)) {
|
309
|
+
result[index] = item
|
310
|
+
}
|
311
|
+
})
|
312
|
+
|
313
|
+
b.forEach(item => {
|
314
|
+
const ai = a.find(ai => ai.name == item.name)
|
315
|
+
if (ai) {
|
316
|
+
result[result.findIndex(slot => slot === undefined)] = ai
|
317
|
+
}
|
318
|
+
})
|
319
|
+
|
320
|
+
return result
|
321
|
+
}
|
322
|
+
|
323
|
+
// 배열 재정렬 실행
|
324
|
+
this.personalFilters = reorderList(xfilters as any, personalFilters as any) as FilterPreference[]
|
325
|
+
|
326
|
+
this.filterColumns = this.personalFilters
|
327
|
+
.map(filter => {
|
328
|
+
const column = this.filterColumns.find(column => column.name == filter.name)
|
329
|
+
if (column?.filter) {
|
330
|
+
;(column.filter as FilterConfigObject)!.hidden = filter.hidden
|
331
|
+
}
|
332
|
+
return column
|
333
|
+
})
|
334
|
+
.filter(Boolean) as ColumnConfig[]
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
338
|
+
const grist = this.closest('ox-grist') as DataGrist
|
339
|
+
|
340
|
+
this.value = (grist?.filters || []).map(filter => {
|
341
|
+
return {
|
342
|
+
...filter,
|
343
|
+
value: this.buildDefaultValue(filter!.operator, filter!.value)
|
344
|
+
}
|
345
|
+
})
|
346
|
+
|
347
|
+
this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0
|
348
|
+
|
349
|
+
this.autoUpdateTargetsOnChange = {}
|
350
|
+
this.filterColumns
|
351
|
+
?.filter(({ filter }) => {
|
352
|
+
return typeof filter == 'object' && filter.boundTo && filter.boundTo.length > 0
|
353
|
+
})
|
354
|
+
.map(({ name, filter }) => {
|
355
|
+
const boundTo = (filter as FilterConfigObject).boundTo
|
356
|
+
|
357
|
+
boundTo!.forEach(to => {
|
358
|
+
const origin = this.autoUpdateTargetsOnChange[to] || []
|
359
|
+
if (name && !origin.includes(name)) {
|
360
|
+
this.autoUpdateTargetsOnChange[to] = [...origin, name]
|
361
|
+
}
|
362
|
+
})
|
363
|
+
})
|
364
|
+
}
|
365
|
+
|
247
366
|
async getQueryFilters(): Promise<QueryFilter[]> {
|
248
367
|
const form = await this.form
|
249
368
|
if (!form) return []
|
@@ -252,6 +371,7 @@ export class FiltersForm extends LitElement {
|
|
252
371
|
const search: string | undefined = formData.get('search')?.toString()
|
253
372
|
|
254
373
|
var filters = this.filterColumns
|
374
|
+
.filter(column => column.name !== 'search' && !(column.filter as FilterConfigObject)!.hidden)
|
255
375
|
.map((column: ColumnConfig) => {
|
256
376
|
const { name, type, filter } = column
|
257
377
|
const operator = (filter as FilterConfigObject).operator
|
@@ -319,4 +439,38 @@ export class FiltersForm extends LitElement {
|
|
319
439
|
const input = this.renderRoot.querySelector(`form [name="${name}"]`) as HTMLInputElement
|
320
440
|
return input?.value
|
321
441
|
}
|
442
|
+
|
443
|
+
private async updateObjectValues() {
|
444
|
+
const form = await this.form
|
445
|
+
if (!form) return []
|
446
|
+
|
447
|
+
const formData = new FormData(form)
|
448
|
+
|
449
|
+
const object = {} as any
|
450
|
+
formData.forEach((value, key) => {
|
451
|
+
const prev = object[key]
|
452
|
+
|
453
|
+
if (key in object) {
|
454
|
+
object[key] = prev instanceof Array ? [...prev, value] : [prev, value]
|
455
|
+
} else {
|
456
|
+
object[key] = value
|
457
|
+
}
|
458
|
+
})
|
459
|
+
|
460
|
+
this.objectValue = object
|
461
|
+
}
|
462
|
+
|
463
|
+
public getFormObjectValue() {
|
464
|
+
return this.objectValue
|
465
|
+
}
|
466
|
+
|
467
|
+
reset() {
|
468
|
+
this.form
|
469
|
+
.then((form: HTMLFormElement) => {
|
470
|
+
form.reset()
|
471
|
+
})
|
472
|
+
.catch((error: any) => {
|
473
|
+
console.error('Error resetting the form:', error)
|
474
|
+
})
|
475
|
+
}
|
322
476
|
}
|
@@ -9,7 +9,7 @@ import { ColumnConfig, FieldRenderer, GristEventHandler } from '../types'
|
|
9
9
|
class GutterDirtyElement extends LitElement {
|
10
10
|
static styles = css`
|
11
11
|
:host {
|
12
|
-
display:
|
12
|
+
display: flex;
|
13
13
|
margin: auto;
|
14
14
|
}
|
15
15
|
|
@@ -21,7 +21,7 @@ class GutterDirtyElement extends LitElement {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
[add] {
|
24
|
-
background-color: var(--primary-
|
24
|
+
background-color: var(--md-sys-color-on-primary-container);
|
25
25
|
}
|
26
26
|
|
27
27
|
[remove] {
|
package/src/index.ts
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
export * from './ox-grist-personalizer'
|