@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
@@ -30,14 +30,47 @@ function getRelativeHourTime(params: RelativeHourTimeParams = {}): string | numb
30
30
  ## 예제
31
31
 
32
32
  ```typescript
33
+ /* get Date() object */
33
34
  const relativeHourTime = getRelativeHourTime({
34
35
  relativeHour: 2,
35
36
  relativeSeconds: 120,
36
37
  timeZone: 'Asia/Seoul',
38
+ loclae: 'en-CA',
37
39
  format: 'date'
38
40
  })
39
41
 
40
42
  console.log(relativeHourTime)
41
43
  ```
42
44
 
45
+ ```typescript
46
+ /* text format style */
47
+ const relativeHourTime = getRelativeHourTime({
48
+ relativeHour: 2,
49
+ relativeSeconds: 120,
50
+ timeZone: 'Asia/Seoul',
51
+ format: 'h:mm:ss'
52
+ })
53
+
54
+ console.log(relativeHourTime)
55
+ ```
56
+
57
+ ```typescript
58
+ /* Intl.DateTimeFormat style */
59
+ const relativeHourTime = getRelativeHourTime({
60
+ relativeHour: 2,
61
+ relativeSeconds: 120,
62
+ timeZone: 'Asia/Seoul',
63
+ loclae: 'en-CA',
64
+ format: {
65
+ hour: 'numeric',
66
+ minute: 'numeric',
67
+ second: 'numeric',
68
+ hour12: false,
69
+ timeZone: 'America/Los_Angeles'
70
+ }
71
+ })
72
+
73
+ console.log(relativeHourTime)
74
+ ```
75
+
43
76
  이 코드는 현재 시간으로부터 2시간 후와 2분 후의 시간을 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
@@ -30,14 +30,47 @@ function getRelativeMinuteTime(params: RelativeMinuteTimeParams = {}): string |
30
30
  ## 예제
31
31
 
32
32
  ```typescript
33
+ /* get Date() object */
33
34
  const relativeMinuteTime = getRelativeMinuteTime({
34
35
  relativeMinutes: 15,
35
36
  relativeSeconds: 30,
36
37
  timeZone: 'Asia/Seoul',
38
+ loclae: 'en-CA',
37
39
  format: 'date'
38
40
  })
39
41
 
40
42
  console.log(relativeMinuteTime)
41
43
  ```
42
44
 
45
+ ```typescript
46
+ /* text format style */
47
+ const relativeMinuteTime = getRelativeMinuteTime({
48
+ relativeMinutes: 15,
49
+ relativeSeconds: 30,
50
+ timeZone: 'Asia/Seoul',
51
+ format: 'mm:ss'
52
+ })
53
+
54
+ console.log(relativeMinuteTime)
55
+ ```
56
+
57
+ ```typescript
58
+ /* Intl.DateTimeFormat style */
59
+ const relativeMinuteTime = getRelativeMinuteTime({
60
+ relativeMinutes: 15,
61
+ relativeSeconds: 30,
62
+ timeZone: 'Asia/Seoul',
63
+ loclae: 'en-CA',
64
+ format: {
65
+ hour: 'numeric',
66
+ minute: 'numeric',
67
+ second: 'numeric',
68
+ hour12: false,
69
+ timeZone: 'America/Los_Angeles'
70
+ }
71
+ })
72
+
73
+ console.log(relativeMinuteTime)
74
+ ```
75
+
43
76
  이 코드는 현재 시간으로부터 15분 30초 후의 시간을 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
@@ -30,10 +30,12 @@ function getRelativeMonthDate(params: RelativeMonthDateParams = {}): string | nu
30
30
  ## 예제
31
31
 
32
32
  ```typescript
33
+ /* get Date() object */
33
34
  const relativeMonthDate = getRelativeMonthDate({
34
35
  relativeMonths: 2,
35
36
  relativeDays: 3,
36
37
  timeZone: 'Asia/Seoul',
38
+ loclae: 'en-CA',
37
39
  format: 'date'
38
40
  })
39
41
 
@@ -28,12 +28,41 @@ function getCurrentTime(
28
28
  ## 예제
29
29
 
30
30
  ```typescript
31
+ /* get Date() object */
31
32
  const currentTime = getCurrentTime({
32
33
  timeZone: 'Asia/Seoul',
34
+ loclae: 'en-CA',
33
35
  format: 'date'
34
36
  })
