@operato/data-grist 2.0.0-alpha.13 → 2.0.0-alpha.132

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 (310) hide show
  1. package/CHANGELOG.md +573 -0
  2. package/demo/data-grist-test.html +25 -14
  3. package/demo/index.html +25 -14
  4. package/demo/report-test.html +13 -2
  5. package/dist/src/configure/column-builder.js.map +1 -1
  6. package/dist/src/configure/rows-option-builder.js +2 -1
  7. package/dist/src/configure/rows-option-builder.js.map +1 -1
  8. package/dist/src/configure/zero-config.js +1 -0
  9. package/dist/src/configure/zero-config.js.map +1 -1
  10. package/dist/src/data-card/data-card-gutter-menu.d.ts +1 -1
  11. package/dist/src/data-card/data-card-gutter-menu.js +5 -5
  12. package/dist/src/data-card/data-card-gutter-menu.js.map +1 -1
  13. package/dist/src/data-card/data-card.d.ts +2 -2
  14. package/dist/src/data-card/data-card.js +3 -3
  15. package/dist/src/data-card/data-card.js.map +1 -1
  16. package/dist/src/data-card/event-handlers/record-card-click-handler.js +1 -1
  17. package/dist/src/data-card/event-handlers/record-card-click-handler.js.map +1 -1
  18. package/dist/src/data-card/record-card.d.ts +2 -2
  19. package/dist/src/data-card/record-card.js +26 -26
  20. package/dist/src/data-card/record-card.js.map +1 -1
  21. package/dist/src/data-grid/data-grid-accum-field.js +9 -2
  22. package/dist/src/data-grid/data-grid-accum-field.js.map +1 -1
  23. package/dist/src/data-grid/data-grid-body-style.js +1 -0
  24. package/dist/src/data-grid/data-grid-body-style.js.map +1 -1
  25. package/dist/src/data-grid/data-grid-body.d.ts +3 -3
  26. package/dist/src/data-grid/data-grid-body.js +6 -4
  27. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  28. package/dist/src/data-grid/data-grid-field.d.ts +1 -1
  29. package/dist/src/data-grid/data-grid-field.js +6 -3
  30. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  31. package/dist/src/data-grid/data-grid-footer.d.ts +2 -2
  32. package/dist/src/data-grid/data-grid-footer.js +17 -9
  33. package/dist/src/data-grid/data-grid-footer.js.map +1 -1
  34. package/dist/src/data-grid/data-grid-header.d.ts +1 -1
  35. package/dist/src/data-grid/data-grid-header.js +38 -35
  36. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  37. package/dist/src/data-grid/data-grid.d.ts +1 -1
  38. package/dist/src/data-grid/data-grid.js +12 -2
  39. package/dist/src/data-grid/data-grid.js.map +1 -1
  40. package/dist/src/data-grist.d.ts +12 -3
  41. package/dist/src/data-grist.js +74 -31
  42. package/dist/src/data-grist.js.map +1 -1
  43. package/dist/src/data-list/data-list-gutter.js +12 -0
  44. package/dist/src/data-list/data-list-gutter.js.map +1 -1
  45. package/dist/src/data-list/data-list.d.ts +2 -2
  46. package/dist/src/data-list/data-list.js +3 -3
  47. package/dist/src/data-list/data-list.js.map +1 -1
  48. package/dist/src/data-list/event-handlers/record-partial-click-handler.js +1 -1
  49. package/dist/src/data-list/event-handlers/record-partial-click-handler.js.map +1 -1
  50. package/dist/src/data-list/record-partial.d.ts +2 -2
  51. package/dist/src/data-list/record-partial.js +20 -18
  52. package/dist/src/data-list/record-partial.js.map +1 -1
  53. package/dist/src/data-report/data-report-body.d.ts +1 -1
  54. package/dist/src/data-report/data-report-component.d.ts +1 -1
  55. package/dist/src/data-report.d.ts +1 -1
  56. package/dist/src/editors/ox-grist-editor-checkbox.d.ts +3 -2
  57. package/dist/src/editors/ox-grist-editor-checkbox.js +9 -2
  58. package/dist/src/editors/ox-grist-editor-checkbox.js.map +1 -1
  59. package/dist/src/editors/ox-grist-editor-color.d.ts +1 -1
  60. package/dist/src/editors/ox-grist-editor-date.d.ts +1 -1
  61. package/dist/src/editors/ox-grist-editor-datetime.d.ts +2 -2
  62. package/dist/src/editors/ox-grist-editor-datetime.js +1 -2
  63. package/dist/src/editors/ox-grist-editor-datetime.js.map +1 -1
  64. package/dist/src/editors/ox-grist-editor-email.d.ts +1 -1
  65. package/dist/src/editors/ox-grist-editor-file.d.ts +3 -2
  66. package/dist/src/editors/ox-grist-editor-file.js +8 -2
  67. package/dist/src/editors/ox-grist-editor-file.js.map +1 -1
  68. package/dist/src/editors/ox-grist-editor-image.d.ts +2 -2
  69. package/dist/src/editors/ox-grist-editor-image.js +8 -8
  70. package/dist/src/editors/ox-grist-editor-image.js.map +1 -1
  71. package/dist/src/editors/ox-grist-editor-month.d.ts +1 -1
  72. package/dist/src/editors/ox-grist-editor-multiple-select.d.ts +1 -1
  73. package/dist/src/editors/ox-grist-editor-number.d.ts +3 -2
  74. package/dist/src/editors/ox-grist-editor-number.js +10 -9
  75. package/dist/src/editors/ox-grist-editor-number.js.map +1 -1
  76. package/dist/src/editors/ox-grist-editor-password.d.ts +1 -1
  77. package/dist/src/editors/ox-grist-editor-select.d.ts +1 -1
  78. package/dist/src/editors/ox-grist-editor-select.js +37 -25
  79. package/dist/src/editors/ox-grist-editor-select.js.map +1 -1
  80. package/dist/src/editors/ox-grist-editor-tel.d.ts +1 -1
  81. package/dist/src/editors/ox-grist-editor-text.d.ts +2 -1
  82. package/dist/src/editors/ox-grist-editor-text.js +3 -0
  83. package/dist/src/editors/ox-grist-editor-text.js.map +1 -1
  84. package/dist/src/editors/ox-grist-editor-textarea.d.ts +2 -1
  85. package/dist/src/editors/ox-grist-editor-textarea.js +3 -0
  86. package/dist/src/editors/ox-grist-editor-textarea.js.map +1 -1
  87. package/dist/src/editors/ox-grist-editor-time.d.ts +1 -1
  88. package/dist/src/editors/ox-grist-editor-tree.d.ts +1 -1
  89. package/dist/src/editors/ox-grist-editor-week.d.ts +1 -1
  90. package/dist/src/editors/ox-grist-editor.d.ts +4 -4
  91. package/dist/src/editors/ox-grist-editor.js +14 -16
  92. package/dist/src/editors/ox-grist-editor.js.map +1 -1
  93. package/dist/src/editors/ox-input-tree.d.ts +1 -1
  94. package/dist/src/empty-note.d.ts +2 -2
  95. package/dist/src/empty-note.js +3 -3
  96. package/dist/src/empty-note.js.map +1 -1
  97. package/dist/src/filters/filter-checkbox.js +12 -5
  98. package/dist/src/filters/filter-checkbox.js.map +1 -1
  99. package/dist/src/filters/filter-range-date.js +12 -1
  100. package/dist/src/filters/filter-range-date.js.map +1 -1
  101. package/dist/src/filters/filter-select.js +30 -16
  102. package/dist/src/filters/filter-select.js.map +1 -1
  103. package/dist/src/filters/filter-styles.js +46 -28
  104. package/dist/src/filters/filter-styles.js.map +1 -1
  105. package/dist/src/filters/filters-form.d.ts +7 -1
  106. package/dist/src/filters/filters-form.js +154 -71
  107. package/dist/src/filters/filters-form.js.map +1 -1
  108. package/dist/src/gutters/gutter-button.d.ts +1 -1
  109. package/dist/src/gutters/gutter-button.js +3 -3
  110. package/dist/src/gutters/gutter-button.js.map +1 -1
  111. package/dist/src/gutters/gutter-dirty.d.ts +1 -1
  112. package/dist/src/gutters/gutter-dirty.js +5 -5
  113. package/dist/src/gutters/gutter-dirty.js.map +1 -1
  114. package/dist/src/handlers/contextmenu-tree-mutation.js +4 -4
  115. package/dist/src/handlers/contextmenu-tree-mutation.js.map +1 -1
  116. package/dist/src/index.d.ts +1 -1
  117. package/dist/src/index.js +1 -1
  118. package/dist/src/index.js.map +1 -1
  119. package/dist/src/personalizer/index.d.ts +1 -0
  120. package/dist/src/personalizer/index.js +2 -0
  121. package/dist/src/personalizer/index.js.map +1 -0
  122. package/dist/src/personalizer/ox-grist-personalizer.d.ts +10 -0
  123. package/dist/src/personalizer/ox-grist-personalizer.js +171 -0
  124. package/dist/src/personalizer/ox-grist-personalizer.js.map +1 -0
  125. package/dist/src/record-view/record-creator.d.ts +2 -2
  126. package/dist/src/record-view/record-creator.js +1 -1
  127. package/dist/src/record-view/record-creator.js.map +1 -1
  128. package/dist/src/record-view/record-view-body.d.ts +3 -3
  129. package/dist/src/record-view/record-view-body.js +4 -4
  130. package/dist/src/record-view/record-view-body.js.map +1 -1
  131. package/dist/src/record-view/record-view.d.ts +2 -2
  132. package/dist/src/record-view/record-view.js +5 -5
  133. package/dist/src/record-view/record-view.js.map +1 -1
  134. package/dist/src/renderers/ox-grist-renderer-progress.d.ts +1 -1
  135. package/dist/src/renderers/ox-grist-renderer-select.js +34 -4
  136. package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
  137. package/dist/src/renderers/ox-grist-renderer-tree.d.ts +1 -1
  138. package/dist/src/renderers/ox-grist-renderer.d.ts +2 -2
  139. package/dist/src/sorters/sorters-control.js +3 -3
  140. package/dist/src/sorters/sorters-control.js.map +1 -1
  141. package/dist/src/types.d.ts +30 -9
  142. package/dist/src/types.js.map +1 -1
  143. package/dist/stories/{accumulator.stories.d.ts → accumulator-format.stories.d.ts} +1 -1
  144. package/dist/stories/{accumulator.stories.js → accumulator-format.stories.js} +50 -125
  145. package/dist/stories/accumulator-format.stories.js.map +1 -0
  146. package/dist/stories/barcode-input-filter.stories.d.ts +1 -1
  147. package/dist/stories/barcode-input-filter.stories.js +41 -79
  148. package/dist/stories/barcode-input-filter.stories.js.map +1 -1
  149. package/dist/stories/bounded-select-filters.stories.d.ts +25 -0
  150. package/dist/stories/bounded-select-filters.stories.js +264 -0
  151. package/dist/stories/bounded-select-filters.stories.js.map +1 -0
  152. package/dist/stories/bounded-select-record.stories.d.ts +25 -0
  153. package/dist/stories/bounded-select-record.stories.js +267 -0
  154. package/dist/stories/bounded-select-record.stories.js.map +1 -0
  155. package/dist/stories/creatable-only-column.stories.d.ts +25 -0
  156. package/dist/stories/creatable-only-column.stories.js +211 -0
  157. package/dist/stories/creatable-only-column.stories.js.map +1 -0
  158. package/dist/stories/default-filters.stories.d.ts +1 -1
  159. package/dist/stories/default-filters.stories.js +84 -79
  160. package/dist/stories/default-filters.stories.js.map +1 -1
  161. package/dist/stories/dynamic-editable.stories.d.ts +1 -1
  162. package/dist/stories/dynamic-editable.stories.js +51 -86
  163. package/dist/stories/dynamic-editable.stories.js.map +1 -1
  164. package/dist/stories/empty-sorters.stories.d.ts +1 -1
  165. package/dist/stories/empty-sorters.stories.js +41 -78
  166. package/dist/stories/empty-sorters.stories.js.map +1 -1
  167. package/dist/stories/explicit-fetch.stories.d.ts +1 -1
  168. package/dist/stories/explicit-fetch.stories.js +42 -79
  169. package/dist/stories/explicit-fetch.stories.js.map +1 -1
  170. package/dist/stories/fixed-column.stories.d.ts +1 -1
  171. package/dist/stories/fixed-column.stories.js +45 -127
  172. package/dist/stories/fixed-column.stories.js.map +1 -1
  173. package/dist/stories/grid-setting.stories.d.ts +42 -0
  174. package/dist/stories/grid-setting.stories.js +415 -0
  175. package/dist/stories/grid-setting.stories.js.map +1 -0
  176. package/dist/stories/grist-modes.stories.d.ts +1 -1
  177. package/dist/stories/grist-modes.stories.js +74 -140
  178. package/dist/stories/grist-modes.stories.js.map +1 -1
  179. package/dist/stories/group-header.stories.d.ts +1 -1
  180. package/dist/stories/group-header.stories.js +45 -127
  181. package/dist/stories/group-header.stories.js.map +1 -1
  182. package/dist/stories/textarea.stories.d.ts +1 -1
  183. package/dist/stories/textarea.stories.js +39 -121
  184. package/dist/stories/textarea.stories.js.map +1 -1
  185. package/dist/stories/tree-column-with-checkbox.stories.d.ts +1 -1
  186. package/dist/stories/tree-column-with-checkbox.stories.js +49 -136
  187. package/dist/stories/tree-column-with-checkbox.stories.js.map +1 -1
  188. package/dist/stories/tree-column.stories.d.ts +1 -1
  189. package/dist/stories/tree-column.stories.js +49 -136
  190. package/dist/stories/tree-column.stories.js.map +1 -1
  191. package/dist/tsconfig.tsbuildinfo +1 -1
  192. package/docs/default-value/default-value.md +1 -1
  193. package/docs/default-value/value-generator/date-generator.md +31 -2
  194. package/docs/default-value/value-generator/hour-time-generator.md +33 -0
  195. package/docs/default-value/value-generator/minute-time-generator.md +33 -0
  196. package/docs/default-value/value-generator/month-date-generator.md +4 -2
  197. package/docs/default-value/value-generator/now-generator.md +29 -0
  198. package/docs/default-value/value-generator/time-generator.md +31 -0
  199. package/docs/default-value/value-generator/today-generator.md +29 -0
  200. package/docs/default-value/value-generator/week-date-generator.md +33 -2
  201. package/docs/default-value/value-generator/year-date-generator.md +33 -2
  202. package/package.json +26 -21
  203. package/src/configure/column-builder.ts +1 -0
  204. package/src/configure/rows-option-builder.ts +11 -1
  205. package/src/configure/zero-config.ts +1 -0
  206. package/src/data-card/data-card-gutter-menu.ts +5 -5
  207. package/src/data-card/data-card.ts +3 -3
  208. package/src/data-card/event-handlers/record-card-click-handler.ts +1 -1
  209. package/src/data-card/record-card.ts +30 -32
  210. package/src/data-grid/data-grid-accum-field.ts +8 -2
  211. package/src/data-grid/data-grid-body-style.ts +1 -0
  212. package/src/data-grid/data-grid-body.ts +7 -5
  213. package/src/data-grid/data-grid-field.ts +4 -2
  214. package/src/data-grid/data-grid-footer.ts +18 -11
  215. package/src/data-grid/data-grid-header.ts +68 -65
  216. package/src/data-grid/data-grid.ts +14 -4
  217. package/src/data-grist.ts +89 -30
  218. package/src/data-list/data-list-gutter.ts +12 -0
  219. package/src/data-list/data-list.ts +3 -3
  220. package/src/data-list/event-handlers/record-partial-click-handler.ts +1 -1
  221. package/src/data-list/record-partial.ts +22 -22
  222. package/src/editors/ox-grist-editor-checkbox.ts +12 -2
  223. package/src/editors/ox-grist-editor-datetime.ts +1 -2
  224. package/src/editors/ox-grist-editor-file.ts +12 -2
  225. package/src/editors/ox-grist-editor-image.ts +10 -7
  226. package/src/editors/ox-grist-editor-number.ts +10 -9
  227. package/src/editors/ox-grist-editor-select.ts +41 -28
  228. package/src/editors/ox-grist-editor-text.ts +4 -0
  229. package/src/editors/ox-grist-editor-textarea.ts +4 -0
  230. package/src/editors/ox-grist-editor.ts +14 -14
  231. package/src/empty-note.ts +3 -3
  232. package/src/filters/filter-checkbox.ts +15 -5
  233. package/src/filters/filter-range-date.ts +16 -1
  234. package/src/filters/filter-select.ts +41 -28
  235. package/src/filters/filter-styles.ts +46 -28
  236. package/src/filters/filters-form.ts +159 -59
  237. package/src/gutters/gutter-button.ts +3 -3
  238. package/src/gutters/gutter-dirty.ts +5 -5
  239. package/src/handlers/contextmenu-tree-mutation.ts +4 -4
  240. package/src/index.ts +1 -1
  241. package/src/personalizer/index.ts +1 -0
  242. package/src/personalizer/ox-grist-personalizer.ts +181 -0
  243. package/src/record-view/record-creator.ts +1 -1
  244. package/src/record-view/record-view-body.ts +4 -4
  245. package/src/record-view/record-view.ts +5 -5
  246. package/src/renderers/ox-grist-renderer-select.ts +41 -6
  247. package/src/sorters/sorters-control.ts +3 -3
  248. package/src/types.ts +36 -10
  249. package/stories/{accumulator.stories.ts → accumulator-format.stories.ts} +48 -126
  250. package/stories/barcode-input-filter.stories.ts +53 -89
  251. package/stories/bounded-select-filters.stories.ts +313 -0
  252. package/stories/bounded-select-record.stories.ts +316 -0
  253. package/stories/creatable-only-column.stories.ts +231 -0
  254. package/stories/default-filters.stories.ts +96 -89
  255. package/stories/dynamic-editable.stories.ts +58 -92
  256. package/stories/empty-sorters.stories.ts +53 -89
  257. package/stories/explicit-fetch.stories.ts +54 -90
  258. package/stories/fixed-column.stories.ts +57 -137
  259. package/stories/grid-setting.stories.ts +462 -0
  260. package/stories/grist-modes.stories.ts +86 -155
  261. package/stories/group-header.stories.ts +57 -137
  262. package/stories/textarea.stories.ts +42 -127
  263. package/stories/tree-column-with-checkbox.stories.ts +53 -138
  264. package/stories/tree-column.stories.ts +53 -138
  265. package/themes/grist-theme.css +2 -0
  266. package/dist/src/value-generator/date-generator.d.ts +0 -6
  267. package/dist/src/value-generator/date-generator.js +0 -30
  268. package/dist/src/value-generator/date-generator.js.map +0 -1
  269. package/dist/src/value-generator/hour-time-generator.d.ts +0 -7
  270. package/dist/src/value-generator/hour-time-generator.js +0 -29
  271. package/dist/src/value-generator/hour-time-generator.js.map +0 -1
  272. package/dist/src/value-generator/index.d.ts +0 -1
  273. package/dist/src/value-generator/index.js +0 -2
  274. package/dist/src/value-generator/index.js.map +0 -1
  275. package/dist/src/value-generator/minute-time-generator.d.ts +0 -7
  276. package/dist/src/value-generator/minute-time-generator.js +0 -29
  277. package/dist/src/value-generator/minute-time-generator.js.map +0 -1
  278. package/dist/src/value-generator/month-date-generator.d.ts +0 -7
  279. package/dist/src/value-generator/month-date-generator.js +0 -31
  280. package/dist/src/value-generator/month-date-generator.js.map +0 -1
  281. package/dist/src/value-generator/now-generator.d.ts +0 -4
  282. package/dist/src/value-generator/now-generator.js +0 -8
  283. package/dist/src/value-generator/now-generator.js.map +0 -1
  284. package/dist/src/value-generator/registry.d.ts +0 -11
  285. package/dist/src/value-generator/registry.js +0 -50
  286. package/dist/src/value-generator/registry.js.map +0 -1
  287. package/dist/src/value-generator/time-generator.d.ts +0 -6
  288. package/dist/src/value-generator/time-generator.js +0 -28
  289. package/dist/src/value-generator/time-generator.js.map +0 -1
  290. package/dist/src/value-generator/today-generator.d.ts +0 -4
  291. package/dist/src/value-generator/today-generator.js +0 -8
  292. package/dist/src/value-generator/today-generator.js.map +0 -1
  293. package/dist/src/value-generator/week-date-generator.d.ts +0 -7
  294. package/dist/src/value-generator/week-date-generator.js +0 -29
  295. package/dist/src/value-generator/week-date-generator.js.map +0 -1
  296. package/dist/src/value-generator/year-date-generator.d.ts +0 -7
  297. package/dist/src/value-generator/year-date-generator.js +0 -29
  298. package/dist/src/value-generator/year-date-generator.js.map +0 -1
  299. package/dist/stories/accumulator.stories.js.map +0 -1
  300. package/src/value-generator/date-generator.ts +0 -35
  301. package/src/value-generator/hour-time-generator.ts +0 -43
  302. package/src/value-generator/index.ts +0 -1
  303. package/src/value-generator/minute-time-generator.ts +0 -43
  304. package/src/value-generator/month-date-generator.ts +0 -38
  305. package/src/value-generator/now-generator.ts +0 -10
  306. package/src/value-generator/registry.ts +0 -58
  307. package/src/value-generator/time-generator.ts +0 -33
  308. package/src/value-generator/today-generator.ts +0 -10
  309. package/src/value-generator/week-date-generator.ts +0 -40
  310. package/src/value-generator/year-date-generator.ts +0 -36
