@operato/data-grist 1.0.0-beta.7 → 1.0.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.
- package/.storybook/main.js +3 -0
- package/.storybook/server.mjs +8 -0
- package/CHANGELOG.md +412 -0
- package/demo/data-grist-test.html +1 -1
- package/demo/index.html +16 -4
- package/demo/report-test.html +1 -1
- package/dist/src/configure/zero-config.d.ts +2 -0
- package/dist/src/configure/zero-config.js +3 -1
- package/dist/src/configure/zero-config.js.map +1 -1
- package/dist/src/data-card/data-card-field.d.ts +1 -1
- package/dist/src/data-card/data-card-field.js +3 -2
- package/dist/src/data-card/data-card-field.js.map +1 -1
- package/dist/src/data-card/data-card.js +1 -0
- package/dist/src/data-card/data-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +4 -2
- package/dist/src/data-grid/data-grid-body.js +74 -40
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-field.d.ts +1 -1
- package/dist/src/data-grid/data-grid-field.js +1 -1
- package/dist/src/data-grid/data-grid-field.js.map +1 -1
- package/dist/src/data-grid/data-grid-footer.d.ts +2 -2
- package/dist/src/data-grid/data-grid-footer.js +9 -10
- package/dist/src/data-grid/data-grid-footer.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.d.ts +4 -6
- package/dist/src/data-grid/data-grid-header.js +39 -48
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.d.ts +2 -2
- package/dist/src/data-grid/data-grid.js +4 -3
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js +9 -11
- package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js.map +1 -1
- package/dist/src/data-grist.d.ts +7 -5
- package/dist/src/data-grist.js +154 -112
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/record-partial.js +1 -5
- package/dist/src/data-list/record-partial.js.map +1 -1
- package/dist/src/data-manipulator.d.ts +4 -1
- package/dist/src/data-manipulator.js +12 -0
- package/dist/src/data-manipulator.js.map +1 -1
- package/dist/src/data-provider.d.ts +4 -6
- package/dist/src/data-provider.js +12 -23
- package/dist/src/data-provider.js.map +1 -1
- package/dist/src/data-report/data-report-body.d.ts +1 -1
- package/dist/src/data-report/data-report-body.js +4 -4
- package/dist/src/data-report/data-report-body.js.map +1 -1
- package/dist/src/data-report/data-report-header.js +4 -4
- package/dist/src/data-report/data-report-header.js.map +1 -1
- package/dist/src/editors/ox-grist-editor.d.ts +1 -1
- package/dist/src/editors/ox-grist-editor.js +7 -4
- package/dist/src/editors/ox-grist-editor.js.map +1 -1
- package/dist/src/filters/filter-checkbox.d.ts +1 -1
- package/dist/src/filters/filter-checkbox.js +1 -1
- package/dist/src/filters/filter-checkbox.js.map +1 -1
- package/dist/src/filters/filter-input-barcode.d.ts +3 -0
- package/dist/src/filters/filter-input-barcode.js +27 -0
- package/dist/src/filters/filter-input-barcode.js.map +1 -0
- package/dist/src/filters/filter-input.js +1 -1
- package/dist/src/filters/filter-input.js.map +1 -1
- package/dist/src/filters/filter-styles.js +65 -17
- package/dist/src/filters/filter-styles.js.map +1 -1
- package/dist/src/filters/filters-form.js +27 -9
- package/dist/src/filters/filters-form.js.map +1 -1
- package/dist/src/filters/registry.d.ts +1 -1
- package/dist/src/filters/registry.js +10 -7
- package/dist/src/filters/registry.js.map +1 -1
- package/dist/src/gutters/gutter-button.js +5 -4
- package/dist/src/gutters/gutter-button.js.map +1 -1
- package/dist/src/gutters/gutter-dirty.d.ts +5 -1
- package/dist/src/gutters/gutter-dirty.js +17 -2
- package/dist/src/gutters/gutter-dirty.js.map +1 -1
- package/dist/src/gutters/gutter-row-selector.js +2 -1
- package/dist/src/gutters/gutter-row-selector.js.map +1 -1
- package/dist/src/gutters/gutter-sequence.js +15 -0
- package/dist/src/gutters/gutter-sequence.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +2 -4
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +2 -2
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -1
- package/dist/src/record-view/record-creator.js +0 -2
- package/dist/src/record-view/record-creator.js.map +1 -1
- package/dist/src/record-view/record-view-body.d.ts +0 -1
- package/dist/src/record-view/record-view-body.js +0 -5
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/record-view/record-view-handler.d.ts +1 -1
- package/dist/src/record-view/record-view.d.ts +0 -1
- package/dist/src/record-view/record-view.js +1 -10
- package/dist/src/record-view/record-view.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-color.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-color.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-json5.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-json5.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-link.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-link.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-select.js +2 -2
- package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-text.js +6 -2
- package/dist/src/renderers/ox-grist-renderer-text.js.map +1 -1
- package/dist/src/sorters/sorters-control.d.ts +1 -1
- package/dist/src/sorters/sorters-control.js +5 -7
- package/dist/src/sorters/sorters-control.js.map +1 -1
- package/dist/src/types.d.ts +7 -4
- package/dist/src/types.js.map +1 -1
- package/dist/stories/{index.stories.d.ts → barcode-input-filter.stories.d.ts} +9 -13
- package/dist/stories/barcode-input-filter.stories.js +200 -0
- package/dist/stories/barcode-input-filter.stories.js.map +1 -0
- package/dist/stories/default-filters.stories.d.ts +20 -0
- package/dist/stories/default-filters.stories.js +187 -0
- package/dist/stories/default-filters.stories.js.map +1 -0
- package/dist/stories/empty-sorters.stories.d.ts +20 -0
- package/dist/stories/empty-sorters.stories.js +180 -0
- package/dist/stories/empty-sorters.stories.js.map +1 -0
- package/dist/stories/explicit-fetch.stories.d.ts +25 -0
- package/dist/stories/explicit-fetch.stories.js +186 -0
- package/dist/stories/explicit-fetch.stories.js.map +1 -0
- package/dist/stories/grist-modes.stories.d.ts +36 -0
- package/dist/stories/grist-modes.stories.js +448 -0
- package/dist/stories/grist-modes.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/src/configure/zero-config.ts +4 -1
- package/src/data-card/data-card-field.ts +5 -3
- package/src/data-card/data-card.ts +1 -0
- package/src/data-grid/data-grid-body.ts +96 -49
- package/src/data-grid/data-grid-field.ts +3 -2
- package/src/data-grid/data-grid-footer.ts +8 -9
- package/src/data-grid/data-grid-header.ts +38 -47
- package/src/data-grid/data-grid.ts +8 -6
- package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +11 -13
- package/src/data-grist.ts +179 -130
- package/src/data-list/record-partial.ts +1 -5
- package/src/data-manipulator.ts +12 -1
- package/src/data-provider.ts +13 -29
- package/src/data-report/data-report-body.ts +5 -5
- package/src/data-report/data-report-header.ts +5 -5
- package/src/editors/ox-grist-editor.ts +8 -5
- package/src/filters/filter-checkbox.ts +3 -3
- package/src/filters/filter-input-barcode.ts +33 -0
- package/src/filters/filter-input.ts +3 -3
- package/src/filters/filter-styles.ts +65 -17
- package/src/filters/filters-form.ts +30 -9
- package/src/filters/registry.ts +11 -8
- package/src/gutters/gutter-button.ts +5 -4
- package/src/gutters/gutter-dirty.ts +21 -3
- package/src/gutters/gutter-row-selector.ts +2 -1
- package/src/gutters/gutter-sequence.ts +18 -2
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +2 -4
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +2 -2
- package/src/record-view/record-creator.ts +0 -2
- package/src/record-view/record-view-body.ts +0 -2
- package/src/record-view/record-view.ts +1 -7
- package/src/renderers/ox-grist-renderer-color.ts +3 -2
- package/src/renderers/ox-grist-renderer-json5.ts +3 -2
- package/src/renderers/ox-grist-renderer-link.ts +3 -2
- package/src/renderers/ox-grist-renderer-select.ts +2 -2
- package/src/renderers/ox-grist-renderer-text.ts +8 -2
- package/src/sorters/sorters-control.ts +6 -9
- package/src/types.ts +8 -4
- package/stories/barcode-input-filter.stories.ts +220 -0
- package/stories/default-filters.stories.ts +204 -0
- package/stories/empty-sorters.stories.ts +197 -0
- package/stories/explicit-fetch.stories.ts +205 -0
- package/stories/grist-modes.stories.ts +488 -0
- package/themes/form-theme.css +75 -0
- package/themes/grist-theme.css +1 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-beforeinput-handler.d.ts +0 -7
- package/dist/src/data-grid/event-handlers/data-grid-body-beforeinput-handler.js +0 -12
- package/dist/src/data-grid/event-handlers/data-grid-body-beforeinput-handler.js.map +0 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-input-handler copy.d.ts +0 -7
- package/dist/src/data-grid/event-handlers/data-grid-body-input-handler copy.js +0 -88
- package/dist/src/data-grid/event-handlers/data-grid-body-input-handler copy.js.map +0 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-input-handler.d.ts +0 -7
- package/dist/src/data-grid/event-handlers/data-grid-body-input-handler.js +0 -88
- package/dist/src/data-grid/event-handlers/data-grid-body-input-handler.js.map +0 -1
- package/dist/src/data-grid/event-handlers/data-grid-body-keydown-handler copy.d.ts +0 -7
- package/dist/src/data-grid/event-handlers/data-grid-body-keydown-handler copy.js +0 -88
- package/dist/src/data-grid/event-handlers/data-grid-body-keydown-handler copy.js.map +0 -1
- package/dist/stories/index.stories.js +0 -33
- package/dist/stories/index.stories.js.map +0 -1
- package/stories/index.stories.ts +0 -52
- package/yarn-error.log +0 -17496
package/src/data-grist.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { HeadroomStyles, ScrollbarStyles, SpinnerStyles } from '@operato/styles'
|
|
|
15
15
|
import { SnapshotTaker, TimeCapsule } from '@operato/utils'
|
|
16
16
|
|
|
17
17
|
import { buildConfig } from './configure/config-builder'
|
|
18
|
-
import { ZERO_CONFIG, ZERO_DATA, ZERO_PAGINATION } from './configure/zero-config'
|
|
18
|
+
import { ZERO_CONFIG, ZERO_DATA, ZERO_PAGES, ZERO_PAGINATION } from './configure/zero-config'
|
|
19
19
|
import { DataCard } from './data-card/data-card'
|
|
20
20
|
import { DataConsumer } from './data-consumer'
|
|
21
21
|
import { DataGrid } from './data-grid/data-grid'
|
|
@@ -23,11 +23,13 @@ import { DataList } from './data-list/data-list'
|
|
|
23
23
|
import { DataProvider } from './data-provider'
|
|
24
24
|
import {
|
|
25
25
|
FetchHandler,
|
|
26
|
+
FilterConfigObject,
|
|
26
27
|
FilterValue,
|
|
27
28
|
GristConfig,
|
|
28
29
|
GristData,
|
|
29
30
|
GristRecord,
|
|
30
31
|
GristSelectFunction,
|
|
32
|
+
PaginationConfig,
|
|
31
33
|
SortersConfig
|
|
32
34
|
} from './types'
|
|
33
35
|
|
|
@@ -62,8 +64,7 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
62
64
|
overflow: auto;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
ox-list {
|
|
67
|
+
#grist {
|
|
67
68
|
flex: 1;
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -92,11 +93,12 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
92
93
|
@property() config: any
|
|
93
94
|
@property() data: GristData = ZERO_DATA
|
|
94
95
|
@property() selectedRecords?: GristRecord[]
|
|
95
|
-
@property({ type: Boolean, attribute: '
|
|
96
|
+
@property({ type: Boolean, attribute: 'explicit-fetch' }) explicitFetch: boolean = false
|
|
96
97
|
@property() fetchHandler?: FetchHandler
|
|
97
98
|
@property() fetchOptions: any
|
|
98
99
|
@property() filters?: FilterValue[]
|
|
99
100
|
@property() sorters?: SortersConfig
|
|
101
|
+
@property() pagination?: PaginationConfig
|
|
100
102
|
@property({ type: Boolean, attribute: 'url-params-sensitive' }) urlParamsSensitive?: boolean
|
|
101
103
|
|
|
102
104
|
@state() _data: GristData = ZERO_DATA
|
|
@@ -108,9 +110,82 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
108
110
|
private _headroom?: Headroom
|
|
109
111
|
private orginPaddingTop?: string
|
|
110
112
|
private originMarginTop?: string
|
|
111
|
-
private
|
|
112
|
-
|
|
113
|
-
private
|
|
113
|
+
private lastLocation: { origin?: string; pathname?: string; search?: string } = {}
|
|
114
|
+
|
|
115
|
+
private _popstateEventHandler: EventListener = ((e: Event) => {
|
|
116
|
+
const { origin, pathname, search } = window.location
|
|
117
|
+
if (
|
|
118
|
+
this.lastLocation.origin &&
|
|
119
|
+
(this.lastLocation.origin !== origin ||
|
|
120
|
+
this.lastLocation.pathname !== pathname ||
|
|
121
|
+
this.lastLocation.search === search)
|
|
122
|
+
) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.lastLocation = {
|
|
127
|
+
origin,
|
|
128
|
+
pathname,
|
|
129
|
+
search
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const queryString = search
|
|
133
|
+
const urlParams = new URLSearchParams(queryString)
|
|
134
|
+
var filters = urlParams.get('filters')
|
|
135
|
+
var sorters = urlParams.get('sorters')
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
if (!isEqual(filters, this.filters) || !isEqual(sorters, this.sorters)) {
|
|
139
|
+
this.dispatchEvent(
|
|
140
|
+
new CustomEvent('fetch-params-change', {
|
|
141
|
+
bubbles: true,
|
|
142
|
+
composed: true,
|
|
143
|
+
detail: {
|
|
144
|
+
filters: json5.parse(filters || '[]'),
|
|
145
|
+
sorters: json5.parse(sorters || '[]'),
|
|
146
|
+
from: 'url-parameter'
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.error(`invalid fetch params on URL query string : ${e}`)
|
|
153
|
+
}
|
|
154
|
+
}).bind(this)
|
|
155
|
+
|
|
156
|
+
private _fetchParamsChangeEventHandler: EventListener = ((e: Event) => {
|
|
157
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
158
|
+
const { sorters, filters, from } = (e as CustomEvent).detail
|
|
159
|
+
|
|
160
|
+
sorters && (this.sorters = sorters)
|
|
161
|
+
filters && (this.filters = filters)
|
|
162
|
+
|
|
163
|
+
if (!this.urlParamsSensitive || from === 'url-parameter') {
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (sorters) {
|
|
168
|
+
if (sorters.length > 0) {
|
|
169
|
+
urlParams.set('sorters', json5.stringify(sorters))
|
|
170
|
+
} else {
|
|
171
|
+
urlParams.delete('sorters')
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (filters) {
|
|
176
|
+
if (filters.length > 0) {
|
|
177
|
+
urlParams.set('filters', json5.stringify(filters))
|
|
178
|
+
} else {
|
|
179
|
+
urlParams.delete('filters')
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const queryString = String(urlParams)
|
|
184
|
+
this.lastLocation.search = queryString ? `?${queryString}` : ''
|
|
185
|
+
const url = `${window.location.pathname}${this.lastLocation.search}`
|
|
186
|
+
|
|
187
|
+
history.pushState({}, document.title, url)
|
|
188
|
+
}).bind(this)
|
|
114
189
|
|
|
115
190
|
@query('slot[name=headroom]') head!: HTMLElement
|
|
116
191
|
@query('#grist') grist!: DataGrid | DataList | DataCard
|
|
@@ -127,12 +202,16 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
127
202
|
this._timeCapsule = new TimeCapsule(10)
|
|
128
203
|
this._snapshotTaker = new SnapshotTaker(this, this._timeCapsule!)
|
|
129
204
|
|
|
205
|
+
this.addEventListener('fetch-params-change', this._fetchParamsChangeEventHandler)
|
|
206
|
+
|
|
130
207
|
await this.updateComplete
|
|
131
208
|
}
|
|
132
209
|
|
|
133
210
|
disconnectedCallback() {
|
|
134
211
|
super.disconnectedCallback()
|
|
135
212
|
|
|
213
|
+
this.removeEventListener('fetch-params-change', this._fetchParamsChangeEventHandler)
|
|
214
|
+
|
|
136
215
|
this._timeCapsule && this._timeCapsule.dispose()
|
|
137
216
|
this._snapshotTaker && this._snapshotTaker.dispose()
|
|
138
217
|
|
|
@@ -172,8 +251,6 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
172
251
|
this.orginPaddingTop = style.paddingTop || '0'
|
|
173
252
|
this.originMarginTop = style.marginTop || '0'
|
|
174
253
|
|
|
175
|
-
console.log(this.orginPaddingTop, this.originMarginTop)
|
|
176
|
-
|
|
177
254
|
this._headroom = new Headroom(this.head, {
|
|
178
255
|
scroller: this.grist,
|
|
179
256
|
onTop: () => {
|
|
@@ -208,10 +285,38 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
208
285
|
: html``}
|
|
209
286
|
<div id="wrap" @keydown=${(e: KeyboardEvent) => this.onKeydown(e)}>
|
|
210
287
|
${this.mode == 'GRID'
|
|
211
|
-
? html`
|
|
288
|
+
? html`
|
|
289
|
+
<ox-grid
|
|
290
|
+
id="grist"
|
|
291
|
+
.config=${this.compiledConfig}
|
|
292
|
+
.data=${this._data}
|
|
293
|
+
.sorters=${this.sorters}
|
|
294
|
+
.filters=${this.filters}
|
|
295
|
+
.pagination=${this.pagination}
|
|
296
|
+
>
|
|
297
|
+
</ox-grid>
|
|
298
|
+
`
|
|
212
299
|
: this.mode == 'CARD'
|
|
213
|
-
? html`
|
|
214
|
-
|
|
300
|
+
? html`
|
|
301
|
+
<ox-card
|
|
302
|
+
id="grist"
|
|
303
|
+
.config=${this.compiledConfig}
|
|
304
|
+
.data=${this._data}
|
|
305
|
+
.sorters=${this.sorters}
|
|
306
|
+
.filters=${this.filters}
|
|
307
|
+
>
|
|
308
|
+
</ox-card>
|
|
309
|
+
`
|
|
310
|
+
: html`
|
|
311
|
+
<ox-list
|
|
312
|
+
id="grist"
|
|
313
|
+
.config=${this.compiledConfig}
|
|
314
|
+
.data=${this._data}
|
|
315
|
+
.sorters=${this.sorters}
|
|
316
|
+
.filters=${this.filters}
|
|
317
|
+
>
|
|
318
|
+
</ox-list>
|
|
319
|
+
`}
|
|
215
320
|
</div>
|
|
216
321
|
|
|
217
322
|
<div id="spinner" ?show=${this._showSpinner}></div>
|
|
@@ -283,127 +388,12 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
283
388
|
async updated(changes: PropertyValues<this>) {
|
|
284
389
|
var needToSetPullToRefresh = false
|
|
285
390
|
|
|
286
|
-
if (changes.has('urlParamsSensitive')) {
|
|
287
|
-
if (this.urlParamsSensitive) {
|
|
288
|
-
this._popstateEventHandler = () => {
|
|
289
|
-
const queryString = window.location.search
|
|
290
|
-
const urlParams = new URLSearchParams(queryString)
|
|
291
|
-
var filters = urlParams.get('filters')
|
|
292
|
-
var sorters = urlParams.get('sorters')
|
|
293
|
-
|
|
294
|
-
if (filters) {
|
|
295
|
-
try {
|
|
296
|
-
this.filters = json5.parse(filters)
|
|
297
|
-
this.dispatchEvent(
|
|
298
|
-
new CustomEvent('filters-change', {
|
|
299
|
-
bubbles: true,
|
|
300
|
-
composed: true,
|
|
301
|
-
detail: {
|
|
302
|
-
filters: json5.parse(filters),
|
|
303
|
-
from: 'url-parameter'
|
|
304
|
-
}
|
|
305
|
-
})
|
|
306
|
-
)
|
|
307
|
-
} catch (e) {
|
|
308
|
-
console.error(`invalid filters params on URL query string : ${e}`)
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
if (sorters) {
|
|
312
|
-
try {
|
|
313
|
-
this.sorters = json5.parse(sorters)
|
|
314
|
-
} catch (e) {
|
|
315
|
-
console.error(`invalid sorters params on URL query string : ${e}`)
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
//@ts-ignore
|
|
321
|
-
this._popstateEventHandler() // call for the first time
|
|
322
|
-
|
|
323
|
-
window.addEventListener('popstate', this._popstateEventHandler)
|
|
324
|
-
|
|
325
|
-
this._urlSensitiveFiltersHandler = (e: Event) => {
|
|
326
|
-
const urlParams = new URLSearchParams(window.location.search)
|
|
327
|
-
const { filters, from } = (e as CustomEvent).detail || {}
|
|
328
|
-
|
|
329
|
-
if (from === 'url-parameter') {
|
|
330
|
-
return
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (filters.length > 0) {
|
|
334
|
-
urlParams.set('filters', json5.stringify(filters))
|
|
335
|
-
} else {
|
|
336
|
-
urlParams.delete('filters')
|
|
337
|
-
}
|
|
338
|
-
const queryString = String(urlParams)
|
|
339
|
-
const url = `${window.location.pathname}${queryString ? `?${queryString}` : ''}`
|
|
340
|
-
|
|
341
|
-
history.pushState({}, document.title, url)
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
this.addEventListener('filters-change', this._urlSensitiveFiltersHandler)
|
|
345
|
-
|
|
346
|
-
this._urlSensitiveSortersHandler = (e: Event) => {
|
|
347
|
-
const urlParams = new URLSearchParams(window.location.search)
|
|
348
|
-
const { sorters, from } = (e as CustomEvent).detail
|
|
349
|
-
|
|
350
|
-
if (from === 'url-parameter') {
|
|
351
|
-
return
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if (sorters.length > 0) {
|
|
355
|
-
urlParams.set('sorters', json5.stringify(sorters))
|
|
356
|
-
} else {
|
|
357
|
-
urlParams.delete('sorters')
|
|
358
|
-
}
|
|
359
|
-
const queryString = String(urlParams)
|
|
360
|
-
const url = `${window.location.pathname}${queryString ? `?${queryString}` : ''}`
|
|
361
|
-
|
|
362
|
-
history.pushState({}, document.title, url)
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
this.addEventListener('sorters-change', this._urlSensitiveSortersHandler)
|
|
366
|
-
} else {
|
|
367
|
-
if (this._popstateEventHandler) {
|
|
368
|
-
window.removeEventListener('popstate', this._popstateEventHandler)
|
|
369
|
-
}
|
|
370
|
-
if (this._urlSensitiveFiltersHandler) {
|
|
371
|
-
this.removeEventListener('popstate', this._urlSensitiveFiltersHandler)
|
|
372
|
-
}
|
|
373
|
-
if (this._urlSensitiveSortersHandler) {
|
|
374
|
-
this.removeEventListener('popstate', this._urlSensitiveSortersHandler)
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
391
|
if (changes.has('filters')) {
|
|
380
392
|
await this.requestUpdate()
|
|
381
|
-
|
|
382
|
-
this.dispatchEvent(
|
|
383
|
-
new CustomEvent('filters-change', {
|
|
384
|
-
bubbles: true,
|
|
385
|
-
composed: true,
|
|
386
|
-
detail: {
|
|
387
|
-
filters: this.filters,
|
|
388
|
-
from: 'url-parameter'
|
|
389
|
-
}
|
|
390
|
-
})
|
|
391
|
-
)
|
|
392
393
|
}
|
|
393
394
|
|
|
394
395
|
if (changes.has('sorters')) {
|
|
395
396
|
await this.requestUpdate()
|
|
396
|
-
|
|
397
|
-
this.dispatchEvent(
|
|
398
|
-
new CustomEvent('sorters-change', {
|
|
399
|
-
bubbles: true,
|
|
400
|
-
composed: true,
|
|
401
|
-
detail: {
|
|
402
|
-
sorters: this.sorters,
|
|
403
|
-
from: 'url-parameter'
|
|
404
|
-
}
|
|
405
|
-
})
|
|
406
|
-
)
|
|
407
397
|
}
|
|
408
398
|
|
|
409
399
|
if (changes.has('config')) {
|
|
@@ -419,12 +409,44 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
419
409
|
})
|
|
420
410
|
)
|
|
421
411
|
|
|
412
|
+
this.pagination = this.compiledConfig.pagination || {}
|
|
413
|
+
|
|
414
|
+
if (!this.urlParamsSensitive) {
|
|
415
|
+
const sorters = this.compiledConfig?.sorters
|
|
416
|
+
const filters = this.compiledConfig?.columns
|
|
417
|
+
.filter(
|
|
418
|
+
column =>
|
|
419
|
+
column.filter &&
|
|
420
|
+
'value' in (column.filter as FilterConfigObject) &&
|
|
421
|
+
(column.filter as FilterConfigObject).value
|
|
422
|
+
)
|
|
423
|
+
.map(column => {
|
|
424
|
+
const filter = column.filter as FilterConfigObject
|
|
425
|
+
return { name: column.name, operator: filter.operator, value: filter.value } as FilterValue
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
this.dispatchEvent(
|
|
429
|
+
new CustomEvent('fetch-params-change', {
|
|
430
|
+
bubbles: true,
|
|
431
|
+
composed: true,
|
|
432
|
+
detail: {
|
|
433
|
+
filters,
|
|
434
|
+
sorters,
|
|
435
|
+
from: 'config'
|
|
436
|
+
}
|
|
437
|
+
})
|
|
438
|
+
)
|
|
439
|
+
}
|
|
440
|
+
|
|
422
441
|
if (this.dataProvider) {
|
|
423
|
-
|
|
424
|
-
this.dataProvider.
|
|
442
|
+
const { limit, pages = ZERO_PAGES } = this._config.pagination || ZERO_PAGINATION
|
|
443
|
+
this.dataProvider.page = 1
|
|
444
|
+
this.dataProvider.limit = limit || pages[0] || ZERO_PAGES[0]
|
|
425
445
|
}
|
|
426
446
|
|
|
427
|
-
this.
|
|
447
|
+
if (!this.urlParamsSensitive && !this.explicitFetch) {
|
|
448
|
+
this.fetch()
|
|
449
|
+
}
|
|
428
450
|
}
|
|
429
451
|
|
|
430
452
|
if (changes.has('fetchHandler')) {
|
|
@@ -470,6 +492,17 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
470
492
|
this.refresh()
|
|
471
493
|
}
|
|
472
494
|
|
|
495
|
+
if (changes.has('urlParamsSensitive')) {
|
|
496
|
+
if (this.urlParamsSensitive) {
|
|
497
|
+
//@ts-ignore
|
|
498
|
+
this._popstateEventHandler() // call for the first time
|
|
499
|
+
|
|
500
|
+
window.addEventListener('popstate', this._popstateEventHandler)
|
|
501
|
+
} else {
|
|
502
|
+
window.removeEventListener('popstate', this._popstateEventHandler)
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
473
506
|
if (needToSetPullToRefresh) {
|
|
474
507
|
await this._setPullToRefresh()
|
|
475
508
|
}
|
|
@@ -690,4 +723,20 @@ export class DataGrist extends LitElement implements DataConsumer {
|
|
|
690
723
|
|
|
691
724
|
this.checkDirties()
|
|
692
725
|
}
|
|
726
|
+
|
|
727
|
+
deleteSelectedRecords(dirty = true) {
|
|
728
|
+
const records = this.selected || ([] as GristRecord[])
|
|
729
|
+
|
|
730
|
+
records.forEach(record => {
|
|
731
|
+
if (dirty) {
|
|
732
|
+
record.__dirty__ = '-'
|
|
733
|
+
} else {
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const rowIndex = this._data.records.findIndex(rec => rec === record)
|
|
737
|
+
this._data.records.splice(rowIndex, 1)
|
|
738
|
+
})
|
|
739
|
+
|
|
740
|
+
this.checkDirties()
|
|
741
|
+
}
|
|
693
742
|
}
|
|
@@ -41,10 +41,6 @@ export class RecordPartial extends LitElement {
|
|
|
41
41
|
min-height: 42px;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
ox-list-gutter {
|
|
45
|
-
flex: 0 0 14px;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
44
|
:host([dirty])::before {
|
|
49
45
|
content: '';
|
|
50
46
|
position: absolute;
|
|
@@ -59,7 +55,7 @@ export class RecordPartial extends LitElement {
|
|
|
59
55
|
|
|
60
56
|
:host > * {
|
|
61
57
|
margin: var(--data-list-item-margin);
|
|
62
|
-
zoom:
|
|
58
|
+
zoom: var(--grist-input-zoom);
|
|
63
59
|
}
|
|
64
60
|
|
|
65
61
|
:host [dirty] {
|
package/src/data-manipulator.ts
CHANGED
|
@@ -2,11 +2,22 @@ import { LitElement } from 'lit'
|
|
|
2
2
|
import { property } from 'lit/decorators.js'
|
|
3
3
|
|
|
4
4
|
import { ZERO_CONFIG, ZERO_DATA } from './configure/zero-config'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ColumnConfig,
|
|
7
|
+
FilterValue,
|
|
8
|
+
GristConfig,
|
|
9
|
+
GristData,
|
|
10
|
+
GristRecord,
|
|
11
|
+
PaginationConfig,
|
|
12
|
+
SortersConfig
|
|
13
|
+
} from './types'
|
|
6
14
|
|
|
7
15
|
export class DataManipulator extends LitElement {
|
|
8
16
|
@property({ type: Object }) config: GristConfig = ZERO_CONFIG
|
|
9
17
|
@property({ type: Object }) data: GristData = ZERO_DATA
|
|
18
|
+
@property({ type: Object }) sorters: SortersConfig = []
|
|
19
|
+
@property({ type: Object }) filters: FilterValue[] = []
|
|
20
|
+
@property({ type: Object }) pagination: PaginationConfig = {}
|
|
10
21
|
|
|
11
22
|
constructor() {
|
|
12
23
|
super()
|
package/src/data-provider.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { DataConsumer } from './data-consumer'
|
|
5
|
-
import { ZERO_RECORDS } from './configure/zero-config'
|
|
6
|
-
import deepEquals from 'lodash-es/isEqual'
|
|
1
|
+
import { ZERO_RECORDS } from './configure/zero-config.js'
|
|
2
|
+
import { DataConsumer } from './data-consumer.js'
|
|
3
|
+
import { FetchHandler, FetchOption, FilterValue, GristRecord, SorterConfig, SortersConfig } from './types.js'
|
|
7
4
|
|
|
8
5
|
function EMPTY_FETCHHANDLER() {
|
|
9
6
|
return {
|
|
@@ -33,8 +30,7 @@ export class DataProvider {
|
|
|
33
30
|
|
|
34
31
|
private _pageChangeHandler: EventListener = this.onPageChange.bind(this)
|
|
35
32
|
private _limitChangeHandler = this.onLimitChange.bind(this)
|
|
36
|
-
private
|
|
37
|
-
private _filtersChangeHandler = this.onFiltersChange.bind(this)
|
|
33
|
+
private _fetchParamsChangeHandler = this.onFetchParamsChange.bind(this)
|
|
38
34
|
private _recordChangeHandler = this.onRecordChange.bind(this)
|
|
39
35
|
private _attachPageHandler: EventListener = this.onAttachPage.bind(this)
|
|
40
36
|
|
|
@@ -49,8 +45,7 @@ export class DataProvider {
|
|
|
49
45
|
this.consumer.addEventListener('attach-page', this._attachPageHandler)
|
|
50
46
|
this.consumer.addEventListener('page-change', this._pageChangeHandler)
|
|
51
47
|
this.consumer.addEventListener('limit-change', this._limitChangeHandler)
|
|
52
|
-
this.consumer.addEventListener('
|
|
53
|
-
this.consumer.addEventListener('filters-change', this._filtersChangeHandler)
|
|
48
|
+
this.consumer.addEventListener('fetch-params-change', this._fetchParamsChangeHandler)
|
|
54
49
|
this.consumer.addEventListener('record-change', this._recordChangeHandler)
|
|
55
50
|
}
|
|
56
51
|
|
|
@@ -58,8 +53,7 @@ export class DataProvider {
|
|
|
58
53
|
this.consumer?.removeEventListener('attach-page', this._attachPageHandler)
|
|
59
54
|
this.consumer?.removeEventListener('page-change', this._pageChangeHandler)
|
|
60
55
|
this.consumer?.removeEventListener('limit-change', this._limitChangeHandler)
|
|
61
|
-
this.consumer?.removeEventListener('
|
|
62
|
-
this.consumer?.removeEventListener('filters-change', this._filtersChangeHandler)
|
|
56
|
+
this.consumer?.removeEventListener('fetch-params-change', this._fetchParamsChangeHandler)
|
|
63
57
|
this.consumer?.removeEventListener('record-change', this._recordChangeHandler)
|
|
64
58
|
}
|
|
65
59
|
|
|
@@ -77,21 +71,17 @@ export class DataProvider {
|
|
|
77
71
|
this.fetch({ limit })
|
|
78
72
|
}
|
|
79
73
|
|
|
80
|
-
|
|
81
|
-
const { sorters } = (e as CustomEvent).detail || {}
|
|
82
|
-
|
|
74
|
+
onFetchParamsChange(e: Event) {
|
|
75
|
+
const { sorters, filters, from } = (e as CustomEvent).detail || {}
|
|
76
|
+
|
|
77
|
+
sorters && (this.sorters = sorters)
|
|
78
|
+
filters && (this.filters = filters)
|
|
83
79
|
|
|
84
80
|
if (this.consumer?.mode !== 'GRID') {
|
|
85
81
|
this.page = 0
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
this.fetch()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
onFiltersChange(e: Event) {
|
|
92
|
-
const { filters } = (e as CustomEvent).detail || {}
|
|
93
|
-
|
|
94
|
-
this.filters = filters
|
|
84
|
+
from !== 'config' && this.fetch()
|
|
95
85
|
}
|
|
96
86
|
|
|
97
87
|
onRecordChange(e: Event) {
|
|
@@ -154,13 +144,7 @@ export class DataProvider {
|
|
|
154
144
|
}
|
|
155
145
|
|
|
156
146
|
set filters(filters) {
|
|
157
|
-
if (this._filters === filters || deepEquals(this._filters, filters)) {
|
|
158
|
-
return
|
|
159
|
-
}
|
|
160
|
-
|
|
161
147
|
this._filters = filters
|
|
162
|
-
|
|
163
|
-
this.fetch()
|
|
164
148
|
}
|
|
165
149
|
|
|
166
150
|
async attach(reset = false) {
|
|
@@ -188,6 +172,7 @@ export class DataProvider {
|
|
|
188
172
|
page,
|
|
189
173
|
limit,
|
|
190
174
|
sorters: this.sorters,
|
|
175
|
+
filters: this.filters,
|
|
191
176
|
options: this.fetchOptions
|
|
192
177
|
}))
|
|
193
178
|
},
|
|
@@ -251,7 +236,6 @@ export class DataProvider {
|
|
|
251
236
|
if (maxpage < page) {
|
|
252
237
|
return await this.fetch({ page: maxpage, limit })
|
|
253
238
|
}
|
|
254
|
-
// CONFIRM-ME 위 코드에 대한 설명이 필요함!!!.
|
|
255
239
|
|
|
256
240
|
// page와 limit이 없는 경우 records 검사 전에 초기화
|
|
257
241
|
this.page = this.page || page
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import './data-report-field'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { LitElement, PropertyValues, html } from 'lit'
|
|
5
|
-
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
3
|
+
import { html, LitElement, PropertyValues } from 'lit'
|
|
6
4
|
import { customElement, property } from 'lit/decorators.js'
|
|
7
5
|
|
|
6
|
+
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
7
|
+
import { ColumnConfig, GristConfig, GristData } from '../types'
|
|
8
|
+
import { dataReportBodyStyle } from './data-report-body-style'
|
|
8
9
|
import { dataReportBodyClickHandler } from './event-handlers/data-report-body-click-handler'
|
|
9
10
|
import { dataReportBodyDblclickHandler } from './event-handlers/data-report-body-dblclick-handler'
|
|
10
11
|
import { dataReportBodyKeydownHandler } from './event-handlers/data-report-body-keydown-handler'
|
|
11
|
-
import { dataReportBodyStyle } from './data-report-body-style'
|
|
12
12
|
|
|
13
13
|
function calcScrollPos(parent: DataReportBody, child: Element) {
|
|
14
14
|
/* getBoundingClientRect는 safari에서 스크롤 상태에서 다른 브라우저와는 다른 값을 리턴함 - 사파리는 약간 이상 작동함. */
|
|
@@ -182,7 +182,7 @@ export class DataReportBody extends LitElement {
|
|
|
182
182
|
focus() {
|
|
183
183
|
super.focus()
|
|
184
184
|
|
|
185
|
-
if (!this.focused || this.focused.row
|
|
185
|
+
if (!this.focused || this.focused.row == null) {
|
|
186
186
|
this.focused = { row: 0, column: 0 }
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LitElement, css, html } from 'lit'
|
|
3
|
-
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
1
|
+
import { css, html, LitElement } from 'lit'
|
|
4
2
|
import { customElement, property } from 'lit/decorators.js'
|
|
3
|
+
import throttle from 'lodash-es/throttle'
|
|
5
4
|
|
|
5
|
+
import { ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'
|
|
6
|
+
import { ColumnConfig, GristConfig, GristData, SortersConfig } from '../types'
|
|
6
7
|
import { supportsPassive } from '../utils'
|
|
7
|
-
import throttle from 'lodash-es/throttle'
|
|
8
8
|
|
|
9
9
|
@customElement('ox-report-header')
|
|
10
10
|
class DataReportHeader extends LitElement {
|
|
@@ -170,7 +170,7 @@ class DataReportHeader extends LitElement {
|
|
|
170
170
|
this._sorters = sorters
|
|
171
171
|
|
|
172
172
|
this.dispatchEvent(
|
|
173
|
-
new CustomEvent('
|
|
173
|
+
new CustomEvent('fetch-params-change', {
|
|
174
174
|
bubbles: true,
|
|
175
175
|
composed: true,
|
|
176
176
|
detail: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LitElement, css, html } from 'lit'
|
|
3
|
-
import { ZERO_COLUMN, ZERO_RECORD } from '../configure/zero-config'
|
|
1
|
+
import { css, html, LitElement } from 'lit'
|
|
4
2
|
import { customElement, property } from 'lit/decorators.js'
|
|
5
3
|
|
|
4
|
+
import { ZERO_COLUMN, ZERO_RECORD } from '../configure/zero-config'
|
|
6
5
|
import { DataGridField } from '../data-grid/data-grid-field'
|
|
6
|
+
import { ColumnConfig, GristRecord } from '../types'
|
|
7
7
|
|
|
8
8
|
const STYLE = css`
|
|
9
9
|
:host {
|
|
@@ -16,13 +16,14 @@ const STYLE = css`
|
|
|
16
16
|
|
|
17
17
|
border: 0;
|
|
18
18
|
background-color: transparent;
|
|
19
|
+
|
|
20
|
+
overflow: hidden;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
:host > * {
|
|
22
24
|
display: flex;
|
|
23
25
|
|
|
24
26
|
width: 100%;
|
|
25
|
-
height: 100%;
|
|
26
27
|
|
|
27
28
|
border: 0;
|
|
28
29
|
background-color: transparent;
|
|
@@ -31,6 +32,8 @@ const STYLE = css`
|
|
|
31
32
|
|
|
32
33
|
font-size: inherit;
|
|
33
34
|
font-family: inherit;
|
|
35
|
+
|
|
36
|
+
align-items: center;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
:host > style {
|
|
@@ -116,7 +119,7 @@ export class OxGristEditor extends LitElement {
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
formatForEditor(value: any): any {
|
|
119
|
-
return value
|
|
122
|
+
return value == null ? '' : value
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
formatFromEditor(e: Event): any {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import '@operato/input/ox-checkbox.js'
|
|
2
2
|
|
|
3
|
-
import { FilterConfigObject, FilterSelectRenderer } from '../types'
|
|
4
|
-
|
|
5
3
|
import { html } from 'lit-html'
|
|
6
4
|
|
|
5
|
+
import { FilterConfigObject, FilterSelectRenderer } from '../types.js'
|
|
6
|
+
|
|
7
7
|
export const FilterCheckbox: FilterSelectRenderer = (column, value, owner) => {
|
|
8
8
|
const filter = column.filter as FilterConfigObject
|
|
9
9
|
const options = filter?.options
|
|
@@ -13,7 +13,7 @@ export const FilterCheckbox: FilterSelectRenderer = (column, value, owner) => {
|
|
|
13
13
|
name=${column.name}
|
|
14
14
|
?checked=${value}
|
|
15
15
|
indeterminatable
|
|
16
|
-
?indeterminate=${value
|
|
16
|
+
?indeterminate=${value == null}
|
|
17
17
|
@change=${(e: CustomEvent) => {
|
|
18
18
|
;(e.target as HTMLElement).dispatchEvent(
|
|
19
19
|
new CustomEvent('filter-change', {
|