35
37
 
36
38
  console.log(currentTime)
37
39
  ```
38
40
 
41
+ ```typescript
42
+ /* text format style */
43
+ const relativeDate = getCurrentTime({
44
+ relativeDays: 1,
45
+ timeZone: 'Asia/Seoul',
46
+ format: 'YYYY-MM-DD'
47
+ })
48
+
49
+ console.log(relativeDate)
50
+ ```
51
+
52
+ ```typescript
53
+ /* Intl.DateTimeFormat style */
54
+ const relativeDate = getCurrentTime({
55
+ relativeDays: 1,
56
+ timeZone: 'Asia/Seoul',
57
+ loclae: 'en-CA' /* YYYY-MM-DD format */,
58
+ format: {
59
+ year: 'numeric',
60
+ month: '2-digit',
61
+ day: '2-digit'
62
+ }
63
+ })
64
+
65
+ console.log(relativeDate)
66
+ ```
67
+
39
68
  이 코드는 현재 시간을 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
@@ -28,13 +28,44 @@ function getRelativeTime(params: RelativeTimeParams = {}): string | number | Dat
28
28
  ## 예제
29
29
 
30
30
  ```typescript
31
+ /* get Date() object */
31
32
  const relativeTime = getRelativeTime({
32
33
  relativeSeconds: 3600,
33
34
  timeZone: 'Asia/Seoul',
35
+ loclae: 'en-CA',
34
36
  format: 'date'
35
37
  })
36
38
 
37
39
  console.log(relativeTime)
38
40
  ```
39
41
 
42
+ ```typescript
43
+ /* text format style */
44
+ const relativeTime = getRelativeTime({
45
+ relativeSeconds: 3600,
46
+ timeZone: 'Asia/Seoul',
47
+ format: 'hh:mm:ss'
48
+ })
49
+
50
+ console.log(relativeTime)
51
+ ```
52
+
53
+ ```typescript
54
+ /* Intl.DateTimeFormat style */
55
+ const relativeTime = getRelativeTime({
56
+ relativeSeconds: 3600,
57
+ timeZone: 'Asia/Seoul',
58
+ loclae: 'en-CA',
59
+ format: {
60
+ hour: 'numeric',
61
+ minute: 'numeric',
62
+ second: 'numeric',
63
+ hour12: false,
64
+ timeZone: 'America/Los_Angeles'
65
+ }
66
+ })
67
+
68
+ console.log(relativeTime)
69
+ ```
70
+
40
71
  이 코드는 현재 시간으로부터 1시간 후의 시간을 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
@@ -28,12 +28,41 @@ function getToday(
28
28
  ## 예제
29
29
 
30
30
  ```typescript
31
+ /* get Date() object */
31
32
  const todayDate = getToday({
32
33
  timeZone: 'Asia/Seoul',
34
+ loclae: 'en-CA',
33
35
  format: 'date'
34
36
  })
35
37
 
36
38
  console.log(todayDate)
37
39
  ```
38
40
 
41
+ ```typescript
42
+ /* text format style */
43
+ const relativeDate = getToday({
44
+ relativeDays: 1,
45
+ timeZone: 'Asia/Seoul',
46
+ format: 'YYYY-MM-DD'
47
+ })
48
+
49
+ console.log(relativeDate)
50
+ ```
51
+
52
+ ```typescript
53
+ /* Intl.DateTimeFormat style */
54
+ const relativeDate = getToday({
55
+ relativeDays: 1,
56
+ timeZone: 'Asia/Seoul',
57
+ loclae: 'en-CA' /* YYYY-MM-DD format */,
58
+ format: {
59
+ year: 'numeric',
60
+ month: '2-digit',
61
+ day: '2-digit'
62
+ }
63
+ })
64
+
65
+ console.log(relativeDate)
66
+ ```
67
+
39
68
  이 코드는 오늘의 날짜를 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
@@ -30,14 +30,45 @@ function getRelativeWeekDate(params: RelativeWeekDateParams = {}): string | numb
30
30
  ## 예제
31
31
 
32
32
  ```typescript
33
+ /* get Date() object */
33
34
  const relativeWeekDate = getRelativeWeekDate({
34
35
  relativeWeeks: 2,
35
36
  relativeDays: 3,
36
37
  timeZone: 'Asia/Seoul',
38
+ loclae: 'en-CA',
37
39
  format: 'date'
38
40
  })
