@operato/data-grist 0.3.15 → 0.3.16
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 +18 -0
- package/assets/images/no-image.png +0 -0
- package/custom-elements.json +722 -166
- package/demo/index.html +19 -54
- package/dist/src/data-card/data-card.d.ts +3 -6
- package/dist/src/data-card/data-card.js +3 -131
- package/dist/src/data-card/data-card.js.map +1 -1
- package/dist/src/data-card/record-card.d.ts +0 -1
- package/dist/src/data-card/record-card.js +0 -3
- package/dist/src/data-card/record-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +1 -1
- package/dist/src/data-grid/data-grid-body.js +5 -5
- package/dist/src/data-grid/data-grid-body.js.map +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-header.d.ts +1 -0
- package/dist/src/data-grid/data-grid-header.js +9 -1
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.d.ts +8 -5
- package/dist/src/data-grid/data-grid.js +7 -133
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/src/data-grist.d.ts +1 -0
- package/dist/src/data-grist.js +3 -0
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/data-list.d.ts +3 -6
- package/dist/src/data-list/data-list.js +3 -131
- package/dist/src/data-list/data-list.js.map +1 -1
- package/dist/src/data-manipulator.d.ts +20 -0
- package/dist/src/data-manipulator.js +148 -0
- package/dist/src/data-manipulator.js.map +1 -0
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.d.ts +7 -0
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +22 -0
- package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -0
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.d.ts +7 -0
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +96 -0
- package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -0
- package/dist/src/record-view/record-creator.d.ts +13 -0
- package/dist/src/record-view/record-creator.js +90 -0
- package/dist/src/record-view/record-creator.js.map +1 -0
- package/dist/src/record-view/record-view-body.d.ts +3 -4
- package/dist/src/record-view/record-view-body.js +15 -37
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/record-view/record-view.d.ts +2 -0
- package/dist/src/record-view/record-view.js +16 -1
- package/dist/src/record-view/record-view.js.map +1 -1
- package/dist/src/sorters/sorters-control.d.ts +12 -0
- package/dist/src/sorters/sorters-control.js +106 -0
- package/dist/src/sorters/sorters-control.js.map +1 -0
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -8
- package/src/data-card/data-card.ts +4 -158
- package/src/data-card/record-card.ts +0 -4
- package/src/data-grid/data-grid-body.ts +6 -6
- package/src/data-grid/data-grid-field.ts +1 -1
- package/src/data-grid/data-grid-header.ts +11 -1
- package/src/data-grid/data-grid.ts +19 -149
- package/src/data-grist.ts +4 -0
- package/src/data-list/data-list.ts +4 -158
- package/src/data-manipulator.ts +201 -0
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +28 -0
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +115 -0
- package/src/record-view/record-creator.ts +111 -0
- package/src/record-view/record-view-body.ts +16 -50
- package/src/record-view/record-view.ts +17 -1
- package/src/sorters/sorters-control.ts +111 -0
- package/src/types.ts +9 -1
- package/dist/src/data-card/event-handlers/data-card-click-handler.d.ts +0 -6
- package/dist/src/data-card/event-handlers/data-card-click-handler.js +0 -16
- package/dist/src/data-card/event-handlers/data-card-click-handler.js.map +0 -1
- package/dist/src/data-card/event-handlers/data-card-dblclick-handler.d.ts +0 -6
- package/dist/src/data-card/event-handlers/data-card-dblclick-handler.js +0 -16
- package/dist/src/data-card/event-handlers/data-card-dblclick-handler.js.map +0 -1
- package/dist/src/data-list/event-handlers/data-list-click-handler.d.ts +0 -6
- package/dist/src/data-list/event-handlers/data-list-click-handler.js +0 -16
- package/dist/src/data-list/event-handlers/data-list-click-handler.js.map +0 -1
- package/dist/src/data-list/event-handlers/data-list-dblclick-handler.d.ts +0 -6
- package/dist/src/data-list/event-handlers/data-list-dblclick-handler.js +0 -16
- package/dist/src/data-list/event-handlers/data-list-dblclick-handler.js.map +0 -1
- package/dist/src/interfaces/index.d.ts +0 -2
- package/dist/src/interfaces/index.js +0 -3
- package/dist/src/interfaces/index.js.map +0 -1
- package/dist/src/interfaces/ox-grist-search-form.d.ts +0 -6
- package/dist/src/interfaces/ox-grist-search-form.js +0 -2
- package/dist/src/interfaces/ox-grist-search-form.js.map +0 -1
- package/dist/src/interfaces/ox-search-field.d.ts +0 -39
- package/dist/src/interfaces/ox-search-field.js +0 -2
- package/dist/src/interfaces/ox-search-field.js.map +0 -1
- package/dist/src/search-form/index.d.ts +0 -7
- package/dist/src/search-form/index.js +0 -8
- package/dist/src/search-form/index.js.map +0 -1
- package/dist/src/search-form/ox-basic-field.d.ts +0 -18
- package/dist/src/search-form/ox-basic-field.js +0 -75
- package/dist/src/search-form/ox-basic-field.js.map +0 -1
- package/dist/src/search-form/ox-checkbox-field.d.ts +0 -11
- package/dist/src/search-form/ox-checkbox-field.js +0 -60
- package/dist/src/search-form/ox-checkbox-field.js.map +0 -1
- package/dist/src/search-form/ox-grist-search-form.d.ts +0 -11
- package/dist/src/search-form/ox-grist-search-form.js +0 -177
- package/dist/src/search-form/ox-grist-search-form.js.map +0 -1
- package/dist/src/search-form/ox-number-field.d.ts +0 -14
- package/dist/src/search-form/ox-number-field.js +0 -112
- package/dist/src/search-form/ox-number-field.js.map +0 -1
- package/dist/src/search-form/ox-search-form.d.ts +0 -15
- package/dist/src/search-form/ox-search-form.js +0 -53
- package/dist/src/search-form/ox-search-form.js.map +0 -1
- package/dist/src/search-form/ox-select-field.d.ts +0 -21
- package/dist/src/search-form/ox-select-field.js +0 -181
- package/dist/src/search-form/ox-select-field.js.map +0 -1
- package/dist/src/search-form/ox-text-field.d.ts +0 -11
- package/dist/src/search-form/ox-text-field.js +0 -60
- package/dist/src/search-form/ox-text-field.js.map +0 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { RecordViewBody } from '../record-view-body'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ox-record-view-body 의 keydown handler
|
|
5
|
+
*
|
|
6
|
+
* - handler의 this 는 ox-record-view-body임.
|
|
7
|
+
*/
|
|
8
|
+
export async function recordViewBodyKeydownHandler(this: RecordViewBody, e: Event): Promise<void> {
|
|
9
|
+
// e.preventDefault()
|
|
10
|
+
|
|
11
|
+
switch ((e as KeyboardEvent).key) {
|
|
12
|
+
case 'Esc':
|
|
13
|
+
case 'Escape':
|
|
14
|
+
/* TODO 편집이 취소되어야 한다. */
|
|
15
|
+
case 'Enter':
|
|
16
|
+
/* 먼저, focus를 옮겨놓아야, focusout 으로 인해서 popup이 닫히는 것을 방지할 수 있다. */
|
|
17
|
+
!this.onlyForEdit && this.focus()
|
|
18
|
+
|
|
19
|
+
if (!this.onlyForEdit && this.currentTarget) {
|
|
20
|
+
this.currentTarget.removeAttribute('editing')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.currentTarget = null
|
|
24
|
+
|
|
25
|
+
break
|
|
26
|
+
default:
|
|
27
|
+
}
|
|
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
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import '@material/mwc-icon'
|
|
2
|
+
import './record-view'
|
|
3
|
+
|
|
4
|
+
import { html, LitElement } from 'lit'
|
|
5
|
+
import { customElement, state } from 'lit/decorators.js'
|
|
6
|
+
|
|
7
|
+
import { OxPopup } from '@operato/popup'
|
|
8
|
+
|
|
9
|
+
import { RecordView } from '.'
|
|
10
|
+
import { ColumnConfig } from '..'
|
|
11
|
+
import { DataGrist } from '../data-grist'
|
|
12
|
+
import { GristRecord } from '../types'
|
|
13
|
+
|
|
14
|
+
@customElement('ox-record-creator')
|
|
15
|
+
export class RecordCreator extends LitElement {
|
|
16
|
+
@state() grist?: DataGrist
|
|
17
|
+
|
|
18
|
+
@state() record: GristRecord = { __dirty__: '+' }
|
|
19
|
+
|
|
20
|
+
constructor() {
|
|
21
|
+
super()
|
|
22
|
+
|
|
23
|
+
this.addEventListener('click', (e: Event) => {
|
|
24
|
+
e.preventDefault()
|
|
25
|
+
e.stopPropagation()
|
|
26
|
+
|
|
27
|
+
this.popupRecordView()
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
connectedCallback(): void {
|
|
32
|
+
super.connectedCallback()
|
|
33
|
+
|
|
34
|
+
this.grist = this.closest('ox-grist') as DataGrist
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
render() {
|
|
38
|
+
return html`<slot></slot>`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
popupRecordView() {
|
|
42
|
+
const config = this.grist!.compiledConfig
|
|
43
|
+
var titleField = config.list.fields[0] || 'name'
|
|
44
|
+
var title = this.record[titleField]
|
|
45
|
+
const rowIndex = -1
|
|
46
|
+
var record: GristRecord = {}
|
|
47
|
+
const columns = config.columns
|
|
48
|
+
|
|
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
|
+
var popup = OxPopup.open({
|
|
56
|
+
template: html`
|
|
57
|
+
<ox-record-view
|
|
58
|
+
only-for-edit
|
|
59
|
+
@field-change=${(e: CustomEvent) => {
|
|
60
|
+
const view = e.currentTarget as RecordView
|
|
61
|
+
|
|
62
|
+
var { after, before, column, record, row } = (e as CustomEvent).detail as {
|
|
63
|
+
after: any
|
|
64
|
+
before: any
|
|
65
|
+
column: ColumnConfig
|
|
66
|
+
record: GristRecord
|
|
67
|
+
row: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var validation = column.validation
|
|
71
|
+
if (validation && typeof validation == 'function') {
|
|
72
|
+
if (!validation.call(this, after, before, record, column)) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
view.record = {
|
|
78
|
+
...record,
|
|
79
|
+
[column.name]: after
|
|
80
|
+
}
|
|
81
|
+
}}
|
|
82
|
+
.config=${config}
|
|
83
|
+
.columns=${columns}
|
|
84
|
+
.record=${record}
|
|
85
|
+
.rowIndex=${rowIndex}
|
|
86
|
+
@reset=${(e: Event) => {
|
|
87
|
+
const view = e.currentTarget as RecordView
|
|
88
|
+
view.record = {}
|
|
89
|
+
}}
|
|
90
|
+
@cancel=${(e: Event) => {
|
|
91
|
+
popup.close()
|
|
92
|
+
}}
|
|
93
|
+
@ok=${(e: Event) => {
|
|
94
|
+
popup.close()
|
|
95
|
+
|
|
96
|
+
const view = e.currentTarget as RecordView
|
|
97
|
+
|
|
98
|
+
this.dispatchEvent(
|
|
99
|
+
new CustomEvent('ok', {
|
|
100
|
+
bubbles: true,
|
|
101
|
+
composed: true,
|
|
102
|
+
detail: view.record
|
|
103
|
+
})
|
|
104
|
+
)
|
|
105
|
+
}}
|
|
106
|
+
></ox-record-view>
|
|
107
|
+
`,
|
|
108
|
+
parent: document.body
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -5,11 +5,9 @@ import { css, html, LitElement } from 'lit'
|
|
|
5
5
|
import { customElement, property } from 'lit/decorators.js'
|
|
6
6
|
|
|
7
7
|
import { ZERO_RECORD } from '../configure/zero-config'
|
|
8
|
-
import { DataGridField } from '../data-grid/data-grid-field'
|
|
9
8
|
import { ColumnConfig, GristRecord } from '../types'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const KEY_ESC = 27
|
|
9
|
+
import { recordViewBodyClickHandler } from './event-handlers/record-view-body-click-handler'
|
|
10
|
+
import { recordViewBodyKeydownHandler } from './event-handlers/record-view-body-keydown-handler'
|
|
13
11
|
|
|
14
12
|
@customElement('ox-record-view-body')
|
|
15
13
|
export class RecordViewBody extends LitElement {
|
|
@@ -67,9 +65,20 @@ export class RecordViewBody extends LitElement {
|
|
|
67
65
|
@property({ type: Array }) columns: ColumnConfig[] = []
|
|
68
66
|
@property({ type: Object }) record: GristRecord = ZERO_RECORD
|
|
69
67
|
@property({ type: Number }) rowIndex: number = -1
|
|
68
|
+
@property({ type: Boolean, attribute: 'only-for-edit' }) onlyForEdit: boolean = false
|
|
69
|
+
|
|
70
|
+
public currentTarget: any
|
|
71
|
+
|
|
72
|
+
connectedCallback() {
|
|
73
|
+
super.connectedCallback()
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
this.setAttribute('tabindex', '0')
|
|
76
|
+
|
|
77
|
+
// if (!this.onlyForEdit) {
|
|
78
|
+
this.renderRoot.addEventListener('keydown', recordViewBodyKeydownHandler.bind(this))
|
|
79
|
+
this.renderRoot.addEventListener('click', recordViewBodyClickHandler.bind(this))
|
|
80
|
+
// }
|
|
81
|
+
}
|
|
73
82
|
|
|
74
83
|
render() {
|
|
75
84
|
var columns = this.columns.filter(column => !column.hidden && column.type != 'gutter')
|
|
@@ -89,56 +98,13 @@ export class RecordViewBody extends LitElement {
|
|
|
89
98
|
.record=${record}
|
|
90
99
|
.value=${record[column.name]}
|
|
91
100
|
?dirty=${!!dirtyFields[column.name]}
|
|
101
|
+
?editing=${this.onlyForEdit}
|
|
92
102
|
></ox-grid-field>
|
|
93
103
|
`
|
|
94
104
|
})}
|
|
95
105
|
`
|
|
96
106
|
}
|
|
97
107
|
|
|
98
|
-
firstUpdated() {
|
|
99
|
-
this.renderRoot.addEventListener('click', e => {
|
|
100
|
-
e.stopPropagation()
|
|
101
|
-
|
|
102
|
-
/* target should be 'ox-grid-field' */
|
|
103
|
-
var target = e.target as DataGridField
|
|
104
|
-
|
|
105
|
-
if (this.editTarget) {
|
|
106
|
-
this.editTarget.removeAttribute('editing')
|
|
107
|
-
this.editTarget = null
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (target.tagName !== 'OX-GRID-FIELD' || !target.column.record.editable) {
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.editTarget = target
|
|
115
|
-
target.setAttribute('editing', 'true')
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
this._focusedListener = (e: KeyboardEvent) => {
|
|
119
|
-
var keyCode = e.keyCode
|
|
120
|
-
switch (keyCode) {
|
|
121
|
-
case KEY_ESC:
|
|
122
|
-
/* TODO 편집이 취소되어야 한다. */
|
|
123
|
-
case KEY_ENTER:
|
|
124
|
-
if (this.editTarget) {
|
|
125
|
-
this.editTarget.removeAttribute('editing')
|
|
126
|
-
this.editTarget = null
|
|
127
|
-
}
|
|
128
|
-
break
|
|
129
|
-
|
|
130
|
-
default:
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
window.addEventListener('keydown', this._focusedListener)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
disconnectedCallback() {
|
|
137
|
-
super.disconnectedCallback()
|
|
138
|
-
|
|
139
|
-
window.removeEventListener('keydown', this._focusedListener)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
108
|
_renderLabel(column: ColumnConfig) {
|
|
143
109
|
var { renderer } = column.header
|
|
144
110
|
var title = renderer.call(this, column)
|
|
@@ -82,12 +82,18 @@ export class RecordView extends LitElement {
|
|
|
82
82
|
@property({ type: Array }) columns: ColumnConfig[] = []
|
|
83
83
|
@property({ type: Object }) record: GristRecord = ZERO_RECORD
|
|
84
84
|
@property({ type: Number }) rowIndex: number = -1
|
|
85
|
+
@property({ type: Boolean, attribute: 'only-for-edit' }) onlyForEdit: boolean = false
|
|
85
86
|
|
|
86
87
|
render() {
|
|
87
88
|
return html`
|
|
88
89
|
<div content>
|
|
89
90
|
<div thumbnail>${this.renderThumbnail()}</div>
|
|
90
|
-
<ox-record-view-body
|
|
91
|
+
<ox-record-view-body
|
|
92
|
+
.columns=${this.columns}
|
|
93
|
+
.record=${this.record}
|
|
94
|
+
.rowIndex=${this.rowIndex}
|
|
95
|
+
?only-for-edit=${this.onlyForEdit}
|
|
96
|
+
>
|
|
91
97
|
</ox-record-view-body>
|
|
92
98
|
</div>
|
|
93
99
|
<div footer>
|
|
@@ -128,7 +134,13 @@ export class RecordView extends LitElement {
|
|
|
128
134
|
// }
|
|
129
135
|
}
|
|
130
136
|
|
|
137
|
+
firstUpdated() {
|
|
138
|
+
this.setAttribute('tabindex', '0')
|
|
139
|
+
}
|
|
140
|
+
|
|
131
141
|
onReset() {
|
|
142
|
+
this.focus()
|
|
143
|
+
|
|
132
144
|
this.dispatchEvent(
|
|
133
145
|
new CustomEvent('reset', {
|
|
134
146
|
detail: this.record
|
|
@@ -137,6 +149,8 @@ export class RecordView extends LitElement {
|
|
|
137
149
|
}
|
|
138
150
|
|
|
139
151
|
onCancel() {
|
|
152
|
+
this.focus()
|
|
153
|
+
|
|
140
154
|
this.dispatchEvent(
|
|
141
155
|
new CustomEvent('cancel', {
|
|
142
156
|
detail: this.record
|
|
@@ -145,6 +159,8 @@ export class RecordView extends LitElement {
|
|
|
145
159
|
}
|
|
146
160
|
|
|
147
161
|
onOK() {
|
|
162
|
+
this.focus()
|
|
163
|
+
|
|
148
164
|
this.dispatchEvent(
|
|
149
165
|
new CustomEvent('ok', {
|
|
150
166
|
detail: this.record
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { css, html, LitElement, PropertyValues, TemplateResult } from 'lit'
|
|
2
|
+
import { customElement, state } from 'lit/decorators.js'
|
|
3
|
+
|
|
4
|
+
import { DataGrist } from '../data-grist'
|
|
5
|
+
import { ColumnConfig, GristConfig, SorterConfig } from '../types'
|
|
6
|
+
|
|
7
|
+
@customElement('ox-sorters-control')
|
|
8
|
+
export class SortersControl extends LitElement {
|
|
9
|
+
static styles = [
|
|
10
|
+
css`
|
|
11
|
+
:host {
|
|
12
|
+
display: block;
|
|
13
|
+
}
|
|
14
|
+
`
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
@state() config!: GristConfig
|
|
18
|
+
@state() columns: ColumnConfig[] = []
|
|
19
|
+
@state() sorters: SorterConfig[] = []
|
|
20
|
+
|
|
21
|
+
connectedCallback(): void {
|
|
22
|
+
super.connectedCallback()
|
|
23
|
+
|
|
24
|
+
const grist = this.closest('ox-grist') as DataGrist
|
|
25
|
+
|
|
26
|
+
if (grist) {
|
|
27
|
+
this.config = grist.config
|
|
28
|
+
|
|
29
|
+
this.closest('ox-grist')?.addEventListener('sorters-change', e => {
|
|
30
|
+
this.sorters = (e as CustomEvent).detail as SorterConfig[]
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
updated(changes: PropertyValues<this>) {
|
|
36
|
+
if (changes.has('config')) {
|
|
37
|
+
const sorters = this.config.sorters || []
|
|
38
|
+
|
|
39
|
+
this.columns = sorters
|
|
40
|
+
.map(({ name }) => this.config.columns.find(column => column.name === name))
|
|
41
|
+
.filter(column => !!column) as ColumnConfig[]
|
|
42
|
+
|
|
43
|
+
this.sorters = this.config.sorters || []
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
render(): TemplateResult {
|
|
48
|
+
const columns = this.columns
|
|
49
|
+
|
|
50
|
+
const current = this.sorters || []
|
|
51
|
+
|
|
52
|
+
return html`
|
|
53
|
+
${columns.map(column => {
|
|
54
|
+
const { name } = column
|
|
55
|
+
var rank = current.findIndex(sorter => sorter.name === name) + 1
|
|
56
|
+
var desc = rank !== 0 ? current[rank - 1].desc : null
|
|
57
|
+
|
|
58
|
+
if (current.length <= 1) {
|
|
59
|
+
rank = 0
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return html`
|
|
63
|
+
<div
|
|
64
|
+
option
|
|
65
|
+
@click=${(e: MouseEvent) => {
|
|
66
|
+
this.onChangeSort(name)
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
${column.header /*.renderer.call(this, column) */}
|
|
70
|
+
${desc === null
|
|
71
|
+
? html``
|
|
72
|
+
: html`
|
|
73
|
+
<mwc-icon>${desc ? 'keyboard_arrow_up' : 'keyboard_arrow_down'}</mwc-icon>
|
|
74
|
+
${rank === 0 ? html`` : html`<sub>${rank}</sub>`}
|
|
75
|
+
`}
|
|
76
|
+
</div>
|
|
77
|
+
`
|
|
78
|
+
})}
|
|
79
|
+
`
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onChangeSort(name: string) {
|
|
83
|
+
var sorters = [...this.sorters]
|
|
84
|
+
|
|
85
|
+
var idx = sorters.findIndex(sorter => sorter.name == name)
|
|
86
|
+
if (idx !== -1) {
|
|
87
|
+
let sorter = sorters[idx]
|
|
88
|
+
if (sorter.desc) {
|
|
89
|
+
sorters.splice(idx, 1)
|
|
90
|
+
} else {
|
|
91
|
+
sorter.desc = true
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
var sorter = {
|
|
95
|
+
name
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
sorters.push(sorter)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.sorters = sorters
|
|
102
|
+
|
|
103
|
+
this.dispatchEvent(
|
|
104
|
+
new CustomEvent('sorters-change', {
|
|
105
|
+
bubbles: true,
|
|
106
|
+
composed: true,
|
|
107
|
+
detail: this.sorters
|
|
108
|
+
})
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -126,7 +126,15 @@ export type FieldRenderer = (
|
|
|
126
126
|
column: ColumnConfig,
|
|
127
127
|
record: GristRecord,
|
|
128
128
|
rowIndex: number,
|
|
129
|
-
owner:
|
|
129
|
+
owner:
|
|
130
|
+
| RecordCard
|
|
131
|
+
| DataCardGutter
|
|
132
|
+
| DataCardField
|
|
133
|
+
| DataListGutter
|
|
134
|
+
| DataListField
|
|
135
|
+
| RecordPartial
|
|
136
|
+
| DataReportField
|
|
137
|
+
| Element
|
|
130
138
|
) => TemplateResult | string | void
|
|
131
139
|
export type FieldEditor = (
|
|
132
140
|
value: any,
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ox-card 의 click handler
|
|
3
|
-
*
|
|
4
|
-
* - handler의 this 는 ox-card임.
|
|
5
|
-
*/
|
|
6
|
-
export function dataCardClickHandler(e) {
|
|
7
|
-
e.stopPropagation();
|
|
8
|
-
/* target should be 'ox-record-card' */
|
|
9
|
-
var target = e.target;
|
|
10
|
-
var { record, rowIndex } = target;
|
|
11
|
-
/* do rows click handler */
|
|
12
|
-
// var { click: rowsClick } = this.config.rows.handlers
|
|
13
|
-
// var columns = this.config.columns
|
|
14
|
-
// rowsClick && rowsClick(columns, this.data, null /* column */, record, rowIndex, target)
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=data-card-click-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-card-click-handler.js","sourceRoot":"","sources":["../../../../src/data-card/event-handlers/data-card-click-handler.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,CAAa;IAChD,CAAC,CAAC,eAAe,EAAE,CAAA;IAEnB,uCAAuC;IACvC,IAAI,MAAM,GAAG,CAAC,CAAC,MAAuB,CAAA;IACtC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAEjC,2BAA2B;IAC3B,uDAAuD;IACvD,oCAAoC;IACpC,0FAA0F;AAC5F,CAAC","sourcesContent":["import { DataCardField } from '../data-card-field'\n\n/**\n * ox-card 의 click handler\n *\n * - handler의 this 는 ox-card임.\n */\nexport function dataCardClickHandler(e: MouseEvent): void {\n e.stopPropagation()\n\n /* target should be 'ox-record-card' */\n var target = e.target as DataCardField\n var { record, rowIndex } = target\n\n /* do rows click handler */\n // var { click: rowsClick } = this.config.rows.handlers\n // var columns = this.config.columns\n // rowsClick && rowsClick(columns, this.data, null /* column */, record, rowIndex, target)\n}\n"]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ox-card 의 dblclick handler
|
|
3
|
-
*
|
|
4
|
-
* - handler의 this 는 ox-card임.
|
|
5
|
-
*/
|
|
6
|
-
export function dataCardDblclickHandler(e) {
|
|
7
|
-
e.stopPropagation();
|
|
8
|
-
/* target should be 'ox-record-card' */
|
|
9
|
-
var target = e.target;
|
|
10
|
-
var { record, rowIndex } = target;
|
|
11
|
-
/* do rows dblclick handler */
|
|
12
|
-
// var { click: rowsDblclick } = this.config.rows.handlers
|
|
13
|
-
// var columns = this.config.columns
|
|
14
|
-
// rowsDblclick && rowsDblclick(columns, this.data, null /* column */, record, rowIndex, target)
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=data-card-dblclick-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-card-dblclick-handler.js","sourceRoot":"","sources":["../../../../src/data-card/event-handlers/data-card-dblclick-handler.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,CAAa;IACnD,CAAC,CAAC,eAAe,EAAE,CAAA;IAEnB,uCAAuC;IACvC,IAAI,MAAM,GAAG,CAAC,CAAC,MAAuB,CAAA;IACtC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAEjC,8BAA8B;IAC9B,0DAA0D;IAC1D,oCAAoC;IACpC,gGAAgG;AAClG,CAAC","sourcesContent":["import { DataCardField } from '../data-card-field'\n\n/**\n * ox-card 의 dblclick handler\n *\n * - handler의 this 는 ox-card임.\n */\nexport function dataCardDblclickHandler(e: MouseEvent): void {\n e.stopPropagation()\n\n /* target should be 'ox-record-card' */\n var target = e.target as DataCardField\n var { record, rowIndex } = target\n\n /* do rows dblclick handler */\n // var { click: rowsDblclick } = this.config.rows.handlers\n // var columns = this.config.columns\n // rowsDblclick && rowsDblclick(columns, this.data, null /* column */, record, rowIndex, target)\n}\n"]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ox-list 의 click handler
|
|
3
|
-
*
|
|
4
|
-
* - handler의 this 는 ox-list임.
|
|
5
|
-
*/
|
|
6
|
-
export function dataListClickHandler(e) {
|
|
7
|
-
e.stopPropagation();
|
|
8
|
-
/* target should be 'record-partial' */
|
|
9
|
-
var target = e.target;
|
|
10
|
-
var { record, rowIndex } = target;
|
|
11
|
-
/* do rows click handler */
|
|
12
|
-
// var { click: rowsClick } = this.config.rows.handlers
|
|
13
|
-
// var columns = this.config.columns
|
|
14
|
-
// rowsClick && rowsClick(columns, this.data, null /* column */, record, rowIndex, target)
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=data-list-click-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-list-click-handler.js","sourceRoot":"","sources":["../../../../src/data-list/event-handlers/data-list-click-handler.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,CAAa;IAChD,CAAC,CAAC,eAAe,EAAE,CAAA;IAEnB,uCAAuC;IACvC,IAAI,MAAM,GAAG,CAAC,CAAC,MAAuB,CAAA;IACtC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAEjC,2BAA2B;IAC3B,uDAAuD;IACvD,oCAAoC;IACpC,0FAA0F;AAC5F,CAAC","sourcesContent":["import { DataListField } from '../data-list-field'\n\n/**\n * ox-list 의 click handler\n *\n * - handler의 this 는 ox-list임.\n */\nexport function dataListClickHandler(e: MouseEvent): void {\n e.stopPropagation()\n\n /* target should be 'record-partial' */\n var target = e.target as DataListField\n var { record, rowIndex } = target\n\n /* do rows click handler */\n // var { click: rowsClick } = this.config.rows.handlers\n // var columns = this.config.columns\n // rowsClick && rowsClick(columns, this.data, null /* column */, record, rowIndex, target)\n}\n"]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ox-list 의 dblclick handler
|
|
3
|
-
*
|
|
4
|
-
* - handler의 this 는 ox-list임.
|
|
5
|
-
*/
|
|
6
|
-
export function dataListDblclickHandler(e) {
|
|
7
|
-
e.stopPropagation();
|
|
8
|
-
/* target should be 'record-partial' */
|
|
9
|
-
var target = e.target;
|
|
10
|
-
var { record, rowIndex } = target;
|
|
11
|
-
/* do rows dblclick handler */
|
|
12
|
-
// var { click: rowsDblclick } = this.config.rows.handlers
|
|
13
|
-
// var columns = this.config.columns
|
|
14
|
-
// rowsDblclick && rowsDblclick(columns, this.data, null /* column */, record, rowIndex, target)
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=data-list-dblclick-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-list-dblclick-handler.js","sourceRoot":"","sources":["../../../../src/data-list/event-handlers/data-list-dblclick-handler.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,CAAa;IACnD,CAAC,CAAC,eAAe,EAAE,CAAA;IAEnB,uCAAuC;IACvC,IAAI,MAAM,GAAG,CAAC,CAAC,MAAuB,CAAA;IACtC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAEjC,8BAA8B;IAC9B,0DAA0D;IAC1D,oCAAoC;IACpC,gGAAgG;AAClG,CAAC","sourcesContent":["import { DataListField } from '../data-list-field'\n\n/**\n * ox-list 의 dblclick handler\n *\n * - handler의 this 는 ox-list임.\n */\nexport function dataListDblclickHandler(e: MouseEvent): void {\n e.stopPropagation()\n\n /* target should be 'record-partial' */\n var target = e.target as DataListField\n var { record, rowIndex } = target\n\n /* do rows dblclick handler */\n // var { click: rowsDblclick } = this.config.rows.handlers\n // var columns = this.config.columns\n // rowsDblclick && rowsDblclick(columns, this.data, null /* column */, record, rowIndex, target)\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA","sourcesContent":["export * from './ox-search-field'\nexport * from './ox-grist-search-form'\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ox-grist-search-form.js","sourceRoot":"","sources":["../../../src/interfaces/ox-grist-search-form.ts"],"names":[],"mappings":"","sourcesContent":["export type QueryFilterRangeValue = [from: number, to: number]\n\nexport type QueryFilter = {\n name: string\n operator?: string\n value: any\n}\n"]}
|