@operato/data-grist 0.3.16 → 0.3.17
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 +10 -0
- package/custom-elements.json +939 -927
- package/demo/index.html +5 -2
- 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.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-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-editor.d.ts +9 -0
- package/dist/src/editors/image-editor.js +53 -0
- package/dist/src/editors/image-editor.js.map +1 -0
- 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 copy.d.ts +75 -0
- package/dist/src/editors/input-editors copy.js +373 -0
- package/dist/src/editors/input-editors copy.js.map +1 -0
- 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/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 copy.d.ts +13 -0
- package/dist/src/record-view/record-creator copy.js +90 -0
- package/dist/src/record-view/record-creator copy.js.map +1 -0
- package/dist/src/record-view/record-creator-backup.d.ts +13 -0
- package/dist/src/record-view/record-creator-backup.js +90 -0
- package/dist/src/record-view/record-creator-backup.js.map +1 -0
- 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 +2 -4
- 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/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- 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.ts +12 -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/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 +2 -4
- package/src/record-view/record-view-handler.ts +86 -0
- package/src/record-view/record-view.ts +12 -62
|
@@ -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,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
|
@@ -2,20 +2,20 @@ import '@material/mwc-icon'
|
|
|
2
2
|
import './record-view'
|
|
3
3
|
|
|
4
4
|
import { html, LitElement } from 'lit'
|
|
5
|
-
import { customElement, state } from 'lit/decorators.js'
|
|
5
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
6
6
|
|
|
7
7
|
import { OxPopup } from '@operato/popup'
|
|
8
8
|
|
|
9
|
-
import { RecordView } from '.'
|
|
10
|
-
import { ColumnConfig } from '..'
|
|
11
9
|
import { DataGrist } from '../data-grist'
|
|
12
|
-
import { GristRecord } from '../types'
|
|
10
|
+
import { ColumnConfig, GristRecord } from '../types'
|
|
11
|
+
import { RecordView } from './record-view'
|
|
13
12
|
|
|
14
13
|
@customElement('ox-record-creator')
|
|
15
14
|
export class RecordCreator extends LitElement {
|
|
16
15
|
@state() grist?: DataGrist
|
|
17
16
|
|
|
18
|
-
@
|
|
17
|
+
@property({ type: Object }) callback?: (operation: { [key: string]: any }) => boolean
|
|
18
|
+
@property({ type: Boolean, attribute: 'light-popup' }) lightPopup: boolean = false
|
|
19
19
|
|
|
20
20
|
constructor() {
|
|
21
21
|
super()
|
|
@@ -24,7 +24,11 @@ export class RecordCreator extends LitElement {
|
|
|
24
24
|
e.preventDefault()
|
|
25
25
|
e.stopPropagation()
|
|
26
26
|
|
|
27
|
-
this.
|
|
27
|
+
if (this.lightPopup) {
|
|
28
|
+
this.lightPopupRecordView()
|
|
29
|
+
} else {
|
|
30
|
+
this.popupRecordView()
|
|
31
|
+
}
|
|
28
32
|
})
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -38,22 +42,16 @@ export class RecordCreator extends LitElement {
|
|
|
38
42
|
return html`<slot></slot>`
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
lightPopupRecordView() {
|
|
42
46
|
const config = this.grist!.compiledConfig
|
|
43
|
-
var
|
|
44
|
-
var title = this.record[titleField]
|
|
47
|
+
var title = 'create'
|
|
45
48
|
const rowIndex = -1
|
|
46
49
|
var record: GristRecord = {}
|
|
47
50
|
const columns = config.columns
|
|
48
51
|
|
|
49
|
-
/* field가 오브젝트형인 경우에는 렌더러를 타이틀로 사용한다. */
|
|
50
|
-
if (typeof title == 'object') {
|
|
51
|
-
var column = config.columns.find(column => column.name == titleField)
|
|
52
|
-
title = column?.record.renderer(title, column, record, rowIndex, this)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
52
|
var popup = OxPopup.open({
|
|
56
53
|
template: html`
|
|
54
|
+
<div title>${title}</div>
|
|
57
55
|
<ox-record-view
|
|
58
56
|
only-for-edit
|
|
59
57
|
@field-change=${(e: CustomEvent) => {
|
|
@@ -79,7 +77,6 @@ export class RecordCreator extends LitElement {
|
|
|
79
77
|
[column.name]: after
|
|
80
78
|
}
|
|
81
79
|
}}
|
|
82
|
-
.config=${config}
|
|
83
80
|
.columns=${columns}
|
|
84
81
|
.record=${record}
|
|
85
82
|
.rowIndex=${rowIndex}
|
|
@@ -108,4 +105,76 @@ export class RecordCreator extends LitElement {
|
|
|
108
105
|
parent: document.body
|
|
109
106
|
})
|
|
110
107
|
}
|
|
108
|
+
|
|
109
|
+
popupRecordView() {
|
|
110
|
+
const config = this.grist!.compiledConfig
|
|
111
|
+
const rowIndex = -1
|
|
112
|
+
var record: GristRecord = {}
|
|
113
|
+
const columns = config.columns
|
|
114
|
+
|
|
115
|
+
var title = 'create'
|
|
116
|
+
|
|
117
|
+
var recordView = document.createElement('ox-record-view') as RecordView
|
|
118
|
+
|
|
119
|
+
recordView.setAttribute('only-for-edit', '')
|
|
120
|
+
recordView.columns = columns
|
|
121
|
+
recordView.record = record
|
|
122
|
+
recordView.rowIndex = rowIndex
|
|
123
|
+
|
|
124
|
+
document.dispatchEvent(
|
|
125
|
+
new CustomEvent('open-popup', {
|
|
126
|
+
detail: {
|
|
127
|
+
template: recordView,
|
|
128
|
+
options: {
|
|
129
|
+
backdrop: true,
|
|
130
|
+
size: 'large',
|
|
131
|
+
title
|
|
132
|
+
},
|
|
133
|
+
callback: (popup: any) => {
|
|
134
|
+
recordView.addEventListener('reset', (e: Event) => {
|
|
135
|
+
const view = e.currentTarget as RecordView
|
|
136
|
+
view.record = {}
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
recordView.addEventListener('cancel', (e: Event) => {
|
|
140
|
+
popup.close()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
recordView.addEventListener('ok', async (e: Event) => {
|
|
144
|
+
const view = e.currentTarget as RecordView
|
|
145
|
+
if (await this.callback?.(view.record)) {
|
|
146
|
+
popup.close()
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
recordView.addEventListener('field-change', (e: Event) => {
|
|
151
|
+
const view = e.currentTarget as RecordView
|
|
152
|
+
|
|
153
|
+
var { after, before, column, record, row } = (e as CustomEvent).detail as {
|
|
154
|
+
after: any
|
|
155
|
+
before: any
|
|
156
|
+
column: ColumnConfig
|
|
157
|
+
record: GristRecord
|
|
158
|
+
row: number
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
var validation = column.validation
|
|
162
|
+
if (validation && typeof validation == 'function') {
|
|
163
|
+
if (!validation.call(this, after, before, record, column)) {
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
view.record = {
|
|
169
|
+
...record,
|
|
170
|
+
[column.name]: after
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
popup.onclosed = () => {}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
)
|
|
179
|
+
}
|
|
111
180
|
}
|
|
@@ -44,6 +44,7 @@ export class RecordViewBody extends LitElement {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
ox-grid-field {
|
|
47
|
+
border-top: none;
|
|
47
48
|
border-bottom: var(--record-view-border-bottom);
|
|
48
49
|
font: var(--record-view-font);
|
|
49
50
|
color: var(--record-view-color);
|
|
@@ -51,7 +52,6 @@ export class RecordViewBody extends LitElement {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
ox-grid-field[editing='true'] {
|
|
54
|
-
border-top: none;
|
|
55
55
|
border-bottom: var(--record-view-edit-border-bottom);
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -74,14 +74,12 @@ export class RecordViewBody extends LitElement {
|
|
|
74
74
|
|
|
75
75
|
this.setAttribute('tabindex', '0')
|
|
76
76
|
|
|
77
|
-
// if (!this.onlyForEdit) {
|
|
78
77
|
this.renderRoot.addEventListener('keydown', recordViewBodyKeydownHandler.bind(this))
|
|
79
78
|
this.renderRoot.addEventListener('click', recordViewBodyClickHandler.bind(this))
|
|
80
|
-
// }
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
render() {
|
|
84
|
-
var columns = this.columns.filter(column => !column.hidden && column.type
|
|
82
|
+
var columns = this.columns.filter(column => !column.hidden && column.type !== 'gutter')
|
|
85
83
|
var record = this.record
|
|
86
84
|
var rowIndex = this.rowIndex
|
|
87
85
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { RecordCard } from '../data-card/record-card'
|
|
2
|
+
import { DataGridBody } from '../data-grid/data-grid-body'
|
|
3
|
+
import { DataGridField } from '../data-grid/data-grid-field'
|
|
4
|
+
import { RecordPartial } from '../data-list/record-partial'
|
|
5
|
+
import { RecordView } from '../record-view/record-view'
|
|
6
|
+
import { ColumnConfig, GristRecord } from '../types'
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* handler들은 ox-grid-field 로부터 호출되는 것을 전제로 하며,
|
|
10
|
+
* 전반적인 처리를 위해서, columns 및 data 정보를 포함해서 제공할 수 있어야 한다.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const RecordViewHandler = function (
|
|
14
|
+
columns: ColumnConfig[],
|
|
15
|
+
record: GristRecord,
|
|
16
|
+
rowIndex: number,
|
|
17
|
+
field: DataGridField | RecordCard | RecordPartial | DataGridBody,
|
|
18
|
+
popupOptions: { [key: string]: any },
|
|
19
|
+
closeCallback?: () => void
|
|
20
|
+
): RecordView {
|
|
21
|
+
var recordView = document.createElement('ox-record-view') as RecordView
|
|
22
|
+
|
|
23
|
+
recordView.columns = columns
|
|
24
|
+
recordView.record = record
|
|
25
|
+
recordView.rowIndex = rowIndex
|
|
26
|
+
|
|
27
|
+
document.dispatchEvent(
|
|
28
|
+
new CustomEvent('open-popup', {
|
|
29
|
+
detail: {
|
|
30
|
+
template: recordView,
|
|
31
|
+
options: {
|
|
32
|
+
backdrop: true,
|
|
33
|
+
size: 'large',
|
|
34
|
+
title: record['name'],
|
|
35
|
+
...popupOptions
|
|
36
|
+
},
|
|
37
|
+
callback: (popup: any) => {
|
|
38
|
+
recordView.addEventListener('field-change', (e: Event) => {
|
|
39
|
+
field.dispatchEvent(
|
|
40
|
+
new CustomEvent('field-change', {
|
|
41
|
+
bubbles: true,
|
|
42
|
+
composed: true,
|
|
43
|
+
detail: (e as any).detail
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
recordView.addEventListener('reset', (e: Event) => {
|
|
49
|
+
field.dispatchEvent(
|
|
50
|
+
new CustomEvent('record-reset', {
|
|
51
|
+
bubbles: true,
|
|
52
|
+
composed: true,
|
|
53
|
+
detail: {
|
|
54
|
+
record: record,
|
|
55
|
+
row: rowIndex
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
recordView.addEventListener('cancel', (e: Event) => {
|
|
62
|
+
field.dispatchEvent(
|
|
63
|
+
new CustomEvent('record-reset', {
|
|
64
|
+
bubbles: true,
|
|
65
|
+
composed: true,
|
|
66
|
+
detail: {
|
|
67
|
+
record: record,
|
|
68
|
+
row: rowIndex
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
)
|
|
72
|
+
popup.close()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
recordView.addEventListener('ok', (e: Event) => {
|
|
76
|
+
popup.close()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
popup.onclosed = closeCallback
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} as any)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return recordView
|
|
86
|
+
}
|