39
41
 
40
42
  console.log(relativeWeekDate)
41
43
  ```
42
44
 
45
+ ```typescript
46
+ /* text format style */
47
+ const relativeWeekDate = getRelativeWeekDate({
48
+ relativeWeeks: 2,
49
+ relativeDays: 3,
50
+ timeZone: 'Asia/Seoul',
51
+ format: 'YYYY-MM-DD'
52
+ })
53
+
54
+ console.log(relativeWeekDate)
55
+ ```
56
+
57
+ ```typescript
58
+ /* Intl.DateTimeFormat style */
59
+ const relativeWeekDate = getRelativeWeekDate({
60
+ relativeWeeks: 2,
61
+ relativeDays: 3,
62
+ timeZone: 'Asia/Seoul',
63
+ loclae: 'en-CA' /* YYYY-MM-DD format */,
64
+ format: {
65
+ year: 'numeric',
66
+ month: '2-digit',
67
+ day: '2-digit'
68
+ }
69
+ })
70
+
71
+ console.log(relativeWeekDate)
72
+ ```
73
+
43
74
  이 코드는 현재 시간으로부터 2주 후와 3일 후의 날짜를 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
@@ -30,14 +30,45 @@ function getRelativeYearDate(params: RelativeYearDateParams = {}): string | numb
30
30
  ## 예제
31
31
 
32
32
  ```typescript
33
+ /* get Date() object */
33
34
  const relativeYearDate = getRelativeYearDate({
34
35
  relativeYears: 2,
35
36
  relativeDays: 3,
36
37
  timeZone: 'Asia/Seoul',
38
+ loclae: 'en-CA',
37
39
  format: 'date'
38
40
  })
39
41
 
40
42
  console.log(relativeYearDate)
