@operato/data-grist 2.0.0-alpha.99 → 2.0.0-beta.0

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 (216) hide show
  1. package/CHANGELOG.md +433 -0
  2. package/demo/data-grist-test.html +1 -1
  3. package/demo/index.html +1 -1
  4. package/dist/src/data-card/data-card-field.js +2 -2
  5. package/dist/src/data-card/data-card-field.js.map +1 -1
  6. package/dist/src/data-card/data-card-gutter-menu.js +5 -5
  7. package/dist/src/data-card/data-card-gutter-menu.js.map +1 -1
  8. package/dist/src/data-card/data-card-gutter.js +6 -6
  9. package/dist/src/data-card/data-card-gutter.js.map +1 -1
  10. package/dist/src/data-card/data-card.js +7 -9
  11. package/dist/src/data-card/data-card.js.map +1 -1
  12. package/dist/src/data-card/record-card.js +9 -10
  13. package/dist/src/data-card/record-card.js.map +1 -1
  14. package/dist/src/data-grid/data-grid-accum-field.js +12 -5
  15. package/dist/src/data-grid/data-grid-accum-field.js.map +1 -1
  16. package/dist/src/data-grid/data-grid-body-style.js +12 -0
  17. package/dist/src/data-grid/data-grid-body-style.js.map +1 -1
  18. package/dist/src/data-grid/data-grid-body.d.ts +0 -1
  19. package/dist/src/data-grid/data-grid-body.js +14 -21
  20. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  21. package/dist/src/data-grid/data-grid-field.js +8 -2
  22. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  23. package/dist/src/data-grid/data-grid-footer.js +4 -2
  24. package/dist/src/data-grid/data-grid-footer.js.map +1 -1
  25. package/dist/src/data-grid/data-grid-header.js +9 -6
  26. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  27. package/dist/src/data-grid/data-grid.js +23 -1
  28. package/dist/src/data-grid/data-grid.js.map +1 -1
  29. package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js +3 -0
  30. package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js.map +1 -1
  31. package/dist/src/data-grist.d.ts +10 -2
  32. package/dist/src/data-grist.js +71 -8
  33. package/dist/src/data-grist.js.map +1 -1
  34. package/dist/src/data-list/data-list-field.js +5 -5
  35. package/dist/src/data-list/data-list-field.js.map +1 -1
  36. package/dist/src/data-list/data-list-gutter.js +3 -3
  37. package/dist/src/data-list/data-list-gutter.js.map +1 -1
  38. package/dist/src/data-list/data-list.js +4 -4
  39. package/dist/src/data-list/data-list.js.map +1 -1
  40. package/dist/src/data-list/record-partial.js +9 -10
  41. package/dist/src/data-list/record-partial.js.map +1 -1
  42. package/dist/src/data-manipulator.d.ts +1 -1
  43. package/dist/src/data-manipulator.js +5 -5
  44. package/dist/src/data-manipulator.js.map +1 -1
  45. package/dist/src/data-report/data-report-field.js +2 -1
  46. package/dist/src/data-report/data-report-field.js.map +1 -1
  47. package/dist/src/data-report/data-report-header.js +2 -2
  48. package/dist/src/data-report/data-report-header.js.map +1 -1
  49. package/dist/src/editors/ox-grist-editor-select.js +37 -25
  50. package/dist/src/editors/ox-grist-editor-select.js.map +1 -1
  51. package/dist/src/editors/ox-input-tree.js +8 -8
  52. package/dist/src/editors/ox-input-tree.js.map +1 -1
  53. package/dist/src/filters/filter-input-barcode.js +1 -0
  54. package/dist/src/filters/filter-input-barcode.js.map +1 -1
  55. package/dist/src/filters/filter-select.js +30 -16
  56. package/dist/src/filters/filter-select.js.map +1 -1
  57. package/dist/src/filters/filter-styles.js +46 -31
  58. package/dist/src/filters/filter-styles.js.map +1 -1
  59. package/dist/src/filters/filters-form.d.ts +15 -4
  60. package/dist/src/filters/filters-form.js +205 -70
  61. package/dist/src/filters/filters-form.js.map +1 -1
  62. package/dist/src/gutters/gutter-dirty.js +2 -2
  63. package/dist/src/gutters/gutter-dirty.js.map +1 -1
  64. package/dist/src/index.d.ts +1 -0
  65. package/dist/src/index.js +1 -0
  66. package/dist/src/index.js.map +1 -1
  67. package/dist/src/personalizer/index.d.ts +1 -0
  68. package/dist/src/personalizer/index.js +2 -0
  69. package/dist/src/personalizer/index.js.map +1 -0
  70. package/dist/src/personalizer/ox-grist-filter-personalizer.d.ts +8 -0
  71. package/dist/src/personalizer/ox-grist-filter-personalizer.js +177 -0
  72. package/dist/src/personalizer/ox-grist-filter-personalizer.js.map +1 -0
  73. package/dist/src/personalizer/ox-grist-personalizer.d.ts +8 -0
  74. package/dist/src/personalizer/ox-grist-personalizer.js +178 -0
  75. package/dist/src/personalizer/ox-grist-personalizer.js.map +1 -0
  76. package/dist/src/record-view/record-creator.js +2 -2
  77. package/dist/src/record-view/record-creator.js.map +1 -1
  78. package/dist/src/renderers/ox-grist-renderer-select.js +34 -4
  79. package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
  80. package/dist/src/renderers/ox-grist-renderer-tree.js +8 -8
  81. package/dist/src/renderers/ox-grist-renderer-tree.js.map +1 -1
  82. package/dist/src/sorters/sorters-control.js +3 -3
  83. package/dist/src/sorters/sorters-control.js.map +1 -1
  84. package/dist/src/types.d.ts +41 -2
  85. package/dist/src/types.js.map +1 -1
  86. package/dist/stories/{accumulator.stories.d.ts → accumulator-format.stories.d.ts} +9 -0
  87. package/dist/stories/{accumulator.stories.js → accumulator-format.stories.js} +24 -12
  88. package/dist/stories/accumulator-format.stories.js.map +1 -0
  89. package/dist/stories/barcode-input-filter.stories.d.ts +5 -0
  90. package/dist/stories/barcode-input-filter.stories.js +29 -5
  91. package/dist/stories/barcode-input-filter.stories.js.map +1 -1
  92. package/dist/stories/bounded-select-filters.stories.d.ts +30 -0
  93. package/dist/stories/bounded-select-filters.stories.js +288 -0
  94. package/dist/stories/bounded-select-filters.stories.js.map +1 -0
  95. package/dist/stories/bounded-select-record.stories.d.ts +30 -0
  96. package/dist/stories/bounded-select-record.stories.js +291 -0
  97. package/dist/stories/bounded-select-record.stories.js.map +1 -0
  98. package/dist/stories/click-event.stories.d.ts +41 -0
  99. package/dist/stories/click-event.stories.js +234 -0
  100. package/dist/stories/click-event.stories.js.map +1 -0
  101. package/dist/stories/creatable-only-column.stories.d.ts +5 -0
  102. package/dist/stories/creatable-only-column.stories.js +46 -21
  103. package/dist/stories/creatable-only-column.stories.js.map +1 -1
  104. package/dist/stories/default-filters.stories.d.ts +5 -0
  105. package/dist/stories/default-filters.stories.js +84 -17
  106. package/dist/stories/default-filters.stories.js.map +1 -1
  107. package/dist/stories/dynamic-editable.stories.d.ts +5 -0
  108. package/dist/stories/dynamic-editable.stories.js +44 -21
  109. package/dist/stories/dynamic-editable.stories.js.map +1 -1
  110. package/dist/stories/empty-sorters.stories.d.ts +7 -1
  111. package/dist/stories/empty-sorters.stories.js +41 -17
  112. package/dist/stories/empty-sorters.stories.js.map +1 -1
  113. package/dist/stories/explicit-fetch.stories.d.ts +5 -0
  114. package/dist/stories/explicit-fetch.stories.js +40 -17
  115. package/dist/stories/explicit-fetch.stories.js.map +1 -1
  116. package/dist/stories/fixed-column.stories.d.ts +5 -0
  117. package/dist/stories/fixed-column.stories.js +53 -30
  118. package/dist/stories/fixed-column.stories.js.map +1 -1
  119. package/dist/stories/grid-setting.stories.d.ts +20 -4
  120. package/dist/stories/grid-setting.stories.js +96 -51
  121. package/dist/stories/grid-setting.stories.js.map +1 -1
  122. package/dist/stories/grist-modes.stories.d.ts +8 -2
  123. package/dist/stories/grist-modes.stories.js +58 -35
  124. package/dist/stories/grist-modes.stories.js.map +1 -1
  125. package/dist/stories/group-header.stories.d.ts +5 -0
  126. package/dist/stories/group-header.stories.js +53 -30
  127. package/dist/stories/group-header.stories.js.map +1 -1
  128. package/dist/stories/textarea.stories.d.ts +8 -2
  129. package/dist/stories/textarea.stories.js +37 -13
  130. package/dist/stories/textarea.stories.js.map +1 -1
  131. package/dist/stories/tree-column-with-checkbox.stories.d.ts +5 -0
  132. package/dist/stories/tree-column-with-checkbox.stories.js +44 -21
  133. package/dist/stories/tree-column-with-checkbox.stories.js.map +1 -1
  134. package/dist/stories/tree-column.stories.d.ts +5 -0
  135. package/dist/stories/tree-column.stories.js +44 -21
  136. package/dist/stories/tree-column.stories.js.map +1 -1
  137. package/dist/tsconfig.tsbuildinfo +1 -1
  138. package/docs/default-value/value-generator/date-generator.md +29 -0
  139. package/docs/default-value/value-generator/hour-time-generator.md +33 -0
  140. package/docs/default-value/value-generator/minute-time-generator.md +33 -0
  141. package/docs/default-value/value-generator/month-date-generator.md +2 -0
  142. package/docs/default-value/value-generator/now-generator.md +29 -0
  143. package/docs/default-value/value-generator/time-generator.md +31 -0
  144. package/docs/default-value/value-generator/today-generator.md +29 -0
  145. package/docs/default-value/value-generator/week-date-generator.md +31 -0
  146. package/docs/default-value/value-generator/year-date-generator.md +31 -0
  147. package/package.json +15 -10
  148. package/src/data-card/data-card-field.ts +2 -2
  149. package/src/data-card/data-card-gutter-menu.ts +5 -5
  150. package/src/data-card/data-card-gutter.ts +6 -6
  151. package/src/data-card/data-card.ts +7 -9
  152. package/src/data-card/record-card.ts +9 -10
  153. package/src/data-grid/data-grid-accum-field.ts +11 -5
  154. package/src/data-grid/data-grid-body-style.ts +12 -0
  155. package/src/data-grid/data-grid-body.ts +16 -29
  156. package/src/data-grid/data-grid-field.ts +7 -2
  157. package/src/data-grid/data-grid-footer.ts +4 -2
  158. package/src/data-grid/data-grid-header.ts +8 -6
  159. package/src/data-grid/data-grid.ts +23 -1
  160. package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +4 -0
  161. package/src/data-grist.ts +88 -8
  162. package/src/data-list/data-list-field.ts +5 -5
  163. package/src/data-list/data-list-gutter.ts +3 -3
  164. package/src/data-list/data-list.ts +4 -4
  165. package/src/data-list/record-partial.ts +9 -10
  166. package/src/data-manipulator.ts +5 -5
  167. package/src/data-report/data-report-field.ts +2 -1
  168. package/src/data-report/data-report-header.ts +2 -2
  169. package/src/editors/ox-grist-editor-select.ts +41 -28
  170. package/src/editors/ox-input-tree.ts +8 -8
  171. package/src/filters/filter-input-barcode.ts +1 -0
  172. package/src/filters/filter-select.ts +41 -28
  173. package/src/filters/filter-styles.ts +46 -31
  174. package/src/filters/filters-form.ts +273 -119
  175. package/src/gutters/gutter-dirty.ts +2 -2
  176. package/src/index.ts +1 -0
  177. package/src/personalizer/index.ts +1 -0
  178. package/src/personalizer/ox-grist-filter-personalizer.ts +191 -0
  179. package/src/personalizer/ox-grist-personalizer.ts +192 -0
  180. package/src/record-view/record-creator.ts +2 -2
  181. package/src/renderers/ox-grist-renderer-select.ts +41 -6
  182. package/src/renderers/ox-grist-renderer-tree.ts +8 -8
  183. package/src/sorters/sorters-control.ts +3 -3
  184. package/src/types.ts +53 -2
  185. package/stories/{accumulator.stories.ts → accumulator-format.stories.ts} +33 -12
  186. package/stories/barcode-input-filter.stories.ts +31 -6
  187. package/stories/bounded-select-filters.stories.ts +339 -0
  188. package/stories/bounded-select-record.stories.ts +342 -0
  189. package/stories/click-event.stories.ts +269 -0
  190. package/stories/creatable-only-column.stories.ts +54 -28
  191. package/stories/default-filters.stories.ts +92 -24
  192. package/stories/dynamic-editable.stories.ts +52 -28
  193. package/stories/empty-sorters.stories.ts +51 -25
  194. package/stories/explicit-fetch.stories.ts +48 -24
  195. package/stories/fixed-column.stories.ts +62 -39
  196. package/stories/grid-setting.stories.ts +120 -63
  197. package/stories/grist-modes.stories.ts +74 -46
  198. package/stories/group-header.stories.ts +61 -39
  199. package/stories/textarea.stories.ts +49 -17
  200. package/stories/tree-column-with-checkbox.stories.ts +52 -28
  201. package/stories/tree-column.stories.ts +52 -28
  202. package/themes/dark-hc.css +151 -0
  203. package/themes/dark-mc.css +151 -0
  204. package/themes/dark.css +151 -0
  205. package/themes/grist-theme.css +103 -100
  206. package/themes/light-hc.css +151 -0
  207. package/themes/light-mc.css +151 -0
  208. package/themes/light.css +151 -0
  209. package/themes/md-typescale-styles.css +100 -0
  210. package/themes/spacing.css +43 -0
  211. package/themes/state-color.css +6 -0
  212. package/dist/stories/accumulator.stories.js.map +0 -1
  213. package/themes/app-theme.css +0 -145
  214. package/themes/form-theme.css +0 -75
  215. package/themes/oops-theme.css +0 -26
  216. package/themes/report-theme.css +0 -47