@@ -6,6 +6,8 @@ import '@operato/input/ox-input-search.js'
6
6
  import { css, html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'
7
7
  import { customElement, property, queryAsync, state } from 'lit/decorators.js'
8
8
 
9
+ import { getDefaultValue } from '@operato/time-calculator'
10
+
9
11
  import { FilterConfigObject } from '..'
10
12
  import { DataGrist } from '../data-grist'
11
13
  import { ColumnConfig, FilterOperator, FilterValue, GristConfig } from '../types'
@@ -21,7 +23,7 @@ export type QueryFilter = {
21
23
  }
22
24
 
23
25
  @customElement('ox-filters-form')
24
- export class FiltersForm extends LitElement {
26
+ export class OxFiltersForm extends LitElement {
25
27
  static styles = [
26
28
  FilterStyles,
27
29
  css`
@@ -40,6 +42,7 @@ export class FiltersForm extends LitElement {
40
42
  form > * {
41
43
  display: flex;
42
44
  align-items: center;
45
+ gap: var(--input-intra-gap, 7px);
43
46
  }
44
47
 
45
48
  label span {
@@ -65,6 +68,9 @@ export class FiltersForm extends LitElement {
65
68
 
66
69
  @queryAsync('form') form!: HTMLFormElement
67
70
 
71
+ private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}
72
+ private objectValue?: object
73
+
68
74
  connectedCallback(): void {
69
75
  super.connectedCallback()
70
76
 
@@ -72,7 +78,6 @@ export class FiltersForm extends LitElement {
72
78
 
73
79
  if (grist) {
74
80
  this.config = grist.compiledConfig
75
- this.value = grist.filters || []
76
81
 
77
82
  grist.addEventListener('config-change', (e: Event) => {
78
83
  this.config = (e as CustomEvent).detail
@@ -88,20 +93,52 @@ export class FiltersForm extends LitElement {
88
93
  })
89
94
 
90
95
  this.renderRoot.addEventListener('change', async (e: Event) => {
91
- this.dispatchEvent(
92
- new CustomEvent('fetch-params-change', {
93
- bubbles: true,
94
- composed: true,
95
- detail: {
96
- filters: await this.getQueryFilters(),
97
- from: 'filters-form'
96
+ const { target, detail: value } = e as CustomEvent
97
+ const name = (target as HTMLInputElement).name
98
+ const { filter } = this.filterColumns.find(filter => filter.name == name) || {}
99
+
100
+ if (this.autoUpdateTargetsOnChange[name]) {
101
+ /* 일단은 심플하게, boundTo로 연결된 필터값이 바뀌면, 폼 전체를 update하도록 함. */
102
+ ;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {
103
+ const target = this.renderRoot.querySelector(`[name='${name}']`)
104
+ if (target) {
105
+ ;(target as HTMLInputElement).value = ''
98
106
  }
99
107
  })
100
- )
108
+
109
+ await this.updateObjectValues()
110
+ this.requestUpdate()
111
+ }
112
+
113
+ const onchange = typeof filter == 'object' ? filter.onchange : null
114
+ const keepGoing = onchange ? await onchange.call(null, value ?? (target as HTMLInputElement).value, this) : true
115
+
116
+ keepGoing &&
117
+ this.dispatchEvent(
118
+ new CustomEvent('fetch-params-change', {
119
+ bubbles: true,
120
+ composed: true,
121
+ detail: {
122
+ filters: await this.getQueryFilters(),
123
+ from: 'filters-form'
124
+ }
125
+ })
126
+ )
101
127
  })
102
128
  }
103
129
  }
104
130
 
131
+ buildDefaultValue(operator: FilterOperator, defaultValue: any) {
132
+ if (defaultValue === undefined) {
133
+ return
134
+ }
135
+ if (operator == 'between') {
136
+ return (defaultValue as Array<any>).map(v => getDefaultValue(v, this))
137
+ } else {
138
+ return getDefaultValue(defaultValue, this)
139
+ }
140
+ }
141
+
105
142
  updated(changes: PropertyValues<this>) {
106
143
  if (changes.has('config')) {
107
144
  const filters = this.config.columns.filter(columnConfig => !!columnConfig.filter)
@@ -114,7 +151,32 @@ export class FiltersForm extends LitElement {
114
151
  return filter!.operator === 'search'
115
152
  })
116
153
 
154
+ const grist = this.closest('ox-grist') as DataGrist
155
+
156
+ this.value = (grist?.filters || []).map(filter => {
157
+ return {
158
+ ...filter,
159
+ value: this.buildDefaultValue(filter!.operator, filter!.value)
160
+ }
161
+ })
162
+
117
163
  this.empty = (this.searchColumns.length === 0 || this.withoutSearch) && this.filterColumns.length === 0
164
+
165
+ this.autoUpdateTargetsOnChange = {}
166
+ this.filterColumns
167
+ ?.filter(({ filter }) => {
168
+ return typeof filter == 'object' && filter.boundTo && filter.boundTo.length > 0
169
+ })
170
+ .map(({ name, filter }) => {
171
+ const boundTo = (filter as FilterConfigObject).boundTo
172
+
173
+ boundTo!.forEach(to => {
174
+ const origin = this.autoUpdateTargetsOnChange[to] || []
175
+ if (name && !origin.includes(name)) {
176
+ this.autoUpdateTargetsOnChange[to] = [...origin, name]
177
+ }
178
+ })
179
+ })
118
180
  }
119
181
  }
120
182
 
@@ -151,8 +213,8 @@ export class FiltersForm extends LitElement {
151
213
  filterLabel !== undefined
152
214
  ? filterLabel
153
215
  : typeof label === 'object' && label.renderer
154
- ? label.renderer(column)
155
- : header.renderer(column) || name
216
+ ? label.renderer(column)
217
+ : header.renderer(column) || name
156
218
 
157
219
  const idx = operator === 'between' ? 1 : 0
158
220
  const renderer = getFilterRenderer(
@@ -160,59 +222,63 @@ export class FiltersForm extends LitElement {
160
222
  ? 'text'
161
223
  : type
162
224
  )[idx]
163
- const value = this.value?.find(filter => filter.name == name)?.value
225
+ const value =
226
+ this.value?.find(filter => filter.name == name)?.value ??
227
+ this.buildDefaultValue(operator!, (filter as FilterConfigObject)?.value)
164
228
 
165
229
  if (!renderer) {
166
230
  return html``
167
231
  }
168
232
 
169
- return type !== 'select' && labelText
170
- ? html`<label filter-title ?between=${operator === 'between'}
171
- ><span>${labelText}</span> ${renderer(column, value, this)}
172
- </label> `
173
- : type !== 'select' && !labelText
233
+ return type === 'boolean' || type === 'checkbox'
174
234
  ? renderer(column, value, this)
175
- : operator === 'in'
176
- ? html`
177
- <ox-select
178
- name=${name}
179
- placeholder=${labelText}
180
- .value=${value}
181
- @change=${(e: CustomEvent) =>
182
- e.target?.dispatchEvent(
183
- new CustomEvent('filter-change', {
184
- detail: {
185
- name,
186
- operator,
187
- value: e.detail
188
- }
189
- })
190
- )}
191
- >
192
- <ox-popup-list multiple attr-selected="checked" with-search>
193
- ${renderer(column, value, this)}
194
- </ox-popup-list>
195
- </ox-select>
196
- `
197
- : html`
198
- <ox-select
199
- name=${name}
200
- placeholder=${labelText}
201
- .value=${value}
202
- @change=${(e: CustomEvent) =>
203
- e.target?.dispatchEvent(
204
- new CustomEvent('filter-change', {
205
- detail: {
206
- name,
207
- operator,
208
- value: e.detail
209
- }
210
- })
211
- )}
212
- >
213
- <ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>
214
- </ox-select>
215
- `
235
+ : type !== 'select' && labelText
236
+ ? html`<label filter-title ?between=${operator === 'between'}
237
+ ><span>${labelText}</span> ${renderer(column, value, this)}
238
+ </label> `
239
+ : type !== 'select' && !labelText
240
+ ? renderer(column, value, this)
241
+ : operator === 'in'
242
+ ? html`
243
+ <ox-select
244
+ name=${name}
245
+ placeholder=${labelText}
246
+ .value=${value}
247
+ @change=${(e: CustomEvent) =>
248
+ e.target?.dispatchEvent(
249
+ new CustomEvent('filter-change', {
250
+ detail: {
251
+ name,
252
+ operator,
253
+ value: e.detail
254
+ }
255
+ })
256
+ )}
257
+ >
258
+ <ox-popup-list multiple attr-selected="checked" with-search>
259
+ ${renderer(column, value, this)}
260
+ </ox-popup-list>
261
+ </ox-select>
262
+ `
263
+ : html`
264
+ <ox-select
265
+ name=${name}
266
+ placeholder=${labelText}
267
+ .value=${value}
268
+ @change=${(e: CustomEvent) =>
269
+ e.target?.dispatchEvent(
270
+ new CustomEvent('filter-change', {
271
+ detail: {
272
+ name,
273
+ operator,
274
+ value: e.detail
275
+ }
276
+ })
277
+ )}
278
+ >
279
+ <ox-popup-list with-search> ${renderer(column, value, this)} </ox-popup-list>
280
+ </ox-select>
281
+ `
216
282
  })}
217
283
  </form>
218
284
  `
@@ -293,4 +359,38 @@ export class FiltersForm extends LitElement {
293
359
  const input = this.renderRoot.querySelector(`form [name="${name}"]`) as HTMLInputElement
294
360
  return input?.value
295
361
  }
362
+
363
+ private async updateObjectValues() {
364
+ const form = await this.form
365
+ if (!form) return []
366
+
367
+ const formData = new FormData(form)
368
+
369
+ const object = {} as any
370
+ formData.forEach((value, key) => {
371
+ const prev = object[key]
372
+
373
+ if (key in object) {
374
+ object[key] = prev instanceof Array ? [...prev, value] : [prev, value]
375
+ } else {
376
+ object[key] = value
377
+ }
378
+ })
379
+
380
+ this.objectValue = object
381
+ }
382
+
383
+ public getFormObjectValue() {
384
+ return this.objectValue
385
+ }
386
+
387
+ reset() {
388
+ this.form
389
+ .then((form: HTMLFormElement) => {
390
+ form.reset()
391
+ })
392
+ .catch((error: any) => {
393
+ console.error('Error resetting the form:', error)
394
+ })
395
+ }
296
396
  }
@@ -1,4 +1,4 @@
1
- import '@material/mwc-icon'
1
+ import '@material/web/icon/icon.js'
2
2
 
3
3
  import { html } from 'lit'
4
4
 
@@ -23,13 +23,13 @@ export class GutterButton {
23
23
  sortable: false,
24
24
  header: {
25
25
  renderer: function (column) {
26
- return html` <mwc-icon style=${inlineHeaderStyle} title=${title}>${iconFn()}</mwc-icon> `
26
+ return html` <md-icon style=${inlineHeaderStyle} title=${title}>${iconFn()}</md-icon> `
27
27
  } as HeaderRenderer
28
28
  },
29
29
  record: {
30
30
  align: 'center',
31
31
  renderer: function (value, column, record, rowIndex, field) {
32
- return html` <mwc-icon style=${inlineRecordStyle} title=${title}>${iconFn(record)}</mwc-icon> `
32
+ return html` <md-icon style=${inlineRecordStyle} title=${title}>${iconFn(record)}</md-icon> `
33
33
  } as FieldRenderer
34
34
  },
35
35
  forGrid: true,
@@ -1,4 +1,4 @@
1
- import '@material/mwc-icon'
1
+ import '@material/web/icon/icon.js'
2
2
 
3
3
  import { css, html, LitElement } from 'lit'
4
4
  import { customElement, property } from 'lit/decorators.js'
@@ -13,7 +13,7 @@ class GutterDirtyElement extends LitElement {
13
13
  margin: auto;
14
14
  }
15
15
 
16
- mwc-icon {
16
+ md-icon {
17
17
  width: var(--grid-record-dirty-icon-size);
18
18
  height: var(--grid-record-dirty-icon-size);
19
19
  border-radius: 50%;
@@ -38,11 +38,11 @@ class GutterDirtyElement extends LitElement {
38
38
  render() {
39
39
  switch (this.value) {
40
40
  case '+':
41
- return html` <mwc-icon style=${INLINESTYLE} center add>add</mwc-icon> `
41
+ return html` <md-icon style=${INLINESTYLE} center add>add</md-icon> `
42
42
  case '-':
43
- return html` <mwc-icon style=${INLINESTYLE} center remove>remove</mwc-icon> `
43
+ return html` <md-icon style=${INLINESTYLE} center remove>remove</md-icon> `
44
44
  case 'M':
45
- return html` <mwc-icon style=${INLINESTYLE} center done>done</mwc-icon> `
45
+ return html` <md-icon style=${INLINESTYLE} center done>done</md-icon> `
46
46
  default:
47
47
  return ''
48
48
  }
@@ -42,7 +42,7 @@ export const ContextMenuTreeMutation = function (
42
42
  dispatchEvent(field, 'add-sibling-node')
43
43
  }}
44
44
  >
45
- <mwc-icon slot="icon">add</mwc-icon>
45
+ <md-icon slot="icon">add</md-icon>
46
46
  </ox-popup-menuitem>
47
47
 
48
48
  <ox-popup-menuitem
@@ -51,7 +51,7 @@ export const ContextMenuTreeMutation = function (
51
51
  dispatchEvent(field, 'add-child-node')
52
52
  }}
53
53
  >
54
- <mwc-icon slot="icon">playlist_add</mwc-icon>
54
+ <md-icon slot="icon">playlist_add</md-icon>
55
55
  </ox-popup-menuitem>
56
56
 
57
57
  <div separator></div>
@@ -62,7 +62,7 @@ export const ContextMenuTreeMutation = function (
62
62
  dispatchEvent(field, 'collapse-all')
63
63
  }}
64
64
  >
65
- <mwc-icon slot="icon">unfold_less</mwc-icon>
65
+ <md-icon slot="icon">unfold_less</md-icon>
66
66
  </ox-popup-menuitem>
67
67
 
68
68
  <ox-popup-menuitem
@@ -71,7 +71,7 @@ export const ContextMenuTreeMutation = function (
71
71
  dispatchEvent(field, 'expand-all')
72
72
  }}
73
73
  >
74
- <mwc-icon slot="icon">unfold_more</mwc-icon>
74
+ <md-icon slot="icon">unfold_more</md-icon>
75
75
  </ox-popup-menuitem>
76
76
  `,
77
77
  top: e.pageY,
package/src/index.ts CHANGED
@@ -12,6 +12,6 @@ export * from './gutters'
12
12
  export * from './filters'
13
13
  export * from './sorters/sorters-control'
14
14
  export * from './record-view'
15
- export * from './value-generator'
15
+ export * from './personalizer'
16
16
 
17
17
  export * from './utils/list-param'
@@ -0,0 +1 @@
1
+ export * from './ox-grist-personalizer'
@@ -0,0 +1,181 @@
1
+ import '@material/web/button/outlined-button.js'
2
+
3
+ import { css, html, LitElement } from 'lit'
4
+ import { customElement, property, state } from 'lit/decorators.js'
5
+
6
+ import { i18next } from '@operato/i18n'
7
+ import { OxPopupList } from '@operato/popup'
8
+ import { OxCheckbox } from '@operato/input'
9
+
10
+ import { ColumnConfig, PersonalGristPreference } from '../types'
11
+ import { DataGrist } from '../data-grist'
12
+
13
+ @customElement('ox-grist-personalizer')
14
+ export class OxGristPersonalizer extends LitElement {
15
+ static styles = [
16
+ css`
17
+ md-icon {
18
+ --md-icon-size: 14px;
19
+ width: 16px;
20
+ height: 16px;
21
+ background-color: rgba(var(--secondary-color-rgb), 0.6);
22
+ color: var(--md-sys-color-secondary-container);
23
+ border-radius: 0px 0px 7px 7px;
24
+ cursor: pointer;
25
+
26
+ &:hover {
27
+ color: var(--md-sys-color-primary-container);
28
+ }
29
+ }
30
+ `
31
+ ]
32
+
33
+ @property({ type: String }) page!: string
34
+ @property({ type: String }) element!: string
35
+ @property({ type: Boolean, attribute: true }) debug: boolean = false
36
+
37
+ @state() private preference?: PersonalGristPreference
38
+
39
+ render() {
40
+ return html`
41
+ <md-icon
42
+ @click=${(e: MouseEvent) => {
43
+ const grist = this.closest('ox-grist') as DataGrist
44
+
45
+ const { config, compiledConfig } = grist
46
+ const { columns: compiledColumns } = compiledConfig
47
+
48
+ const columns = compiledColumns
49
+ .filter(ccolumn => {
50
+ const column = config.columns.find((column: Partial<ColumnConfig>) => column.name == ccolumn.name)
51
+ return column && column.name && column.type !== 'gutter' && !column.hidden && !column.unusable
52
+ })
53
+ .map(column => compiledColumns.find(compiledColumn => compiledColumn.name == column.name)!)
54
+
55
+ this.preference = {
56
+ columns: columns.map(column => {
57
+ return {
58
+ name: column.name,
59
+ hidden: column.hidden,
60
+ width: column.width
61
+ }
62
+ })
63
+ }
64
+
65
+ const template = html`
66
+ <div class="personalizer-header" slot="header">
67
+ <md-icon
68
+ style="margin-left: auto;"
69
+ @click=${async (e: MouseEvent) => {
70
+ if (grist.personalConfigProvider) {
71
+ grist.personalConfig = this.preference = await grist.personalConfigProvider.save(this.preference)
72
+ }
73
+ popup.close()
74
+ }}
75
+ title=${String(i18next.t('button.save'))}
76
+ >keep</md-icon
77
+ ><md-icon
78
+ @click=${async (e: MouseEvent) => {
79
+ if (grist.personalConfigProvider) {
80
+ grist.personalConfig = this.preference = {}
81
+ await grist.personalConfigProvider.reset()
82
+ }
83
+ popup.close()
84
+ }}
85
+ title=${String(i18next.t('button.delete'))}
86
+ >keep_off</md-icon
87
+ ><md-icon @click=${async (e: MouseEvent) => popup.close()} title=${String(i18next.t('button.close'))}
88
+ >close</md-icon
89
+ >
90
+ </div>
91
+
92
+ ${columns.map(
93
+ column => html`
94
+ <ox-checkbox label="checkbox" ?checked=${!column.hidden} value=${column.name} option
95
+ >${column.header.renderer(column)}<span style="position: absolute; right: 10px; cursor: move;" handle
96
+ >☰</span
97
+ ></ox-checkbox
98
+ >
99
+ `
100
+ )}
101
+ `
102
+
103
+ const popup = OxPopupList.open({
104
+ template,
105
+ multiple: true,
106
+ sortable: true,
107
+ debug: this.debug,
108
+ attrSelected: 'checked',
109
+ top: e.pageY,
110
+ left: e.pageX,
111
+ styles: css`
112
+ :host {
113
+ width: 240px;
114
+ max-height: 300px;
115
+ overflow: auto;
116
+ }
117
+
118
+ ::slotted(.personalizer-header) {
119
+ --md-icon-size: 1.4em;
120
+
121
+ display: flex;
122
+ flex-direction: row;
123
+ align-items: center;
124
+ text-transform: capitalize;
125
+ box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3);
126
+ }
127
+
128
+ ::slotted([option]) {
129
+ position: relative;
130
+ user-select: none;
131
+ }
132
+ `
133
+ })
134
+
135
+ popup.onselect = (e: Event) => {
136
+ const selected = (e as CustomEvent).detail
137
+
138
+ const pconfig: PersonalGristPreference = grist.personalConfig || {}
139
+ const pcolumns = this.preference?.columns || columns
140
+
141
+ pconfig.columns = pcolumns.map(column => {
142
+ return {
143
+ name: column.name,
144
+ hidden: selected.indexOf(column.name) == -1,
145
+ width: column.width
146
+ }
147
+ })
148
+
149
+ this.preference = pconfig
150
+
151
+ grist.personalConfig = this.preference
152
+
153
+ grist.applyUpdatedConfiguration()
154
+ }
155
+
156
+ popup.addEventListener('sorted', (e: Event) => {
157
+ const sorted = (e as CustomEvent).detail as HTMLElement[]
158
+
159
+ const pconfig: PersonalGristPreference = grist.personalConfig || {}
160
+
161
+ pconfig.columns = sorted.map(element => {
162
+ const name = (element as OxCheckbox).value
163
+ return {
164
+ name,
165
+ hidden: !element.hasAttribute('checked'),
166
+ width: columns.find(column => column.name == name)?.width
167
+ }
168
+ })
169
+
170
+ this.preference = pconfig
171
+
172
+ grist.personalConfig = this.preference
173
+
174
+ grist.applyUpdatedConfiguration()
175
+ })
176
+ }}
177
+ >settings</md-icon
178
+ >
179
+ `
180
+ }
181
+ }
@@ -1,4 +1,4 @@
1
- import '@material/mwc-icon'
1
+ import '@material/web/icon/icon.js'
2
2
  import './record-view'
3
3
 
4
4
  import { html, LitElement } from 'lit'
@@ -1,4 +1,4 @@
1
- import '@material/mwc-icon'
1
+ import '@material/web/icon/icon.js'
2
2
  import '../data-grid/data-grid-field'
3
3
 
4
4
  import { css, html, LitElement } from 'lit'
@@ -34,7 +34,7 @@ export class RecordViewBody extends LitElement {
34
34
  color: var(--record-view-label-color);
35
35
  }
36
36
 
37
- label mwc-icon {
37
+ label md-icon {
38
38
  display: none;
39
39
  }
40
40
 
@@ -43,7 +43,7 @@ export class RecordViewBody extends LitElement {
43
43
  font-weight: bold;
44
44
  }
45
45
 
46
- label[editable] mwc-icon {
46
+ label[editable] md-icon {
47
47
  display: inline-block;
48
48
  font-size: var(--record-view-label-icon-size);
49
49
  opacity: 0.5;
@@ -99,7 +99,7 @@ export class RecordViewBody extends LitElement {
99
99
 
100
100
  return html`
101
101
  <label ?editable=${editable}
102
- ><span>${mandatory ? '*' : ''}${this._renderLabel(column)}</span> <mwc-icon>edit</mwc-icon></label
102
+ ><span>${mandatory ? '*' : ''}${this._renderLabel(column)}</span> <md-icon>edit</md-icon></label
103
103
  >
104
104
  <ox-grid-field
105
105
  .rowIndex=${rowIndex}
@@ -1,4 +1,4 @@
1
- import '@material/mwc-icon'
1
+ import '@material/web/icon/icon.js'
2
2
  import './record-view-body'
3
3
  import '@operato/input/ox-input-file.js'
4
4
  import '../data-grid/data-grid-field'
@@ -53,7 +53,7 @@ export class RecordView extends LitElement {
53
53
  vertical-align: middle;
54
54
  }
55
55
 
56
- [footer] button mwc-icon {
56
+ [footer] button md-icon {
57
57
  margin-top: -3px;
58
58
  margin-right: 5px;
59
59
  font-size: var(--record-view-footer-iconbutton-size);
@@ -74,9 +74,9 @@ export class RecordView extends LitElement {
74
74
  <ox-record-view-body .columns=${this.columns} .record=${this.record} .rowIndex=${this.rowIndex}>
75
75
  </ox-record-view-body>
76
76
  <div footer>
77
- <button @click=${this.onReset.bind(this)}><mwc-icon>refresh</mwc-icon><span>Reset</span></button>
78
- <button @click=${this.onCancel.bind(this)}><mwc-icon>clear</mwc-icon><span>Cancel</span></button>
79
- <button @click=${this.onOK.bind(this)} ok><mwc-icon>radio_button_unchecked</mwc-icon><span>OK</span></button>
77
+ <button @click=${this.onReset.bind(this)}><md-icon>refresh</md-icon><span>Reset</span></button>
78
+ <button @click=${this.onCancel.bind(this)}><md-icon>clear</md-icon><span>Cancel</span></button>
79
+ <button @click=${this.onOK.bind(this)} ok><md-icon>radio_button_unchecked</md-icon><span>OK</span></button>
80
80
  </div>
81
81
  `
82
82
  }