41
43
  ```
42
44
 
45
+ ```typescript
46
+ /* text format style */
47
+ const relativeYearDate = getRelativeYearDate({
48
+ relativeYears: 2,
49
+ relativeDays: 3,
50
+ timeZone: 'Asia/Seoul',
51
+ format: 'YYYY-MM-DD'
52
+ })
53
+
54
+ console.log(relativeYearDate)
55
+ ```
56
+
57
+ ```typescript
58
+ /* Intl.DateTimeFormat style */
59
+ const relativeYearDate = getRelativeYearDate({
60
+ relativeYears: 2,
61
+ relativeDays: 3,
62
+ timeZone: 'Asia/Seoul',
63
+ loclae: 'en-CA' /* YYYY-MM-DD format */,
64
+ format: {
65
+ year: 'numeric',
66
+ month: '2-digit',
67
+ day: '2-digit'
68
+ }
69
+ })
70
+
71
+ console.log(relativeYearDate)
72
+ ```
73
+
43
74
  이 코드는 현재 시간으로부터 2년 후와 3일 후의 날짜를 `'Asia/Seoul'` 시간대에서의 Date 객체로 반환합니다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/data-grist",
3
- "version": "2.0.0-alpha.102",
3
+ "version": "2.0.0-alpha.104",
4
4
  "description": "User interface for grid (desktop) and list (mobile)",
5
5
  "author": "heartyoh",
6
6
  "main": "dist/index.js",
@@ -61,7 +61,7 @@
61
61
  "@operato/popup": "^2.0.0-alpha.102",
62
62
  "@operato/pull-to-refresh": "^2.0.0-alpha.57",
63
63
  "@operato/styles": "^2.0.0-alpha.102",
64
- "@operato/time-calculator": "^2.0.0-alpha.57",
64
+ "@operato/time-calculator": "^2.0.0-alpha.104",
65
65
  "@operato/utils": "^2.0.0-alpha.68",
66
66
  "i18next": "^21.5.4",
67
67
  "json5": "^2.2.0",
@@ -101,5 +101,5 @@
101
101
  "prettier --write"
102
102
  ]
103
103
  },
104
- "gitHead": "2c56687a2c8170f73a8bcbfbf916386c0c234f1f"
104
+ "gitHead": "804d35e90d66abb8d769a19f4787b440873ecd66"
105
105
  }
@@ -1,6 +1,38 @@
1
- import { OxGristEditor } from './ox-grist-editor.js'
2
- import { customElement } from 'lit/decorators.js'
3
1
  import { html } from 'lit'
2
+ import { customElement } from 'lit/decorators.js'
3
+ import { until } from 'lit/directives/until.js'
4
+
5
+ import { OxGristEditor } from './ox-grist-editor.js'
6
+ import { SelectOption, SelectOptionObject } from '../types.js'
7
+
8
+ function buildOptions(options: SelectOption[], value: any) {
9
+ const selectOptionObjects = options.map(option => {
10
+ switch (typeof option) {
11
+ case 'string':
12
+ return {
13
+ display: option,
14
+ value: option
15
+ }
16
+ case 'object':
17
+ return {
18
+ display: option.display || option.name,
19
+ value: option.value
20
+ }
21
+ default:
22
+ return option
23
+ }
24
+ }) as SelectOptionObject[]
25
+
26
+ return html`
27
+ <select>
28
+ ${selectOptionObjects.map(
29
+ (option: any) => html`
30
+ <option ?selected=${option.value == value} value=${option.value}>${option.display}</option>
31
+ `
32
+ )}
33
+ </select>
34
+ `
35
+ }
4
36
 
5
37
  @customElement('ox-grist-editor-select')
6
38
  export class OxGristEditorSelect extends OxGristEditor {
@@ -10,33 +42,14 @@ export class OxGristEditorSelect extends OxGristEditor {
10
42
 
11
43
  if (typeof options == 'function') {
12
44
  options = options.call(null, this.value, this.column, this.record, this.rowIndex, this.field)
13
- }
14
45
 
15
- options = options.map((option: any) => {
16
- switch (typeof option) {
17
- case 'string':
18
- return {
19
- display: option,
20
- value: option
21
- }
22
- case 'object':
23
- return {
24
- display: option.display,
25
- value: option.value
26
- }
27
- default:
28
- return option
46
+ if (options instanceof Promise) {
47
+ return html`${until(options.then(options => buildOptions(options, this.value)))}`
48
+ } else {
49
+ return buildOptions((options || []) as SelectOption[], rowOptionField.display || this.value)
29
50
  }
30
- })
31
-
32
- return html`
33
- <select>
34
- ${options.map(
35
- (option: any) => html`
36
- <option ?selected=${option.value == this.value} value=${option.value}>${option.display}</option>
37
- `
38
- )}
39
- </select>
40
- `
51
+ } else {
52
+ return buildOptions((options || []) as SelectOption[], this.value)
53
+ }
41
54
  }
42
55
  }
@@ -1,26 +1,14 @@
1
1
  import '@operato/input/ox-checkbox.js'
2
2
 
3
- import { FilterConfigObject, FilterSelectRenderer } from '../types'
3
+ import { html } from 'lit'
4
+ import { until } from 'lit/directives/until.js'
4
5
 
5
- import { html } from 'lit-html'
6
+ import { FilterConfigObject, FilterOperator, FilterSelectRenderer, SelectOption, SelectOptionObject } from '../types'
7
+ import { OxFiltersForm } from './filters-form'
8
+ import { DataGridHeader } from '../data-grid/data-grid-header'
6
9
 
7
- export const FilterSelect: FilterSelectRenderer = (column, value, owner) => {
8
- /* value는 filters-form이나 grid-header에서 처리되므로 이 곳에서는 무시한다. */
9
- const filter = column.filter as FilterConfigObject
10
- const operator = filter?.operator
11
-
12
- var options = filter?.options || column.record.options || []
13
-
14
- if (typeof options === 'function') {
15
- if (!filter?.options) {
16
- console.warn(
17
- 'ox-grist의 column.filter 속성에서는 column.record.options의 함수형 options을 사용할 수 없으므로, filter 속성에서 재지정해야한다.'
18
- )
19
- }
20
- options = options.call(column, owner)
21
- }
22
-
23
- options = options.map((option: any) => {
10
+ function buildOptions(options: SelectOption[], operator?: FilterOperator) {
11
+ const selectOptionObjects = options.map(option => {
24
12
  switch (typeof option) {
25
13
  case 'string':
26
14
  return {
@@ -29,27 +17,52 @@ export const FilterSelect: FilterSelectRenderer = (column, value, owner) => {
29
17
  }
30
18
  case 'object':
31
19
  return {
32
- display: option.display,
20
+ display: option.display || option.name,
33
21
  value: option.value
34
22
  }
35
23
  default:
36
24
  return option
37
25
  }
38
- })
26
+ }) as SelectOptionObject[]
39
27
 
40
28
  return operator === 'in'
41
29
  ? html`
