@operato/data-grist 1.0.0-beta.9 → 1.0.6

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 (189) hide show
  1. package/.storybook/main.js +3 -0
  2. package/.storybook/server.mjs +8 -0
  3. package/CHANGELOG.md +433 -0
  4. package/demo/data-grist-test.html +1 -1
  5. package/demo/index.html +13 -2
  6. package/demo/report-test.html +1 -1
  7. package/dist/src/configure/zero-config.d.ts +2 -0
  8. package/dist/src/configure/zero-config.js +3 -1
  9. package/dist/src/configure/zero-config.js.map +1 -1
  10. package/dist/src/data-card/data-card-field.d.ts +1 -1
  11. package/dist/src/data-card/data-card-field.js +3 -2
  12. package/dist/src/data-card/data-card-field.js.map +1 -1
  13. package/dist/src/data-card/data-card.js +1 -0
  14. package/dist/src/data-card/data-card.js.map +1 -1
  15. package/dist/src/data-grid/data-grid-body.d.ts +4 -2
  16. package/dist/src/data-grid/data-grid-body.js +74 -40
  17. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  18. package/dist/src/data-grid/data-grid-field.d.ts +1 -1
  19. package/dist/src/data-grid/data-grid-field.js +1 -1
  20. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  21. package/dist/src/data-grid/data-grid-footer.d.ts +2 -2
  22. package/dist/src/data-grid/data-grid-footer.js +9 -10
  23. package/dist/src/data-grid/data-grid-footer.js.map +1 -1
  24. package/dist/src/data-grid/data-grid-header.d.ts +4 -6
  25. package/dist/src/data-grid/data-grid-header.js +39 -48
  26. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  27. package/dist/src/data-grid/data-grid.d.ts +2 -2
  28. package/dist/src/data-grid/data-grid.js +4 -3
  29. package/dist/src/data-grid/data-grid.js.map +1 -1
  30. package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js +9 -11
  31. package/dist/src/data-grid/event-handlers/data-grid-body-click-handler.js.map +1 -1
  32. package/dist/src/data-grist.d.ts +7 -5
  33. package/dist/src/data-grist.js +154 -112
  34. package/dist/src/data-grist.js.map +1 -1
  35. package/dist/src/data-list/record-partial.js +1 -5
  36. package/dist/src/data-list/record-partial.js.map +1 -1
  37. package/dist/src/data-manipulator.d.ts +4 -1
  38. package/dist/src/data-manipulator.js +12 -0
  39. package/dist/src/data-manipulator.js.map +1 -1
  40. package/dist/src/data-provider.d.ts +4 -6
  41. package/dist/src/data-provider.js +12 -23
  42. package/dist/src/data-provider.js.map +1 -1
  43. package/dist/src/data-report/data-report-body.d.ts +1 -1
  44. package/dist/src/data-report/data-report-body.js +4 -4
  45. package/dist/src/data-report/data-report-body.js.map +1 -1
  46. package/dist/src/data-report/data-report-header.js +4 -4
  47. package/dist/src/data-report/data-report-header.js.map +1 -1
  48. package/dist/src/editors/ox-grist-editor.d.ts +1 -1
  49. package/dist/src/editors/ox-grist-editor.js +7 -4
  50. package/dist/src/editors/ox-grist-editor.js.map +1 -1
  51. package/dist/src/filters/filter-checkbox.d.ts +1 -1
  52. package/dist/src/filters/filter-checkbox.js +1 -1
  53. package/dist/src/filters/filter-checkbox.js.map +1 -1
  54. package/dist/src/filters/filter-input-barcode.d.ts +3 -0
  55. package/dist/src/filters/{filter-input copy.js → filter-input-barcode.js} +8 -6
  56. package/dist/src/filters/filter-input-barcode.js.map +1 -0
  57. package/dist/src/filters/filter-input.js +1 -1
  58. package/dist/src/filters/filter-input.js.map +1 -1
  59. package/dist/src/filters/filter-styles.js +18 -23
  60. package/dist/src/filters/filter-styles.js.map +1 -1
  61. package/dist/src/filters/filters-form.js +5 -3
  62. package/dist/src/filters/filters-form.js.map +1 -1
  63. package/dist/src/filters/registry.d.ts +1 -1
  64. package/dist/src/filters/registry.js +10 -7
  65. package/dist/src/filters/registry.js.map +1 -1
  66. package/dist/src/gutters/gutter-button.js +5 -4
  67. package/dist/src/gutters/gutter-button.js.map +1 -1
  68. package/dist/src/gutters/gutter-dirty.d.ts +5 -1
  69. package/dist/src/gutters/gutter-dirty.js +17 -2
  70. package/dist/src/gutters/gutter-dirty.js.map +1 -1
  71. package/dist/src/gutters/gutter-row-selector.js +2 -1
  72. package/dist/src/gutters/gutter-row-selector.js.map +1 -1
  73. package/dist/src/gutters/gutter-sequence.js +15 -0
  74. package/dist/src/gutters/gutter-sequence.js.map +1 -1
  75. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js +2 -4
  76. package/dist/src/record-view/event-handlers/record-view-body-click-handler.js.map +1 -1
  77. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js +2 -2
  78. package/dist/src/record-view/event-handlers/record-view-body-keydown-handler.js.map +1 -1
  79. package/dist/src/record-view/record-creator.js +0 -2
  80. package/dist/src/record-view/record-creator.js.map +1 -1
  81. package/dist/src/record-view/record-view-body.d.ts +0 -1
  82. package/dist/src/record-view/record-view-body.js +0 -5
  83. package/dist/src/record-view/record-view-body.js.map +1 -1
  84. package/dist/src/record-view/record-view-handler.d.ts +1 -1
  85. package/dist/src/record-view/record-view.d.ts +0 -1
  86. package/dist/src/record-view/record-view.js +1 -10
  87. package/dist/src/record-view/record-view.js.map +1 -1
  88. package/dist/src/renderers/ox-grist-renderer-color.js +1 -1
  89. package/dist/src/renderers/ox-grist-renderer-color.js.map +1 -1
  90. package/dist/src/renderers/ox-grist-renderer-json5.js +1 -1
  91. package/dist/src/renderers/ox-grist-renderer-json5.js.map +1 -1
  92. package/dist/src/renderers/ox-grist-renderer-link.js +1 -1
  93. package/dist/src/renderers/ox-grist-renderer-link.js.map +1 -1
  94. package/dist/src/renderers/ox-grist-renderer-select.js +2 -2
  95. package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
  96. package/dist/src/renderers/ox-grist-renderer-text.js +6 -2
  97. package/dist/src/renderers/ox-grist-renderer-text.js.map +1 -1
  98. package/dist/src/sorters/sorters-control.d.ts +1 -1
  99. package/dist/src/sorters/sorters-control.js +5 -7
  100. package/dist/src/sorters/sorters-control.js.map +1 -1
  101. package/dist/src/types.d.ts +7 -4
  102. package/dist/src/types.js.map +1 -1
  103. package/dist/stories/{index.stories.d.ts → barcode-input-filter.stories.d.ts} +9 -13
  104. package/dist/stories/barcode-input-filter.stories.js +200 -0
  105. package/dist/stories/barcode-input-filter.stories.js.map +1 -0
  106. package/dist/stories/default-filters.stories.d.ts +20 -0
  107. package/dist/stories/default-filters.stories.js +187 -0
  108. package/dist/stories/default-filters.stories.js.map +1 -0
  109. package/dist/stories/empty-sorters.stories.d.ts +20 -0
  110. package/dist/stories/empty-sorters.stories.js +180 -0
  111. package/dist/stories/empty-sorters.stories.js.map +1 -0
  112. package/dist/stories/explicit-fetch.stories.d.ts +25 -0
  113. package/dist/stories/explicit-fetch.stories.js +186 -0
  114. package/dist/stories/explicit-fetch.stories.js.map +1 -0
  115. package/dist/stories/grist-modes.stories.d.ts +36 -0
  116. package/dist/stories/grist-modes.stories.js +448 -0
  117. package/dist/stories/grist-modes.stories.js.map +1 -0
  118. package/dist/tsconfig.tsbuildinfo +1 -1
  119. package/package.json +30 -11
  120. package/src/configure/zero-config.ts +4 -1
  121. package/src/data-card/data-card-field.ts +5 -3
  122. package/src/data-card/data-card.ts +1 -0
  123. package/src/data-grid/data-grid-body.ts +96 -49
  124. package/src/data-grid/data-grid-field.ts +3 -2
  125. package/src/data-grid/data-grid-footer.ts +8 -9
  126. package/src/data-grid/data-grid-header.ts +38 -47
  127. package/src/data-grid/data-grid.ts +8 -6
  128. package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +11 -13
  129. package/src/data-grist.ts +179 -130
  130. package/src/data-list/record-partial.ts +1 -5
  131. package/src/data-manipulator.ts +12 -1
  132. package/src/data-provider.ts +13 -29
  133. package/src/data-report/data-report-body.ts +5 -5
  134. package/src/data-report/data-report-header.ts +5 -5
  135. package/src/editors/ox-grist-editor.ts +8 -5
  136. package/src/filters/filter-checkbox.ts +3 -3
  137. package/src/filters/filter-input-barcode.ts +33 -0
  138. package/src/filters/filter-input.ts +3 -3
  139. package/src/filters/filter-styles.ts +18 -23
  140. package/src/filters/filters-form.ts +5 -3
  141. package/src/filters/registry.ts +11 -8
  142. package/src/gutters/gutter-button.ts +5 -4
  143. package/src/gutters/gutter-dirty.ts +21 -3
  144. package/src/gutters/gutter-row-selector.ts +2 -1
  145. package/src/gutters/gutter-sequence.ts +18 -2
  146. package/src/record-view/event-handlers/record-view-body-click-handler.ts +2 -4
  147. package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +2 -2
  148. package/src/record-view/record-creator.ts +0 -2
  149. package/src/record-view/record-view-body.ts +0 -2
  150. package/src/record-view/record-view.ts +1 -7
  151. package/src/renderers/ox-grist-renderer-color.ts +3 -2
  152. package/src/renderers/ox-grist-renderer-json5.ts +3 -2
  153. package/src/renderers/ox-grist-renderer-link.ts +3 -2
  154. package/src/renderers/ox-grist-renderer-select.ts +2 -2
  155. package/src/renderers/ox-grist-renderer-text.ts +8 -2
  156. package/src/sorters/sorters-control.ts +6 -9
  157. package/src/types.ts +8 -4
  158. package/stories/barcode-input-filter.stories.ts +220 -0
  159. package/stories/default-filters.stories.ts +204 -0
  160. package/stories/empty-sorters.stories.ts +197 -0
  161. package/stories/explicit-fetch.stories.ts +205 -0
  162. package/stories/grist-modes.stories.ts +488 -0
  163. package/themes/grist-theme.css +1 -1
  164. package/dist/src/filters/filter-input copy.d.ts +0 -2
  165. package/dist/src/filters/filter-input copy.js.map +0 -1
  166. package/dist/src/filters/filter-mwc-checkbox.d.ts +0 -4
  167. package/dist/src/filters/filter-mwc-checkbox.js +0 -30
  168. package/dist/src/filters/filter-mwc-checkbox.js.map +0 -1
  169. package/dist/src/filters/filter-mwc-textfield.d.ts +0 -3
  170. package/dist/src/filters/filter-mwc-textfield.js +0 -27
  171. package/dist/src/filters/filter-mwc-textfield.js.map +0 -1
  172. package/dist/src/filters/grist-filter-registry.d.ts +0 -12
  173. package/dist/src/filters/grist-filter-registry.js +0 -47
  174. package/dist/src/filters/grist-filter-registry.js.map +0 -1
  175. package/dist/src/filters/ox-grist-filter-editor-checkbox.d.ts +0 -5
  176. package/dist/src/filters/ox-grist-filter-editor-checkbox.js +0 -27
  177. package/dist/src/filters/ox-grist-filter-editor-checkbox.js.map +0 -1
  178. package/dist/src/filters/ox-grist-filter-editor-input.d.ts +0 -4
  179. package/dist/src/filters/ox-grist-filter-editor-input.js +0 -54
  180. package/dist/src/filters/ox-grist-filter-editor-input.js.map +0 -1
  181. package/dist/src/filters/ox-grist-filter-editor-select.d.ts +0 -4
  182. package/dist/src/filters/ox-grist-filter-editor-select.js +0 -46
  183. package/dist/src/filters/ox-grist-filter-editor-select.js.map +0 -1
  184. package/dist/src/filters/ox-grist-filter-editor.d.ts +0 -16
  185. package/dist/src/filters/ox-grist-filter-editor.js +0 -122
  186. package/dist/src/filters/ox-grist-filter-editor.js.map +0 -1
  187. package/dist/stories/index.stories.js +0 -33
  188. package/dist/stories/index.stories.js.map +0 -1
  189. package/stories/index.stories.ts +0 -52
