@operato/data-grist 8.0.0-alpha.8 → 8.0.0-beta.1

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