@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.
Files changed (80) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/custom-elements.json +939 -927
  3. package/demo/index.html +5 -2
  4. package/dist/src/data-card/record-card.d.ts +0 -2
  5. package/dist/src/data-card/record-card.js +7 -59
  6. package/dist/src/data-card/record-card.js.map +1 -1
  7. package/dist/src/data-grid/data-grid-body.d.ts +7 -1
  8. package/dist/src/data-grid/data-grid-body.js +21 -0
  9. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  10. package/dist/src/data-grid/data-grid.d.ts +1 -0
  11. package/dist/src/data-grid/data-grid.js +6 -0
  12. package/dist/src/data-grid/data-grid.js.map +1 -1
  13. package/dist/src/data-list/record-partial.d.ts +0 -2
  14. package/dist/src/data-list/record-partial.js +7 -58
  15. package/dist/src/data-list/record-partial.js.map +1 -1
  16. package/dist/src/editors/image-editor.d.ts +9 -0
  17. package/dist/src/editors/image-editor.js +53 -0
  18. package/dist/src/editors/image-editor.js.map +1 -0
  19. package/dist/src/editors/image-input.d.ts +7 -0
  20. package/dist/src/editors/image-input.js +31 -0
  21. package/dist/src/editors/image-input.js.map +1 -0
  22. package/dist/src/editors/index.d.ts +1 -0
  23. package/dist/src/editors/index.js +1 -0
  24. package/dist/src/editors/index.js.map +1 -1
  25. package/dist/src/editors/input-editors copy.d.ts +75 -0
  26. package/dist/src/editors/input-editors copy.js +373 -0
  27. package/dist/src/editors/input-editors copy.js.map +1 -0
  28. package/dist/src/editors/input-editors.d.ts +1 -8
  29. package/dist/src/editors/input-editors.js +3 -47
  30. package/dist/src/editors/input-editors.js.map +1 -1
  31. package/dist/src/editors/registry.js +2 -1
  32. package/dist/src/editors/registry.js.map +1 -1
  33. package/dist/src/handlers/record-view-handler.d.ts +1 -2
  34. package/dist/src/handlers/record-view-handler.js +5 -35
  35. package/dist/src/handlers/record-view-handler.js.map +1 -1
  36. package/dist/src/handlers/select-row-toggle.d.ts +1 -1
  37. package/dist/src/handlers/select-row-toggle.js.map +1 -1
  38. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +3 -1
  39. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -1
  40. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +0 -74
  41. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -1
  42. package/dist/src/record-view/index.d.ts +1 -0
  43. package/dist/src/record-view/index.js +1 -0
  44. package/dist/src/record-view/index.js.map +1 -1
  45. package/dist/src/record-view/record-creator copy.d.ts +13 -0
  46. package/dist/src/record-view/record-creator copy.js +90 -0
  47. package/dist/src/record-view/record-creator copy.js.map +1 -0
  48. package/dist/src/record-view/record-creator-backup.d.ts +13 -0
  49. package/dist/src/record-view/record-creator-backup.js +90 -0
  50. package/dist/src/record-view/record-creator-backup.js.map +1 -0
  51. package/dist/src/record-view/record-creator.d.ts +5 -2
  52. package/dist/src/record-view/record-creator.js +69 -14
  53. package/dist/src/record-view/record-creator.js.map +1 -1
  54. package/dist/src/record-view/record-view-body.js +2 -4
  55. package/dist/src/record-view/record-view-body.js.map +1 -1
  56. package/dist/src/record-view/record-view-handler.d.ts +9 -0
  57. package/dist/src/record-view/record-view-handler.js +57 -0
  58. package/dist/src/record-view/record-view-handler.js.map +1 -0
  59. package/dist/src/record-view/record-view.d.ts +2 -3
  60. package/dist/src/record-view/record-view.js +11 -61
  61. package/dist/src/record-view/record-view.js.map +1 -1
  62. package/dist/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +7 -7
  64. package/src/data-card/record-card.ts +14 -74
  65. package/src/data-grid/data-grid-body.ts +38 -1
  66. package/src/data-grid/data-grid.ts +12 -0
  67. package/src/data-list/record-partial.ts +14 -73
  68. package/src/editors/image-input.ts +29 -0
  69. package/src/editors/index.ts +1 -0
  70. package/src/editors/input-editors.ts +5 -48
  71. package/src/editors/registry.ts +1 -1
  72. package/src/handlers/record-view-handler.ts +8 -44
  73. package/src/handlers/select-row-toggle.ts +1 -2
  74. package/src/record-view/event-handlers/record-view-body-click-handler.ts +3 -1
  75. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -89
  76. package/src/record-view/index.ts +1 -0
  77. package/src/record-view/record-creator.ts +85 -16
  78. package/src/record-view/record-view-body.ts +2 -4
  79. package/src/record-view/record-view-handler.ts +86 -0
  80. 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
+ }
@@ -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,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 { 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 로부터 호출되는 것을 전제로 하며,
@@ -24,5 +24,7 @@ export function recordViewBodyClickHandler(this: RecordViewBody, e: Event): void
24
24
  }
25
25
 
26
26
  this.currentTarget = target
27
- target.setAttribute('editing', 'true')
27
+ if (!this.onlyForEdit) {
28
+ target.setAttribute('editing', 'true')
29
+ }
28
30
  }
@@ -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
  }
@@ -1 +1,2 @@
1
1
  export * from './record-view'
2
+ export * from './record-creator'
@@ -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
- @state() record: GristRecord = { __dirty__: '+' }
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.popupRecordView()
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
- popupRecordView() {
45
+ lightPopupRecordView() {
42
46
  const config = this.grist!.compiledConfig
43
- var titleField = config.list.fields[0] || 'name'
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 != 'gutter')
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
+ }