42
- ${options
43
- ?.filter((option: { display: string; value: any }) => !!option)
30
+ ${selectOptionObjects
31
+ ?.filter(option => !!option)
44
32
  .map(
45
- (option: { display: string; value: any }) =>
46
- html` <ox-checkbox option value=${option.value}>${option.display}</ox-checkbox> `
33
+ ({ value, display, name }) => html` <ox-checkbox option value=${value}>${display || name}</ox-checkbox> `
47
34
  )}
48
35
  `
49
36
  : html`
50
- ${options?.map(
51
- (option: { display: string; value: any }) =>
52
- html` <div option value=${option.value}>${option.display}&nbsp;</div> `
37
+ ${selectOptionObjects?.map(
38
+ ({ value, display, name }) => html` <div option value=${value}>${display || name}&nbsp;</div> `
53
39
  )}
54
40
  `
55
41
  }
42
+
43
+ export const FilterSelect: FilterSelectRenderer = (column, value, owner) => {
44
+ /* value는 filters-form이나 grid-header에서 처리되므로 이 곳에서는 무시한다. */
45
+ const filter = column.filter as FilterConfigObject
46
+ const operator = filter?.operator
47
+ const form = owner as OxFiltersForm | DataGridHeader
48
+
49
+ var options = filter?.options || column.record.options || []
50
+
51
+ if (typeof options === 'function') {
52
+ if (!filter?.options) {
53
+ console.warn(
54
+ 'ox-grist의 column.filter 속성에서는 column.record.options의 함수형 options을 사용할 수 없으므로, filter 속성에서 재지정해야한다.'
55
+ )
56
+ }
57
+
58
+ options = options.call(null, value, column, form instanceof OxFiltersForm ? form.getFormObjectValue() : {}, owner)
59
+
60
+ if (options instanceof Promise) {
61
+ return html`${until(options.then(options => buildOptions(options, operator)))}`
62
+ } else {
63
+ return buildOptions((options || []) as SelectOption[], operator)
64
+ }
65
+ } else {
66
+ return buildOptions((options || []) as SelectOption[], operator)
67
+ }
68
+ }
@@ -23,7 +23,7 @@ export type QueryFilter = {
23
23
  }
24
24
 
25
25
  @customElement('ox-filters-form')
26
- export class FiltersForm extends LitElement {
26
+ export class OxFiltersForm extends LitElement {
27
27
  static styles = [
28
28
  FilterStyles,
29
29
  css`
@@ -68,6 +68,9 @@ export class FiltersForm extends LitElement {
68
68
 
69
69
  @queryAsync('form') form!: HTMLFormElement
70
70
 
71
+ private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}
72
+ private objectValue?: object
73
+
71
74
  connectedCallback(): void {
72
75
  super.connectedCallback()
73
76
 
@@ -90,21 +93,42 @@ export class FiltersForm extends LitElement {
90
93
  })
91
94
 
92
95
  this.renderRoot.addEventListener('change', async (e: Event) => {
93
- this.dispatchEvent(
94
- new CustomEvent('fetch-params-change', {
95
- bubbles: true,
96
- composed: true,
97
- detail: {
98
- filters: await this.getQueryFilters(),
99
- 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 = ''
100
106
  }
101
107
  })
102
- )
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
+ )
103
127
  })
104
128
  }
105
129
  }
106
130
 
107
- buildDefaultValue(operator: string, defaultValue: any) {
131
+ buildDefaultValue(operator: FilterOperator, defaultValue: any) {
108
132
  if (defaultValue === undefined) {
109
133
  return
110
134
  }
@@ -137,6 +161,22 @@ export class FiltersForm extends LitElement {
137
161
  })
138
162
 
139
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
+ })
140
180
  }
141
181
  }
142
182
 
@@ -319,4 +359,28 @@ export class FiltersForm extends LitElement {
319
359
  const input = this.renderRoot.querySelector(`form [name="${name}"]`) as HTMLInputElement
320
360
  return input?.value
321
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
+ }
322
386
  }