@@ -6,6 +6,7 @@ import '@operato/popup/ox-popup-list.js'
6
6
  import '@material/web/icon/icon.js'
7
7
 
8
8
  import { html, TemplateResult } from 'lit'
9
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
9
10
 
10
11
  import {
11
12
  ColumnConfig,
@@ -17,6 +18,7 @@ import {
17
18
  } from '../src/types.js'
18
19
 
19
20
  import { CommonHeaderStyles, CommonGristStyles } from '@operato/styles'
21
+ import { OxPrompt } from '@operato/popup'
20
22
 
21
23
  const fetchHandler: FetchHandler = async ({ page, limit }) => {
22
24
  var total = 120993
@@ -176,20 +178,18 @@ const config = {
176
178
  filter: 'search',
177
179
  sortable: true,
178
180
  width: 130,
179
- validation: function (after, before, record, column) {
181
+ validation: (async (after, before, record, column) => {
180
182
  if (after.indexOf('@') == -1) {
181
- document.dispatchEvent(
182
- new CustomEvent('notify', {
183
- detail: {
184
- type: 'error',
185
- message: `invalid value - ${after}`
186
- }
187
- })
188
- )
189
- return false
183
+ return await OxPrompt.open({
184
+ title: '잘못된 이메일 포맷',
185
+ text: '그래도 변경하시겠습니까?',
186
+ cancelButton: { text: 'No' },
187
+ confirmButton: { text: 'Yes' }
188
+ })
190
189
  }
190
+
191
191
  return true
192
- } as ValidationCallback
192
+ }) as ValidationCallback
193
193
  },
194
194
  {
195
195
  type: 'boolean',
@@ -318,7 +318,8 @@ export default {
318
318
  title: 'fixed column',
319
319
  component: 'ox-grist',
320
320
  argTypes: {
321
- config: { control: 'object' }
321
+ config: { control: 'object' },
322
+ theme: { control: 'select', options: ['light', 'dark'] }
322
323
  }
323
324
  }
324
325
 
@@ -330,10 +331,18 @@ interface Story<T> {
330
331
 
331
332
  interface ArgTypes {
332
333
  config: object
334
+ theme: 'light' | 'dark'
333
335
  }
334
336
 
335
- const Template: Story<ArgTypes> = ({ config }: ArgTypes) =>
336
- html` <link
337
+ const Template: Story<ArgTypes> = ({ config, theme = 'light' }: ArgTypes) =>
338
+ html` <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
339
+
340
+ <link href="/themes/light.css" rel="stylesheet" />
341
+ <link href="/themes/dark.css" rel="stylesheet" />
342
+ <link href="/themes/spacing.css" rel="stylesheet" />
343
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
344
+
345
+ <link
337
346
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
338
347
  rel="stylesheet"
339
348
  />
@@ -346,46 +355,60 @@ const Template: Story<ArgTypes> = ({ config }: ArgTypes) =>
346
355
  rel="stylesheet"
347
356
  />
348
357
 
349
- <link href="/themes/app-theme.css" rel="stylesheet" />
350
- <link href="/themes/oops-theme.css" rel="stylesheet" />
351
- <link href="/themes/grist-theme.css" rel="stylesheet" />
358
+ <style>
359
+ ${MDTypeScaleStyles.cssText}
360
+ </style>
352
361
 
353
362
  <style>
354
363
  ${CommonGristStyles.cssText}
355
364
  ${CommonHeaderStyles.cssText}
356
365
  </style>
357
366
 
367
+ <script>
368
+ document.body.classList.add('${theme}')
369
+ </script>
370
+
371
+ <style>
372
+ ox-grist {
373
+ height: 600px;
374
+ }
375
+
376
+ ox-filters-form {
377
+ flex: 1;
378
+ }
379
+ </style>
380
+
358
381
  <ox-grist
359
382
  mode="GRID"
360
383
  .config=${config}
361
384
  .fetchHandler=${fetchHandler}
362
385
  @filters-change=${(e: Event) => console.log('filters', (e.target as any).filters)}
363
386
  >
364
- <div slot="headroom">
365
- <div id="filters">
387
+ <div slot="headroom" class="header">
388
+ <div class="filters">
366
389
  <ox-filters-form autofocus></ox-filters-form>
367
- </div>
368
390
 
369
- <div id="sorters">
370
- Sort
371
- <md-icon
372
- @click=${(e: Event) => {
373
- const target = e.currentTarget as HTMLElement
374
- ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
375
- right: 0,
376
- top: target.offsetTop + target.offsetHeight
377
- })
378
- }}
379
- >expand_more</md-icon
380
- >
381
- <ox-popup id="sorter-control">
382
- <ox-sorters-control> </ox-sorters-control>
383
- </ox-popup>
384
- </div>
391
+ <div id="sorters">
392
+ Sort
393
+ <md-icon
394
+ @click=${(e: Event) => {
395
+ const target = e.currentTarget as HTMLElement
396
+ ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
397
+ right: 0,
398
+ top: target.offsetTop + target.offsetHeight
399
+ })
400
+ }}
401
+ >expand_more</md-icon
402
+ >
403
+ <ox-popup id="sorter-control">
404
+ <ox-sorters-control> </ox-sorters-control>
405
+ </ox-popup>
406
+ </div>
385
407
 
