@operato/data-grist 0.3.13 → 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.
Files changed (126) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/assets/images/no-image.png +0 -0
  3. package/custom-elements.json +2382 -1803
  4. package/demo/index.html +41 -62
  5. package/dist/src/configure/list-option-builder.js +0 -2
  6. package/dist/src/configure/list-option-builder.js.map +1 -1
  7. package/dist/src/configure/zero-config.d.ts +0 -1
  8. package/dist/src/configure/zero-config.js +0 -2
  9. package/dist/src/configure/zero-config.js.map +1 -1
  10. package/dist/src/data-card/data-card.d.ts +3 -6
  11. package/dist/src/data-card/data-card.js +3 -131
  12. package/dist/src/data-card/data-card.js.map +1 -1
  13. package/dist/src/data-card/record-card.d.ts +0 -3
  14. package/dist/src/data-card/record-card.js +22 -71
  15. package/dist/src/data-card/record-card.js.map +1 -1
  16. package/dist/src/data-grid/data-grid-body.d.ts +7 -1
  17. package/dist/src/data-grid/data-grid-body.js +26 -5
  18. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  19. package/dist/src/data-grid/data-grid-field.js +1 -1
  20. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  21. package/dist/src/data-grid/data-grid-header.d.ts +1 -0
  22. package/dist/src/data-grid/data-grid-header.js +9 -1
  23. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  24. package/dist/src/data-grid/data-grid.d.ts +8 -4
  25. package/dist/src/data-grid/data-grid.js +12 -132
  26. package/dist/src/data-grid/data-grid.js.map +1 -1
  27. package/dist/src/data-grist.d.ts +1 -0
  28. package/dist/src/data-grist.js +3 -0
  29. package/dist/src/data-grist.js.map +1 -1
  30. package/dist/src/data-list/data-list.d.ts +3 -6
  31. package/dist/src/data-list/data-list.js +3 -131
  32. package/dist/src/data-list/data-list.js.map +1 -1
  33. package/dist/src/data-list/record-partial.d.ts +0 -2
  34. package/dist/src/data-list/record-partial.js +7 -58
  35. package/dist/src/data-list/record-partial.js.map +1 -1
  36. package/dist/src/data-manipulator.d.ts +20 -0
  37. package/dist/src/data-manipulator.js +148 -0
  38. package/dist/src/data-manipulator.js.map +1 -0
  39. package/dist/src/editors/image-editor.d.ts +9 -0
  40. package/dist/src/editors/image-editor.js +53 -0
  41. package/dist/src/editors/image-editor.js.map +1 -0
  42. package/dist/src/editors/image-input.d.ts +7 -0
  43. package/dist/src/editors/image-input.js +31 -0
  44. package/dist/src/editors/image-input.js.map +1 -0
  45. package/dist/src/editors/index.d.ts +1 -0
  46. package/dist/src/editors/index.js +1 -0
  47. package/dist/src/editors/index.js.map +1 -1
  48. package/dist/src/editors/input-editors copy.d.ts +75 -0
  49. package/dist/src/editors/input-editors copy.js +373 -0
  50. package/dist/src/editors/input-editors copy.js.map +1 -0
  51. package/dist/src/editors/input-editors.d.ts +1 -8
  52. package/dist/src/editors/input-editors.js +3 -47
  53. package/dist/src/editors/input-editors.js.map +1 -1
  54. package/dist/src/editors/registry.d.ts +1 -1
  55. package/dist/src/editors/registry.js +2 -1
  56. package/dist/src/editors/registry.js.map +1 -1
  57. package/dist/src/handlers/record-view-handler.d.ts +1 -2
  58. package/dist/src/handlers/record-view-handler.js +5 -35
  59. package/dist/src/handlers/record-view-handler.js.map +1 -1
  60. package/dist/src/handlers/select-row-toggle.d.ts +1 -1
  61. package/dist/src/handlers/select-row-toggle.js.map +1 -1
  62. package/dist/src/record-view/event-handlers/record-view-body-click-handler.d.ts +7 -0
  63. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +24 -0
  64. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -0
  65. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.d.ts +7 -0
  66. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +22 -0
  67. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -0
  68. package/dist/src/record-view/index.d.ts +1 -0
  69. package/dist/src/record-view/index.js +1 -0
  70. package/dist/src/record-view/index.js.map +1 -1
  71. package/dist/src/record-view/record-creator copy.d.ts +13 -0
  72. package/dist/src/record-view/record-creator copy.js +90 -0
  73. package/dist/src/record-view/record-creator copy.js.map +1 -0
  74. package/dist/src/record-view/record-creator-backup.d.ts +13 -0
  75. package/dist/src/record-view/record-creator-backup.js +90 -0
  76. package/dist/src/record-view/record-creator-backup.js.map +1 -0
  77. package/dist/src/record-view/record-creator.d.ts +16 -0
  78. package/dist/src/record-view/record-creator.js +145 -0
  79. package/dist/src/record-view/record-creator.js.map +1 -0
  80. package/dist/src/record-view/record-view-body.d.ts +3 -4
  81. package/dist/src/record-view/record-view-body.js +15 -42
  82. package/dist/src/record-view/record-view-body.js.map +1 -1
  83. package/dist/src/record-view/record-view-handler.d.ts +9 -0
  84. package/dist/src/record-view/record-view-handler.js +57 -0
  85. package/dist/src/record-view/record-view-handler.js.map +1 -0
  86. package/dist/src/record-view/record-view.d.ts +5 -1
  87. package/dist/src/record-view/record-view.js +61 -36
  88. package/dist/src/record-view/record-view.js.map +1 -1
  89. package/dist/src/renderers/image-renderer.js +12 -4
  90. package/dist/src/renderers/image-renderer.js.map +1 -1
  91. package/dist/src/sorters/sorters-control.d.ts +12 -0
  92. package/dist/src/sorters/sorters-control.js +106 -0
  93. package/dist/src/sorters/sorters-control.js.map +1 -0
  94. package/dist/src/types.d.ts +2 -3
  95. package/dist/src/types.js.map +1 -1
  96. package/dist/tsconfig.tsbuildinfo +1 -1
  97. package/package.json +10 -8
  98. package/src/configure/list-option-builder.ts +0 -2
  99. package/src/configure/zero-config.ts +0 -2
  100. package/src/data-card/data-card.ts +4 -158
  101. package/src/data-card/record-card.ts +30 -87
  102. package/src/data-grid/data-grid-body.ts +43 -6
  103. package/src/data-grid/data-grid-field.ts +1 -1
  104. package/src/data-grid/data-grid-header.ts +11 -1
  105. package/src/data-grid/data-grid.ts +25 -143
  106. package/src/data-grist.ts +4 -0
  107. package/src/data-list/data-list.ts +4 -158
  108. package/src/data-list/record-partial.ts +14 -73
  109. package/src/data-manipulator.ts +201 -0
  110. package/src/editors/image-input.ts +29 -0
  111. package/src/editors/index.ts +1 -0
  112. package/src/editors/input-editors.ts +5 -48
  113. package/src/editors/registry.ts +3 -4
  114. package/src/handlers/record-view-handler.ts +8 -44
  115. package/src/handlers/select-row-toggle.ts +1 -2
  116. package/src/record-view/event-handlers/record-view-body-click-handler.ts +30 -0
  117. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +26 -0
  118. package/src/record-view/index.ts +1 -0
  119. package/src/record-view/record-creator.ts +180 -0
  120. package/src/record-view/record-view-body.ts +16 -55
  121. package/src/record-view/record-view-handler.ts +86 -0
  122. package/src/record-view/record-view.ts +69 -42
  123. package/src/renderers/image-renderer.ts +14 -5
  124. package/src/sorters/sorters-control.ts +111 -0
  125. package/src/types.ts +10 -3
  126. package/yarn-error.log +16718 -0