@@ -0,0 +1,205 @@
1
+ import '../src/index.js'
2
+ import '../src/filters/filters-form.js'
3
+ import '../src/sorters/sorters-control.js'
4
+ import '@operato/popup/ox-popup-list.js'
5
+ import '@material/mwc-icon'
6
+
7
+ import { html, TemplateResult } from 'lit'
8
+
9
+ import { FetchHandler } from '../src/types.js'
10
+
11
+ const fetchHandler: FetchHandler = async ({ page, limit }) => {
12
+ var total = 120993
13
+ var start = (page! - 1) * limit!
14
+
15
+ await new Promise(resolve => setTimeout(resolve, 500))
16
+
17
+ return {
18
+ total,
19
+ records: Array(limit! * page! > total ? total % limit! : limit)
20
+ .fill('')
21
+ .map((item, idx) => {
22
+ return {
23
+ id: String(idx),
24
+ name: idx % 2 ? `shnam-${start + idx + 1}` : `heartyoh-${start + idx + 1}`,
25
+ description: idx % 2 ? `hatiolabmanager${start + idx + 1}1234567890` : `hatiosea manager-${start + idx + 1}`,
26
+ createdAt: Date.now(),
27
+ updatedAt: Date.now()
28
+ }
29
+ })
30
+ }
31
+ }
32
+
33
+ const config = {
34
+ list: {
35
+ fields: ['name', 'description'],
36
+ details: ['updatedAt', 'createdAt']
37
+ },
38
+ columns: [
39
+ {
40
+ type: 'gutter',
41
+ gutterName: 'sequence'
42
+ },
43
+ {
44
+ type: 'string',
45
+ name: 'id',
46
+ hidden: true
47
+ },
48
+ {
49
+ type: 'string',
50
+ name: 'name',
51
+ label: true,
52
+ header: 'name',
53
+ filter: 'search',
54
+ sortable: true,
55
+ width: 120
56
+ },
57
+ {
58
+ type: 'string',
59
+ name: 'description',
60
+ header: 'description',
61
+ filter: 'search',
62
+ record: {
63
+ align: 'left'
64
+ },
65
+ width: 200
66
+ },
67
+ {
68
+ type: 'datetime',
69
+ name: 'updatedAt',
70
+ header: 'updated at',
71
+ width: 180
72
+ },
73
+ {
74
+ type: 'datetime',
75
+ name: 'createdAt',
76
+ header: 'created at',
77
+ width: 180
78
+ }
79
+ ],
80
+ rows: {},
81
+ sorters: [
82
+ {
83
+ name: 'name',
84
+ desc: true
85
+ }
86
+ ],
87
+ pagination: {
88
+ pages: [30, 50, 100, 200]
89
+ }
90
+ }
91
+
92
+ export default {
93
+ title: 'explicit-fetch attribute for ox-grist',
94
+ component: 'ox-grist',
95
+ argTypes: {
96
+ explicitFetch: { control: 'boolean' }
97
+ }
98
+ }
99
+
100
+ interface Story<T> {
101
+ (args: T): TemplateResult
102
+ args?: Partial<T>
103
+ argTypes?: Record<string, unknown>
104
+ }
105
+
106
+ interface ArgTypes {
107
+ explicitFetch: boolean
108
+ }
109
+
110
+ const Template: Story<ArgTypes> = ({ explicitFetch = false }: ArgTypes) => html` <link
111
+ href="https://fonts.googleapis.com/css?family=Material+Icons&display=block"
112
+ rel="stylesheet"
113
+ />
114
+ <link href="/themes/app-theme.css" rel="stylesheet" />
115
+ <link href="/themes/oops-theme.css" rel="stylesheet" />
116
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
117
+
118
+ <style>
119
+ [slot='headroom'] {
120
+ display: flex;
121
+ flex-direction: row;
122
+ align-items: center;
123
+ padding: var(--padding-default) var(--padding-wide);
124
+ border-top: 2px solid rgba(0, 0, 0, 0.2);
125
+ background-color: var(--theme-white-color);
126
+ box-shadow: var(--box-shadow);
127
+
128
+ --mdc-icon-size: 24px;
129
+ }
130
+ #sorters mwc-icon,
131
+ #modes mwc-icon {
132
+ --mdc-icon-size: 18px;
133
+ }
134
+ #sorters {
135
+ margin-left: auto;
136
+ margin-right: var(--margin-default);
137
+ padding-left: var(--padding-narrow);
138
+ border-bottom: var(--border-dark-color);
139
+ position: relative;
140
+ color: var(--secondary-color);
141
+ font-size: var(--fontsize-default);
142
+ user-select: none;
143
+ }
144
+
145
+ #sorters > * {
146
+ padding: var(--padding-narrow);
147
+ vertical-align: middle;
148
+ }
149
+
150
+ #filters {
151
+ display: flex;
152
+ justify-content: center;
153
+ align-items: center;
154
+ }
155
+
156
+ #filters * {
157
+ margin-right: var(--margin-default);
158
+ }
159
+
160
+ @media only screen and (max-width: 460px) {
161
+ #filters {
162
+ flex-direction: column;
163
+ }
164
+
165
+ #modes {
166
+ display: none;
167
+ }
168
+ }
169
+ </style>
170
+
171
+ <ox-grist
172
+ .config=${config}
173
+ mode="GRID"
174
+ ?explicit-fetch=${explicitFetch}
175
+ .fetchHandler=${fetchHandler}
176
+ @filters-change=${(e: Event) => console.log('filters', (e.target as any).filters)}
177
+ >
178
+ <div slot="headroom">
179
+ <div id="filters">
180
+ <ox-filters-form></ox-filters-form>
181
+ </div>
182
+
183
+ <div id="sorters">
184
+ Sort
185
+ <mwc-icon
186
+ @click=${(e: Event) => {
187
+ const target = e.currentTarget as HTMLElement
188
+ ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
189
+ right: 0,
190
+ top: target.offsetTop + target.offsetHeight
191
+ })
192
+ }}
193
+ >expand_more</mwc-icon
194
+ >
195
+ <ox-popup id="sorter-control">
196
+ <ox-sorters-control> </ox-sorters-control>
197
+ </ox-popup>
198
+ </div>
199
+ </div>
200
+ </ox-grist>`
201
+
202
+ export const Regular = Template.bind({})
203
+ Regular.args = {
204
+ explicitFetch: true
205
+ }
@@ -0,0 +1,488 @@
1
+ import '../src/index.js'
2
+ import '../src/filters/filters-form.js'
3
+ import '../src/sorters/sorters-control.js'
4
+ import '../src/record-view/record-creator.js'
5
+ import '@operato/popup/ox-popup-list.js'
6
+ import '@material/mwc-icon'
7
+
8
+ import { html, TemplateResult } from 'lit'
9
+
10
+ import {
11
+ ColumnConfig,
12
+ FetchHandler,
13
+ GristClassifier,
14
+ GristEventHandlerSet,
15
+ GristRecord,
16
+ ValidationCallback
17
+ } from '../src/types.js'
18
+
19
+ const fetchHandler: FetchHandler = async ({ page, limit }) => {
20
+ var total = 120993
21
+ var start = (page! - 1) * limit!
22
+
23
+ await new Promise(resolve => setTimeout(resolve, 500))
24
+
25
+ return {
26
+ total,
27
+ records: Array(limit! * page! > total ? total % limit! : limit)
28
+ .fill('')
29
+ .map((item, idx) => {
30
+ return {
31
+ id: String(idx),
32
+ name: idx % 2 ? `shnam-${start + idx + 1}` : `heartyoh-${start + idx + 1}`,
33
+ description: idx % 2 ? `hatiolabmanager${start + idx + 1}1234567890` : `hatiosea manager-${start + idx + 1}`,
34
+ email: idx % 2 ? `shnam-${start + idx + 1}@gmail.com` : `heartyoh-${start + idx + 1}@gmail.com`,
35
+ active: Math.round(Math.random() * 2) % 2 ? true : false,
36
+ barcode: idx % 2 ? `1234567890${start + idx + 1}` : `0987654321${start + idx + 1}`,
37
+ company:
38
+ idx % 2
39
+ ? {
40
+ id: '2',
41
+ name: 'HatioLAB',
42
+ description: `경기도 성남시-${start + idx + 1}`
43
+ }
44
+ : {
45
+ id: '3',
46
+ name: 'HatioSEA',
47
+ description: `말레이시아 세티아알람-${start + idx + 1}`
48
+ },
49
+ thumbnail:
50
+ idx % 4 === 0
51
+ ? '' /* no source */
52
+ : idx % 4 === 1
53
+ ? `http://www.hatiolab.com/assets/img/operato-biz3.png`
54
+ : idx % 4 === 2
55
+ ? `http://www.hatiolab.com/assets/img/thingsboard-30.png`
56
+ : `http://www.hatiolab.com/wrong-url.png` /* wrong source */,
57
+ role: ['admin', 'worker', 'tester'][idx % 3],
58
+ color: idx % 2 ? `#87f018` : `#180f87`,
59
+ rate: Math.round(Math.random() * 100),
60
+ dynamicType: ['text', 'email', 'checkbox', 'color', 'progress', 'barcode'][idx % 5],
61
+ dynamicValue: ['abcdefghijkl', 'heartyoh@hatiolab.com', 'true', 'orange', '50', '1234567890'][idx % 5],
62
+ homepage:
63
+ idx % 2 ? `http://hatiolab.com/${start + idx + 1}` : `http://deadpool.hatiolab.com/${start + idx + 1}`,
64
+ json5: {
65
+ abc: 'abc',
66
+ value: 123
67
+ },
68
+ createdAt: Date.now(),
69
+ updatedAt: Date.now()
70
+ }
71
+ })
72
+ }
73
+ }
74
+
75
+ const config = {
76
+ list: {
77
+ thumbnail: 'thumbnail',
78
+ fields: ['name', 'description'],
79
+ details: ['role', 'email']
80
+ },
81
+ columns: [
82
+ {
83
+ type: 'gutter',
84
+ gutterName: 'dirty'
85
+ },
86
+ {
87
+ type: 'gutter',
88
+ gutterName: 'sequence'
89
+ },
90
+ {
91
+ type: 'gutter',
92
+ gutterName: 'row-selector',
93
+ multiple: true
94
+ },
95
+ {
96
+ type: 'gutter',
97
+ gutterName: 'button',
98
+ icon: 'edit',
99
+ title: 'edit',
100
+ handlers: {
101
+ click: function () {
102
+ console.log('clicked')
103
+ }
104
+ }
105
+ },
106
+ {
107
+ type: 'gutter',
108
+ gutterName: 'button',
109
+ icon: 'add',
110
+ title: 'add',
111
+ handlers: {
112
+ click: 'record-copy'
113
+ }
114
+ },
115
+ {
116
+ type: 'gutter',
117
+ gutterName: 'button',
118
+ icon: 'arrow_downward',
119
+ title: 'download',
120
+ handlers: {
121
+ click: 'move-down'
122
+ }
123
+ },
124
+ {
125
+ type: 'string',
126
+ name: 'id',
127
+ hidden: true
128
+ },
129
+ {
130
+ type: 'link',
131
+ name: 'name',
132
+ label: true,
133
+ header: 'name',
134
+ record: {
135
+ editable: true,
136
+ options: {
137
+ // href: 'http://hatiolab.com',
138
+ href: function (column: ColumnConfig, record: GristRecord, rowIndex: number) {
139
+ return record['homepage']
140
+ },
141
+ target: '_blank'
142
+ }
143
+ },
144
+ filter: 'search',
145
+ sortable: true,
146
+ width: 120
147
+ },
148
+ {
149
+ type: 'string',
150
+ name: 'description',
151
+ header: 'description',
152
+ filter: 'search',
153
+ record: {
154
+ editable: true,
155
+ align: 'left'
156
+ },
157
+ width: 200,
158
+ handlers: {
159
+ click: (columns, data, column, record, rowIndex, target) => {
160
+ alert(`${column!.name} ${record![column!.name]}, row : ${rowIndex}`)
161
+ }
162
+ } as GristEventHandlerSet
163
+ },
164
+ {
165
+ type: 'email',
166
+ name: 'email',
167
+ label: true,
168
+ header: 'email',
169
+ record: {
170
+ editable: true
171
+ },
172
+ filter: 'search',
173
+ sortable: true,
174
+ width: 130,
175
+ validation: function (after, before, record, column) {
176
+ if (after.indexOf('@') == -1) {
177
+ document.dispatchEvent(
178
+ new CustomEvent('notify', {
179
+ detail: {
180
+ type: 'error',
181
+ message: `invalid value - ${after}`
182
+ }
183
+ })
184
+ )
185
+ return false
186
+ }
187
+ return true
188
+ } as ValidationCallback
189
+ },
190
+ {
191
+ type: 'boolean',
192
+ name: 'active',
193
+ header: 'active',
194
+ record: {
195
+ editable: true
196
+ },
197
+ filter: true,
198
+ handlers: {
199
+ dblclick: () => {
200
+ const grist = document.querySelector('ox-grist') as any
201
+ console.log(grist!.dirtyRecords)
202
+ }
203
+ },
204
+ sortable: true,
205
+ width: 60
206
+ },
207
+ {
208
+ type: 'select',
209
+ name: 'role',
210
+ label: true,
211
+ header: 'role',
212
+ record: {
213
+ options: ['', 'admin', 'worker', 'tester'],
214
+ editable: true
215
+ },
216
+ filter: true,
217
+ sortable: true,
218
+ width: 120
219
+ },
220
+ {
221
+ type: 'color',
222
+ name: 'color',
223
+ header: 'color',
224
+ record: {
225
+ editable: true
226
+ },
227
+ sortable: true,
228
+ width: 50
229
+ },
230
+ {
231
+ type: 'float',
232
+ name: 'rate',
233
+ header: 'rate',
234
+ record: {
235
+ align: 'right',
236
+ editable: true
237
+ },
238
+ filter: 'between',
239
+ sortable: true,
240
+ width: 50
241
+ },
242
+ {
243
+ type: 'json5',
244
+ name: 'json5',
245
+ header: 'JSON5',
246
+ width: 200
247
+ },
248
+ {
249
+ type: 'image',
250
+ name: 'thumbnail',
251
+ header: 'thumbnail',
252
+ record: {
253
+ editable: true
254
+ }
255
+ },
256
+ {
257
+ type: 'datetime',
258
+ name: 'updatedAt',
259
+ header: 'updated at',
260
+ record: {
261
+ editable: true
262
+ },
263
+ filter: 'between',
264
+ sortable: true,
265
+ width: 180
266
+ },
267
+ {
268
+ type: 'datetime',
269
+ name: 'createdAt',
270
+ header: 'created at',
271
+ record: {
272
+ editable: false
273
+ },
274
+ sortable: true,
275
+ width: 180
276
+ }
277
+ ],
278
+ rows: {
279
+ selectable: {
280
+ multiple: true
281
+ },
282
+ handlers: {
283
+ click: 'select-row-toggle'
284
+ },
285
+ classifier: function (record, rowIndex) {
286
+ const rate = record['rate']
287
+ const emphasized =
288
+ rate < 10 ? ['black', 'white'] : rate < 25 ? ['yellow', 'blue'] : rate < 40 ? ['cyan', 'red'] : undefined
289
+ return {
290
+ emphasized
291
+ }
292
+ } as GristClassifier
293
+ },
294
+ sorters: [
295
+ {
296
+ name: 'name',
297
+ desc: true
298
+ },
299
+ {
300
+ name: 'email'
301
+ }
302
+ ],
303
+ pagination: {
304
+ pages: [20, 30, 50, 100, 200]
305
+ }
306
+ }
307
+
308
+ export default {
309
+ title: '3 modes in ox-grist',
310
+ component: 'ox-grist',
311
+ argTypes: {
312
+ config: { control: 'object' },
313
+ mode: { control: 'select', options: ['GRID', 'LIST', 'CARD'] },
314
+ urlParamsSensitive: { control: 'boolean' }
315
+ }
316
+ }
317
+
318
+ interface Story<T> {
319
+ (args: T): TemplateResult
320
+ args?: Partial<T>
321
+ argTypes?: Record<string, unknown>
322
+ }
323
+
324
+ interface ArgTypes {
325
+ config: object
326
+ mode: string
327
+ urlParamsSensitive: boolean
328
+ fetchHandler: object
329
+ }
330
+
331
+ const Template: Story<ArgTypes> = ({
332
+ config,
333
+ mode = 'GRID',
334
+ urlParamsSensitive = false,
335
+ fetchHandler
336
+ }: ArgTypes) => html` <link
337
+ href="https://fonts.googleapis.com/css?family=Material+Icons&display=block"
338
+ rel="stylesheet"
339
+ />
340
+ <link href="/themes/app-theme.css" rel="stylesheet" />
341
+ <link href="/themes/oops-theme.css" rel="stylesheet" />
342
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
343
+
344
+ <style>
345
+ [slot='headroom'] {
346
+ display: flex;
347
+ flex-direction: row;
348
+ align-items: center;
349
+ padding: var(--padding-default) var(--padding-wide);
350
+ border-top: 2px solid rgba(0, 0, 0, 0.2);
351
+ background-color: var(--theme-white-color);
352
+ box-shadow: var(--box-shadow);
353
+
354
+ --mdc-icon-size: 24px;
355
+ }
356
+ #sorters mwc-icon,
357
+ #modes mwc-icon {
358
+ --mdc-icon-size: 18px;
359
+ }
360
+ #sorters {
361
+ margin-left: auto;
362
+ margin-right: var(--margin-default);
363
+ padding-left: var(--padding-narrow);
364
+ border-bottom: var(--border-dark-color);
365
+ position: relative;
366
+ color: var(--secondary-color);
367
+ font-size: var(--fontsize-default);
368
+ user-select: none;
369
+ }
370
+
371
+ #sorters > * {
372
+ padding: var(--padding-narrow);
373
+ vertical-align: middle;
374
+ }
375
+
376
+ #modes > * {
377
+ padding: var(--padding-narrow);
378
+ opacity: 0.5;
379
+ color: var(--primary-text-color);
380
+ cursor: pointer;
381
+ }
382
+
383
+ #modes > mwc-icon[active] {
384
+ border-radius: 9px;
385
+ background-color: rgba(var(--primary-color-rgb), 0.05);
386
+ opacity: 1;
387
+ color: var(--secondary-text-color);
388
+ cursor: default;
389
+ }
390
+
391
+ #modes > mwc-icon:hover {
392
+ opacity: 1;
393
+ color: var(--secondary-text-color);
394
+ }
395
+
396
+ #add {
397
+ width: 50px;
398
+ text-align: right;
399
+ }
400
+
401
+ #add button {
402
+ background-color: var(--status-success-color);
403
+ border: 0;
404
+ border-radius: 50%;
405
+ padding: 5px;
406
+ width: 36px;
407
+ height: 36px;
408
+ cursor: pointer;
409
+ }
410
+
411
+ #add button:hover {
412
+ background-color: var(--focus-background-color);
413
+ box-shadow: var(--box-shadow);
414
+ }
415
+
416
+ #add button mwc-icon {
417
+ font-size: 2em;
418
+ color: var(--theme-white-color);
419
+ }
420
+
421
+ #filters {
422
+ display: flex;
423
+ justify-content: center;
424
+ align-items: center;
425
+ }
426
+
427
+ #filters * {
428
+ margin-right: var(--margin-default);
429
+ }
430
+
431
+ @media only screen and (max-width: 460px) {
432
+ #filters {
433
+ flex-direction: column;
434
+ }
435
+
436
+ #modes {
437
+ display: none;
438
+ }
439
+ }
440
+ </style>
441
+
442
+ <ox-grist
443
+ .config=${config}
444
+ .mode=${mode}
445
+ .fetchHandler=${fetchHandler}
446
+ ?url-params-sensitive=${urlParamsSensitive}
447
+ @filters-change=${(e: Event) => console.log('filters', (e.target as any).filters)}
448
+ >
449
+ <div slot="headroom">
450
+ <div id="filters">
451
+ <ox-filters-form autofocus></ox-filters-form>
452
+ </div>
453
+
454
+ <div id="sorters">
455
+ Sort
456
+ <mwc-icon
457
+ @click=${(e: Event) => {
458
+ const target = e.currentTarget as HTMLElement
459
+ ;(target.closest('#sorters')!.querySelector('#sorter-control') as any).open({
460
+ right: 0,
461
+ top: target.offsetTop + target.offsetHeight
462
+ })
463
+ }}
464
+ >expand_more</mwc-icon
465
+ >
466
+ <ox-popup id="sorter-control">
467
+ <ox-sorters-control> </ox-sorters-control>
468
+ </ox-popup>
469
+ </div>
470
+
471
+ <div id="modes">
472
+ <mwc-icon @click=${() => (mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
473
+ <mwc-icon @click=${() => (mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
474
+ <mwc-icon @click=${() => (mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
475
+ </div>
476
+
477
+ <ox-record-creator id="add" light-popup>
478
+ <button><mwc-icon>add</mwc-icon></button>
479
+ </ox-record-creator>
480
+ </div>
481
+ </ox-grist>`
482
+
483
+ export const Regular = Template.bind({})
484
+ Regular.args = {
485
+ config,
486
+ fetchHandler,
487
+ mode: 'GRID'
488
+ }
@@ -38,7 +38,7 @@ body {
38
38
 
39
39
  --grid-record-background-color: var(--theme-white-color);
40
40
  --grid-record-odd-background-color: rgba(255, 255, 255, 0.4);
41
- --grid-record-padding: var(--padding-default) 0 var(--padding-default) var(--padding-default);
41
+ --grid-record-padding: var(--padding-default);
42
42
  --grid-record-color: var(--secondary-color);
43
43
  --grid-record-color-hover: var(--primary-color);
44
44
  --grid-record-wide-fontsize: var(--fontsize-small);
@@ -1,2 +0,0 @@
1
- import { FilterSelectRenderer } from '../types';
2
- export declare const FilterInput: FilterSelectRenderer;
@@ -1 +0,0 @@
1
- {"version":3,"file":"filter-input copy.js","sourceRoot":"","sources":["../../../src/filters/filter-input copy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAE/B,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IACxE,MAAM,MAAM,GAAG,MAAM,CAAC,MAA4B,CAAA;IAClD,MAAM,IAAI,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,KAAI,MAAM,CAAC,IAAI,CAAA;IAExC,OAAO,IAAI,CAAA;;aAEA,IAAI;aACJ,MAAM,CAAC,IAAI;eACT,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;gBAC/B,CAAC,CAAc,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,MAA0B,CAAA;QAC1C,KAAK,CAAC,aAAa,CACjB,IAAI,WAAW,CAAC,eAAe,EAAE;YAC/B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB;SACF,CAAC,CACH,CAAA;IACH,CAAC;;GAEJ,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { FilterConfigObject, FilterSelectRenderer } from '../types'\n\nimport { html } from 'lit-html'\n\nexport const FilterInput: FilterSelectRenderer = (column, value, owner) => {\n const filter = column.filter as FilterConfigObject\n const type = filter?.type || column.type\n\n return html`\n <input\n type=${type}\n name=${column.name}\n .value=${value === undefined ? '' : value}\n @change=${(e: CustomEvent) => {\n const input = e.target as HTMLInputElement\n input.dispatchEvent(\n new CustomEvent('filter-change', {\n bubbles: true,\n composed: true,\n detail: {\n name: column.name,\n operator: filter.operator,\n value: input.value\n }\n })\n )\n }}\n />\n `\n}\n"]}
@@ -1,4 +0,0 @@
1
- import '@material/mwc-checkbox';
2
- import '@material/mwc-formfield';
3
- import { FilterSelectRenderer } from '../types';
4
- export declare const FilterMwcCheckbox: FilterSelectRenderer;