386
- <ox-record-creator id="add" light-popup>
387
- <button><md-icon>add</md-icon></button>
388
- </ox-record-creator>
408
+ <ox-record-creator id="add" light-popup>
409
+ <button><md-icon>add</md-icon></button>
410
+ </ox-record-creator>
411
+ </div>
389
412
  </div>
390
413
  </ox-grist>`
391
414
 
@@ -1,11 +1,17 @@
1
+ import '@material/web/icon/icon.js'
2
+ import '@operato/popup/ox-popup-list.js'
3
+
4
+ import { sleep } from '@operato/utils'
5
+
1
6
  import '../src/index.js'
2
7
  import '../src/filters/filters-form.js'
3
8
  import '../src/sorters/sorters-control.js'
4
9
  import '../src/record-view/record-creator.js'
5
- import '@operato/popup/ox-popup-list.js'
6
- import '@material/web/icon/icon.js'
10
+ import '../src/personalizer/ox-grist-personalizer.js'
11
+ import '../src/personalizer/ox-grist-filter-personalizer.js'
7
12
 
8
13
  import { html, TemplateResult } from 'lit'
14
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
9
15
 
10
16
  import { CommonHeaderStyles, CommonGristStyles } from '@operato/styles'
11
17
 
@@ -15,9 +21,10 @@ import {
15
21
  GristClassifier,
16
22
  GristEventHandlerSet,
17
23
  GristRecord,
24
+ PersonalGristPreference,
18
25
  ValidationCallback
19
26
  } from '../src/types.js'
20
- import { DataGrist } from '../src/index.js'
27
+ import { OxPrompt } from '@operato/popup'
21
28
 
22
29
  const fetchHandler: FetchHandler = async ({ page, limit }) => {
23
30
  var total = 120993
@@ -176,20 +183,17 @@ const config = {
176
183
  filter: 'search',
177
184
  sortable: true,
178
185
  width: 130,
179
- validation: function (after, before, record, column) {
186
+ validation: (async (after, before, record, column) => {
180
187
  if (after.indexOf('@') == -1) {
181
- document.dispatchEvent(
182
- new CustomEvent('notify', {
183
- detail: {
184
- type: 'error',
185
- message: `invalid value - ${after}`
186
- }
187
- })
188
- )
189
- return false
188
+ return await OxPrompt.open({
189
+ title: '잘못된 이메일 포맷',
190
+ text: '그래도 변경하시겠습니까?',
191
+ cancelButton: { text: 'No' },
192
+ confirmButton: { text: 'Yes' }
193
+ })
190
194
  }
191
195
  return true
192
- } as ValidationCallback
196
+ }) as ValidationCallback
193
197
  },
194
198
  {
195
199
  type: 'boolean',
@@ -341,7 +345,10 @@ export default {
341
345
  argTypes: {
342
346
  config: { control: 'object' },
343
347
  mode: { control: 'select', options: ['GRID', 'LIST', 'CARD'] },
344
- urlParamsSensitive: { control: 'boolean' }
348
+ urlParamsSensitive: { control: 'boolean' },
349
+ theme: { control: 'select', options: ['light', 'dark'] },
350
+ withoutSearch: { control: 'boolean' },
351
+ debug: { control: 'boolean' }
345
352
  }
346
353
  }
347
354
 
@@ -353,13 +360,42 @@ interface Story<T> {
353
360
 
354
361
  interface ArgTypes {
355
362
  config: object
356
- mode: string
363
+ mode: 'GRID' | 'LIST' | 'CARD'
357
364
  urlParamsSensitive: boolean
358
- fetchHandler: object
365
+ withoutSearch: boolean
366
+ fetchHandler: FetchHandler
367
+ theme: 'light' | 'dark'
368
+ debug: boolean
369
+ }
370
+
371
+ var personalConfig: PersonalGristPreference = {
372
+ columns: [
373
+ { name: 'name', hidden: false, width: 200 },
374
+ { name: 'description', hidden: true }
375
+ ],
376
+ pagination: {
377
+ pages: [20, 30, 50, 100, 200],
378
+ limit: 30
379
+ }
359
380
  }
360
381
 
361
- const Template: Story<ArgTypes> = ({ config, mode = 'GRID', urlParamsSensitive = false, fetchHandler }: ArgTypes) =>
362
- html` <link
382
+ const Template: Story<ArgTypes> = ({
383
+ config,
384
+ mode = 'GRID',
385
+ urlParamsSensitive = false,
386
+ withoutSearch = false,
387
+ debug = false,
388
+ fetchHandler,
389
+ theme = 'light'
390
+ }: ArgTypes) =>
391
+ html` <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
392
+
393
+ <link href="/themes/light.css" rel="stylesheet" />
394
+ <link href="/themes/dark.css" rel="stylesheet" />
395
+ <link href="/themes/spacing.css" rel="stylesheet" />
396
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
397
+
398
+ <link
363
399
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
364
400
  rel="stylesheet"
365
401
  />
@@ -372,65 +408,86 @@ const Template: Story<ArgTypes> = ({ config, mode = 'GRID', urlParamsSensitive =
372
408
  rel="stylesheet"
373
409
  />
374
410
 
375
- <link href="/themes/app-theme.css" rel="stylesheet" />
376
- <link href="/themes/oops-theme.css" rel="stylesheet" />
377
- <link href="/themes/grist-theme.css" rel="stylesheet" />
411
+ <style>
412
+ ${MDTypeScaleStyles.cssText}
413
+ </style>
378
414
 
379
415
  <style>
380
- ${CommonGristStyles.cssText}
381
- ${CommonHeaderStyles.cssText}
416
+ ${CommonGristStyles.cssText} ${CommonHeaderStyles.cssText}
417
+ </style>
418
+
419
+ <style>
420
+ ox-grist {
421
+ height: 600px;
422
+ }
423
+
424
+ ox-filters-form {
425
+ flex: 1;
426
+ }
382
427
  </style>
383
428
 
384
429
  <ox-grist
385
- .config=${config}
386
430
  .mode=${mode}
431
+ .config=${config}
387
432
  .fetchHandler=${fetchHandler}
433
+ .personalConfigProvider=${{
434
+ async load() {
435
+ await sleep(1000)
436
+ return personalConfig
437
+ },
438
+ async save(preference: PersonalGristPreference) {
439
+ await sleep(1000)
440
+ personalConfig = {
441
+ ...personalConfig,
442
+ ...preference
443
+ }
444
+ console.log('saving preference', personalConfig)
445
+ return preference
446
+ },
447
+ async reset() {
448
+ personalConfig = {}
449
+ await sleep(1000)
450
+ }
451
+ }}
388
452
  ?url-params-sensitive=${urlParamsSensitive}
389
453
  @filters-change=${(e: Event) => console.log('filters', (e.target as any).filters)}
390
454
  >
391
- <div slot="headroom">
392
- <div id="filters">
393
- <ox-filters-form autofocus></ox-filters-form>
394
- </div>
455
+ <div slot="headroom" class="header">
456
+ <div class="filters">
457
+ <ox-filters-form autofocus ?without-search=${withoutSearch}>
458
+ <ox-grist-filter-personalizer slot="setting"></ox-grist-filter-personalizer>
459
+ </ox-filters-form>
395
460
 
396
- <div id="sorters">
397
- Sort
398
- <md-icon
399
- @click=${(e: Event) => {
400
- const target = e.currentTarget as HTMLElement
401
- ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
402
- right: 0,
403
- top: target.offsetTop + target.offsetHeight
404
- })
405
- }}
406
- >expand_more</md-icon
407
- >
408
- <ox-popup id="sorter-control">
409
- <ox-sorters-control> </ox-sorters-control>
410
- </ox-popup>
411
- </div>
461
+ <div id="sorters">
462
+ Sort
463
+ <md-icon
464
+ @click=${(e: Event) => {
465
+ const target = e.currentTarget as HTMLElement
466
+ ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
467
+ right: 0,
468
+ top: target.offsetTop + target.offsetHeight
469
+ })
470
+ }}
471
+ >expand_more</md-icon
472
+ >
473
+ <ox-popup id="sorter-control">
474
+ <ox-sorters-control> </ox-sorters-control>
475
+ </ox-popup>
476
+ </div>
412
477
 
413
- <div id="modes">
414
- <md-icon @click=${() => (mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
415
- <md-icon @click=${() => (mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
416
- <md-icon @click=${() => (mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
417
- </div>
478
+ <div id="modes">
479
+ <md-icon @click=${() => (mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
480
+ <md-icon @click=${() => (mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
481
+ <md-icon @click=${() => (mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
482
+ </div>
418
483
 
419
- <ox-record-creator id="add" light-popup>
420
- <button><md-icon>add</md-icon></button>
421
- </ox-record-creator>
484
+ <ox-record-creator id="add" light-popup>
485
+ <button><md-icon>add</md-icon></button>
486
+ </ox-record-creator>
487
+ </div>
422
488
  </div>
423
489
 
424
- <md-icon
425
- title="personal setting"
426
- slot="setting"
427
- @click=${(e: MouseEvent) => {
428
- const grist = (e.target as HTMLElement).closest('ox-grist') as DataGrist
429
- alert('setting clicked. will fetch again.')
430
- grist?.fetch()
431
- }}
432
- >tune</md-icon
433
- >
490
+ <ox-grist-personalizer slot="setting" ?debug=${debug}></ox-grist-personalizer>
434
491
  </ox-grist>`