@@ -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
- document.dispatchEvent(
238
- new CustomEvent('open-popup', {
239
- detail: {
240
- template: this.recordView,
241
- options: {
242
- backdrop: true,
243
- size: 'large',
244
- title
245
- },
246
- callback: (popup: any) => {
247
- this.recordView.addEventListener('reset', () => {
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,201 @@
1
+ import { LitElement } from 'lit'
2
+ import { property } from 'lit/decorators.js'
3
+
4
+ import { ZERO_CONFIG, ZERO_DATA } from './configure/zero-config'
5
+ import { ColumnConfig, GristConfig, GristData, GristRecord } from './types'
6
+
7
+ export class DataManipulator extends LitElement {
8
+ @property({ type: Object }) config: GristConfig = ZERO_CONFIG
9
+ @property({ type: Object }) data: GristData = ZERO_DATA
10
+
11
+ constructor() {
12
+ super()
13
+
14
+ this.addEventListener('select-record-change', e => {
15
+ var {
16
+ records: selectedRecords,
17
+ added = [],
18
+ removed = []
19
+ } = (e as CustomEvent).detail as {
20
+ records: GristRecord[]
21
+ added: GristRecord[]
22
+ removed: GristRecord[]
23
+ }
24
+
25
+ this.onSelectRecordChanged({
26
+ selectedRecords,
27
+ added,
28
+ removed
29
+ })
30
+ })
31
+
32
+ /* field change processing */
33
+ this.addEventListener('field-change', e => {
34
+ var { after, before, column, record, row } = (e as CustomEvent).detail as {
35
+ after: any
36
+ before: any
37
+ column: ColumnConfig
38
+ record: GristRecord
39
+ row: number
40
+ }
41
+
42
+ this.onFieldChange({ after, before, column, record, row })
43
+ })
44
+
45
+ /* record reset processing */
46
+ this.addEventListener('record-reset', e => {
47
+ var { record, row } = (e as CustomEvent).detail as {
48
+ record: GristRecord
49
+ row: number
50
+ }
51
+
52
+ this.onRecordChanged(record['__origin__'], row, null)
53
+ })
54
+ }
55
+
56
+ onFieldChange({
57
+ after,
58
+ before,
59
+ column,
60
+ record,
61
+ row
62
+ }: {
63
+ after: any
64
+ before: any
65
+ column: ColumnConfig
66
+ record: GristRecord
67
+ row: number
68
+ }) {
69
+ /* compare changes */
70
+ if (after === before) {
71
+ return
72
+ }
73
+
74
+ var validation = column.validation
75
+ if (validation && typeof validation == 'function') {
76
+ if (!validation.call(this, after, before, record, column)) {
77
+ return
78
+ }
79
+ }
80
+
81
+ this.onRecordChanged({ [column.name]: after }, row, column)
82
+ }
83
+
84
+ onSelectRecordChanged({
85
+ selectedRecords,
86
+ added = [],
87
+ removed = []
88
+ }: {
89
+ selectedRecords: GristRecord[]
90
+ added: GristRecord[]
91
+ removed: GristRecord[]
92
+ }) {
93
+ var { records } = this.data || {}
94
+ var { selectable = false } = this.config.rows || {}
95
+
96
+ if (!records || !selectable) {
97
+ return
98
+ }
99
+
100
+ if (selectable && !selectable.multiple) {
101
+ records.forEach(record => (record['__selected__'] = false))
102
+ }
103
+
104
+ if (selectedRecords) {
105
+ records.forEach(record => (record['__selected__'] = false))
106
+ selectedRecords.forEach(record => (record['__selected__'] = true))
107
+ } else {
108
+ removed.forEach(record => (record['__selected__'] = false))
109
+ added.forEach(record => (record['__selected__'] = true))
110
+ }
111
+
112
+ this.requestUpdate()
113
+ }
114
+
115
+ onRecordChanged(
116
+ recordData: GristRecord,
117
+ row: number,
118
+ column: ColumnConfig | null /* TODO column should be removed */
119
+ ) {
120
+ // TODO 오브젝트나 배열 타입인 경우 deepCompare 후에 변경 적용 여부를 결정한다.
121
+
122
+ /* 빈 그리드로 시작한 경우, data 설정이 되어있지 않을 수 있다. */
123
+ var records = this.data.records
124
+
125
+ var beforeRecord = records[row]
126
+ var afterRecord: GristRecord
127
+ var wantToDelete = false
128
+ var wantToAppend = false
129
+
130
+ if (!recordData) {
131
+ if (!beforeRecord) {
132
+ /* recordData가 없고, beforeRecord도 없다면, 레코드 생성 중에 리셋된 경우이므로 아무것도 하지 않는다. */
133
+ this.requestUpdate()
134
+ return
135
+ } else {
136
+ /*
137
+ * beforeRecord가 있는데, 빈데이타로 업데이트하고자 한다면,
138
+ * 삭제하고자 하는 의도로 이해된다. (주의 필요)
139
+ */
140
+ if (beforeRecord['__dirty__'] == '+') {
141
+ wantToDelete = true
142
+ } else {
143
+ afterRecord = {
144
+ ...beforeRecord,
145
+ __dirty__: '-'
146
+ }
147
+ }
148
+ }
149
+ } else {
150
+ if (!beforeRecord) {
151
+ /* 기존 레코드가 없는 경우에는 새로운 레코드가 생성된다 */
152
+ afterRecord = {
153
+ ...recordData,
154
+ __dirty__: '+'
155
+ }
156
+
157
+ wantToAppend = true
158
+ } else {
159
+ let beforeDirty = beforeRecord['__dirty__']
160
+ if (beforeDirty == '+') {
161
+ /* 기존에 새로 생성된 레코드가 있었으며 계속 수정중이다. */
162
+ afterRecord = {
163
+ ...beforeRecord,
164
+ ...recordData,
165
+ __dirty__: '+'
166
+ }
167
+ } else {
168
+ /* 기존에 레코드가 있었으며 계속 수정중이다. */
169
+ afterRecord = {
170
+ ...beforeRecord,
171
+ ...recordData,
172
+ __dirty__: 'M'
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ if (wantToAppend) {
179
+ records.push(afterRecord!)
180
+ } else if (wantToDelete) {
181
+ records.splice(row, 1)
182
+ } else {
183
+ records.splice(row, 1, afterRecord!)
184
+ }
185
+
186
+ this.dispatchEvent(
187
+ new CustomEvent('record-change', {
188
+ bubbles: true,
189
+ composed: true,
190
+ detail: {
191
+ before: beforeRecord,
192
+ after: afterRecord!,
193
+ column,
194
+ row
195
+ }
196
+ })
197
+ )
198
+
199
+ this.requestUpdate()
200
+ }
201
+ }
@@ -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
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './registry'
2
2
 
3
3
  export * from './input-editors'
4
+ export * from './image-input'
@@ -1,9 +1,9 @@
1
- import { ColumnConfig, GristRecord } from '../types'
2
- import { LitElement, css, html } from 'lit'
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: block;
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() {
@@ -1,10 +1,12 @@
1
+ import { DataGridField } from '../data-grid/data-grid-field'
2
+ import { ColumnConfig, FieldEditor, GristRecord } from '../types'
3
+ import { ImageInput } from './image-input'
1
4
  import {
2
5
  CheckboxInput,
3
6
  ColorInput,
4
7
  DateInput,
5
8
  DateTimeInput,
6
9
  EmailInput,
7
- ImageInput,
8
10
  InputEditor,
9
11
  MonthInput,
10
12
  NumberInput,
@@ -15,9 +17,6 @@ import {
15
17
  TimeInput,
16
18
  WeekInput
17
19
  } from './input-editors'
18
- import { ColumnConfig, FieldEditor, GristRecord } from '../types'
19
-
20
- import { DataGridField } from '../data-grid/data-grid-field'
21
20
 
22
21
  var EDITORS: { [name: string]: { new (): InputEditor } } = {
23
22
  string: TextInput,
@@ -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 { html } from 'lit'
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
- document.dispatchEvent(
22
- new CustomEvent('open-popup', {
17
+ field.dispatchEvent(
18
+ new CustomEvent('show-record-view', {
19
+ bubbles: true,
20
+ composed: true,
23
21
  detail: {
24
- template: html`
25
- <record-view
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
- } as any)
25
+ })
62
26
  )
63
27
  }
@@ -1,6 +1,5 @@
1
- import { ColumnConfig, GristData, GristRecord } from '../types'
2
-
3
1
  import { DataGridField } from '../data-grid/data-grid-field'
2
+ import { ColumnConfig, GristData, GristRecord } from '../types'
4
3
 
5
4
  /*
6
5
  * handler들은 ox-grid-field 로부터 호출되는 것을 전제로 하며,
@@ -0,0 +1,30 @@
1
+ import { DataGridField } from '../../data-grid/data-grid-field'
2
+ import { RecordViewBody } from '../record-view-body'
3
+
4
+ /**
5
+ * ox-record-view-body 의 click handler
6
+ *
7
+ * - handler의 this 는 ox-record-view-body임.
8
+ */
9
+ export function recordViewBodyClickHandler(this: RecordViewBody, e: Event): void {
10
+ e.stopPropagation()
11
+
12
+ /* target should be 'ox-grid-field' */
13
+ var target = e.target as DataGridField
14
+
15
+ if (!this.onlyForEdit && this.currentTarget) {
16
+ this.focus()
17
+ this.currentTarget.removeAttribute('editing')
18
+ }
19
+
20
+ if (target.tagName !== 'OX-GRID-FIELD' || !target.column.record.editable) {
21
+ this.focus()
22
+ this.currentTarget = null
23
+ return
24
+ }
25
+
26
+ this.currentTarget = target
27
+ if (!this.onlyForEdit) {
28
+ target.setAttribute('editing', 'true')
29
+ }
30
+ }
@@ -0,0 +1,26 @@
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
+ switch ((e as KeyboardEvent).key) {
10
+ case 'Esc':
11
+ case 'Escape':
12
+ /* TODO 편집이 취소되어야 한다. */
13
+ case 'Enter':
14
+ /* 먼저, focus를 옮겨놓아야, focusout 으로 인해서 popup이 닫히는 것을 방지할 수 있다. */
15
+ !this.onlyForEdit && this.focus()
16
+
17
+ if (!this.onlyForEdit && this.currentTarget) {
18
+ this.currentTarget.removeAttribute('editing')
19
+ }
20
+
21
+ this.currentTarget = null
22
+
23
+ break
24
+ default:
25
+ }
26
+ }
@@ -1 +1,2 @@
1
1
  export * from './record-view'
2
+ export * from './record-creator'