@operato/form 2.0.0-alpha.94 → 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 (97) hide show
  1. package/CHANGELOG.md +272 -0
  2. package/dist/src/components/ox-custom-input.js +5 -5
  3. package/dist/src/components/ox-custom-input.js.map +1 -1
  4. package/dist/src/components/ox-custom-select.js +2 -1
  5. package/dist/src/components/ox-custom-select.js.map +1 -1
  6. package/dist/src/components/ox-file-uploader.js +1 -1
  7. package/dist/src/components/ox-file-uploader.js.map +1 -1
  8. package/dist/src/components/ox-search-form.d.ts +12 -23
  9. package/dist/src/components/ox-search-form.js +227 -91
  10. package/dist/src/components/ox-search-form.js.map +1 -1
  11. package/dist/src/filters/filter-checkbox.js +2 -1
  12. package/dist/src/filters/filter-checkbox.js.map +1 -1
  13. package/dist/src/filters/filter-input-barcode.js +5 -3
  14. package/dist/src/filters/filter-input-barcode.js.map +1 -1
  15. package/dist/src/filters/filter-input.js +2 -1
  16. package/dist/src/filters/filter-input.js.map +1 -1
  17. package/dist/src/filters/filter-range-date.js +3 -1
  18. package/dist/src/filters/filter-range-date.js.map +1 -1
  19. package/dist/src/filters/filter-range-number.js +3 -1
  20. package/dist/src/filters/filter-range-number.js.map +1 -1
  21. package/dist/src/filters/filter-select.js +23 -11
  22. package/dist/src/filters/filter-select.js.map +1 -1
  23. package/dist/src/filters/filter-styles.js +56 -24
  24. package/dist/src/filters/filter-styles.js.map +1 -1
  25. package/dist/src/filters/ox-filter-personalizer.d.ts +8 -0
  26. package/dist/src/filters/ox-filter-personalizer.js +175 -0
  27. package/dist/src/filters/ox-filter-personalizer.js.map +1 -0
  28. package/dist/src/filters/ox-filters-form-base.d.ts +13 -3
  29. package/dist/src/filters/ox-filters-form-base.js +196 -60
  30. package/dist/src/filters/ox-filters-form-base.js.map +1 -1
  31. package/dist/src/styles/multi-column-form-styles.js +6 -6
  32. package/dist/src/styles/multi-column-form-styles.js.map +1 -1
  33. package/dist/src/styles/search-form-styles.js +23 -18
  34. package/dist/src/styles/search-form-styles.js.map +1 -1
  35. package/dist/src/styles/single-column-form-styles.js +5 -5
  36. package/dist/src/styles/single-column-form-styles.js.map +1 -1
  37. package/dist/src/types.d.ts +42 -2
  38. package/dist/src/types.js.map +1 -1
  39. package/dist/stories/ox-filters-form-barcode.stories.d.ts +5 -0
  40. package/dist/stories/ox-filters-form-barcode.stories.js +51 -12
  41. package/dist/stories/ox-filters-form-barcode.stories.js.map +1 -1
  42. package/dist/stories/ox-filters-form-base-bounded.stories.d.ts +35 -0
  43. package/dist/stories/ox-filters-form-base-bounded.stories.js +187 -0
  44. package/dist/stories/ox-filters-form-base-bounded.stories.js.map +1 -0
  45. package/dist/stories/ox-filters-form-base-change-handler.stories.d.ts +35 -0
  46. package/dist/stories/ox-filters-form-base-change-handler.stories.js +199 -0
  47. package/dist/stories/ox-filters-form-base-change-handler.stories.js.map +1 -0
  48. package/dist/stories/ox-filters-form-base-page-preference.stories.d.ts +31 -0
  49. package/dist/stories/ox-filters-form-base-page-preference.stories.js +173 -0
  50. package/dist/stories/ox-filters-form-base-page-preference.stories.js.map +1 -0
  51. package/dist/stories/ox-filters-form-base.stories.d.ts +5 -0
  52. package/dist/stories/ox-filters-form-base.stories.js +57 -27
  53. package/dist/stories/ox-filters-form-base.stories.js.map +1 -1
  54. package/dist/stories/ox-search-form-change-handler.stories.d.ts +34 -0
  55. package/dist/stories/ox-search-form-change-handler.stories.js +227 -0
  56. package/dist/stories/ox-search-form-change-handler.stories.js.map +1 -0
  57. package/dist/stories/ox-search-form.stories.d.ts +45 -0
  58. package/dist/stories/ox-search-form.stories.js +235 -0
  59. package/dist/stories/ox-search-form.stories.js.map +1 -0
  60. package/dist/tsconfig.tsbuildinfo +1 -1
  61. package/package.json +7 -5
  62. package/src/components/ox-custom-input.ts +5 -5
  63. package/src/components/ox-custom-select.ts +2 -1
  64. package/src/components/ox-file-uploader.ts +1 -1
  65. package/src/components/ox-search-form.ts +231 -97
  66. package/src/filters/filter-checkbox.ts +2 -1
  67. package/src/filters/filter-input-barcode.ts +5 -3
  68. package/src/filters/filter-input.ts +2 -1
  69. package/src/filters/filter-range-date.ts +3 -1
  70. package/src/filters/filter-range-number.ts +3 -1
  71. package/src/filters/filter-select.ts +29 -20
  72. package/src/filters/filter-styles.ts +56 -24
  73. package/src/filters/ox-filter-personalizer.ts +188 -0
  74. package/src/filters/ox-filters-form-base.ts +222 -79
  75. package/src/styles/multi-column-form-styles.ts +6 -6
  76. package/src/styles/search-form-styles.ts +23 -18
  77. package/src/styles/single-column-form-styles.ts +5 -5
  78. package/src/types.ts +48 -2
  79. package/stories/ox-filters-form-barcode.stories.ts +54 -14
  80. package/stories/ox-filters-form-base-bounded.stories.ts +213 -0
  81. package/stories/ox-filters-form-base-change-handler.stories.ts +225 -0
  82. package/stories/ox-filters-form-base-page-preference.stories.ts +192 -0
  83. package/stories/ox-filters-form-base.stories.ts +63 -31
  84. package/stories/ox-search-form-change-handler.stories.ts +252 -0
  85. package/stories/ox-search-form.stories.ts +269 -0
  86. package/themes/dark-hc.css +151 -0
  87. package/themes/dark-mc.css +151 -0
  88. package/themes/dark.css +151 -0
  89. package/themes/grist-theme.css +169 -0
  90. package/themes/light-hc.css +151 -0
  91. package/themes/light-mc.css +151 -0
  92. package/themes/light.css +151 -0
  93. package/themes/md-typescale-styles.css +100 -0
  94. package/themes/spacing.css +43 -0
  95. package/themes/state-color.css +6 -0
  96. package/themes/app-theme.css +0 -145
  97. package/themes/form-theme.css +0 -75