435
492
 
436
493
  export const Regular = Template.bind({})
@@ -6,6 +6,7 @@ import '@operato/popup/ox-popup-list.js'
6
6
  import '@material/web/icon/icon.js'
7
7
 
8
8
  import { html, TemplateResult } from 'lit'
9
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
9
10
 
10
11
  import { CommonHeaderStyles, CommonGristStyles } from '@operato/styles'
11
12
 
@@ -17,6 +18,7 @@ import {
17
18
  GristRecord,
18
19
  ValidationCallback
19
20
  } from '../src/types.js'
21
+ import { OxPrompt } from '@operato/popup'
20
22
 
21
23
  const fetchHandler: FetchHandler = async ({ page, limit }) => {
22
24
  var total = 120993
@@ -175,20 +177,17 @@ const config = {
175
177
  filter: 'search',
176
178
  sortable: true,
177
179
  width: 130,
178
- validation: function (after, before, record, column) {
180
+ validation: (async (after, before, record, column) => {
179
181
  if (after.indexOf('@') == -1) {
180
- document.dispatchEvent(
181
- new CustomEvent('notify', {
182
- detail: {
183
- type: 'error',
184
- message: `invalid value - ${after}`
185
- }
186
- })
187
- )
188
- return false
182
+ return await OxPrompt.open({
183
+ title: '잘못된 이메일 포맷',
184
+ text: '그래도 변경하시겠습니까?',
185
+ cancelButton: { text: 'No' },
186
+ confirmButton: { text: 'Yes' }
187
+ })
189
188
  }
190
189
  return true
191
- } as ValidationCallback
190
+ }) as ValidationCallback
192
191
  },
193
192
  {
194
193
  type: 'boolean',
@@ -340,7 +339,8 @@ export default {
340
339
  argTypes: {
341
340
  config: { control: 'object' },
342
341
  mode: { control: 'select', options: ['GRID', 'LIST', 'CARD'] },
343
- urlParamsSensitive: { control: 'boolean' }
342
+ urlParamsSensitive: { control: 'boolean' },
343
+ theme: { control: 'select', options: ['light', 'dark'] }
344
344
  }
345
345
  }
346
346
 
@@ -352,13 +352,27 @@ interface Story<T> {
352
352
 
353
353
  interface ArgTypes {
354
354
  config: object
355
- mode: string
355
+ mode: 'GRID' | 'LIST' | 'CARD'
356
356
  urlParamsSensitive: boolean
357
- fetchHandler: object
357
+ theme: 'light' | 'dark'
358
+ fetchHandler: FetchHandler
358
359
  }
359
360
 
360
- const Template: Story<ArgTypes> = ({ config, mode = 'GRID', urlParamsSensitive = false, fetchHandler }: ArgTypes) =>
361
- html` <link
361
+ const Template: Story<ArgTypes> = ({
362
+ config,
363
+ mode = 'GRID',
364
+ urlParamsSensitive = false,
365
+ fetchHandler,
366
+ theme = 'light'
367
+ }: ArgTypes) =>
368
+ html` <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
369
+
370
+ <link href="/themes/light.css" rel="stylesheet" />
371
+ <link href="/themes/dark.css" rel="stylesheet" />
372
+ <link href="/themes/spacing.css" rel="stylesheet" />
373
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
374
+
375
+ <link
362
376
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
363
377
  rel="stylesheet"
364
378
  />
@@ -371,15 +385,29 @@ const Template: Story<ArgTypes> = ({ config, mode = 'GRID', urlParamsSensitive =
371
385
  rel="stylesheet"
372
386
  />
373
387
 
374
- <link href="/themes/app-theme.css" rel="stylesheet" />
375
- <link href="/themes/oops-theme.css" rel="stylesheet" />
376
- <link href="/themes/grist-theme.css" rel="stylesheet" />
388
+ <style>
389
+ ${MDTypeScaleStyles.cssText}
390
+ </style>
377
391
 
378
392
  <style>
379
393
  ${CommonGristStyles.cssText}
380
394
  ${CommonHeaderStyles.cssText}
381
395
  </style>
382
396
 
397
+ <script>
398
+ document.body.classList.add('${theme}')
399
+ </script>
400
+
401
+ <style>
402
+ ox-grist {
403
+ height: 600px;
404
+ }
405
+
406
+ ox-filters-form {
407
+ flex: 1;
408
+ }
409
+ </style>
410
+
383
411
  <ox-grist
384
412
  .config=${config}
385
413
  .mode=${mode}
@@ -387,37 +415,37 @@ const Template: Story<ArgTypes> = ({ config, mode = 'GRID', urlParamsSensitive =
387
415
  ?url-params-sensitive=${urlParamsSensitive}
388
416
  @filters-change=${(e: Event) => console.log('filters', (e.target as any).filters)}
389
417
  >
390
- <div slot="headroom">
391
- <div id="filters">
418
+ <div slot="headroom" class="header">
419
+ <div class="filters">
392
420
  <ox-filters-form autofocus></ox-filters-form>
393
- </div>
394
421
 
395
- <div id="sorters">
396
- Sort
397
- <md-icon
398
- @click=${(e: Event) => {
399
- const target = e.currentTarget as HTMLElement
400
- ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
401
- right: 0,
402
- top: target.offsetTop + target.offsetHeight
403
- })
404
- }}
405
- >expand_more</md-icon
406
- >
407
- <ox-popup id="sorter-control">
408
- <ox-sorters-control> </ox-sorters-control>
409
- </ox-popup>
410
- </div>
422
+ <div id="sorters">
423
+ Sort
424
+ <md-icon
425
+ @click=${(e: Event) => {
426
+ const target = e.currentTarget as HTMLElement
427
+ ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
428
+ right: 0,
429
+ top: target.offsetTop + target.offsetHeight
430
+ })
431
+ }}
432
+ >expand_more</md-icon
433
+ >
434
+ <ox-popup id="sorter-control">
435
+ <ox-sorters-control> </ox-sorters-control>
436
+ </ox-popup>
437
+ </div>
411
438
 
412
- <div id="modes">
413
- <md-icon @click=${() => (mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
414
- <md-icon @click=${() => (mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
415
- <md-icon @click=${() => (mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
416
- </div>
439
+ <div id="modes">
440
+ <md-icon @click=${() => (mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
441
+ <md-icon @click=${() => (mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
442
+ <md-icon @click=${() => (mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
443
+ </div>
417
444
 
418
- <ox-record-creator id="add" light-popup>
419
- <button><md-icon>add</md-icon></button>
420
- </ox-record-creator>
445
+ <ox-record-creator id="add" light-popup>
446
+ <button><md-icon>add</md-icon></button>
447
+ </ox-record-creator>
448
+ </div>
421
449
  </div>
422
450
  </ox-grist>`
423
451