@operato/data-grist 2.0.0-alpha.102 → 2.0.0-alpha.104

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 (40) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/src/editors/ox-grist-editor-select.js +37 -25
  3. package/dist/src/editors/ox-grist-editor-select.js.map +1 -1
  4. package/dist/src/filters/filter-select.js +30 -16
  5. package/dist/src/filters/filter-select.js.map +1 -1
  6. package/dist/src/filters/filters-form.d.ts +6 -2
  7. package/dist/src/filters/filters-form.js +74 -21
  8. package/dist/src/filters/filters-form.js.map +1 -1
  9. package/dist/src/renderers/ox-grist-renderer-select.js +34 -4
  10. package/dist/src/renderers/ox-grist-renderer-select.js.map +1 -1
  11. package/dist/src/types.d.ts +14 -1
  12. package/dist/src/types.js.map +1 -1
  13. package/dist/stories/bounded-select-filters.stories.d.ts +25 -0
  14. package/dist/stories/bounded-select-filters.stories.js +264 -0
  15. package/dist/stories/bounded-select-filters.stories.js.map +1 -0
  16. package/dist/stories/bounded-select-record.stories.d.ts +25 -0
  17. package/dist/stories/bounded-select-record.stories.js +267 -0
  18. package/dist/stories/bounded-select-record.stories.js.map +1 -0
  19. package/dist/stories/default-filters.stories.js +43 -0
  20. package/dist/stories/default-filters.stories.js.map +1 -1
  21. package/dist/tsconfig.tsbuildinfo +1 -1
  22. package/docs/default-value/value-generator/date-generator.md +29 -0
  23. package/docs/default-value/value-generator/hour-time-generator.md +33 -0
  24. package/docs/default-value/value-generator/minute-time-generator.md +33 -0
  25. package/docs/default-value/value-generator/month-date-generator.md +2 -0
  26. package/docs/default-value/value-generator/now-generator.md +29 -0
  27. package/docs/default-value/value-generator/time-generator.md +31 -0
  28. package/docs/default-value/value-generator/today-generator.md +29 -0
  29. package/docs/default-value/value-generator/week-date-generator.md +31 -0
  30. package/docs/default-value/value-generator/year-date-generator.md +31 -0
  31. package/package.json +3 -3
  32. package/src/editors/ox-grist-editor-select.ts +41 -28
  33. package/src/filters/filter-select.ts +41 -28
  34. package/src/filters/filters-form.ts +74 -10
  35. package/src/renderers/ox-grist-renderer-select.ts +41 -6
  36. package/src/types.ts +19 -1
  37. package/stories/bounded-select-filters.stories.ts +313 -0
  38. package/stories/bounded-select-record.stories.ts +316 -0
  39. package/stories/default-filters.stories.ts +43 -0
  40. package/yarn-error.log +0 -16971
