@operato/data-grist 7.1.30 → 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.
Files changed (175) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/src/data-grid/data-grid-body-style.js +2 -2
  3. package/dist/src/data-grid/data-grid-body-style.js.map +1 -1
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/package.json +10 -10
  6. package/.storybook/main.js +0 -3
  7. package/.storybook/preview.js +0 -52
  8. package/.storybook/server.mjs +0 -8
  9. package/demo/data-grist-test.html +0 -468
  10. package/demo/favicon.ico +0 -0
  11. package/demo/index.html +0 -541
  12. package/demo/report-test.html +0 -249
  13. package/dist/src/record-view/record-creator.d.ts +0 -17
  14. package/dist/src/record-view/record-creator.js +0 -148
  15. package/dist/src/record-view/record-creator.js.map +0 -1
  16. package/src/accumulator/accumulator.ts +0 -63
  17. package/src/configure/column-builder.ts +0 -114
  18. package/src/configure/config-builder.ts +0 -40
  19. package/src/configure/filters-option-builder.ts +0 -8
  20. package/src/configure/imex-option-builder.ts +0 -5
  21. package/src/configure/list-option-builder.ts +0 -9
  22. package/src/configure/rows-option-builder.ts +0 -38
  23. package/src/configure/tree-option-builder.ts +0 -22
  24. package/src/configure/zero-config.ts +0 -83
  25. package/src/const.ts +0 -1
  26. package/src/data-card/data-card-field.ts +0 -94
  27. package/src/data-card/data-card-gutter-menu.ts +0 -94
  28. package/src/data-card/data-card-gutter.ts +0 -103
  29. package/src/data-card/data-card.ts +0 -154
  30. package/src/data-card/event-handlers/record-card-click-handler.ts +0 -34
  31. package/src/data-card/event-handlers/record-card-dblclick-handler.ts +0 -34
  32. package/src/data-card/record-card.ts +0 -289
  33. package/src/data-consumer.ts +0 -11
  34. package/src/data-grid/data-grid-accum-field.ts +0 -109
  35. package/src/data-grid/data-grid-body-style.ts +0 -99
  36. package/src/data-grid/data-grid-body.ts +0 -753
  37. package/src/data-grid/data-grid-field.ts +0 -236
  38. package/src/data-grid/data-grid-footer.ts +0 -117
  39. package/src/data-grid/data-grid-header.ts +0 -574
  40. package/src/data-grid/data-grid.ts +0 -293
  41. package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +0 -69
  42. package/src/data-grid/event-handlers/data-grid-body-contextmenu-handler.ts +0 -32
  43. package/src/data-grid/event-handlers/data-grid-body-dblclick-handler.ts +0 -42
  44. package/src/data-grid/event-handlers/data-grid-body-focus-change-handler.ts +0 -24
  45. package/src/data-grid/event-handlers/data-grid-body-keydown-handler.ts +0 -234
  46. package/src/data-grist.ts +0 -1233
  47. package/src/data-list/data-list-field.ts +0 -82
  48. package/src/data-list/data-list-gutter.ts +0 -108
  49. package/src/data-list/data-list.ts +0 -145
  50. package/src/data-list/event-handlers/record-partial-click-handler.ts +0 -34
  51. package/src/data-list/event-handlers/record-partial-dblclick-handler.ts +0 -33
  52. package/src/data-list/event-handlers/record-partial-long-press-handler.ts +0 -33
  53. package/src/data-list/record-partial.ts +0 -255
  54. package/src/data-manipulator.ts +0 -426
  55. package/src/data-provider.ts +0 -271
  56. package/src/data-report/data-report-body-style.ts +0 -58
  57. package/src/data-report/data-report-body.ts +0 -189
  58. package/src/data-report/data-report-component.ts +0 -138
  59. package/src/data-report/data-report-field.ts +0 -83
  60. package/src/data-report/data-report-header.ts +0 -242
  61. package/src/data-report/event-handlers/data-report-body-click-handler.ts +0 -38
  62. package/src/data-report/event-handlers/data-report-body-dblclick-handler.ts +0 -25
  63. package/src/data-report/event-handlers/data-report-body-keydown-handler.ts +0 -68
  64. package/src/data-report.ts +0 -424
  65. package/src/editors/index.ts +0 -4
  66. package/src/editors/ox-grist-editor-checkbox.ts +0 -28
  67. package/src/editors/ox-grist-editor-color.ts +0 -10
  68. package/src/editors/ox-grist-editor-date.ts +0 -10
  69. package/src/editors/ox-grist-editor-datetime.ts +0 -27
  70. package/src/editors/ox-grist-editor-email.ts +0 -10
  71. package/src/editors/ox-grist-editor-file.ts +0 -28
  72. package/src/editors/ox-grist-editor-image.ts +0 -31
  73. package/src/editors/ox-grist-editor-month.ts +0 -10
  74. package/src/editors/ox-grist-editor-multiple-select.ts +0 -57
  75. package/src/editors/ox-grist-editor-number.ts +0 -27
  76. package/src/editors/ox-grist-editor-password.ts +0 -10
  77. package/src/editors/ox-grist-editor-select.ts +0 -55
  78. package/src/editors/ox-grist-editor-tel.ts +0 -10
  79. package/src/editors/ox-grist-editor-text.ts +0 -14
  80. package/src/editors/ox-grist-editor-textarea.ts +0 -16
  81. package/src/editors/ox-grist-editor-time.ts +0 -10
  82. package/src/editors/ox-grist-editor-tree.ts +0 -27
  83. package/src/editors/ox-grist-editor-varname.ts +0 -36
  84. package/src/editors/ox-grist-editor-week.ts +0 -10
  85. package/src/editors/ox-grist-editor.ts +0 -207
  86. package/src/editors/ox-input-tree.ts +0 -226
  87. package/src/editors/registry.ts +0 -82
  88. package/src/empty-note.ts +0 -46
  89. package/src/filters/filter-checkbox.ts +0 -49
  90. package/src/filters/filter-input-barcode.ts +0 -34
  91. package/src/filters/filter-input.ts +0 -30
  92. package/src/filters/filter-range-date.ts +0 -81
  93. package/src/filters/filter-range-number.ts +0 -64
  94. package/src/filters/filter-select-buttons.ts +0 -60
  95. package/src/filters/filter-select.ts +0 -68
  96. package/src/filters/filter-styles.ts +0 -119
  97. package/src/filters/filters-form.ts +0 -476
  98. package/src/filters/index.ts +0 -10
  99. package/src/filters/registry.ts +0 -56
  100. package/src/formatters/date-formatter.ts +0 -3
  101. package/src/formatters/index.ts +0 -1
  102. package/src/formatters/number-formatter.ts +0 -3
  103. package/src/formatters/registry.ts +0 -30
  104. package/src/formatters/text-formatter.ts +0 -3
  105. package/src/gutters/gutter-button.ts +0 -51
  106. package/src/gutters/gutter-dirty.ts +0 -96
  107. package/src/gutters/gutter-row-selector.ts +0 -89
  108. package/src/gutters/gutter-sequence.ts +0 -54
  109. package/src/gutters/index.ts +0 -1
  110. package/src/gutters/registry.ts +0 -32
  111. package/src/handlers/contextmenu-tree-mutation.ts +0 -80
  112. package/src/handlers/index.ts +0 -1
  113. package/src/handlers/move-down.ts +0 -44
  114. package/src/handlers/move-up.ts +0 -44
  115. package/src/handlers/record-copy.ts +0 -38
  116. package/src/handlers/record-delete.ts +0 -30
  117. package/src/handlers/record-view-handler.ts +0 -27
  118. package/src/handlers/registry.ts +0 -42
  119. package/src/handlers/select-row-toggle.ts +0 -30
  120. package/src/handlers/select-row.ts +0 -27
  121. package/src/index.ts +0 -17
  122. package/src/personalizer/index.ts +0 -1
  123. package/src/personalizer/ox-grist-filter-personalizer.ts +0 -192
  124. package/src/personalizer/ox-grist-personalizer.ts +0 -226
  125. package/src/record-view/event-handlers/record-view-body-click-handler.ts +0 -33
  126. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -26
  127. package/src/record-view/index.ts +0 -2
  128. package/src/record-view/ox-record-creator.ts +0 -289
  129. package/src/record-view/record-view-body.ts +0 -250
  130. package/src/record-view/record-view-handler.ts +0 -86
  131. package/src/record-view/record-view.ts +0 -122
  132. package/src/renderers/index.ts +0 -14
  133. package/src/renderers/ox-grist-renderer-boolean.ts +0 -43
  134. package/src/renderers/ox-grist-renderer-color.ts +0 -15
  135. package/src/renderers/ox-grist-renderer-date.ts +0 -62
  136. package/src/renderers/ox-grist-renderer-file.ts +0 -31
  137. package/src/renderers/ox-grist-renderer-image.ts +0 -27
  138. package/src/renderers/ox-grist-renderer-json5.ts +0 -36
  139. package/src/renderers/ox-grist-renderer-link.ts +0 -17
  140. package/src/renderers/ox-grist-renderer-password.ts +0 -7
  141. package/src/renderers/ox-grist-renderer-progress.ts +0 -45
  142. package/src/renderers/ox-grist-renderer-select.ts +0 -58
  143. package/src/renderers/ox-grist-renderer-text.ts +0 -16
  144. package/src/renderers/ox-grist-renderer-textarea.ts +0 -7
  145. package/src/renderers/ox-grist-renderer-tree.ts +0 -189
  146. package/src/renderers/ox-grist-renderer.ts +0 -35
  147. package/src/renderers/registry.ts +0 -111
  148. package/src/sorters/sorters-control.ts +0 -143
  149. package/src/types.ts +0 -813
  150. package/src/utils/index.ts +0 -2
  151. package/src/utils/list-param.ts +0 -72
  152. package/src/utils/supports-passive.ts +0 -13
  153. package/stories/accumulator-format.stories.ts +0 -276
  154. package/stories/barcode-input-filter.stories.ts +0 -216
  155. package/stories/bounded-select-filters.stories.ts +0 -333
  156. package/stories/bounded-select-record.stories.ts +0 -336
  157. package/stories/click-event-custom.stories.ts +0 -288
  158. package/stories/click-event.stories.ts +0 -283
  159. package/stories/creatable-only-column.stories.ts +0 -253
  160. package/stories/default-filters.stories.ts +0 -241
  161. package/stories/dynamic-editable.stories.ts +0 -313
  162. package/stories/empty-sorters.stories.ts +0 -180
  163. package/stories/explicit-fetch.stories.ts +0 -186
  164. package/stories/fixed-column.stories.ts +0 -416
  165. package/stories/grid-setting.stories.ts +0 -501
  166. package/stories/grist-modes.stories.ts +0 -451
  167. package/stories/group-header.stories.ts +0 -442
  168. package/stories/record-view.stories.ts +0 -143
  169. package/stories/textarea.stories.ts +0 -261
  170. package/stories/tree-column-with-checkbox.stories.ts +0 -297
  171. package/stories/tree-column.stories.ts +0 -296
  172. package/tsconfig.json +0 -26
  173. package/web-dev-server.config.mjs +0 -27
  174. package/web-test-runner.config.mjs +0 -45
  175. package/yarn-error.log +0 -16971
