@operato/data-grist 7.1.31 → 7.1.32
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/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/demo/data-grist-test.html +0 -468
- package/demo/favicon.ico +0 -0
- package/demo/index.html +0 -541
- package/demo/report-test.html +0 -249
- package/dist/src/record-view/record-creator.d.ts +0 -17
- package/dist/src/record-view/record-creator.js +0 -148
- package/dist/src/record-view/record-creator.js.map +0 -1
- package/src/accumulator/accumulator.ts +0 -63
- package/src/configure/column-builder.ts +0 -114
- package/src/configure/config-builder.ts +0 -40
- package/src/configure/filters-option-builder.ts +0 -8
- package/src/configure/imex-option-builder.ts +0 -5
- package/src/configure/list-option-builder.ts +0 -9
- package/src/configure/rows-option-builder.ts +0 -38
- package/src/configure/tree-option-builder.ts +0 -22
- package/src/configure/zero-config.ts +0 -83
- package/src/const.ts +0 -1
- package/src/data-card/data-card-field.ts +0 -94
- package/src/data-card/data-card-gutter-menu.ts +0 -94
- package/src/data-card/data-card-gutter.ts +0 -103
- package/src/data-card/data-card.ts +0 -154
- package/src/data-card/event-handlers/record-card-click-handler.ts +0 -34
- package/src/data-card/event-handlers/record-card-dblclick-handler.ts +0 -34
- package/src/data-card/record-card.ts +0 -289
- package/src/data-consumer.ts +0 -11
- package/src/data-grid/data-grid-accum-field.ts +0 -109
- package/src/data-grid/data-grid-body-style.ts +0 -99
- package/src/data-grid/data-grid-body.ts +0 -753
- package/src/data-grid/data-grid-field.ts +0 -236
- package/src/data-grid/data-grid-footer.ts +0 -117
- package/src/data-grid/data-grid-header.ts +0 -574
- package/src/data-grid/data-grid.ts +0 -293
- package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +0 -69
- package/src/data-grid/event-handlers/data-grid-body-contextmenu-handler.ts +0 -32
- package/src/data-grid/event-handlers/data-grid-body-dblclick-handler.ts +0 -42
- package/src/data-grid/event-handlers/data-grid-body-focus-change-handler.ts +0 -24
- package/src/data-grid/event-handlers/data-grid-body-keydown-handler.ts +0 -234
- package/src/data-grist.ts +0 -1233
- package/src/data-list/data-list-field.ts +0 -82
- package/src/data-list/data-list-gutter.ts +0 -108
- package/src/data-list/data-list.ts +0 -145
- package/src/data-list/event-handlers/record-partial-click-handler.ts +0 -34
- package/src/data-list/event-handlers/record-partial-dblclick-handler.ts +0 -33
- package/src/data-list/event-handlers/record-partial-long-press-handler.ts +0 -33
- package/src/data-list/record-partial.ts +0 -255
- package/src/data-manipulator.ts +0 -426
- package/src/data-provider.ts +0 -271
- package/src/data-report/data-report-body-style.ts +0 -58
- package/src/data-report/data-report-body.ts +0 -189
- package/src/data-report/data-report-component.ts +0 -138
- package/src/data-report/data-report-field.ts +0 -83
- package/src/data-report/data-report-header.ts +0 -242
- package/src/data-report/event-handlers/data-report-body-click-handler.ts +0 -38
- package/src/data-report/event-handlers/data-report-body-dblclick-handler.ts +0 -25
- package/src/data-report/event-handlers/data-report-body-keydown-handler.ts +0 -68
- package/src/data-report.ts +0 -424
- package/src/editors/index.ts +0 -4
- package/src/editors/ox-grist-editor-checkbox.ts +0 -28
- package/src/editors/ox-grist-editor-color.ts +0 -10
- package/src/editors/ox-grist-editor-date.ts +0 -10
- package/src/editors/ox-grist-editor-datetime.ts +0 -27
- package/src/editors/ox-grist-editor-email.ts +0 -10
- package/src/editors/ox-grist-editor-file.ts +0 -28
- package/src/editors/ox-grist-editor-image.ts +0 -31
- package/src/editors/ox-grist-editor-month.ts +0 -10
- package/src/editors/ox-grist-editor-multiple-select.ts +0 -57
- package/src/editors/ox-grist-editor-number.ts +0 -27
- package/src/editors/ox-grist-editor-password.ts +0 -10
- package/src/editors/ox-grist-editor-select.ts +0 -55
- package/src/editors/ox-grist-editor-tel.ts +0 -10
- package/src/editors/ox-grist-editor-text.ts +0 -14
- package/src/editors/ox-grist-editor-textarea.ts +0 -16
- package/src/editors/ox-grist-editor-time.ts +0 -10
- package/src/editors/ox-grist-editor-tree.ts +0 -27
- package/src/editors/ox-grist-editor-varname.ts +0 -36
- package/src/editors/ox-grist-editor-week.ts +0 -10
- package/src/editors/ox-grist-editor.ts +0 -207
- package/src/editors/ox-input-tree.ts +0 -226
- package/src/editors/registry.ts +0 -82
- package/src/empty-note.ts +0 -46
- package/src/filters/filter-checkbox.ts +0 -49
- package/src/filters/filter-input-barcode.ts +0 -34
- package/src/filters/filter-input.ts +0 -30
- package/src/filters/filter-range-date.ts +0 -81
- package/src/filters/filter-range-number.ts +0 -64
- package/src/filters/filter-select-buttons.ts +0 -60
- package/src/filters/filter-select.ts +0 -68
- package/src/filters/filter-styles.ts +0 -119
- package/src/filters/filters-form.ts +0 -476
- package/src/filters/index.ts +0 -10
- package/src/filters/registry.ts +0 -56
- package/src/formatters/date-formatter.ts +0 -3
- package/src/formatters/index.ts +0 -1
- package/src/formatters/number-formatter.ts +0 -3
- package/src/formatters/registry.ts +0 -30
- package/src/formatters/text-formatter.ts +0 -3
- package/src/gutters/gutter-button.ts +0 -51
- package/src/gutters/gutter-dirty.ts +0 -96
- package/src/gutters/gutter-row-selector.ts +0 -89
- package/src/gutters/gutter-sequence.ts +0 -54
- package/src/gutters/index.ts +0 -1
- package/src/gutters/registry.ts +0 -32
- package/src/handlers/contextmenu-tree-mutation.ts +0 -80
- package/src/handlers/index.ts +0 -1
- package/src/handlers/move-down.ts +0 -44
- package/src/handlers/move-up.ts +0 -44
- package/src/handlers/record-copy.ts +0 -38
- package/src/handlers/record-delete.ts +0 -30
- package/src/handlers/record-view-handler.ts +0 -27
- package/src/handlers/registry.ts +0 -42
- package/src/handlers/select-row-toggle.ts +0 -30
- package/src/handlers/select-row.ts +0 -27
- package/src/index.ts +0 -17
- package/src/personalizer/index.ts +0 -1
- package/src/personalizer/ox-grist-filter-personalizer.ts +0 -192
- package/src/personalizer/ox-grist-personalizer.ts +0 -226
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +0 -33
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -26
- package/src/record-view/index.ts +0 -2
- package/src/record-view/ox-record-creator.ts +0 -289
- package/src/record-view/record-view-body.ts +0 -250
- package/src/record-view/record-view-handler.ts +0 -86
- package/src/record-view/record-view.ts +0 -122
- package/src/renderers/index.ts +0 -14
- package/src/renderers/ox-grist-renderer-boolean.ts +0 -43
- package/src/renderers/ox-grist-renderer-color.ts +0 -15
- package/src/renderers/ox-grist-renderer-date.ts +0 -62
- package/src/renderers/ox-grist-renderer-file.ts +0 -31
- package/src/renderers/ox-grist-renderer-image.ts +0 -27
- package/src/renderers/ox-grist-renderer-json5.ts +0 -36
- package/src/renderers/ox-grist-renderer-link.ts +0 -17
- package/src/renderers/ox-grist-renderer-password.ts +0 -7
- package/src/renderers/ox-grist-renderer-progress.ts +0 -45
- package/src/renderers/ox-grist-renderer-select.ts +0 -58
- package/src/renderers/ox-grist-renderer-text.ts +0 -16
- package/src/renderers/ox-grist-renderer-textarea.ts +0 -7
- package/src/renderers/ox-grist-renderer-tree.ts +0 -189
- package/src/renderers/ox-grist-renderer.ts +0 -35
- package/src/renderers/registry.ts +0 -111
- package/src/sorters/sorters-control.ts +0 -143
- package/src/types.ts +0 -813
- package/src/utils/index.ts +0 -2
- package/src/utils/list-param.ts +0 -72
- package/src/utils/supports-passive.ts +0 -13
- package/stories/accumulator-format.stories.ts +0 -276
- package/stories/barcode-input-filter.stories.ts +0 -216
- package/stories/bounded-select-filters.stories.ts +0 -333
- package/stories/bounded-select-record.stories.ts +0 -336
- package/stories/click-event-custom.stories.ts +0 -288
- package/stories/click-event.stories.ts +0 -283
- package/stories/creatable-only-column.stories.ts +0 -253
- package/stories/default-filters.stories.ts +0 -241
- package/stories/dynamic-editable.stories.ts +0 -313
- package/stories/empty-sorters.stories.ts +0 -180
- package/stories/explicit-fetch.stories.ts +0 -186
- package/stories/fixed-column.stories.ts +0 -416
- package/stories/grid-setting.stories.ts +0 -501
- package/stories/grist-modes.stories.ts +0 -451
- package/stories/group-header.stories.ts +0 -442
- package/stories/record-view.stories.ts +0 -143
- package/stories/textarea.stories.ts +0 -261
- package/stories/tree-column-with-checkbox.stories.ts +0 -297
- package/stories/tree-column.stories.ts +0 -296
- package/tsconfig.json +0 -26
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -45
- package/yarn-error.log +0 -16971
@@ -1,293 +0,0 @@
|
|
1
|
-
import '../empty-note'
|
2
|
-
import './data-grid-header'
|
3
|
-
import './data-grid-body'
|
4
|
-
import './data-grid-footer'
|
5
|
-
|
6
|
-
import { css, html, LitElement, PropertyValues } from 'lit'
|
7
|
-
import { customElement, property, query, state } from 'lit/decorators.js'
|
8
|
-
import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
|
9
|
-
|
10
|
-
import { ScrollbarStyles } from '@operato/styles'
|
11
|
-
|
12
|
-
import { DataManipulator } from '../data-manipulator'
|
13
|
-
import { ColumnConfig, GristRecord, PaginationConfig } from '../types'
|
14
|
-
import { supportsPassive } from '../utils'
|
15
|
-
import { DataGridHeader } from './data-grid-header'
|
16
|
-
|
17
|
-
/**
|
18
|
-
* DataGrid
|
19
|
-
*/
|
20
|
-
@customElement('ox-grid')
|
21
|
-
export class DataGrid extends DataManipulator {
|
22
|
-
static styles = [
|
23
|
-
MDTypeScaleStyles,
|
24
|
-
ScrollbarStyles,
|
25
|
-
css`
|
26
|
-
:host {
|
27
|
-
display: flex;
|
28
|
-
flex-direction: column;
|
29
|
-
|
30
|
-
overflow: hidden;
|
31
|
-
|
32
|
-
border-width: var(--grid-container-border-width);
|
33
|
-
}
|
34
|
-
|
35
|
-
ox-grid-body {
|
36
|
-
flex: 1;
|
37
|
-
position: relative;
|
38
|
-
|
39
|
-
font-variation-settings: 'FILL' 1;
|
40
|
-
}
|
41
|
-
|
42
|
-
ox-grid-header {
|
43
|
-
font-variation-settings: 'FILL' 1;
|
44
|
-
}
|
45
|
-
|
46
|
-
ox-grid-footer {
|
47
|
-
font-variation-settings: 'FILL' 1;
|
48
|
-
}
|
49
|
-
|
50
|
-
ox-empty-note {
|
51
|
-
display: block;
|
52
|
-
position: absolute;
|
53
|
-
left: 50%;
|
54
|
-
top: 50%;
|
55
|
-
transform: translate(-50%, -50%);
|
56
|
-
}
|
57
|
-
|
58
|
-
div[setting] {
|
59
|
-
position: relative;
|
60
|
-
z-index: 5;
|
61
|
-
}
|
62
|
-
|
63
|
-
@media print {
|
64
|
-
:host {
|
65
|
-
zoom: 80%;
|
66
|
-
}
|
67
|
-
}
|
68
|
-
`
|
69
|
-
]
|
70
|
-
|
71
|
-
@property({ type: Object }) focused?: { row: number; column: number }
|
72
|
-
@property({ type: Boolean }) empty?: boolean
|
73
|
-
|
74
|
-
@query('ox-grid-body', true) body!: LitElement
|
75
|
-
@query('ox-grid-header', true) header!: DataGridHeader
|
76
|
-
@query('ox-grid-footer', true) footer!: LitElement
|
77
|
-
|
78
|
-
@state() fixedLefts: number[] = []
|
79
|
-
|
80
|
-
firstUpdated() {
|
81
|
-
/* header and body scroll synchronization */
|
82
|
-
this.header.addEventListener('scroll', e => {
|
83
|
-
if (this.body.scrollLeft !== this.header.scrollLeft) {
|
84
|
-
this.body.scrollLeft = this.header.scrollLeft
|
85
|
-
}
|
86
|
-
})
|
87
|
-
|
88
|
-
this.body.addEventListener('scroll', e => {
|
89
|
-
if (this.body.scrollLeft !== this.header.scrollLeft) {
|
90
|
-
this.header.scrollLeft = this.body.scrollLeft
|
91
|
-
}
|
92
|
-
})
|
93
|
-
|
94
|
-
this.header.addEventListener('wheel', this.onWheelEvent.bind(this))
|
95
|
-
this.footer && this.footer.addEventListener('wheel', this.onWheelEvent.bind(this))
|
96
|
-
|
97
|
-
/* record selection processing */
|
98
|
-
this.addEventListener('select-all-change', e => {
|
99
|
-
if (this.data.records.length == 0) {
|
100
|
-
return
|
101
|
-
}
|
102
|
-
|
103
|
-
var { selected } = (e as CustomEvent).detail
|
104
|
-
var { records } = this.data
|
105
|
-
|
106
|
-
records.forEach(record => (record['__selected__'] = selected))
|
107
|
-
|
108
|
-
this.header.requestUpdate()
|
109
|
-
this.body.requestUpdate()
|
110
|
-
})
|
111
|
-
|
112
|
-
this.addEventListener('focus-change', e => {
|
113
|
-
const { row, column } = (e as CustomEvent).detail || {}
|
114
|
-
if (!this.focused || this.focused.row != row || this.focused.column != column) {
|
115
|
-
this.focused = { row, column }
|
116
|
-
this.focus()
|
117
|
-
this.requestUpdate()
|
118
|
-
}
|
119
|
-
})
|
120
|
-
}
|
121
|
-
|
122
|
-
onWheelEvent(e: WheelEvent) {
|
123
|
-
if (this.body.scrollWidth > this.body.clientWidth) {
|
124
|
-
var delta = Math.max(-1, Math.min(1, e.deltaY || 0))
|
125
|
-
this.body.scrollLeft = Math.max(0, this.body.scrollLeft - delta * 30)
|
126
|
-
|
127
|
-
var maxScrollLeft = this.body.scrollWidth - this.body.clientWidth
|
128
|
-
|
129
|
-
var atStart = this.body.scrollLeft === 0
|
130
|
-
var atEnd = this.body.scrollLeft === maxScrollLeft
|
131
|
-
|
132
|
-
// 스크롤이 맨 앞으로 와 있는 상태에서 휠을 올리는 경우 또는
|
133
|
-
// 스크롤이 맨 끝으로 가 있는 상태에서 휠을 내리는 경우에만 디폴트 동작 허용
|
134
|
-
if ((atStart && delta > 0) || (atEnd && delta < 0)) {
|
135
|
-
return true
|
136
|
-
}
|
137
|
-
|
138
|
-
e.preventDefault()
|
139
|
-
}
|
140
|
-
}
|
141
|
-
|
142
|
-
onSelectRecordChanged({
|
143
|
-
selectedRecords,
|
144
|
-
added,
|
145
|
-
removed
|
146
|
-
}: {
|
147
|
-
selectedRecords: GristRecord[]
|
148
|
-
added: GristRecord[]
|
149
|
-
removed: GristRecord[]
|
150
|
-
}): void {
|
151
|
-
super.onSelectRecordChanged({ selectedRecords, added, removed })
|
152
|
-
|
153
|
-
this.header.requestUpdate()
|
154
|
-
this.body.requestUpdate()
|
155
|
-
}
|
156
|
-
|
157
|
-
onRecordChanged(
|
158
|
-
recordData: GristRecord,
|
159
|
-
row: number,
|
160
|
-
column: ColumnConfig | null /* TODO column should be removed */
|
161
|
-
) {
|
162
|
-
/* record-viewer 등 grid 외에서 변경되는 경우에도 header와 body를 refresh 하도록 한다. */
|
163
|
-
super.onRecordChanged(recordData, row, column)
|
164
|
-
|
165
|
-
this.header.requestUpdate()
|
166
|
-
this.body.requestUpdate()
|
167
|
-
}
|
168
|
-
|
169
|
-
updated(changes: PropertyValues<this>) {
|
170
|
-
if (changes.has('data')) {
|
171
|
-
/*
|
172
|
-
* 데이타 내용에 따라 동적으로 컬럼의 폭이 달라지는 경우(예를 들면, sequence field)가 있으므로,
|
173
|
-
* data의 변동에 대해서도 다시 계산되어야 한다.
|
174
|
-
*/
|
175
|
-
this.calculateWidths(this.config.columns)
|
176
|
-
|
177
|
-
if (this.focused && 'row' in this.focused) {
|
178
|
-
var { row = 0, column = 0 } = this.focused
|
179
|
-
var { records: oldrecords = [] } = changes.get('data') || {}
|
180
|
-
var { records: newrecords } = this.data
|
181
|
-
|
182
|
-
var oldrecord = oldrecords[row]
|
183
|
-
|
184
|
-
if (oldrecord && oldrecord !== newrecords[row]) {
|
185
|
-
var newrecord = newrecords.find(
|
186
|
-
record =>
|
187
|
-
/* TODO keyfields를 정의하고, keyfields의 동일성으로 확정해야 한다. */
|
188
|
-
oldrecord === record ||
|
189
|
-
('id' in oldrecord
|
190
|
-
? record.id == oldrecord.id
|
191
|
-
: 'name' in oldrecord
|
192
|
-
? record.name == oldrecord.name
|
193
|
-
: false)
|
194
|
-
)
|
195
|
-
|
196
|
-
this.focused = {
|
197
|
-
row: newrecord ? newrecords.indexOf(newrecord) : row,
|
198
|
-
column
|
199
|
-
}
|
200
|
-
}
|
201
|
-
}
|
202
|
-
} else if (changes.has('config')) {
|
203
|
-
this.calculateWidths(this.config.columns)
|
204
|
-
}
|
205
|
-
|
206
|
-
/* grid fetch 후에 grid로 focus를 주어야 하는 지 검토가 필요하다. */
|
207
|
-
// this.focus()
|
208
|
-
}
|
209
|
-
|
210
|
-
calculateWidths(columns: ColumnConfig[]) {
|
211
|
-
/*
|
212
|
-
* 컬럼 모델 마지막에 'auto' cell을 추가하여, 자투리 영역을 꽉 채워서 표시한다.
|
213
|
-
*/
|
214
|
-
const widths = columns
|
215
|
-
.filter(column => !column.hidden)
|
216
|
-
.map(column => {
|
217
|
-
switch (typeof column.width) {
|
218
|
-
case 'number':
|
219
|
-
return column.width + 'px'
|
220
|
-
case 'string':
|
221
|
-
return column.width
|
222
|
-
case 'function':
|
223
|
-
return column.width.call(this, column)
|
224
|
-
default:
|
225
|
-
return 'auto'
|
226
|
-
}
|
227
|
-
})
|
228
|
-
.concat(['auto'])
|
229
|
-
.join(' ')
|
230
|
-
|
231
|
-
this.style.setProperty('--grid-template-columns', widths)
|
232
|
-
this.style.setProperty('--grid-template-print-columns', widths.replace(/px/gi, 'fr'))
|
233
|
-
}
|
234
|
-
|
235
|
-
render() {
|
236
|
-
var { pagination = {} as PaginationConfig, columns = [], filters } = this.config
|
237
|
-
|
238
|
-
var paginatable = !pagination.infinite
|
239
|
-
var data = this.data
|
240
|
-
|
241
|
-
return html`
|
242
|
-
<div setting>
|
243
|
-
<slot name="setting"></slot>
|
244
|
-
</div>
|
245
|
-
|
246
|
-
<ox-grid-header
|
247
|
-
class="md-typescale-label-medium-prominent"
|
248
|
-
.columns=${columns}
|
249
|
-
.sorters=${this.sorters}
|
250
|
-
.filters=${this.filters}
|
251
|
-
.data=${data}
|
252
|
-
?filtering-feature=${filters?.header}
|
253
|
-
@column-width-change=${(e: CustomEvent) => {
|
254
|
-
let { idx, width } = e.detail
|
255
|
-
columns[idx].width = width
|
256
|
-
this.calculateWidths(columns)
|
257
|
-
}}
|
258
|
-
@fixed-lefts-change=${(e: CustomEvent) => (this.fixedLefts = e.detail)}
|
259
|
-
>
|
260
|
-
</ox-grid-header>
|
261
|
-
|
262
|
-
<ox-grid-body
|
263
|
-
class="md-typescale-body-medium"
|
264
|
-
.config=${this.config}
|
265
|
-
.columns=${columns}
|
266
|
-
.data=${data}
|
267
|
-
.focused=${this.focused!}
|
268
|
-
.fixedLefts=${this.fixedLefts}
|
269
|
-
>
|
270
|
-
${this.empty ? html` <ox-empty-note title="NO RECORDS"></ox-empty-note> ` : html``}
|
271
|
-
</ox-grid-body>
|
272
|
-
${paginatable
|
273
|
-
? html`
|
274
|
-
<ox-grid-footer
|
275
|
-
class="md-typescale-body-medium"
|
276
|
-
.data=${data}
|
277
|
-
.pagination=${this.pagination}
|
278
|
-
></ox-grid-footer>
|
279
|
-
`
|
280
|
-
: html``}
|
281
|
-
`
|
282
|
-
}
|
283
|
-
|
284
|
-
focus() {
|
285
|
-
super.focus()
|
286
|
-
|
287
|
-
this.body.focus()
|
288
|
-
}
|
289
|
-
|
290
|
-
get pullToRefreshTarget() {
|
291
|
-
return this.body
|
292
|
-
}
|
293
|
-
}
|
@@ -1,69 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* ox-grid-body 의 click handler
|
3
|
-
*
|
4
|
-
* - handler의 this 는 ox-grid-body임.
|
5
|
-
*/
|
6
|
-
|
7
|
-
import { DataGridBody } from '../data-grid-body'
|
8
|
-
import { DataGridField } from '../data-grid-field'
|
9
|
-
|
10
|
-
export function dataGridBodyClickHandler(this: DataGridBody, e: Event): void {
|
11
|
-
e.stopPropagation()
|
12
|
-
|
13
|
-
if ((e as MouseEvent).detail === 2) {
|
14
|
-
return;
|
15
|
-
}
|
16
|
-
|
17
|
-
if (this.editTarget) {
|
18
|
-
/* editTarget이 새로 설정되지 않았다면, 이후 기능이 실행된다. */
|
19
|
-
return
|
20
|
-
}
|
21
|
-
|
22
|
-
/* target should be 'ox-grid-field' */
|
23
|
-
var target = (e.target as Element).closest('ox-grid-field') as DataGridField
|
24
|
-
var { column, record, rowIndex, columnIndex } = target || {}
|
25
|
-
|
26
|
-
// if (!column) {
|
27
|
-
// /* 여백 컬럼이 클릭된 경우 */
|
28
|
-
// return
|
29
|
-
// }
|
30
|
-
|
31
|
-
// this.dispatchEvent(
|
32
|
-
// new CustomEvent('focus-change', {
|
33
|
-
// bubbles: true,
|
34
|
-
// composed: true,
|
35
|
-
// detail: {
|
36
|
-
// row: rowIndex,
|
37
|
-
// column: columnIndex
|
38
|
-
// }
|
39
|
-
// })
|
40
|
-
// )
|
41
|
-
|
42
|
-
/* 만약, 클릭 이벤트에 포커스만 바꾸고 싶다면, 아래 코멘트를 제거한다. */
|
43
|
-
/*
|
44
|
-
this.resetEdit()
|
45
|
-
*/
|
46
|
-
|
47
|
-
/* 만약, 클릭 이벤트에 포커스만 바꾸고 싶다면, 아래 부분을 코멘트처리한다. */
|
48
|
-
// if (!isNaN(rowIndex) && !isNaN(columnIndex)) {
|
49
|
-
// this.startEditTarget(rowIndex, columnIndex)
|
50
|
-
// if (this.editTarget) {
|
51
|
-
// /* editTarget이 새로 설정되지 않았다면, 이후 기능이 실행된다. */
|
52
|
-
// return
|
53
|
-
// }
|
54
|
-
// } else {
|
55
|
-
// console.error('should not be here.')
|
56
|
-
// return
|
57
|
-
// }
|
58
|
-
/* 만약, 클릭 이벤트에 포커스만 바꾸고 싶다면, 여기까지 코멘트 처리한다. */
|
59
|
-
|
60
|
-
/* do column click handler */
|
61
|
-
if (column) {
|
62
|
-
var { click } = column.handlers
|
63
|
-
click && click(this.columns, this.data, column, record, rowIndex, target, e)
|
64
|
-
}
|
65
|
-
|
66
|
-
/* do rows click handler */
|
67
|
-
var { click: rowsClick } = this.config.rows.handlers
|
68
|
-
rowsClick && rowsClick(this.columns, this.data, column, record, rowIndex, target, e)
|
69
|
-
}
|
@@ -1,32 +0,0 @@
|
|
1
|
-
import { DataGridBody } from '../data-grid-body'
|
2
|
-
import { DataGridField } from '../data-grid-field'
|
3
|
-
|
4
|
-
/**
|
5
|
-
* ox-grid-body 의 focus-change handler
|
6
|
-
*
|
7
|
-
* - handler의 this 는 ox-grid-body임.
|
8
|
-
*/
|
9
|
-
export async function dataGridBodyContextMenuHandler(this: DataGridBody, e: Event): Promise<void> {
|
10
|
-
e.stopPropagation()
|
11
|
-
|
12
|
-
if (this.editTarget) {
|
13
|
-
/* editTarget이 새로 설정되지 않았다면, 이후 기능이 실행된다. */
|
14
|
-
return
|
15
|
-
}
|
16
|
-
|
17
|
-
/* target should be 'ox-grid-field' */
|
18
|
-
var target = (e.target as Element).closest('ox-grid-field') as DataGridField
|
19
|
-
var { column, record, rowIndex, columnIndex } = target || {}
|
20
|
-
|
21
|
-
var { column, record } = target || {}
|
22
|
-
|
23
|
-
/* do column contextmenu handler */
|
24
|
-
if (column) {
|
25
|
-
var { contextmenu } = column.handlers
|
26
|
-
contextmenu && contextmenu(this.columns, this.data, column, record, rowIndex, target, e)
|
27
|
-
}
|
28
|
-
|
29
|
-
/* do rows contextmenu handler */
|
30
|
-
var { contextmenu: rowsContextMenu } = this.config.rows.handlers
|
31
|
-
rowsContextMenu && rowsContextMenu(this.columns, this.data, column, record, rowIndex, target, e)
|
32
|
-
}
|
@@ -1,42 +0,0 @@
|
|
1
|
-
import { DataGridBody } from '../data-grid-body'
|
2
|
-
import { DataGridField } from '../data-grid-field'
|
3
|
-
|
4
|
-
/**
|
5
|
-
* ox-grid-body 의 dblclick handler
|
6
|
-
*
|
7
|
-
* - handler의 this 는 ox-grid-body임.
|
8
|
-
*/
|
9
|
-
export async function dataGridBodyDblclickHandler(this: DataGridBody, e: Event): Promise<void> {
|
10
|
-
e.stopPropagation()
|
11
|
-
|
12
|
-
if (this.editTarget) {
|
13
|
-
/* editTarget이 새로 설정되지 않았다면, 이후 기능이 실행된다. */
|
14
|
-
return
|
15
|
-
}
|
16
|
-
|
17
|
-
/* target should be 'ox-grid-field' */
|
18
|
-
var target = (e.target as Element).closest('ox-grid-field') as DataGridField
|
19
|
-
var { column, record, rowIndex, columnIndex } = target || {}
|
20
|
-
|
21
|
-
// if (!column) {
|
22
|
-
// /* 여백 컬럼이 클릭된 경우 */
|
23
|
-
// return
|
24
|
-
// }
|
25
|
-
|
26
|
-
// if (!isNaN(rowIndex) && !isNaN(columnIndex)) {
|
27
|
-
// this.startEditTarget(rowIndex, columnIndex)
|
28
|
-
// } else {
|
29
|
-
// console.error('should not be here.')
|
30
|
-
// return
|
31
|
-
// }
|
32
|
-
|
33
|
-
/* do column dblclick handler */
|
34
|
-
if (column) {
|
35
|
-
var { dblclick } = column.handlers
|
36
|
-
dblclick && dblclick(this.columns, this.data, column, record, rowIndex, target, e)
|
37
|
-
}
|
38
|
-
|
39
|
-
/* do rows dblclick handler */
|
40
|
-
var { dblclick: rowsDblclick } = this.config.rows.handlers
|
41
|
-
rowsDblclick && rowsDblclick(this.columns, this.data, column, record, rowIndex, target, e)
|
42
|
-
}
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import { DataGridBody } from '../data-grid-body'
|
2
|
-
|
3
|
-
/**
|
4
|
-
* ox-grid-body 의 focus-change handler
|
5
|
-
*
|
6
|
-
* - handler의 this 는 ox-grid-body임.
|
7
|
-
*/
|
8
|
-
export async function dataGridBodyFocusChangeHandler(this: DataGridBody, e: Event): Promise<void> {
|
9
|
-
const { row: rowIndex, column: columnIndex } = (e as CustomEvent).detail
|
10
|
-
|
11
|
-
const target = this.getFieldByIndex(rowIndex, columnIndex)
|
12
|
-
|
13
|
-
var { column, record } = target || {}
|
14
|
-
|
15
|
-
/* do column focus handler */
|
16
|
-
if (column) {
|
17
|
-
var { focus } = column.handlers
|
18
|
-
focus && focus(this.columns, this.data, column, record, rowIndex, target, e)
|
19
|
-
}
|
20
|
-
|
21
|
-
/* do rows focus handler */
|
22
|
-
var { focus: rowsFocus } = this.config.rows.handlers
|
23
|
-
rowsFocus && rowsFocus(this.columns, this.data, column, record, rowIndex, target, e)
|
24
|
-
}
|
@@ -1,234 +0,0 @@
|
|
1
|
-
import { DataGridBody } from '../data-grid-body'
|
2
|
-
|
3
|
-
/**
|
4
|
-
* ox-grid-body 의 keydown handler
|
5
|
-
*
|
6
|
-
* - handler의 this 는 ox-grid-body임.
|
7
|
-
*/
|
8
|
-
export async function dataGridBodyKeydownHandler(this: DataGridBody, e: KeyboardEvent): Promise<void> {
|
9
|
-
// 한글 Composing 이벤트는 무시
|
10
|
-
if (e.isComposing) return
|
11
|
-
|
12
|
-
// arrow-key
|
13
|
-
const key = e.key
|
14
|
-
var { row = 0, column = 0 } = this.focused || {}
|
15
|
-
var { records = [] } = this.data || {}
|
16
|
-
var maxrow = this.config.rows.appendable ? records.length : records.length - 1
|
17
|
-
var maxcolumn = (this.columns || []).filter(column => !column.hidden).length - 1
|
18
|
-
|
19
|
-
if (this.editTarget) {
|
20
|
-
switch (key) {
|
21
|
-
case 'Escape':
|
22
|
-
case 'Esc':
|
23
|
-
/* TODO 편집이 취소되어야 한다. */
|
24
|
-
case 'Enter':
|
25
|
-
this.editTarget = null
|
26
|
-
|
27
|
-
this.focus()
|
28
|
-
return
|
29
|
-
|
30
|
-
case 'Tab':
|
31
|
-
this.editTarget = null
|
32
|
-
if (e.shiftKey) {
|
33
|
-
column = Math.max(0, column - 1)
|
34
|
-
} else {
|
35
|
-
column = Math.min(maxcolumn, column + 1)
|
36
|
-
}
|
37
|
-
this.focus()
|
38
|
-
break
|
39
|
-
|
40
|
-
// case 'Down':
|
41
|
-
// case 'ArrowDown':
|
42
|
-
// this.editTarget = null
|
43
|
-
// row = Math.min(maxrow, row + 1)
|
44
|
-
// this.focus()
|
45
|
-
// break
|
46
|
-
|
47
|
-
case 'PageUp':
|
48
|
-
case 'PageDown':
|
49
|
-
case 'End':
|
50
|
-
case 'Home':
|
51
|
-
// e.preventDefault()
|
52
|
-
// return
|
53
|
-
break
|
54
|
-
|
55
|
-
default:
|
56
|
-
if (e.metaKey || e.ctrlKey) {
|
57
|
-
/* Window System에 선택된 영역이 없다면, 셀을 복사/붙여넣기 한다. */
|
58
|
-
switch (e.key) {
|
59
|
-
case 'c':
|
60
|
-
const selection = window.getSelection()
|
61
|
-
if (!selection || !selection.anchorNode || selection.type != 'Range') {
|
62
|
-
/*
|
63
|
-
editor가 select 인 경우 자체 복사 기능이 없으므로 this.copy()를 사용하도록 하기 위해서, selection.type != 'Range' 조건을 추가했다.
|
64
|
-
select인 경우에는 selection.type 이 'Caret' 이었다.
|
65
|
-
*/
|
66
|
-
this.copy()
|
67
|
-
e.preventDefault()
|
68
|
-
}
|
69
|
-
break
|
70
|
-
case 'v':
|
71
|
-
this.paste()
|
72
|
-
break
|
73
|
-
}
|
74
|
-
}
|
75
|
-
return
|
76
|
-
}
|
77
|
-
} else {
|
78
|
-
switch (key) {
|
79
|
-
case 'Up':
|
80
|
-
case 'ArrowUp':
|
81
|
-
if (e.shiftKey) {
|
82
|
-
let { start } = this._selectBlock || {}
|
83
|
-
let focused = this.focusedField
|
84
|
-
if (focused && focused.rowIndex > 0) {
|
85
|
-
this.setSelectBlock(start || focused, this.getFieldByIndex(focused.rowIndex - 1, focused.columnIndex))
|
86
|
-
}
|
87
|
-
} else {
|
88
|
-
this.setSelectBlock()
|
89
|
-
if (e.metaKey || e.ctrlKey) {
|
90
|
-
row = 0
|
91
|
-
} else {
|
92
|
-
row = Math.max(0, row - 1)
|
93
|
-
}
|
94
|
-
}
|
95
|
-
break
|
96
|
-
|
97
|
-
case 'Down':
|
98
|
-
case 'ArrowDown':
|
99
|
-
if (e.shiftKey) {
|
100
|
-
let { start } = this._selectBlock || {}
|
101
|
-
let focused = this.focusedField
|
102
|
-
if (focused) {
|
103
|
-
let end = this.getFieldByIndex(focused.rowIndex + 1, focused.columnIndex)
|
104
|
-
if (end) {
|
105
|
-
this.setSelectBlock(start || focused, end)
|
106
|
-
}
|
107
|
-
}
|
108
|
-
} else {
|
109
|
-
this.setSelectBlock()
|
110
|
-
if (e.metaKey || e.ctrlKey) {
|
111
|
-
row = maxrow
|
112
|
-
} else {
|
113
|
-
row = Math.min(maxrow, row + 1)
|
114
|
-
}
|
115
|
-
}
|
116
|
-
break
|
117
|
-
|
118
|
-
case 'Enter':
|
119
|
-
this.setSelectBlock()
|
120
|
-
this.startEditTarget(row, column, null)
|
121
|
-
return
|
122
|
-
|
123
|
-
case 'Left':
|
124
|
-
case 'ArrowLeft':
|
125
|
-
case 'Backspace':
|
126
|
-
if (e.shiftKey) {
|
127
|
-
let { start } = this._selectBlock || {}
|
128
|
-
let focused = this.focusedField
|
129
|
-
if (focused && focused.columnIndex > 0) {
|
130
|
-
this.setSelectBlock(start || focused, this.getFieldByIndex(focused.rowIndex, focused.columnIndex - 1))
|
131
|
-
}
|
132
|
-
} else {
|
133
|
-
this.setSelectBlock()
|
134
|
-
if (e.metaKey || e.ctrlKey) {
|
135
|
-
column = 0
|
136
|
-
} else {
|
137
|
-
column = Math.max(0, column - 1)
|
138
|
-
}
|
139
|
-
}
|
140
|
-
break
|
141
|
-
|
142
|
-
case 'Right':
|
143
|
-
case 'ArrowRight':
|
144
|
-
if (e.shiftKey) {
|
145
|
-
let { start } = this._selectBlock || {}
|
146
|
-
let focused = this.focusedField
|
147
|
-
if (focused) {
|
148
|
-
let end = this.getFieldByIndex(focused.rowIndex, focused.columnIndex + 1, false)
|
149
|
-
if (end) {
|
150
|
-
this.setSelectBlock(start || focused, end)
|
151
|
-
}
|
152
|
-
}
|
153
|
-
} else {
|
154
|
-
this.setSelectBlock()
|
155
|
-
if (e.metaKey || e.ctrlKey) {
|
156
|
-
column = maxcolumn
|
157
|
-
} else {
|
158
|
-
column = Math.min(maxcolumn, column + 1)
|
159
|
-
}
|
160
|
-
}
|
161
|
-
break
|
162
|
-
|
163
|
-
case 'Tab':
|
164
|
-
this.editTarget = null
|
165
|
-
this.setSelectBlock()
|
166
|
-
if (e.shiftKey) {
|
167
|
-
column = Math.max(0, column - 1)
|
168
|
-
} else {
|
169
|
-
column = Math.min(maxcolumn, column + 1)
|
170
|
-
}
|
171
|
-
this.focus()
|
172
|
-
break
|
173
|
-
|
174
|
-
case 'PageUp':
|
175
|
-
/* TODO 페이지당 레코드의 수를 계산해서 증감시켜야 한다. */
|
176
|
-
this.setSelectBlock()
|
177
|
-
row = Math.max(0, row - 10)
|
178
|
-
break
|
179
|
-
|
180
|
-
case 'PageDown':
|
181
|
-
case ' ':
|
182
|
-
this.setSelectBlock()
|
183
|
-
row = Math.min(maxrow, row + 10)
|
184
|
-
break
|
185
|
-
|
186
|
-
case 'Esc':
|
187
|
-
case 'Escape':
|
188
|
-
this.setSelectBlock()
|
189
|
-
return
|
190
|
-
|
191
|
-
case 'End':
|
192
|
-
this.setSelectBlock()
|
193
|
-
row = maxrow
|
194
|
-
break
|
195
|
-
|
196
|
-
case 'Home':
|
197
|
-
this.setSelectBlock()
|
198
|
-
row = 0
|
199
|
-
break
|
200
|
-
|
201
|
-
default:
|
202
|
-
if (e.metaKey || e.ctrlKey) {
|
203
|
-
switch (e.key) {
|
204
|
-
case 'c':
|
205
|
-
const selection = window.getSelection()
|
206
|
-
if (!selection || !selection.anchorNode || selection.type != 'Range') {
|
207
|
-
/*
|
208
|
-
에디터 상태가 아닌 경우에도, selection.type != 'Range' 조건을 추가해서,
|
209
|
-
셀렉션이 된 상태에서는 기본 동작으로 텍스트 복사를 할 수 있도록 했다.
|
210
|
-
보통은, 싱글 필드가 셀렉션박스로 지정된 경우에 자체 텍스트의 일부를 복사하기 위해서 필요하다.
|
211
|
-
*/
|
212
|
-
this.copy()
|
213
|
-
e.preventDefault()
|
214
|
-
}
|
215
|
-
break
|
216
|
-
case 'v':
|
217
|
-
this.paste()
|
218
|
-
break
|
219
|
-
}
|
220
|
-
return
|
221
|
-
} else if (key.length === 1) {
|
222
|
-
this.setSelectBlock()
|
223
|
-
this.startEditTarget(row, column, key)
|
224
|
-
}
|
225
|
-
}
|
226
|
-
}
|
227
|
-
|
228
|
-
if (!this.focused || this.focused.row !== row || this.focused.column !== column) {
|
229
|
-
this.dispatchEvent(new CustomEvent('focus-change', { bubbles: true, composed: true, detail: { row, column } }))
|
230
|
-
}
|
231
|
-
|
232
|
-
/* arrow key에 의한 scrollbar의 자동 움직임을 하지 못하도록 한다. */
|
233
|
-
e.preventDefault()
|
234
|
-
}
|