@@ -1,14 +1,17 @@
1
+ import { CommonHeaderStyles } from '@operato/styles'
1
2
  import '../src/filters/ox-filters-form-base.js'
2
3
 
3
4
  import { html, TemplateResult } from 'lit'
5
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
4
6
 
5
7
  export default {
6
8
  title: 'ox-filters-form-barcode',
7
- component: 'ox-filters-form-barcode',
9
+ component: 'ox-filters-form-base',
8
10
  argTypes: {
9
11
  value: { control: 'object' },
10
12
  filters: { control: 'object' },
11
- urlParamsSensitive: { control: 'boolean' }
13
+ urlParamsSensitive: { control: 'boolean' },
14
+ theme: { control: 'select', options: ['light', 'dark'] }
12
15
  }
13
16
  }
14
17
 
@@ -22,11 +25,15 @@ interface ArgTypes {
22
25
  value?: object
23
26
  filters?: object
24
27
  urlParamsSensitive: boolean
28
+ theme: 'light' | 'dark'
25
29
  }
26
30
 
27
- const Template: Story<ArgTypes> = ({ value, filters, urlParamsSensitive }: ArgTypes) => html`
28
- <link href="/themes/app-theme.css" rel="stylesheet" />
29
- <link href="/themes/form-theme.css" rel="stylesheet" />
31
+ const Template: Story<ArgTypes> = ({ value, filters, urlParamsSensitive, theme = 'light' }: ArgTypes) => html`
32
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
33
+
34
+ <link href="/themes/light.css" rel="stylesheet" />
35
+ <link href="/themes/dark.css" rel="stylesheet" />
36
+ <link href="/themes/spacing.css" rel="stylesheet" />
30
37
 