@@ -1,289 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import './record-view'
3
-
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, property, state } from 'lit/decorators.js'
6
-
7
- import { OxPopup } from '@operato/popup'
8
-
9
- import { DataGrist } from '../data-grist'
10
- import { ColumnConfig, GristRecord, ValidationReason } from '../types'
11
- import { RecordView } from './record-view'
12
-
13
- @customElement('ox-record-creator')
14
- export class OxRecordCreator extends LitElement {
15
- static styles = [
16
- css`
17
- ::slotted([slot='popup']) {
18
- display: none;
19
- }
20
- `
21
- ]
22
-
23
- @state() grist?: DataGrist
24
-
25
- @property({ type: Object }) callback?: (record: GristRecord) => boolean
26
- @property({ type: Object }) customPopupCallback?: (popup: any) => boolean
27
- @property({ type: Boolean, attribute: 'light-popup' }) lightPopup: boolean = false
28
- @property({ type: Boolean, attribute: 'prevent-close-on-blur' }) preventCloseOnBlur = false
29
-
30
- constructor() {
31
- super()
32
-
33
- this.addEventListener('click', (e: Event) => {
34
- e.preventDefault()
35
- e.stopPropagation()
36
-
37
- if (this.lightPopup) {
38
- this.openLightPopup()
39
- } else {
40
- this.openPopup()
41
- }
42
- })
43
- }
44
-
45
- connectedCallback(): void {
46
- super.connectedCallback()
47
-
48
- this.grist = this.closest('ox-grist') as DataGrist
49
- }
50
-
51
- render() {
52
- return html`
53
- <slot></slot>
54
- <slot name="popup"></slot>
55
- `
56
- }
57
-
58
- validateRecord(record: GristRecord): { field: string; reason: ValidationReason }[] {
59
- const columns = this.grist!.compiledConfig.columns
60
- const invalidFields: { field: string; reason: ValidationReason }[] = []
61
-
62
- columns
63
- .filter(column => !column.hidden)
64
- .forEach(column => {
65
- if (
66
- column.record?.mandatory &&
67
- (record[column.name] === undefined || record[column.name] === null || record[column.name] === '')
68
- ) {
69
- invalidFields.push({
70
- field: column.name,
71
- reason: ValidationReason.MANDATORY
72
- })
73
- }
74
- })
75
-
76
- return invalidFields
77
- }
78
-
79
- openLightPopup() {
80
- const slot = this.renderRoot?.querySelector(`slot[name='popup']`) as HTMLSlotElement
81
- const slottedElements = slot?.assignedElements({ flatten: true })
82
- const originalContent = slottedElements?.[0] as HTMLElement
83
-
84
- if (originalContent) {
85
- this.lightPopupCustomCreator(originalContent)
86
- } else {
87
- this.lightPopupRecordView()
88
- }
89
- }
90
-
91
- openPopup() {
92
- const slot = this.renderRoot?.querySelector(`slot[name='popup']`) as HTMLSlotElement
93
- const slottedElements = slot?.assignedElements({ flatten: true })
94
- const originalContent = slottedElements?.[0] as HTMLElement
95
-
96
- if (originalContent) {
97
- this.popupCustomCreator(originalContent)
98
- } else {
99
- this.popupRecordView()
100
- }
101
- }
102
-
103
- lightPopupRecordView() {
104
- const config = this.grist!.compiledConfig
105
- var title = 'create'
106
- const rowIndex = -1
107
- var record: GristRecord = {}
108
- const columns = config.columns
109
-
110
- var popup = OxPopup.open({
111
- template: html`
112
- <div title>${title}</div>
113
- <ox-record-view
114
- @field-change=${(e: CustomEvent) => {
115
- const view = e.currentTarget as RecordView
116
-
117
- var { after, before, column, record, row } = (e as CustomEvent).detail as {
118
- after: any
119
- before: any
120
- column: ColumnConfig
121
- record: GristRecord
122
- row: number
123
- }
124
-
125
- var validation = column.validation
126
- if (validation && typeof validation == 'function') {
127
- if (!validation.call(this, after, before, record, column)) {
128
- return
129
- }
130
- }
131
-
132
- view.record = {
133
- ...record,
134
- [column.name]: after
135
- }
136
- }}
137
- .columns=${columns}
138
- .record=${record}
139
- .rowIndex=${rowIndex}
140
- @reset=${(e: Event) => {
141
- const view = e.currentTarget as RecordView
142
- view.record = {}
143
- }}
144
- @cancel=${(e: Event) => {
145
- popup.close()
146
- }}
147
- @ok=${async (e: Event) => {
148
- const view = e.currentTarget as RecordView
149
-
150
- const invalidFields = await this.validateRecord(view.record)
151
- if (invalidFields.length > 0) {
152
- view.setFocusOnInvalid(invalidFields)
153
- return false
154
- }
155
-
156
- popup.close()
157
-
158
- this.dispatchEvent(
159
- new CustomEvent('ok', {
160
- bubbles: true,
161
- composed: true,
162
- detail: view.record
163
- })
164
- )
165
- }}
166
- ></ox-record-view>
167
- `,
168
- parent: document.body,
169
- preventCloseOnBlur: this.preventCloseOnBlur
170
- })
171
- }
172
-
173
- popupRecordView() {
174
- const config = this.grist!.compiledConfig
175
- const rowIndex = -1
176
- var record: GristRecord = {}
177
- const columns = config.columns
178
-
179
- var title = 'create'
180
-
181
- var recordView = document.createElement('ox-record-view') as RecordView
182
-
183
- recordView.columns = columns
184
- recordView.record = record
185
- recordView.rowIndex = rowIndex
186
-
187
- document.dispatchEvent(
188
- new CustomEvent('open-popup', {
189
- detail: {
190
- template: recordView,
191
- options: {
192
- backdrop: true,
193
- size: 'large',
194
- title
195
- },
196
- callback: (popup: any) => {
197
- recordView.addEventListener('reset', (e: Event) => {
198
- const view = e.currentTarget as RecordView
199
- view.record = {}
200
- })
201
-
202
- recordView.addEventListener('cancel', (e: Event) => {
203
- popup.close()
204
- })
205
-
206
- recordView.addEventListener('ok', async (e: Event) => {
207
- const view = e.currentTarget as RecordView
208
-
209
- const invalidFields = await this.validateRecord(view.record)
210
- if (invalidFields.length > 0) {
211
- view.setFocusOnInvalid(invalidFields)
212
- return false
213
- }
214
-
215
- if (await this.callback?.(view.record)) {
216
- popup.close()
217
- } else {
218
- console.error('validation failed')
219
- }
220
- })
221
-
222
- recordView.addEventListener('field-change', async (e: Event) => {
223
- const view = e.currentTarget as RecordView
224
-
225
- var { after, before, column, record, row } = (e as CustomEvent).detail as {
226
- after: any
227
- before: any
228
- column: ColumnConfig
229
- record: GristRecord
230
- row: number
231
- }
232
-
233
- var validation = column.validation
234
- if (validation && typeof validation == 'function') {
235
- if (!(await validation.call(this, after, before, record, column))) {
236
- return
237
- }
238
- }
239
-
240
- view.record = {
241
- ...record,
242
- [column.name]: after
243
- }
244
- })
245
-
246
- popup.onclosed = () => {}
247
- }
248
- }
249
- })
250
- )
251
- }
252
-
253
- lightPopupCustomCreator(originalContent: HTMLElement) {
254
- const title = 'create'
255
- const popupContent = originalContent.cloneNode(true) as HTMLElement
256
- popupContent.removeAttribute('slot')
257
-
258
- OxPopup.open({
259
- template: html`
260
- <div title>${title}</div>
261
- ${popupContent}
262
- `,
263
- parent: document.body,
264
- preventCloseOnBlur: this.preventCloseOnBlur
265
- })
266
-
267
- this.customPopupCallback?.(popupContent) // 사용자 정의 팝업용 콜백 실행
268
- }
269
-
270
- popupCustomCreator(originalContent: HTMLElement) {
271
- const title = 'create'
272
- const popupContent = originalContent.cloneNode(true) as HTMLElement
273
- popupContent.removeAttribute('slot')
274
-
275
- document.dispatchEvent(
276
- new CustomEvent('open-popup', {
277
- detail: {
278
- template: popupContent,
279
- options: {
280
- backdrop: true,
281
- size: 'large',
282
- title
283
- },
284
- callback: this.customPopupCallback
285
- }
286
- })
287
- )
288
- }
289
- }
@@ -1,250 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '../data-grid/data-grid-field'
3
-
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, property } from 'lit/decorators.js'
6
-
7
- import { ZERO_RECORD } from '../configure/zero-config'
8
- import { ColumnConfig, GristRecord, ValidationReason } from '../types'
9
- import { recordViewBodyClickHandler } from './event-handlers/record-view-body-click-handler'
10
- import i18next from 'i18next'
11
-
12
- @customElement('ox-record-view-body')
13
- export class RecordViewBody extends LitElement {
14
- static styles = [
15
- css`
16
- :host {
17
- display: flex;
18
- justify-content: center;
19
- }
20
-
21
- div[content] {
22
- display: grid;
23
- grid-template-columns: 2fr 3fr 2fr 3fr;
24
- grid-auto-rows: min-content;
25
- grid-gap: var(--spacing-large) 0;
26
-
27
- padding: var(--spacing-large) var(--spacing-huge);
28
- font-size: 16px; /* for ios safari */
29
- flex: 1;
30
- max-width: 1300px;
31
- box-sizing: border-box;
32
- }
33
-
34
- label {
35
- display: flex;
36
- align-items: center;
37
- position: relative;
38
- text-transform: capitalize;
39
- padding: var(--record-view-item-padding);
40
- font: var(--record-view-label-font);
41
- color: var(--record-view-label-color);
42
- text-align: right;
43
- padding-right: var(--spacing-large);
44
- }
45
-
46
- label[wide] {
47
- grid-column: 1 / 2;
48
- }
49
-
50
- label md-icon {
51
- display: none;
52
- }
53
-
54
- label > span {
55
- margin-left: auto;
56
- }
57
-
58
- label[editable] md-icon {
59
- display: inline-block;
60
- font-size: var(--record-view-label-icon-size);
61
- opacity: 0.5;
62
- }
63
-
64
- ox-grid-field {
65
- background-color: var(--record-view-grid-field-background-color, var(--md-sys-color-surface-container-lowest));
66
- border: var(--record-view-grid-field-border);
67
- border-radius: var(--md-sys-shape-corner-small);
68
- padding: var(--spacing-tiny) var(--spacing-small);
69
-
70
- font: var(--record-view-font);
71
- color: var(--record-view-color);
72
-
73
- max-width: 360px;
74
- }
75
-
76
- ox-grid-field[editing='true'] {
77
- border: var(--record-view-edit-border);
78
- }
79
-
80
- ox-grid-field[wide] {
81
- grid-column: 2 / 5;
82
- width: 100%;
83
- max-width: 986px;
84
- }
85
-
86
- :first-child + ox-grid-field {
87
- color: var(--record-view-focus-color);
88
- font-weight: bold;
89
- }
90
-
91
- .highlight-invalid {
92
- position: relative;
93
- padding: var(--spacing-tiny) var(--spacing-small);
94
- }
95
-
96
- .highlight-invalid::after {
97
- content: attr(data-reason); /* 콘텐츠를 동적으로 변경하기 위해 data-reason 속성을 사용 */
98
- color: red;
99
- font-size: 12px;
100
- position: absolute;
101
- left: 0;
102
- bottom: -8px; /* 라벨 아래쪽에 메시지를 표시 */
103
- }
104
-
105
- @media only screen and (max-width: 1000px) {
106
- div[content] {
107
- grid-template-columns: 2fr 3fr;
108
- padding: var(--spacing-medium);
109
- }
110
-
111
- label[wide] {
112
- grid-column: 1 / 2;
113
- }
114
-
115
- ox-grid-field[wide] {
116
- grid-column: 2 / 3;
117
- width: 100%;
118
- max-width: 360px;
119
- }
120
- }
121
-
122
- @media only screen and (max-width: 600px) {
123
- div[content] {
124
- grid-template-columns: 2fr 3fr;
125
- padding: var(--spacing-medium);
126
- }
127
-
128
- label[wide] {
129
- grid-column: 1 / 2;
130
- }
131
-
132
- ox-grid-field[wide] {
133
- grid-column: 1 / 3;
134
- width: 100%;
135
- max-width: unset;
136
- }
137
- }
138
- `
139
- ]
140
-
141
- @property({ type: Array }) columns: ColumnConfig[] = []
142
- @property({ type: Object }) record: GristRecord = ZERO_RECORD
143
- @property({ type: Number }) rowIndex: number = -1
144
-
145
- public currentTarget: any
146
-
147
- connectedCallback() {
148
- super.connectedCallback()
149
-
150
- this.setAttribute('tabindex', '0')
151
-
152
- this.addEventListener('keydown', this._onKeyDown)
153
- this.renderRoot.addEventListener('click', recordViewBodyClickHandler.bind(this))
154
- }
155
-
156
- disconnectedCallback() {
157
- super.disconnectedCallback()
158
- this.removeEventListener('keydown', this._onKeyDown)
159
- }
160
-
161
- setFocus(fieldElement: HTMLElement) {
162
- fieldElement?.dispatchEvent(new CustomEvent('click', { bubbles: true, composed: true }))
163
- }
164
-
165
- setFocusOnInvalid(invalidFields: { field: string; reason: ValidationReason }[]) {
166
- const allLabels = this.renderRoot.querySelectorAll('label')
167
- allLabels.forEach((label: HTMLLabelElement) => {
168
- label.classList.remove('highlight-invalid')
169
- label.removeAttribute('data-reason')
170
- });
171
-
172
- // 유효성 검사를 통과하지 못한 필드에 대해 처리
173
- invalidFields.forEach(({ field, reason }, index) => {
174
- const labelElement = this.renderRoot.querySelector(`[data-name="${field}"]`) as HTMLLabelElement
175
- const fieldElement = this.renderRoot.querySelector(`[data-name="${field}"] + ox-grid-field`) as HTMLInputElement
176
-
177
- // 동적으로 data-reason 속성을 설정하여 메시지를 변경
178
- if (labelElement) {
179
- labelElement.classList.add('highlight-invalid');
180
- labelElement.setAttribute('data-reason', '(' + i18next.t(`text.validation-reason.${reason}`) + ')')
181
- }
182
-
183
- // 첫 번째 필드에 포커스 설정
184
- if (index === 0 && fieldElement) {
185
- this.setFocus(fieldElement)
186
- }
187
- });
188
- }
189
-
190
-
191
- _onKeyDown(event: KeyboardEvent) {
192
- if (event.key === 'Tab') {
193
- const fields = Array.from(this.renderRoot.querySelectorAll('ox-grid-field[tabstop]'))
194
- const focused = this.renderRoot.querySelector('ox-grid-field[editing]')
195
- const focusedIndex = fields.findIndex(field => field === focused)
196
-
197
- let nextIndex = focusedIndex + (event.shiftKey ? -1 : 1)
198
-
199
- if (nextIndex >= fields.length || nextIndex < 0) {
200
- return // Let the default behavior happen if it's the last or first element
201
- }
202
-
203
- event.preventDefault()
204
- const nextField = fields[nextIndex] as HTMLInputElement
205
- nextField && this.setFocus(nextField)
206
- }
207
- }
208
-
209
- render() {
210
- var columns = this.columns.filter(column => !column.hidden && column.type !== 'gutter')
211
- var record = this.record
212
- var rowIndex = this.rowIndex
213
-
214
- return html`
215
- <div content>
216
- ${columns.map((column, index) => {
217
- let { editable, mandatory, wide } = column.record
218
- if (typeof editable === 'function') {
219
- editable = editable.call(this, record[column.name], column, record, rowIndex, this)
220
- }
221
-
222
- let dirtyFields = record['__dirtyfields__'] || {}
223
-
224
- return html`
225
- <label ?editable=${editable} ?wide=${wide} data-name=${column.name}>
226
- <span>${mandatory ? '*' : ''}${this._renderLabel(column)}</span>
227
- <md-icon>edit</md-icon>
228
- </label>
229
- <ox-grid-field
230
- .rowIndex=${rowIndex}
231
- .column=${column}
232
- .record=${record}
233
- .value=${record[column.name]}
234
- ?dirty=${!!dirtyFields[column.name]}
235
- ?tabstop=${!!editable}
236
- ?wide=${wide}
237
- ></ox-grid-field>
238
- `
239
- })}
240
- </div>
241
- `
242
- }
243
-
244
- _renderLabel(column: ColumnConfig) {
245
- var { renderer } = column.header
246
- var title = renderer.call(this, column)
247
-
248
- return html` ${title} `
249
- }
250
- }
@@ -1,86 +0,0 @@
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
- }