@operato/data-grist 0.3.16 → 0.3.20
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 +39 -0
- package/custom-elements.json +693 -674
- package/demo/data-grist-test.html +142 -85
- package/demo/index.html +65 -97
- package/dist/src/configure/column-builder.js +26 -2
- package/dist/src/configure/column-builder.js.map +1 -1
- package/dist/src/data-card/record-card.d.ts +0 -2
- package/dist/src/data-card/record-card.js +7 -59
- package/dist/src/data-card/record-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +7 -1
- package/dist/src/data-grid/data-grid-body.js +21 -0
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.js +5 -3
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.d.ts +1 -0
- package/dist/src/data-grid/data-grid.js +6 -0
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/src/data-grist.js +5 -0
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/record-partial.d.ts +0 -2
- package/dist/src/data-list/record-partial.js +7 -58
- package/dist/src/data-list/record-partial.js.map +1 -1
- package/dist/src/editors/image-input.d.ts +7 -0
- package/dist/src/editors/image-input.js +31 -0
- package/dist/src/editors/image-input.js.map +1 -0
- package/dist/src/editors/index.d.ts +1 -0
- package/dist/src/editors/index.js +1 -0
- package/dist/src/editors/index.js.map +1 -1
- package/dist/src/editors/input-editors.d.ts +1 -8
- package/dist/src/editors/input-editors.js +3 -47
- package/dist/src/editors/input-editors.js.map +1 -1
- package/dist/src/editors/registry.js +2 -1
- package/dist/src/editors/registry.js.map +1 -1
- package/dist/src/filters/filter-checkbox.js +2 -2
- package/dist/src/filters/filter-checkbox.js.map +1 -1
- package/dist/src/filters/filter-input.js +1 -1
- package/dist/src/filters/filter-input.js.map +1 -1
- package/dist/src/filters/filter-range-date.js +1 -1
- package/dist/src/filters/filter-range-date.js.map +1 -1
- package/dist/src/filters/filter-range-number.js +1 -1
- package/dist/src/filters/filter-range-number.js.map +1 -1
- package/dist/src/filters/filter-select.js +2 -2
- package/dist/src/filters/filter-select.js.map +1 -1
- package/dist/src/filters/filters-form.d.ts +9 -5
- package/dist/src/filters/filters-form.js +63 -15
- package/dist/src/filters/filters-form.js.map +1 -1
- package/dist/src/handlers/record-view-handler.d.ts +1 -2
- package/dist/src/handlers/record-view-handler.js +5 -35
- package/dist/src/handlers/record-view-handler.js.map +1 -1
- package/dist/src/handlers/select-row-toggle.d.ts +1 -1
- package/dist/src/handlers/select-row-toggle.js.map +1 -1
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +3 -1
- 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 +0 -74
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -1
- package/dist/src/record-view/index.d.ts +1 -0
- package/dist/src/record-view/index.js +1 -0
- package/dist/src/record-view/index.js.map +1 -1
- package/dist/src/record-view/record-creator.d.ts +5 -2
- package/dist/src/record-view/record-creator.js +69 -14
- package/dist/src/record-view/record-creator.js.map +1 -1
- package/dist/src/record-view/record-view-body.js +6 -6
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/record-view/record-view-handler.d.ts +9 -0
- package/dist/src/record-view/record-view-handler.js +57 -0
- package/dist/src/record-view/record-view-handler.js.map +1 -0
- package/dist/src/record-view/record-view.d.ts +2 -3
- package/dist/src/record-view/record-view.js +11 -61
- package/dist/src/record-view/record-view.js.map +1 -1
- package/dist/src/sorters/sorters-control.js +22 -8
- package/dist/src/sorters/sorters-control.js.map +1 -1
- package/dist/src/types.d.ts +6 -3
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/configure/column-builder.ts +29 -3
- package/src/data-card/record-card.ts +14 -74
- package/src/data-grid/data-grid-body.ts +38 -1
- package/src/data-grid/data-grid-header.ts +7 -5
- package/src/data-grid/data-grid.ts +12 -0
- package/src/data-grist.ts +8 -0
- package/src/data-list/record-partial.ts +14 -73
- package/src/editors/image-input.ts +29 -0
- package/src/editors/index.ts +1 -0
- package/src/editors/input-editors.ts +5 -48
- package/src/editors/registry.ts +1 -1
- package/src/filters/filter-checkbox.ts +3 -2
- package/src/filters/filter-input.ts +3 -3
- package/src/filters/filter-range-date.ts +3 -3
- package/src/filters/filter-range-number.ts +3 -3
- package/src/filters/filter-select.ts +3 -2
- package/src/filters/filters-form.ts +77 -41
- package/src/handlers/record-view-handler.ts +8 -44
- package/src/handlers/select-row-toggle.ts +1 -2
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +3 -1
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -89
- package/src/record-view/index.ts +1 -0
- package/src/record-view/record-creator.ts +85 -16
- package/src/record-view/record-view-body.ts +6 -6
- package/src/record-view/record-view-handler.ts +86 -0
- package/src/record-view/record-view.ts +12 -62
- package/src/sorters/sorters-control.ts +22 -8
- package/src/types.ts +33 -30
|
@@ -7,6 +7,7 @@ import { css, html, LitElement, PropertyValues } from 'lit'
|
|
|
7
7
|
import { customElement, property } from 'lit/decorators.js'
|
|
8
8
|
|
|
9
9
|
import { ZERO_CONFIG, ZERO_DATA, ZERO_RECORD } from '../configure/zero-config'
|
|
10
|
+
import { RecordViewHandler } from '../record-view/record-view-handler'
|
|
10
11
|
import { GristConfig, GristData, GristRecord } from '../types'
|
|
11
12
|
import { recordPartialClickHandler } from './event-handlers/record-partial-click-handler'
|
|
12
13
|
import { recordPartialDblClickHandler } from './event-handlers/record-partial-dblclick-handler'
|
|
@@ -122,32 +123,6 @@ export class RecordPartial extends LitElement {
|
|
|
122
123
|
super.attributeChangedCallback(name, oldval, newval)
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
onFieldChange(e: Event) {
|
|
126
|
-
/* record-view의 이벤트를 부모에게로 전달한다. */
|
|
127
|
-
this.dispatchEvent(
|
|
128
|
-
new CustomEvent('field-change', {
|
|
129
|
-
bubbles: true,
|
|
130
|
-
composed: true,
|
|
131
|
-
detail: (e as any).detail
|
|
132
|
-
})
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
get recordView() {
|
|
137
|
-
if (!this._recordView) {
|
|
138
|
-
this._recordView = document.createElement('ox-record-view')
|
|
139
|
-
this._recordView.addEventListener('field-change', (e: CustomEvent) => this.onFieldChange(e))
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
var columns = this.config.columns
|
|
143
|
-
|
|
144
|
-
this._recordView.columns = columns
|
|
145
|
-
this._recordView.record = this.record
|
|
146
|
-
this._recordView.rowIndex = this.rowIndex
|
|
147
|
-
|
|
148
|
-
return this._recordView
|
|
149
|
-
}
|
|
150
|
-
|
|
151
126
|
firstUpdated() {
|
|
152
127
|
/*
|
|
153
128
|
long-press
|
|
@@ -158,6 +133,8 @@ export class RecordPartial extends LitElement {
|
|
|
158
133
|
// this.renderRoot.addEventListener('long-press', recordPartialLongPressHandler.bind(this))
|
|
159
134
|
this.renderRoot.addEventListener('click', recordPartialClickHandler.bind(this) as EventListener)
|
|
160
135
|
this.renderRoot.addEventListener('dblclick', recordPartialDblClickHandler.bind(this) as EventListener)
|
|
136
|
+
|
|
137
|
+
this.addEventListener('show-record-view', () => this.popupRecordView())
|
|
161
138
|
}
|
|
162
139
|
|
|
163
140
|
updated(changes: PropertyValues<this>) {
|
|
@@ -234,53 +211,17 @@ export class RecordPartial extends LitElement {
|
|
|
234
211
|
title = column?.record.renderer(title, column, this.record, this.rowIndex, this /* cautious */)
|
|
235
212
|
}
|
|
236
213
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this.dispatchEvent(
|
|
249
|
-
new CustomEvent('record-reset', {
|
|
250
|
-
bubbles: true,
|
|
251
|
-
composed: true,
|
|
252
|
-
detail: {
|
|
253
|
-
record: this.record,
|
|
254
|
-
row: this.rowIndex
|
|
255
|
-
}
|
|
256
|
-
})
|
|
257
|
-
)
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
this.recordView.addEventListener('cancel', () => {
|
|
261
|
-
this.dispatchEvent(
|
|
262
|
-
new CustomEvent('record-reset', {
|
|
263
|
-
bubbles: true,
|
|
264
|
-
composed: true,
|
|
265
|
-
detail: {
|
|
266
|
-
record: this.record,
|
|
267
|
-
row: this.rowIndex
|
|
268
|
-
}
|
|
269
|
-
})
|
|
270
|
-
)
|
|
271
|
-
popup.close()
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
this.recordView.addEventListener('ok', () => {
|
|
275
|
-
popup.close()
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
popup.onclosed = () => {
|
|
279
|
-
delete this._recordView
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
})
|
|
214
|
+
this._recordView = RecordViewHandler(
|
|
215
|
+
this.config.columns,
|
|
216
|
+
this.record,
|
|
217
|
+
this.rowIndex,
|
|
218
|
+
this,
|
|
219
|
+
{
|
|
220
|
+
title
|
|
221
|
+
},
|
|
222
|
+
() => {
|
|
223
|
+
delete this._recordView
|
|
224
|
+
}
|
|
284
225
|
)
|
|
285
226
|
}
|
|
286
227
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import '@operato/input/ox-input-image.js'
|
|
2
|
+
|
|
3
|
+
import { html } from 'lit'
|
|
4
|
+
import { customElement } from 'lit/decorators.js'
|
|
5
|
+
|
|
6
|
+
import { InputEditor } from './input-editors'
|
|
7
|
+
|
|
8
|
+
@customElement('ox-image-input')
|
|
9
|
+
export class ImageInput extends InputEditor {
|
|
10
|
+
get editorTemplate() {
|
|
11
|
+
return html` <ox-input-image .value=${this.value}></ox-input-image> `
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
_onchange(e: Event) {
|
|
15
|
+
e.stopPropagation()
|
|
16
|
+
this._dirtyValue = this.formatFromEditor(e)
|
|
17
|
+
this._onfocusout()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
formatFromEditor(e: Event) {
|
|
21
|
+
// value가 image file object인지, image url인지 확인
|
|
22
|
+
const input = e.target as HTMLInputElement
|
|
23
|
+
if (input.files?.[0]) {
|
|
24
|
+
return input.files[0]
|
|
25
|
+
} else {
|
|
26
|
+
return input.value
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/editors/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ZERO_COLUMN, ZERO_RECORD } from '../configure/zero-config'
|
|
4
|
-
import { customElement, property, query } from 'lit/decorators.js'
|
|
1
|
+
import { css, html, LitElement } from 'lit'
|
|
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 {
|
|
@@ -17,7 +17,7 @@ const STYLE = css`
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
:host > * {
|
|
20
|
-
display:
|
|
20
|
+
display: flex;
|
|
21
21
|
|
|
22
22
|
width: 100%;
|
|
23
23
|
height: 100%;
|
|
@@ -279,49 +279,6 @@ export class CheckboxInput extends InputEditor {
|
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
@customElement('ox-image-input')
|
|
283
|
-
export class ImageInput extends InputEditor {
|
|
284
|
-
@query('input[type=file]') imageInput!: HTMLElement
|
|
285
|
-
|
|
286
|
-
get editorTemplate() {
|
|
287
|
-
return html`${this.value
|
|
288
|
-
? html`<span
|
|
289
|
-
>${this.value.name || this.value}<button
|
|
290
|
-
@click=${() => {
|
|
291
|
-
this.imageInput.dispatchEvent(
|
|
292
|
-
new Event('change', {
|
|
293
|
-
bubbles: true
|
|
294
|
-
})
|
|
295
|
-
)
|
|
296
|
-
}}
|
|
297
|
-
>
|
|
298
|
-
X
|
|
299
|
-
</button></span
|
|
300
|
-
>`
|
|
301
|
-
: ''} <input type="file" accept="image/*" /> `
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
focus() {
|
|
305
|
-
if (!this.value) this.imageInput.click()
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
_onchange(e: Event) {
|
|
309
|
-
e.stopPropagation()
|
|
310
|
-
this._dirtyValue = this.formatFromEditor(e)
|
|
311
|
-
this._onfocusout()
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
formatFromEditor(e: Event) {
|
|
315
|
-
// value가 image file object인지, image url인지 확인
|
|
316
|
-
const input = e.target as HTMLInputElement
|
|
317
|
-
if (input.files?.[0]) {
|
|
318
|
-
return input.files[0]
|
|
319
|
-
} else {
|
|
320
|
-
return input.value
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
282
|
@customElement('ox-select-input')
|
|
326
283
|
export class Select extends InputEditor {
|
|
327
284
|
get editorTemplate() {
|
package/src/editors/registry.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { DataGridField } from '../data-grid/data-grid-field'
|
|
2
2
|
import { ColumnConfig, FieldEditor, GristRecord } from '../types'
|
|
3
|
+
import { ImageInput } from './image-input'
|
|
3
4
|
import {
|
|
4
5
|
CheckboxInput,
|
|
5
6
|
ColorInput,
|
|
6
7
|
DateInput,
|
|
7
8
|
DateTimeInput,
|
|
8
9
|
EmailInput,
|
|
9
|
-
ImageInput,
|
|
10
10
|
InputEditor,
|
|
11
11
|
MonthInput,
|
|
12
12
|
NumberInput,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { html } from 'lit-html'
|
|
2
2
|
|
|
3
|
-
import { FilterSelectRenderer } from '../types'
|
|
3
|
+
import { FilterConfigObject, FilterSelectRenderer } from '../types'
|
|
4
4
|
|
|
5
5
|
export const FilterCheckbox: FilterSelectRenderer = (column, owner) => {
|
|
6
|
-
const
|
|
6
|
+
const filter = column.filter as FilterConfigObject
|
|
7
|
+
const options = filter?.options
|
|
7
8
|
|
|
8
9
|
return html`
|
|
9
10
|
<input
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { html } from 'lit-html'
|
|
2
2
|
|
|
3
|
-
import { FilterSelectRenderer } from '../types'
|
|
3
|
+
import { FilterConfigObject, FilterSelectRenderer } from '../types'
|
|
4
4
|
|
|
5
5
|
export const FilterInput: FilterSelectRenderer = (column, owner) => {
|
|
6
|
-
const filter = column.filter
|
|
7
|
-
const type =
|
|
6
|
+
const filter = column.filter as FilterConfigObject
|
|
7
|
+
const type = filter?.type || column.type
|
|
8
8
|
|
|
9
9
|
return html` <input type=${type} name="${column.name}" /> `
|
|
10
10
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { html } from 'lit-html'
|
|
2
2
|
|
|
3
|
-
import { FilterSelectRenderer } from '../types'
|
|
3
|
+
import { FilterConfigObject, FilterSelectRenderer } from '../types'
|
|
4
4
|
|
|
5
5
|
export const FilterRangeDate: FilterSelectRenderer = (column, owner) => {
|
|
6
|
-
const filter = column.filter
|
|
7
|
-
var type =
|
|
6
|
+
const filter = column.filter as FilterConfigObject
|
|
7
|
+
var type = filter?.type || column.type
|
|
8
8
|
if (type === 'datetime') {
|
|
9
9
|
type = 'datetime-local'
|
|
10
10
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { html } from 'lit-html'
|
|
2
2
|
|
|
3
|
-
import { FilterSelectRenderer } from '../types'
|
|
3
|
+
import { FilterConfigObject, FilterSelectRenderer } from '../types'
|
|
4
4
|
|
|
5
5
|
export const FilterRangeNumber: FilterSelectRenderer = (column, owner) => {
|
|
6
|
-
const filter = column.filter
|
|
7
|
-
const type =
|
|
6
|
+
const filter = column.filter as FilterConfigObject
|
|
7
|
+
const type = filter?.type || column.type
|
|
8
8
|
|
|
9
9
|
return html`
|
|
10
10
|
<input name="${column.name}" type="number" placeholder="minimum" /> ~
|
|
@@ -2,10 +2,11 @@ import '@operato/input/ox-checkbox.js'
|
|
|
2
2
|
|
|
3
3
|
import { html } from 'lit-html'
|
|
4
4
|
|
|
5
|
-
import { FilterSelectRenderer } from '../types'
|
|
5
|
+
import { FilterConfigObject, FilterSelectRenderer } from '../types'
|
|
6
6
|
|
|
7
7
|
export const FilterSelect: FilterSelectRenderer = (column, owner) => {
|
|
8
|
-
const
|
|
8
|
+
const filter = column.filter as FilterConfigObject
|
|
9
|
+
const options = filter?.options || []
|
|
9
10
|
|
|
10
11
|
return html`
|
|
11
12
|
${options?.map((option: string) => html` <ox-checkbox option value=${option}>${option}</ox-checkbox> `)}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import '@operato/input/ox-checkbox.js'
|
|
2
2
|
import '@operato/input/ox-select.js'
|
|
3
3
|
import '@operato/popup/ox-popup-list.js'
|
|
4
|
+
import '@operato/input/ox-input-search.js'
|
|
4
5
|
|
|
5
|
-
import { css, html, LitElement, TemplateResult } from 'lit'
|
|
6
|
-
import { customElement,
|
|
6
|
+
import { css, html, LitElement, PropertyValues, TemplateResult } from 'lit'
|
|
7
|
+
import { customElement, queryAsync, state } from 'lit/decorators.js'
|
|
7
8
|
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { FilterConfigObject } from '..'
|
|
10
|
+
import { DataGrist } from '../data-grist'
|
|
11
|
+
import { ColumnConfig, FilterOperator, GristConfig } from '../types'
|
|
10
12
|
import { FilterStyles } from './filter-styles'
|
|
11
13
|
import { getFilterRenderer } from './registry'
|
|
12
14
|
|
|
@@ -14,30 +16,7 @@ export type QueryFilterRangeValue = [from: number, to: number]
|
|
|
14
16
|
|
|
15
17
|
export type QueryFilter = {
|
|
16
18
|
name: string
|
|
17
|
-
operator
|
|
18
|
-
| 'eq'
|
|
19
|
-
| 'between'
|
|
20
|
-
| 'gte'
|
|
21
|
-
| 'lte'
|
|
22
|
-
| 'is_not_true'
|
|
23
|
-
| 'in'
|
|
24
|
-
| 'like'
|
|
25
|
-
| 'i_like'
|
|
26
|
-
| 'noteq'
|
|
27
|
-
| 'is_empty_num_id'
|
|
28
|
-
| 'is_blank'
|
|
29
|
-
| 'is_present'
|
|
30
|
-
| 'is_not_false'
|
|
31
|
-
| 'is_true'
|
|
32
|
-
| 'is_false'
|
|
33
|
-
| 'is_not_null'
|
|
34
|
-
| 'is_null'
|
|
35
|
-
| 'notin_with_null'
|
|
36
|
-
| 'notin'
|
|
37
|
-
| 'gt'
|
|
38
|
-
| 'lt'
|
|
39
|
-
| 'i_nlike'
|
|
40
|
-
| 'nlike'
|
|
19
|
+
operator: FilterOperator
|
|
41
20
|
value: any
|
|
42
21
|
}
|
|
43
22
|
|
|
@@ -61,16 +40,57 @@ export class FiltersForm extends LitElement {
|
|
|
61
40
|
`
|
|
62
41
|
]
|
|
63
42
|
|
|
64
|
-
@
|
|
65
|
-
@property({ type: String }) defaultOperator: string = 'eq'
|
|
66
|
-
@query('form') form!: HTMLFormElement
|
|
43
|
+
@state() config!: GristConfig
|
|
67
44
|
|
|
68
|
-
|
|
69
|
-
|
|
45
|
+
@state() filterColumns: ColumnConfig[] = []
|
|
46
|
+
@state() searchColumns: ColumnConfig[] = []
|
|
47
|
+
|
|
48
|
+
@queryAsync('form') form!: HTMLFormElement
|
|
49
|
+
|
|
50
|
+
connectedCallback(): void {
|
|
51
|
+
super.connectedCallback()
|
|
52
|
+
|
|
53
|
+
const grist = this.closest('ox-grist') as DataGrist
|
|
54
|
+
|
|
55
|
+
if (grist) {
|
|
56
|
+
this.config = grist.compiledConfig
|
|
57
|
+
grist.addEventListener('config-change', (e: Event) => {
|
|
58
|
+
this.config = (e as CustomEvent).detail
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
this.renderRoot.addEventListener('change', async (e: Event) => {
|
|
62
|
+
e.stopPropagation()
|
|
63
|
+
|
|
64
|
+
this.dispatchEvent(
|
|
65
|
+
new CustomEvent('change', {
|
|
66
|
+
bubbles: true,
|
|
67
|
+
composed: true,
|
|
68
|
+
detail: await this.getQueryFilters()
|
|
69
|
+
})
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
}
|
|
70
74
|
|
|
75
|
+
updated(changes: PropertyValues<this>) {
|
|
76
|
+
if (changes.has('config')) {
|
|
77
|
+
const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter)
|
|
78
|
+
this.filterColumns = filters.filter((columnConfig: ColumnConfig) => {
|
|
79
|
+
const filter = columnConfig.filter as FilterConfigObject
|
|
80
|
+
return filter!.operator !== 'search'
|
|
81
|
+
})
|
|
82
|
+
this.searchColumns = filters.filter(columnConfig => {
|
|
83
|
+
const filter = columnConfig.filter as FilterConfigObject
|
|
84
|
+
return filter!.operator === 'search'
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
render(): TemplateResult {
|
|
71
90
|
return html`
|
|
72
91
|
<form>
|
|
73
|
-
${
|
|
92
|
+
${this.searchColumns.length === 0 ? html`` : html` <ox-input-search name="search"></ox-input-search> `}
|
|
93
|
+
${this.filterColumns.map((column: ColumnConfig) => {
|
|
74
94
|
const { name, label, filter } = column
|
|
75
95
|
const placeholder =
|
|
76
96
|
typeof label === 'string'
|
|
@@ -81,8 +101,8 @@ export class FiltersForm extends LitElement {
|
|
|
81
101
|
? label.renderer()
|
|
82
102
|
: name
|
|
83
103
|
|
|
84
|
-
const type =
|
|
85
|
-
const idx =
|
|
104
|
+
const type = (filter as FilterConfigObject).type
|
|
105
|
+
const idx = (filter as FilterConfigObject).operator === 'between' ? 1 : 0
|
|
86
106
|
const renderer = getFilterRenderer(type)[idx]
|
|
87
107
|
|
|
88
108
|
if (!renderer) {
|
|
@@ -103,14 +123,14 @@ export class FiltersForm extends LitElement {
|
|
|
103
123
|
`
|
|
104
124
|
}
|
|
105
125
|
|
|
106
|
-
|
|
107
|
-
|
|
126
|
+
async getQueryFilters(): Promise<QueryFilter[]> {
|
|
127
|
+
const formData = new FormData(await this.form)
|
|
128
|
+
const search: string | undefined = formData.get('search')?.toString()
|
|
108
129
|
|
|
109
|
-
|
|
110
|
-
.filter(columnConfig => columnConfig.filter)
|
|
130
|
+
var filters = this.filterColumns
|
|
111
131
|
.map((column: ColumnConfig) => {
|
|
112
132
|
const { name, filter } = column
|
|
113
|
-
const operator =
|
|
133
|
+
const operator = (filter as FilterConfigObject).operator
|
|
114
134
|
|
|
115
135
|
var value = formData.getAll(name)
|
|
116
136
|
if (value.length == 0) {
|
|
@@ -128,5 +148,21 @@ export class FiltersForm extends LitElement {
|
|
|
128
148
|
}
|
|
129
149
|
})
|
|
130
150
|
.filter(result => result !== undefined) as QueryFilter[]
|
|
151
|
+
|
|
152
|
+
if (search) {
|
|
153
|
+
filters = filters.concat(
|
|
154
|
+
this.searchColumns.map((column: ColumnConfig) => {
|
|
155
|
+
const { name } = column
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
name,
|
|
159
|
+
operator: 'search',
|
|
160
|
+
value: `%${search}%`
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return filters
|
|
131
167
|
}
|
|
132
168
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import '../record-view/record-view'
|
|
2
|
-
|
|
3
|
-
import { ColumnConfig, GristData, GristRecord } from '../types'
|
|
4
|
-
|
|
5
1
|
import { DataGridField } from '../data-grid/data-grid-field'
|
|
6
|
-
import {
|
|
2
|
+
import { ColumnConfig, GristData, GristRecord } from '../types'
|
|
7
3
|
|
|
8
4
|
/*
|
|
9
5
|
* handler들은 ox-grid-field 로부터 호출되는 것을 전제로 하며,
|
|
@@ -18,46 +14,14 @@ export const RecordViewHandler = function (
|
|
|
18
14
|
rowIndex: number,
|
|
19
15
|
field: DataGridField
|
|
20
16
|
): void {
|
|
21
|
-
|
|
22
|
-
new CustomEvent('
|
|
17
|
+
field.dispatchEvent(
|
|
18
|
+
new CustomEvent('show-record-view', {
|
|
19
|
+
bubbles: true,
|
|
20
|
+
composed: true,
|
|
23
21
|
detail: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.field=${field}
|
|
27
|
-
.columns=${columns}
|
|
28
|
-
.column=${column}
|
|
29
|
-
.record=${record}
|
|
30
|
-
.rowIndex=${rowIndex}
|
|
31
|
-
@reset=${(e: Event) => {
|
|
32
|
-
field.dispatchEvent(
|
|
33
|
-
new CustomEvent('record-reset', {
|
|
34
|
-
bubbles: true,
|
|
35
|
-
composed: true,
|
|
36
|
-
detail: record
|
|
37
|
-
})
|
|
38
|
-
)
|
|
39
|
-
}}
|
|
40
|
-
@cancel=${(e: Event) => {
|
|
41
|
-
field.dispatchEvent(
|
|
42
|
-
new CustomEvent('record-reset', {
|
|
43
|
-
bubbles: true,
|
|
44
|
-
composed: true,
|
|
45
|
-
detail: record
|
|
46
|
-
})
|
|
47
|
-
)
|
|
48
|
-
// popup.close()
|
|
49
|
-
}}
|
|
50
|
-
@ok=${(e: Event) => {
|
|
51
|
-
// popup.close()
|
|
52
|
-
}}
|
|
53
|
-
></record-view>
|
|
54
|
-
`
|
|
55
|
-
},
|
|
56
|
-
options: {
|
|
57
|
-
backdrop: true,
|
|
58
|
-
size: 'large',
|
|
59
|
-
title: record['name']
|
|
22
|
+
record,
|
|
23
|
+
row: rowIndex
|
|
60
24
|
}
|
|
61
|
-
}
|
|
25
|
+
})
|
|
62
26
|
)
|
|
63
27
|
}
|
|
@@ -6,8 +6,6 @@ import { RecordViewBody } from '../record-view-body'
|
|
|
6
6
|
* - handler의 this 는 ox-record-view-body임.
|
|
7
7
|
*/
|
|
8
8
|
export async function recordViewBodyKeydownHandler(this: RecordViewBody, e: Event): Promise<void> {
|
|
9
|
-
// e.preventDefault()
|
|
10
|
-
|
|
11
9
|
switch ((e as KeyboardEvent).key) {
|
|
12
10
|
case 'Esc':
|
|
13
11
|
case 'Escape':
|
|
@@ -25,91 +23,4 @@ export async function recordViewBodyKeydownHandler(this: RecordViewBody, e: Even
|
|
|
25
23
|
break
|
|
26
24
|
default:
|
|
27
25
|
}
|
|
28
|
-
|
|
29
|
-
// arrow-key
|
|
30
|
-
// var keyCode = e.keyCode
|
|
31
|
-
// var { row = 0, column = 0 } = this.focused || {}
|
|
32
|
-
// var { records = [] } = this.data || {}
|
|
33
|
-
// var maxrow = this.config.rows.appendable ? records.length : records.length - 1
|
|
34
|
-
// var maxcolumn = (this.columns || []).filter(column => !column.hidden).length - 1
|
|
35
|
-
|
|
36
|
-
// if (this.currentTarget) {
|
|
37
|
-
// switch (keyCode) {
|
|
38
|
-
// case KEYCODE.KEY_ESC:
|
|
39
|
-
// /* TODO 편집이 취소되어야 한다. */
|
|
40
|
-
// case KEYCODE.KEY_ENTER:
|
|
41
|
-
// this.currentTarget = null
|
|
42
|
-
// this.focus()
|
|
43
|
-
// return
|
|
44
|
-
|
|
45
|
-
// // case KEYCODE.KEY_TAP:
|
|
46
|
-
// // this.currentTarget = null
|
|
47
|
-
// // column = Math.min(maxcolumn, column + 1)
|
|
48
|
-
// // this.focus()
|
|
49
|
-
// // break
|
|
50
|
-
|
|
51
|
-
// // case KEYCODE.KEY_DOWN:
|
|
52
|
-
// // this.currentTarget = null
|
|
53
|
-
// // row = Math.min(maxrow, row + 1)
|
|
54
|
-
// // this.focus()
|
|
55
|
-
// // break
|
|
56
|
-
|
|
57
|
-
// default:
|
|
58
|
-
// return
|
|
59
|
-
// }
|
|
60
|
-
// } else {
|
|
61
|
-
// switch (keyCode) {
|
|
62
|
-
// case KEYCODE.KEY_UP:
|
|
63
|
-
// row = Math.max(0, row - 1)
|
|
64
|
-
// break
|
|
65
|
-
|
|
66
|
-
// case KEYCODE.KEY_DOWN:
|
|
67
|
-
// row = Math.min(maxrow, row + 1)
|
|
68
|
-
// break
|
|
69
|
-
|
|
70
|
-
// case KEYCODE.KEY_ENTER:
|
|
71
|
-
// this.startEditTarget(row, column)
|
|
72
|
-
// return
|
|
73
|
-
|
|
74
|
-
// case KEYCODE.KEY_LEFT:
|
|
75
|
-
// case KEYCODE.KEY_BACKSPACE:
|
|
76
|
-
// column = Math.max(0, column - 1)
|
|
77
|
-
// break
|
|
78
|
-
|
|
79
|
-
// case KEYCODE.KEY_RIGHT:
|
|
80
|
-
// case KEYCODE.KEY_TAP:
|
|
81
|
-
// column = Math.min(maxcolumn, column + 1)
|
|
82
|
-
// break
|
|
83
|
-
|
|
84
|
-
// case KEYCODE.KEY_PAGEUP:
|
|
85
|
-
// /* TODO 페이지당 레코드의 수를 계산해서 증감시켜야 한다. */
|
|
86
|
-
// row = Math.max(0, row - 10)
|
|
87
|
-
// break
|
|
88
|
-
|
|
89
|
-
// case KEYCODE.KEY_PAGEDOWN:
|
|
90
|
-
// row = Math.min(maxrow, row + 10)
|
|
91
|
-
// break
|
|
92
|
-
|
|
93
|
-
// case KEYCODE.KEY_ESC:
|
|
94
|
-
// return
|
|
95
|
-
|
|
96
|
-
// default:
|
|
97
|
-
// if (
|
|
98
|
-
// (keyCode > 47 && keyCode < 58) || // number keys
|
|
99
|
-
// keyCode == 32 ||
|
|
100
|
-
// keyCode == 13 || // spacebar & return key(s) (if you want to allow carriage returns)
|
|
101
|
-
// (keyCode > 64 && keyCode < 91) || // letter keys
|
|
102
|
-
// (keyCode > 95 && keyCode < 112) || // numpad keys
|
|
103
|
-
// (keyCode > 185 && keyCode < 193) || // ;=,-./` (in order)
|
|
104
|
-
// (keyCode > 218 && keyCode < 223) // [\]' (in order)
|
|
105
|
-
// ) {
|
|
106
|
-
// this.startEditTarget(row, column)
|
|
107
|
-
// }
|
|
108
|
-
// return
|
|
109
|
-
// }
|
|
110
|
-
// }
|
|
111
|
-
|
|
112
|
-
// if (!this.focused || this.focused.row !== row || this.focused.column !== column) {
|
|
113
|
-
// this.dispatchEvent(new CustomEvent('focus-change', { bubbles: true, composed: true, detail: { row, column } }))
|
|
114
|
-
// }
|
|
115
26
|
}
|
package/src/record-view/index.ts
CHANGED