31
38
  <link
32
39
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
@@ -41,15 +48,48 @@ const Template: Story<ArgTypes> = ({ value, filters, urlParamsSensitive }: ArgTy
41
48
  rel="stylesheet"
42
49
  />
43
50
 
44
- <ox-filters-form-base
45
- .value=${value}
46
- .filters=${filters}
47
- ?url-params-sensitive=${urlParamsSensitive}
48
- @filters-change=${(e: CustomEvent) => {
49
- console.log('filters changed', e.detail)
50
- }}
51
- >
52
- </ox-filters-form-base>
51
+ <style>
52
+ ${MDTypeScaleStyles.cssText}
53
+ </style>
54
+
55
+ <style>
56
+ ${CommonHeaderStyles.cssText}
57
+ </style>
58
+
59
+ <style>
60
+ body {
61
+ width: 100%;
62
+ height: 500px;
63
+ text-align: center;
64
+
65
+ background-color: var(--md-sys-color-background);
66
+ color: var(--md-sys-color-on-background);
67
+ }
68
+
69
+ .header {
70
+ padding: var(--spacing-small) var(--spacing-medium);
71
+ background-color: var(--md-sys-color-primary-container);
72
+ color: var(--md-sys-color-on-primary-container);
73
+ }
74
+ </style>
75
+
76
+ <script>
77
+ document.body.classList.add('${theme}')
78
+ </script>
79
+
80
+ <div class="header">
81
+ <div class="filters">
82
+ <ox-filters-form-base
83
+ .value=${value}
84
+ .filters=${filters}
85
+ ?url-params-sensitive=${urlParamsSensitive}
86
+ @filters-change=${(e: CustomEvent) => {
87
+ console.log('filters changed', e.detail)
88
+ }}
89
+ >
90
+ </ox-filters-form-base>
91
+ </div>
92
+ </div>
53
93
  `
54
94
 
55
95
  export const Regular = Template.bind({})
@@ -0,0 +1,213 @@
1
+ import { CommonHeaderStyles } from '@operato/styles'
2
+ import { sleep } from '@operato/utils'
3
+ import '../src/filters/ox-filters-form-base.js'
4
+
5
+ import { html, TemplateResult } from 'lit'
6
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
7
+
8
+ import { OxFiltersFormBase, FilterConfig, FilterValue } from '../src/index.js'
9
+
10
+ export default {
11
+ title: 'ox-filters-form-base bounded',
12
+ component: 'ox-filters-form-base',
13
+ argTypes: {
14
+ value: { control: 'object' },
15
+ filters: { control: 'object' },
16
+ urlParamsSensitive: { control: 'boolean' },
17
+ theme: { control: 'select', options: ['light', 'dark'] }
18
+ }
19
+ }
20
+
21
+ interface Story<T> {
22
+ (args: T): TemplateResult
23
+ args?: Partial<T>
24
+ argTypes?: Record<string, unknown>
25
+ }
26
+
27
+ interface ArgTypes {
28
+ value?: FilterValue[]
29
+ filters?: FilterConfig[]
30
+ urlParamsSensitive: boolean
31
+ theme: 'light' | 'dark'
32
+ }
33
+
34
+ const Template: Story<ArgTypes> = ({ value, filters, urlParamsSensitive, theme = 'light' }: ArgTypes) => html`
35
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
36
+
37
+ <link href="/themes/light.css" rel="stylesheet" />
38
+ <link href="/themes/dark.css" rel="stylesheet" />
39
+ <link href="/themes/spacing.css" rel="stylesheet" />
40
+
41
+ <link
42
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
43
+ rel="stylesheet"
44
+ />
45
+ <link
46
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL@20..48,100..700,0..1"
47
+ rel="stylesheet"
48
+ />
49
+ <link
50
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL@20..48,100..700,0..1"
51
+ rel="stylesheet"
52
+ />
53
+
54
+ <style>
55
+ ${MDTypeScaleStyles.cssText}
56
+ </style>
57
+
58
+ <style>
59
+ ${CommonHeaderStyles.cssText}
60
+ </style>
61
+
62
+ <style>
63
+ body {
64
+ width: 100%;
65
+ height: 500px;
66
+ text-align: center;
67
+
68
+ background-color: var(--md-sys-color-background);
69
+ color: var(--md-sys-color-on-background);
70
+ }
71
+
72
+ .header {
73
+ padding: var(--spacing-medium);
74
+ background-color: var(--md-sys-color-primary-container);
75
+ color: var(--md-sys-color-on-primary-container);
76
+ }
77
+ </style>
78
+
79
+ <script>
80
+ document.body.classList.add('${theme}')
81
+ </script>
82
+
83
+ <div class="header">
84
+ <div class="filters">
85
+ <ox-filters-form-base
86
+ .value=${value!}
87
+ .filters=${filters!}
88
+ ?url-params-sensitive=${urlParamsSensitive}
89
+ @filters-change=${(e: CustomEvent) => {}}
90
+ >
91
+ </ox-filters-form-base>
92
+ </div>
93
+ </div>
94
+ `
95
+
96
+ const WAREHOUSE = [
97
+ {
98
+ id: '01',
99
+ name: '제 1 창고',
100
+ zones: [
101
+ {
102
+ id: 'W1Z001',
103
+ name: 'Zone 01-001',
104
+ locations: ['L01-001-01', 'L01-001-02', 'L01-001-03', 'L01-001-04', 'L01-001-05']
105
+ },
106
+ {
107
+ id: 'W1Z002',
108
+ name: 'Zone 01-002',
109
+ locations: ['L01-002-01', 'L01-002-02', 'L01-002-03', 'L01-002-04', 'L01-002-05']
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ id: '02',
115
+ name: '제 2 창고',
116
+ zones: [
117
+ {
118
+ id: 'W2Z001',
119
+ name: 'Zone 02-001',
120
+ locations: ['L02-001-01', 'L02-001-02', 'L02-001-03', 'L02-001-04', 'L02-001-05']
121
+ },
122
+ {
123
+ id: 'W2Z002',
124
+ name: 'Zone 02-002',
125
+ locations: ['L02-002-01', 'L02-002-02', 'L02-002-03', 'L02-002-04', 'L02-002-05']
126
+ }
127
+ ]
128
+ }
129
+ ]
130
+
131
+ export const Regular = Template.bind({})
132
+ Regular.args = {
133
+ filters: [
134
+ {
135
+ name: 'warehouse',
136
+ type: 'select',
137
+ label: 'warehouse',
138
+ operator: 'eq',
139
+ value: '01',
140
+ options: async (form: OxFiltersFormBase) => {
141
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
142
+ return [
143
+ {
144
+ display: '',
145
+ value: ''
146
+ }
147
+ ].concat(
148
+ WAREHOUSE.map(w => {
149
+ return {
150
+ display: w.name,
151
+ value: w.id
152
+ }
153
+ })
154
+ )
155
+ }
156
+ },
157
+ {
158
+ name: 'zone',
159
+ type: 'select',
160
+ label: 'zone',
161
+ operator: 'eq',
162
+ value: 'W1Z001',
163
+ boundTo: ['warehouse'],
164
+ options: async (form: OxFiltersFormBase) => {
165
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
166
+ const formData = new FormData(await form.form)
167
+ const warehouse = formData?.get('warehouse')
168
+ console.log('warehouse', warehouse)
169
+
170
+ const targetWH = warehouse && WAREHOUSE.find(w => w.id == warehouse)
171
+ const zones = targetWH
172
+ ? targetWH.zones
173
+ : WAREHOUSE.reduce((sum, warehouse) => {
174
+ sum = sum.concat(warehouse.zones)
175
+ return sum
176
+ }, [] as any[])
177
+
178
+ return [
179
+ {
180
+ display: '',
181
+ value: ''
182
+ }
183
+ ].concat(
184
+ zones.map((z: any) => {
185
+ return {
186
+ display: z.name,
187
+ value: z.id
188
+ }
189
+ })
190
+ )
191
+ }
192
+ },
193
+ {
194
+ name: 'location',
195
+ type: 'select',
196
+ label: 'location',
197
+ operator: 'eq',
198
+ value: '',
199
+ boundTo: ['warehouse', 'zone'],
200
+ options: async (form: OxFiltersFormBase) => {
201
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
202
+ const formData = new FormData(await form.form)
203
+ const warehouse = formData?.get('warehouse')
204
+ const zone = formData?.get('zone')
205
+ console.log('warehouse, zone', warehouse, zone)
206
+
207
+ const targetWH = (warehouse && WAREHOUSE.find(w => w.id == warehouse)) || null
208
+ const targetZone = zone && targetWH?.zones.find(z => z.id == zone)
209
+ return targetZone ? ['', ...targetZone.locations] : []
210
+ }
211
+ }
212
+ ]
213
+ }
@@ -0,0 +1,225 @@
1
+ import { CommonHeaderStyles } from '@operato/styles'
2
+ import { sleep } from '@operato/utils'
3
+ import '../src/filters/ox-filters-form-base.js'
4
+
5
+ import { html, TemplateResult } from 'lit'
6
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
7
+
8
+ import { OxFiltersFormBase, FilterConfig, FilterValue } from '../src/index.js'
9
+
10
+ export default {
11
+ title: 'ox-filters-form-base change-handler',
12
+ component: 'ox-filters-form-base',
13
+ argTypes: {
14
+ value: { control: 'object' },
15
+ filters: { control: 'object' },
16
+ urlParamsSensitive: { control: 'boolean' },
17
+ theme: { control: 'select', options: ['light', 'dark'] }
18
+ }
19
+ }
20
+
21
+ interface Story<T> {
22
+ (args: T): TemplateResult
23
+ args?: Partial<T>
24
+ argTypes?: Record<string, unknown>
25
+ }
26
+
27
+ interface ArgTypes {
28
+ value?: FilterValue[]
29
+ filters?: FilterConfig[]
30
+ urlParamsSensitive: boolean
31
+ theme: 'light' | 'dark'
32
+ }
33
+
34
+ const Template: Story<ArgTypes> = ({ value, filters, urlParamsSensitive, theme = 'light' }: ArgTypes) => html`
35
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
36
+
37
+ <link href="/themes/light.css" rel="stylesheet" />
38
+ <link href="/themes/dark.css" rel="stylesheet" />
39
+ <link href="/themes/spacing.css" rel="stylesheet" />
40
+
41
+ <link
42
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
43
+ rel="stylesheet"
44
+ />
45
+ <link
46
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL@20..48,100..700,0..1"
47
+ rel="stylesheet"
48
+ />
49
+ <link
50
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL@20..48,100..700,0..1"
51
+ rel="stylesheet"
52
+ />
53
+
54
+ <style>
55
+ ${MDTypeScaleStyles.cssText}
56
+ </style>
57
+
58
+ <style>
59
+ ${CommonHeaderStyles.cssText}
60
+ </style>
61
+
62
+ <style>
63
+ body {
64
+ width: 100%;
65
+ height: 500px;
66
+ text-align: center;
67
+
68
+ background-color: var(--md-sys-color-background);
69
+ color: var(--md-sys-color-on-background);
70
+ }
71
+
72
+ .header {
73
+ padding: var(--spacing-medium);
74
+ background-color: var(--md-sys-color-primary-container);
75
+ color: var(--md-sys-color-on-primary-container);
76
+ }
77
+ </style>
78
+
79
+ <script>
80
+ document.body.classList.add('${theme}')
81
+ </script>
82
+
83
+ <div class="header">
84
+ <div class="filters">
85
+ <ox-filters-form-base
86
+ .value=${value!}
87
+ .filters=${filters!}
88
+ ?url-params-sensitive=${urlParamsSensitive}
89
+ @filters-change=${(e: CustomEvent) => {
90
+ const { filters } = e.detail
91
+ const { value } = e.currentTarget as any
92
+ console.log('filters-change event fired', filters, value, e.currentTarget)
93
+ }}
94
+ >
95
+ </ox-filters-form-base>
96
+ </div>
97
+ </div>
98
+ `
99
+
100
+ const WAREHOUSE = [
101
+ {
102
+ id: '01',
103
+ name: '제 1 창고',
104
+ zones: [
105
+ {
106
+ id: 'W1Z001',
107
+ name: 'Zone 01-001',
108
+ locations: ['L01-001-01', 'L01-001-02', 'L01-001-03', 'L01-001-04', 'L01-001-05']
109
+ },
110
+ {
111
+ id: 'W1Z002',
112
+ name: 'Zone 01-002',
113
+ locations: ['L01-002-01', 'L01-002-02', 'L01-002-03', 'L01-002-04', 'L01-002-05']
114
+ }
115
+ ]
116
+ },
117
+ {
118
+ id: '02',
119
+ name: '제 2 창고',
120
+ zones: [
121
+ {
122
+ id: 'W2Z001',
123
+ name: 'Zone 02-001',
124
+ locations: ['L02-001-01', 'L02-001-02', 'L02-001-03', 'L02-001-04', 'L02-001-05']
125
+ },
126
+ {
127
+ id: 'W2Z002',
128
+ name: 'Zone 02-002',
129
+ locations: ['L02-002-01', 'L02-002-02', 'L02-002-03', 'L02-002-04', 'L02-002-05']
130
+ }
131
+ ]
132
+ }
133
+ ]
134
+
135
+ export const Regular = Template.bind({})
136
+ Regular.args = {
137
+ filters: [
138
+ {
139
+ name: 'warehouse',
140
+ type: 'select',
141
+ label: 'warehouse',
142
+ operator: 'eq',
143
+ value: '01',
144
+ options: async (form: OxFiltersFormBase) => {
145
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
146
+ return [
147
+ {
148
+ display: '',
149
+ value: ''
150
+ }
151
+ ].concat(
152
+ WAREHOUSE.map(w => {
153
+ return {
154
+ display: w.name,
155
+ value: w.id
156
+ }
157
+ })
158
+ )
159
+ },
160
+ onchange: async (value: any, form: OxFiltersFormBase) => {
161
+ await sleep(1000)
162
+ console.log("won't submit..")
163
+ return false
164
+ }
165
+ },
166
+ {
167
+ name: 'zone',
168
+ type: 'select',
169
+ label: 'zone',
170
+ operator: 'eq',
171
+ value: 'W1Z001',
172
+ boundTo: ['warehouse'],
173
+ options: async (form: OxFiltersFormBase) => {
174
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
175
+ const formData = new FormData(await form.form)
176
+ const warehouse = formData?.get('warehouse')
177
+ console.log('warehouse', warehouse)
178
+
179
+ const targetWH = warehouse && WAREHOUSE.find(w => w.id == warehouse)
180
+ const zones = targetWH
181
+ ? targetWH.zones
182
+ : WAREHOUSE.reduce((sum, warehouse) => {
183
+ sum = sum.concat(warehouse.zones)
184
+ return sum
185
+ }, [] as any[])
186
+
187
+ return [
188
+ {
189
+ display: '',
190
+ value: ''
191
+ }
192
+ ].concat(
193
+ zones.map((z: any) => {
194
+ return {
195
+ display: z.name,
196
+ value: z.id
197
+ }
198
+ })
199
+ )
200
+ },
201
+ onchange: () => {
202
+ return false
203
+ }
204
+ },
205
+ {
206
+ name: 'location',
207
+ type: 'select',
208
+ label: 'location',
209
+ operator: 'eq',
210
+ value: '',
211
+ boundTo: ['warehouse', 'zone'],
212
+ options: async (form: OxFiltersFormBase) => {
213
+ await sleep(1000) // 테스트를 위해서 강제로 1초 쉬기
214
+ const formData = new FormData(await form.form)
215
+ const warehouse = formData?.get('warehouse')
216
+ const zone = formData?.get('zone')
217
+ console.log('warehouse, zone', warehouse, zone)
218
+
219
+ const targetWH = (warehouse && WAREHOUSE.find(w => w.id == warehouse)) || null
220
+ const targetZone = zone && targetWH?.zones.find(z => z.id == zone)
221
+ return targetZone ? ['', ...targetZone.locations] : []
222
+ }
223
+ }
224
+ ]
225
+ }