@@ -0,0 +1,316 @@
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/web/icon/icon.js'
6
+
7
+ import { html, TemplateResult } from 'lit'
8
+ import { sleep } from '@operato/utils'
9
+
10
+ import { ColumnConfig, FetchHandler, FieldEditor, GristRecord, SelectOption } from '../src/types.js'
11
+
12
+ import { CommonHeaderStyles, CommonGristStyles } from '@operato/styles'
13
+ import { DataGridField } from '../src/data-grid/data-grid-field.js'
14
+
15
+ const fetchHandler: FetchHandler = async ({ sorters = [], filters, page, limit }) => {
16
+ var total = 120993
17
+ var start = (page! - 1) * limit!
18
+
19
+ await new Promise(resolve => setTimeout(resolve, 500))
20
+
21
+ return {
22
+ total,
23
+ records: Array(limit! * page! > total ? total % limit! : limit)
24
+ .fill('')
25
+ .map((item, idx) => {
26
+ const warehouse: string = idx % 2 ? '01' : '02'
27
+ const zone: string = idx % 2 ? 'Z001' : 'Z002'
28
+
29
+ return {
30
+ id: String(idx),
31
+ name: idx % 2 ? `shnam-${start + idx + 1}` : `heartyoh-${start + idx + 1}`,
32
+ description: idx % 2 ? `hatiolabmanager${start + idx + 1}1234567890` : `hatiosea manager-${start + idx + 1}`,
33
+ warehouse,
34
+ zone,
35
+ location: `L${warehouse}-${zone}-0${(idx % 5) + 1}`,
36
+ createdAt: Date.now(),
37
+ updatedAt: Date.now()
38
+ }
39
+ })
40
+ }
41
+ }
42
+
43
+ function buildConfig({ headerFilter }: { headerFilter: boolean }) {
44
+ return {
45
+ list: {
46
+ fields: ['name', 'description'],
47
+ details: ['updatedAt', 'createdAt']
48
+ },
49
+ columns: [
50
+ {
51
+ type: 'gutter',
52
+ gutterName: 'sequence'
53
+ },
54
+ {
55
+ type: 'string',
56
+ name: 'id',
57
+ hidden: true
58
+ },
59
+ {
60
+ type: 'string',
61
+ name: 'name',
62
+ label: true,
63
+ header: 'name',
64
+ filter: {
65
+ operator: 'eq',
66
+ value: 'shnam'
67
+ },
68
+ sortable: true,
69
+ width: 120
70
+ },
71
+ {
72
+ type: 'string',
73
+ name: 'description',
74
+ header: 'description',
75
+ record: {
76
+ align: 'left'
77
+ },
78
+ width: 200
79
+ },
80
+ {
81
+ type: 'select',
82
+ name: 'warehouse',
83
+ header: 'warehouse',
84
+ filter: {
85
+ operator: 'eq'
86
+ },
87
+ record: {
88
+ align: 'left',
89
+ editable: true,
90
+ options: async (
91
+ value: any,
92
+ column: ColumnConfig,
93
+ record: GristRecord,
94
+ rowIndex: number,
95
+ field: DataGridField
96
+ ): Promise<SelectOption[]> => {
97
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
98
+ return [
99
+ {
100
+ display: '',
101
+ value: ''
102
+ }
103
+ ].concat(
104
+ WAREHOUSE.map(w => {
105
+ return {
106
+ display: w.name,
107
+ value: w.id
108
+ }
109
+ })
110
+ )
111
+ }
112
+ },
113
+ width: 200
114
+ },
115
+ {
116
+ type: 'select',
117
+ name: 'zone',
118
+ header: 'zone',
119
+ filter: {
120
+ operator: 'eq',
121
+ boundTo: ['warehouse'],
122
+ onchange: () => {
123
+ console.log('warehousde filter value changed.')
124
+ }
125
+ },
126
+ record: {
127
+ align: 'left',
128
+ editable: true,
129
+ options: async (
130
+ value: any,
131
+ column: ColumnConfig,
132
+ record: GristRecord,
133
+ rowIndex: number,
134
+ field: DataGridField
135
+ ): Promise<SelectOption[]> => {
136
+ console.log('arguments', arguments)
137
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
138
+ const warehouse = record.warehouse
139
+ console.log('warehouse', warehouse)
140
+
141
+ const targetWH = warehouse && WAREHOUSE.find(w => w.id == warehouse)
142
+ const zones = targetWH
143
+ ? targetWH.zones
144
+ : WAREHOUSE.reduce((sum, warehouse) => {
145
+ sum = sum.concat(warehouse.zones)
146
+ return sum
147
+ }, [] as any[])
148
+
149
+ return [
150
+ {
151
+ display: '',
152
+ value: ''
153
+ }
154
+ ].concat(
155
+ zones.map((z: any) => {
156
+ return {
157
+ display: z.name,
158
+ value: z.id
159
+ }
160
+ })
161
+ )
162
+ }
163
+ },
164
+ width: 200
165
+ },
166
+ {
167
+ type: 'select',
168
+ name: 'location',
169
+ header: 'location',
170
+ filter: {
171
+ operator: 'eq',
172
+ boundTo: ['warehouse', 'zone']
173
+ },
174
+ record: {
175
+ align: 'left',
176
+ editable: true,
177
+ options: async (
178
+ value: any,
179
+ column: ColumnConfig,
180
+ record: GristRecord,
181
+ rowIndex: number,
182
+ field: DataGridField
183
+ ): Promise<SelectOption[]> => {
184
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
185
+ const warehouse = record.warehouse
186
+ const zone = record.zone
187
+ console.log('warehouse, zone', warehouse, zone)
188
+
189
+ const targetWH = (warehouse && WAREHOUSE.find(w => w.id == warehouse)) || null
190
+ const targetZone = zone && targetWH?.zones.find((z: any) => z.id == zone)
191
+ return targetZone ? ['', ...targetZone.locations] : []
192
+ }
193
+ },
194
+ width: 200
195
+ },
196
+ {
197
+ type: 'datetime',
198
+ name: 'updatedAt',
199
+ header: 'updated at',
200
+ width: 180
201
+ },
202
+ {
203
+ type: 'datetime',
204
+ name: 'createdAt',
205
+ header: 'created at',
206
+ width: 180
207
+ }
208
+ ],
209
+ rows: {},
210
+ sorters: [
211
+ {
212
+ name: 'name',
213
+ desc: true
214
+ }
215
+ ],
216
+ filters: {
217
+ header: headerFilter
218
+ },
219
+ pagination: {
220
+ pages: [30, 50, 100, 200]
221
+ }
222
+ }
223
+ }
224
+
225
+ const WAREHOUSE = [
226
+ {
227
+ id: '01',
228
+ name: '제 1 창고',
229
+ zones: [
230
+ {
231
+ id: 'Z001',
232
+ name: 'Zone 01-001',
233
+ locations: ['L01-001-01', 'L01-001-02', 'L01-001-03', 'L01-001-04', 'L01-001-05']
234
+ },
235
+ {
236
+ id: 'Z002',
237
+ name: 'Zone 01-002',
238
+ locations: ['L01-002-01', 'L01-002-02', 'L01-002-03', 'L01-002-04', 'L01-002-05']
239
+ }
240
+ ]
241
+ },
242
+ {
243
+ id: '02',
244
+ name: '제 2 창고',
245
+ zones: [
246
+ {
247
+ id: 'Z001',
248
+ name: 'Zone 02-001',
249
+ locations: ['L02-001-01', 'L02-001-02', 'L02-001-03', 'L02-001-04', 'L02-001-05']
250
+ },
251
+ {
252
+ id: 'Z002',
253
+ name: 'Zone 02-002',
254
+ locations: ['L02-002-01', 'L02-002-02', 'L02-002-03', 'L02-002-04', 'L02-002-05']
255
+ }
256
+ ]
257
+ }
258
+ ]
259
+
260
+ export default {
261
+ title: 'bounded select record for ox-grist',
262
+ component: 'ox-grist',
263
+ argTypes: {
264
+ headerFilter: { control: 'boolean' }
265
+ }
266
+ }
267
+
268
+ interface Story<T> {
269
+ (args: T): TemplateResult
270
+ args?: Partial<T>
271
+ argTypes?: Record<string, unknown>
272
+ }
273
+
274
+ interface ArgTypes {
275
+ headerFilter: boolean
276
+ }
277
+
278
+ const Template: Story<ArgTypes> = ({ headerFilter }: ArgTypes) =>
279
+ html` <link
280
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
281
+ rel="stylesheet"
282
+ />
283
+ <link
284
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL@20..48,100..700,0..1"
285
+ rel="stylesheet"
286
+ />
287
+ <link
288
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL@20..48,100..700,0..1"
289
+ rel="stylesheet"
290
+ />
291
+ <link href="/themes/app-theme.css" rel="stylesheet" />
292
+ <link href="/themes/oops-theme.css" rel="stylesheet" />
293
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
294
+
295
+ <style>
296
+ ${CommonGristStyles.cssText}
297
+ ${CommonHeaderStyles.cssText}
298
+ </style>
299
+
300
+ <ox-grist
301
+ .config=${buildConfig({ headerFilter })}
302
+ mode="GRID"
303
+ .fetchHandler=${fetchHandler}
304
+ @filters-change=${(e: Event) => console.log('filters', (e.target as any).filters)}
305
+ >
306
+ <div slot="headroom">
307
+ <div id="filters">
308
+ <ox-filters-form></ox-filters-form>
309
+ </div>
310
+ </div>
311
+ </ox-grist>`
312
+
313
+ export const Regular = Template.bind({})
314
+ Regular.args = {
315
+ headerFilter: true
316
+ }
@@ -25,6 +25,7 @@ const fetchHandler: FetchHandler = async ({ sorters = [], filters, page, limit }
25
25
  id: String(idx),
26
26
  name: idx % 2 ? `shnam-${start + idx + 1}` : `heartyoh-${start + idx + 1}`,
27
27
  description: idx % 2 ? `hatiolabmanager${start + idx + 1}1234567890` : `hatiosea manager-${start + idx + 1}`,
28
+ due: idx % 2 ? '2024-01-01' : '2024-02-01',
28
29
  createdAt: Date.now(),
29
30
  updatedAt: Date.now()
30
31
  }
@@ -73,10 +74,52 @@ function buildConfig({ headerFilter }: { headerFilter: boolean }) {
73
74
  },
74
75
  width: 200
75
76
  },
77
+ {
78
+ type: 'date',
79
+ name: 'due',
80
+ header: 'due',
81
+ filter: {
82
+ operator: 'between',
83
+ value: [
84
+ {
85
+ name: 'today',
86
+ params: {
87
+ relativeDays: -2,
88
+ timeZone: 'Asia/Seoul',
89
+ format: 'YYYY-MM-DD'
90
+ }
91
+ },
92
+ {
93
+ name: 'today',
94
+ params: {
95
+ relativeDays: 1,
96
+ timeZone: 'Asia/Seoul',
97
+ locale: 'en-CA' /* 'YYYY-MM-DD' format */,
98
+ format: {
99
+ year: 'numeric',
100
+ month: '2-digit',
101
+ day: '2-digit'
102
+ }
103
+ }
104
+ }
105
+ ]
106
+ },
107
+ record: {
108
+ align: 'left'
109
+ },
110
+ width: 120
111
+ },
76
112
  {
77
113
  type: 'datetime',
78
114
  name: 'updatedAt',
79
115
  header: 'updated at',
116
+ filter: {
117
+ operator: 'between',
118
+ value: [
119
+ { name: 'week', params: { relativeWeeks: -1 } },
120
+ { name: 'today', params: { relativeDays: +1 } }
121
+ ]
122
+ },
80
123
  width: 180
81
124
  },
82
125
  {