@operato/data-grist 0.2.35 → 0.2.36

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 (98) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/custom-elements.json +1697 -5
  3. package/demo/data-grist-test.html +1 -1
  4. package/demo/index.html +18 -1
  5. package/dist/src/data-card/data-card-gutter-menu.js +2 -2
  6. package/dist/src/data-card/data-card-gutter-menu.js.map +1 -1
  7. package/dist/src/data-card/data-card-gutter.d.ts +13 -1
  8. package/dist/src/data-card/data-card-gutter.js +1 -0
  9. package/dist/src/data-card/data-card-gutter.js.map +1 -1
  10. package/dist/src/data-grid/data-grid-field.d.ts +2 -2
  11. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  12. package/dist/src/data-grid/data-grid-header.d.ts +3 -0
  13. package/dist/src/data-grid/data-grid-header.js +38 -10
  14. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  15. package/dist/src/data-grist.d.ts +9 -7
  16. package/dist/src/data-grist.js +26 -18
  17. package/dist/src/data-grist.js.map +1 -1
  18. package/dist/src/data-list/data-list-field.js +3 -3
  19. package/dist/src/data-list/data-list-field.js.map +1 -1
  20. package/dist/src/data-list/data-list-gutter.d.ts +13 -1
  21. package/dist/src/data-list/data-list-gutter.js +1 -0
  22. package/dist/src/data-list/data-list-gutter.js.map +1 -1
  23. package/dist/src/data-report/data-report-field.d.ts +2 -2
  24. package/dist/src/data-report/data-report-field.js.map +1 -1
  25. package/dist/src/filters/index.d.ts +2 -0
  26. package/dist/src/filters/index.js +3 -0
  27. package/dist/src/filters/index.js.map +1 -0
  28. package/dist/src/filters/list-select.d.ts +3 -0
  29. package/dist/src/filters/list-select.js +12 -0
  30. package/dist/src/filters/list-select.js.map +1 -0
  31. package/dist/src/filters/registry.d.ts +7 -0
  32. package/dist/src/filters/registry.js +40 -0
  33. package/dist/src/filters/registry.js.map +1 -0
  34. package/dist/src/index.d.ts +2 -0
  35. package/dist/src/index.js +2 -0
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/interfaces/index.d.ts +2 -0
  38. package/dist/src/interfaces/index.js +3 -0
  39. package/dist/src/interfaces/index.js.map +1 -0
  40. package/dist/src/interfaces/ox-grist-search-form.d.ts +6 -0
  41. package/dist/src/interfaces/ox-grist-search-form.js +2 -0
  42. package/dist/src/interfaces/ox-grist-search-form.js.map +1 -0
  43. package/dist/src/interfaces/ox-search-field.d.ts +39 -0
  44. package/dist/src/interfaces/ox-search-field.js +2 -0
  45. package/dist/src/interfaces/ox-search-field.js.map +1 -0
  46. package/dist/src/search-form/index.d.ts +7 -0
  47. package/dist/src/search-form/index.js +8 -0
  48. package/dist/src/search-form/index.js.map +1 -0
  49. package/dist/src/search-form/ox-basic-field.d.ts +18 -0
  50. package/dist/src/search-form/ox-basic-field.js +75 -0
  51. package/dist/src/search-form/ox-basic-field.js.map +1 -0
  52. package/dist/src/search-form/ox-checkbox-field.d.ts +11 -0
  53. package/dist/src/search-form/ox-checkbox-field.js +60 -0
  54. package/dist/src/search-form/ox-checkbox-field.js.map +1 -0
  55. package/dist/src/search-form/ox-grist-search-form.d.ts +11 -0
  56. package/dist/src/search-form/ox-grist-search-form.js +177 -0
  57. package/dist/src/search-form/ox-grist-search-form.js.map +1 -0
  58. package/dist/src/search-form/ox-number-field.d.ts +14 -0
  59. package/dist/src/search-form/ox-number-field.js +112 -0
  60. package/dist/src/search-form/ox-number-field.js.map +1 -0
  61. package/dist/src/search-form/ox-search-form.d.ts +15 -0
  62. package/dist/src/search-form/ox-search-form.js +53 -0
  63. package/dist/src/search-form/ox-search-form.js.map +1 -0
  64. package/dist/src/search-form/ox-select-field.d.ts +21 -0
  65. package/dist/src/search-form/ox-select-field.js +181 -0
  66. package/dist/src/search-form/ox-select-field.js.map +1 -0
  67. package/dist/src/search-form/ox-text-field.d.ts +11 -0
  68. package/dist/src/search-form/ox-text-field.js +60 -0
  69. package/dist/src/search-form/ox-text-field.js.map +1 -0
  70. package/dist/src/types.d.ts +20 -3
  71. package/dist/src/types.js.map +1 -1
  72. package/dist/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +7 -6
  74. package/src/data-card/data-card-gutter-menu.ts +2 -2
  75. package/src/data-card/data-card-gutter.ts +3 -3
  76. package/src/data-grid/data-grid-field.ts +2 -2
  77. package/src/data-grid/data-grid-header.ts +42 -11
  78. package/src/data-grist.ts +30 -20
  79. package/src/data-list/data-list-field.ts +3 -3
  80. package/src/data-list/data-list-gutter.ts +3 -3
  81. package/src/data-report/data-report-field.ts +2 -2
  82. package/src/filters/index.ts +3 -0
  83. package/src/filters/list-select.ts +14 -0
  84. package/src/filters/registry.ts +48 -0
  85. package/src/index.ts +3 -0
  86. package/src/interfaces/index.ts +2 -0
  87. package/src/interfaces/ox-grist-search-form.ts +7 -0
  88. package/src/interfaces/ox-search-field.ts +52 -0
  89. package/src/search-form/index.ts +7 -0
  90. package/src/search-form/ox-basic-field.ts +86 -0
  91. package/src/search-form/ox-checkbox-field.ts +57 -0
  92. package/src/search-form/ox-grist-search-form.ts +200 -0
  93. package/src/search-form/ox-number-field.ts +113 -0
  94. package/src/search-form/ox-search-form.ts +71 -0
  95. package/src/search-form/ox-select-field.ts +188 -0
  96. package/src/search-form/ox-text-field.ts +55 -0
  97. package/src/types.ts +28 -3
  98. package/yarn-error.log +2427 -3205
package/src/data-grist.ts CHANGED
@@ -88,37 +88,44 @@ export class DataGrist extends LitElement implements DataConsumer {
88
88
  @state() private _showSpinner: boolean = false
89
89
 
90
90
  private dataProvider?: DataProvider
91
- private pulltorefreshHandle?: any
92
- private headroom?: Headroom
91
+ private _pulltorefreshHandle?: any
92
+ private _headroom?: Headroom
93
+ private _resizeObserver = new ResizeObserver(entries => {
94
+ this._adjustPaddingTop()
95
+ })
93
96
 
94
97
  @query('slot[name=headroom]') head!: HTMLElement
95
98
  @query('#grist') grist!: DataGrid | DataList | DataCard
96
99
  @queryAsync('#wrap') private wrap!: Promise<HTMLElement>
97
100
 
98
- connectedCallback() {
101
+ async connectedCallback() {
99
102
  super.connectedCallback()
100
103
 
101
104
  this.dataProvider = new DataProvider(this)
105
+
106
+ await this.updateComplete
107
+ this._resizeObserver.observe(this.head)
102
108
  }
103
109
 
104
110
  disconnectedCallback() {
105
111
  super.disconnectedCallback()
106
112
 
107
113
  this.dataProvider?.dispose()
108
- this.resetPullToRefresh()
114
+ this._resetPullToRefresh()
115
+ this._resizeObserver.unobserve(this.head)
109
116
  }
110
117
 
111
- private resetPullToRefresh() {
112
- if (this.pulltorefreshHandle) {
113
- this.pulltorefreshHandle()
114
- delete this.pulltorefreshHandle
118
+ private _resetPullToRefresh() {
119
+ if (this._pulltorefreshHandle) {
120
+ this._pulltorefreshHandle()
121
+ delete this._pulltorefreshHandle
115
122
  }
116
123
  }
117
124
 
118
- private async setPullToRefresh() {
119
- this.resetPullToRefresh()
125
+ private async _setPullToRefresh() {
126
+ this._resetPullToRefresh()
120
127
  if (this.fetchHandler) {
121
- this.pulltorefreshHandle = pulltorefresh({
128
+ this._pulltorefreshHandle = pulltorefresh({
122
129
  container: await this.wrap,
123
130
  scrollable: this.grist.pullToRefreshTarget,
124
131
  refresh: () => {
@@ -128,17 +135,20 @@ export class DataGrist extends LitElement implements DataConsumer {
128
135
  }
129
136
  }
130
137
 
131
- setHeadroom() {
132
- this.headroom?.destroy()
138
+ private _adjustPaddingTop() {
139
+ this.grist.style.paddingTop = this.head.clientHeight + 'px'
140
+ }
141
+
142
+ private _setHeadroom() {
143
+ this._headroom?.destroy()
133
144
 
134
145
  if (this.grist && this.head) {
135
- var originPaddingTop = parseFloat(getComputedStyle(this.grist, null).getPropertyValue('padding-top'))
136
- this.grist.style.paddingTop = this.head.clientHeight + originPaddingTop + 'px'
146
+ this._adjustPaddingTop()
137
147
 
138
- this.headroom = new Headroom(this.head, {
148
+ this._headroom = new Headroom(this.head, {
139
149
  scroller: this.grist
140
150
  })
141
- this.headroom.init()
151
+ this._headroom.init()
142
152
  }
143
153
  }
144
154
 
@@ -228,7 +238,7 @@ export class DataGrist extends LitElement implements DataConsumer {
228
238
 
229
239
  if (changes.has('mode')) {
230
240
  needToSetPullToRefresh = true
231
- this.setHeadroom()
241
+ this._setHeadroom()
232
242
  }
233
243
 
234
244
  if (changes.has('selectedRecords')) {
@@ -251,7 +261,7 @@ export class DataGrist extends LitElement implements DataConsumer {
251
261
  }
252
262
 
253
263
  if (needToSetPullToRefresh) {
254
- await this.setPullToRefresh()
264
+ await this._setPullToRefresh()
255
265
  }
256
266
  }
257
267
 
@@ -355,7 +365,7 @@ export class DataGrist extends LitElement implements DataConsumer {
355
365
  /**
356
366
  * Forced internal data to be reflected on the screen
357
367
  * Data changing through a normal method is automatically reflected on the screen, so it is a method that does not need to be used in general.
358
- Therefore, it will be deprecated.
368
+ * Therefore, it will be deprecated.
359
369
  * @deprecated
360
370
  * @method
361
371
  */
@@ -61,14 +61,14 @@ export class DataListField extends LitElement {
61
61
 
62
62
  var {
63
63
  label,
64
- record: { renderer: recordRenderer }
64
+ record: { renderer: fieldRenderer }
65
65
  } = column
66
66
 
67
67
  if (typeof label == 'object') {
68
68
  let { renderer: labelRenderer } = label
69
- return html`<label>${labelRenderer()}</label>${recordRenderer(value, column, record, rowIndex, this)}`
69
+ return html`<label>${labelRenderer()}</label>${fieldRenderer(value, column, record, rowIndex, this)}`
70
70
  } else {
71
- return html`${recordRenderer(value, column, record, rowIndex, this)}`
71
+ return html`${fieldRenderer(value, column, record, rowIndex, this)}`
72
72
  }
73
73
  }
74
74
  }
@@ -1,12 +1,12 @@
1
1
  import { ColumnConfig, GristRecord } from '../types'
2
- import { LitElement, PropertyValues, css, html } from 'lit'
2
+ import { LitElement, PropertyValues, TemplateResult, css, html } from 'lit'
3
3
  import { ZERO_COLUMN, ZERO_RECORD } from '../configure/zero-config'
4
4
  import { customElement, property } from 'lit/decorators.js'
5
5
 
6
6
  const DEFAULT_TEXT_ALIGN = 'left'
7
7
 
8
8
  @customElement('ox-list-gutter')
9
- class DataListGutter extends LitElement {
9
+ export class DataListGutter extends LitElement {
10
10
  static styles = [
11
11
  css`
12
12
  :host {
@@ -46,7 +46,7 @@ class DataListGutter extends LitElement {
46
46
  return this.hasAttribute('editing')
47
47
  }
48
48
 
49
- render() {
49
+ render(): TemplateResult {
50
50
  if (!this.column) {
51
51
  return html``
52
52
  }
@@ -1,5 +1,5 @@
1
1
  import { ColumnConfig, GristRecord } from '../types'
2
- import { LitElement, PropertyValues, css, html } from 'lit'
2
+ import { LitElement, PropertyValues, TemplateResult, css, html } from 'lit'
3
3
  import { ZERO_COLUMN, ZERO_RECORD } from '../configure/zero-config'
4
4
  import { customElement, property } from 'lit/decorators.js'
5
5
 
@@ -52,7 +52,7 @@ export class DataReportField extends LitElement {
52
52
  @property({ type: Number }) columnIndex: number = -1
53
53
  @property({ type: Object }) value: any
54
54
 
55
- render() {
55
+ render(): TemplateResult {
56
56
  if (!this.column) {
57
57
  return html``
58
58
  }
@@ -0,0 +1,3 @@
1
+ export * from './registry'
2
+
3
+ export * from './list-select'
@@ -0,0 +1,14 @@
1
+ import '@operato/popup'
2
+
3
+ import { FilterSelectRenderer } from '../types'
4
+ import { html } from 'lit-html'
5
+
6
+ export const ListSelect: FilterSelectRenderer = (column, owner) => {
7
+ const options = column.filter?.options
8
+
9
+ return html`
10
+ <ox-popup-list .config=${column} multiple attr-selected="checked" popup>
11
+ ${options?.map((option: string) => html` <ox-checkbox option value="${option}">${option}</ox-checkbox> `)}
12
+ </ox-popup-list>
13
+ `
14
+ }
@@ -0,0 +1,48 @@
1
+ import { FilterSelectRenderer } from '../types'
2
+ import { ListSelect } from './list-select'
3
+
4
+ var RENDERERS: {
5
+ [name: string]: FilterSelectRenderer
6
+ } = {
7
+ string: ListSelect,
8
+ text: ListSelect,
9
+ email: ListSelect,
10
+ tel: ListSelect,
11
+ password: ListSelect,
12
+ integer: ListSelect,
13
+ float: ListSelect,
14
+ number: ListSelect,
15
+ select: ListSelect,
16
+ boolean: ListSelect,
17
+ checkbox: ListSelect,
18
+ month: ListSelect,
19
+ week: ListSelect,
20
+ date: ListSelect,
21
+ time: ListSelect,
22
+ datetime: ListSelect,
23
+ color: ListSelect,
24
+ progress: ListSelect,
25
+ link: ListSelect,
26
+ image: ListSelect,
27
+ json5: ListSelect
28
+ }
29
+
30
+ export function registerRenderer(type: string, renderer: FilterSelectRenderer) {
31
+ RENDERERS[type] = renderer
32
+ }
33
+
34
+ export function unregisterRenderer(type: string): void {
35
+ delete RENDERERS[type]
36
+ }
37
+
38
+ export function getRenderers(): { [name: string]: FilterSelectRenderer } {
39
+ return { ...RENDERERS }
40
+ }
41
+
42
+ export function getRenderer(type: string | FilterSelectRenderer): FilterSelectRenderer {
43
+ if (typeof type == 'function') {
44
+ return type
45
+ }
46
+
47
+ return RENDERERS[type || 'text'] || ListSelect
48
+ }
package/src/index.ts CHANGED
@@ -7,3 +7,6 @@ export * from './renderers'
7
7
  export * from './handlers'
8
8
  export * from './formatters'
9
9
  export * from './gutters'
10
+
11
+ export * from './interfaces'
12
+ export * from './search-form'
@@ -0,0 +1,2 @@
1
+ export * from './ox-search-field'
2
+ export * from './ox-grist-search-form'
@@ -0,0 +1,7 @@
1
+ export type QueryFilterRangeValue = [from: number, to: number]
2
+
3
+ export type QueryFilter = {
4
+ name: string
5
+ operator?: string
6
+ value: any
7
+ }
@@ -0,0 +1,52 @@
1
+ export type OXSearchFieldType = 'select' | 'checkbox' | 'text' | 'number'
2
+
3
+ export interface OXFieldOptionProps {
4
+ name?: string
5
+ value: string
6
+ }
7
+
8
+ export interface OXBasicFieldProps {
9
+ name: string
10
+ type?: OXSearchFieldType
11
+ hidden?: boolean
12
+ id?: string
13
+ placeholder?: string
14
+ handlers?: Record<string, (event: Event) => void>
15
+ defaultValue?: any
16
+ operator?: string
17
+ }
18
+
19
+ export interface OXTextFieldProps extends OXBasicFieldProps {
20
+ defaultValue?: string
21
+ }
22
+
23
+ export interface OXNumberFieldProps extends OXBasicFieldProps {
24
+ min?: number
25
+ max?: number
26
+ step: number
27
+ defaultValue?: number
28
+ }
29
+
30
+ export interface OXObjectFieldProps extends OXBasicFieldProps {
31
+ field: string
32
+ queryName: string
33
+ defaultValue?: Record<string, any>
34
+ }
35
+
36
+ export interface OXSelectFieldProps extends OXBasicFieldProps {
37
+ searchEnable?: boolean
38
+ options: OXFieldOptionProps[]
39
+ defaultValue?: any
40
+ }
41
+
42
+ export interface OXCheckboxFieldProps extends OXBasicFieldProps {
43
+ indeterminate?: boolean
44
+ defaultValue?: boolean
45
+ }
46
+
47
+ export type OXSearchFieldProps =
48
+ | OXTextFieldProps
49
+ | OXNumberFieldProps
50
+ | OXObjectFieldProps
51
+ | OXSelectFieldProps
52
+ | OXCheckboxFieldProps
@@ -0,0 +1,7 @@
1
+ export * from './ox-search-form'
2
+ export * from './ox-grist-search-form'
3
+ export * from './ox-basic-field'
4
+ export * from './ox-checkbox-field'
5
+ export * from './ox-number-field'
6
+ export * from './ox-select-field'
7
+ export * from './ox-text-field'
@@ -0,0 +1,86 @@
1
+ import { css, LitElement } from 'lit-element'
2
+
3
+ import { OXBasicFieldProps } from '../interfaces/ox-search-field'
4
+
5
+ export abstract class OXBasicField extends LitElement {
6
+ static styles = [
7
+ css`
8
+ input,
9
+ select {
10
+ background-color: transparent;
11
+ border: none;
12
+ box-sizing: border-box;
13
+ outline: none;
14
+ padding: 4px 9px;
15
+ font-size: var(--fontsize-default, 14px);
16
+ color: var(--primary-text-color, #476172);
17
+ font-weight: bold;
18
+ }
19
+ `
20
+ ]
21
+
22
+ field!: OXBasicFieldProps
23
+
24
+ private form: HTMLFormElement | null = null
25
+ value?: any
26
+
27
+ abstract setDefaultValue(defaultValue: unknown): void
28
+
29
+ get input(): HTMLInputElement | HTMLSelectElement {
30
+ if (!this.field.name) throw new Error('No name property provided')
31
+ const input: HTMLInputElement | null = this.renderRoot.querySelector(
32
+ `input[name=${this.field.name}],select[name=${this.field.name}]`
33
+ )
34
+ if (!input) throw new Error('Failed to find input element')
35
+
36
+ return input
37
+ }
38
+
39
+ override connectedCallback(): void {
40
+ super.connectedCallback()
41
+ this.form = this.findFormElement()
42
+ this.form?.addEventListener('formdata', this.appendFormData.bind(this))
43
+ }
44
+
45
+ override disconnectedCallback(): void {
46
+ super.disconnectedCallback()
47
+ this.form?.removeEventListener('formdata', this.appendFormData.bind(this))
48
+ this.form = null
49
+ }
50
+
51
+ override firstUpdated(): void {
52
+ const { handlers } = this.field || {}
53
+
54
+ this.registerBasicEventHandlers()
55
+ if (handlers) this.registerCustomEventHandlers(handlers)
56
+ if (this.field.defaultValue !== undefined) this.setDefaultValue(this.field.defaultValue)
57
+ }
58
+
59
+ private findFormElement(): HTMLFormElement | null {
60
+ const rootNode: HTMLElement = this.getRootNode() as HTMLElement
61
+ const forms: HTMLFormElement[] = Array.from(rootNode.querySelectorAll('form'))
62
+
63
+ return forms.find((form: HTMLFormElement) => form.contains(this)) || null
64
+ }
65
+
66
+ private registerCustomEventHandlers(handlers: Record<string, (event: Event) => void>): void {
67
+ const eventNames: string[] = Object.keys(handlers)
68
+ if (!eventNames.length) return
69
+
70
+ eventNames.forEach((eventName: string) => this.input.addEventListener(eventName, handlers[eventName]))
71
+ }
72
+
73
+ private registerBasicEventHandlers(): void {
74
+ this.input.onkeydown = (event: KeyboardEvent) => {
75
+ if (event.key === 'Enter') this.submit()
76
+ }
77
+ }
78
+
79
+ private appendFormData({ formData }: FormDataEvent): void {
80
+ formData.append(this.field.name, this.value)
81
+ }
82
+
83
+ private submit(): void {
84
+ if (this.form) this.dispatchEvent(new CustomEvent('submit-field', { composed: true, bubbles: true }))
85
+ }
86
+ }
@@ -0,0 +1,57 @@
1
+ import { css, html, TemplateResult } from 'lit'
2
+ import { ifDefined } from 'lit-html/directives/if-defined.js'
3
+ import { customElement, property } from 'lit/decorators.js'
4
+
5
+ import { OXCheckboxFieldProps } from '..'
6
+ import { OXBasicField } from './ox-basic-field'
7
+
8
+ @customElement('ox-checkbox-field')
9
+ export class OXCheckboxField extends OXBasicField {
10
+ @property({ type: Object }) field!: OXCheckboxFieldProps
11
+ @property({ type: Boolean }) value?: boolean
12
+
13
+ static styles = [
14
+ css`
15
+ label {
16
+ font-size: var(--fontsize-default, 14px);
17
+ color: var(--primary-text-color, #476172);
18
+ }
19
+ `
20
+ ]
21
+
22
+ setDefaultValue(defaultValue: boolean): void {
23
+ this.value = defaultValue
24
+ }
25
+
26
+ render(): TemplateResult {
27
+ const { name, hidden, placeholder, id } = this.field
28
+
29
+ return html`<label ?hidden=${hidden}>
30
+ <input
31
+ id=${ifDefined(id)}
32
+ type="checkbox"
33
+ name=${name}
34
+ .checked=${Boolean(this.value)}
35
+ @click=${this.onClickHandler.bind(this)}
36
+ />
37
+ ${placeholder || name}
38
+ </label>`
39
+ }
40
+
41
+ private onClickHandler(): void {
42
+ const checkbox: HTMLInputElement = this.input as HTMLInputElement
43
+
44
+ if (!this.field.indeterminate) {
45
+ this.value = !this.value
46
+ } else {
47
+ if (this.value === false) {
48
+ this.value = undefined
49
+ checkbox.indeterminate = true
50
+ } else if (this.value === undefined) {
51
+ this.value = true
52
+ } else {
53
+ this.value = false
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,200 @@
1
+ import { ColumnConfig, GristConfig } from '../types'
2
+ import { LitElement, TemplateResult, html } from 'lit'
3
+ import {
4
+ OXBasicFieldProps,
5
+ OXCheckboxFieldProps,
6
+ OXNumberFieldProps,
7
+ OXSearchFieldProps,
8
+ OXSearchFieldTypes,
9
+ OXSearchForm,
10
+ OXSelectFieldProps,
11
+ OXTextFieldProps,
12
+ QueryFilter
13
+ } from '..'
14
+ import { customElement, property } from 'lit/decorators.js'
15
+
16
+ @customElement('ox-grist-search-form')
17
+ export class OXGristSearchForm extends LitElement {
18
+ @property({ type: Object }) config!: GristConfig
19
+ @property({ type: String }) defaultOperator: string = 'eq'
20
+
21
+ private timeout?: NodeJS.Timeout
22
+
23
+ render(): TemplateResult {
24
+ const fields: OXSearchFieldProps[] = this.convertToSearchFields(this.config)
25
+
26
+ return html` <ox-search-form .fields=${fields}></ox-search-form> `
27
+ }
28
+
29
+ private convertToSearchFields(config: GristConfig): OXSearchFieldProps[] {
30
+ const supportingTypes: string[] = ['string', 'integer', 'number', 'float', 'select', 'boolean', 'checkbox']
31
+
32
+ return config.columns
33
+ .filter((columnConfig: ColumnConfig) => supportingTypes.indexOf(columnConfig.type) >= 0)
34
+ .map((columnConfig: ColumnConfig) => {
35
+ let fieldProps: OXBasicFieldProps = {
36
+ name: columnConfig.name,
37
+ hidden: Boolean(columnConfig.hidden),
38
+ placeholder: typeof columnConfig.label === 'string' ? columnConfig.label : columnConfig.name
39
+ }
40
+
41
+ switch (columnConfig.type) {
42
+ case 'string':
43
+ return {
44
+ ...fieldProps,
45
+ type: 'text'
46
+ } as OXTextFieldProps
47
+
48
+ case 'integer':
49
+ return {
50
+ ...fieldProps,
51
+ type: 'number',
52
+ min: columnConfig.record?.options?.min || undefined,
53
+ max: columnConfig.record?.options?.max || undefined
54
+ } as OXNumberFieldProps
55
+
56
+ case 'number':
57
+ return {
58
+ ...fieldProps,
59
+ type: 'number',
60
+ min: columnConfig.record?.options?.min || undefined,
61
+ max: columnConfig.record?.options?.max || undefined
62
+ } as OXNumberFieldProps
63
+
64
+ case 'float':
65
+ return {
66
+ ...fieldProps,
67
+ type: 'number',
68
+ min: columnConfig.record?.options?.min || undefined,
69
+ max: columnConfig.record?.options?.max || undefined
70
+ } as OXNumberFieldProps
71
+
72
+ case 'select':
73
+ return {
74
+ ...fieldProps,
75
+ type: 'select',
76
+ searchEnable: true,
77
+ options: columnConfig.record?.options.map((option: string | Record<string, any>) => {
78
+ if (typeof option === 'string') {
79
+ return { value: option }
80
+ } else if (option.display && option.value) {
81
+ return {
82
+ name: option.display,
83
+ value: option.value
84
+ }
85
+ } else {
86
+ throw new Error('Unexpected option property')
87
+ }
88
+ })
89
+ } as OXSelectFieldProps
90
+
91
+ case 'boolean':
92
+ return {
93
+ ...fieldProps,
94
+ type: 'checkbox',
95
+ indeterminate: true
96
+ } as OXCheckboxFieldProps
97
+
98
+ case 'checkbox':
99
+ return {
100
+ ...fieldProps,
101
+ type: 'checkbox',
102
+ indeterminate: true
103
+ } as OXCheckboxFieldProps
104
+
105
+ default:
106
+ throw new Error('Non-supported type of column config')
107
+ }
108
+ })
109
+
110
+ // return searchFields
111
+ // .filter((searchField: string) => fieldMap.has(searchField))
112
+ // .map((searchField: string) => {
113
+ // const columnConfig: ColumnConfig | undefined = fieldMap.get(searchField)
114
+ // if (!columnConfig) throw new Error('No matched column config')
115
+
116
+ // let fieldProps: OXBasicFieldProps = {
117
+ // name: columnConfig.name,
118
+ // hidden: Boolean(columnConfig.hidden),
119
+ // label: typeof columnConfig.label === 'string' ? columnConfig.label : undefined
120
+ // }
121
+
122
+ // switch (columnConfig.type) {
123
+ // case 'string':
124
+ // return {
125
+ // ...fieldProps,
126
+ // type: 'text'
127
+ // } as OXTextFieldProps
128
+
129
+ // case 'integer':
130
+ // return {
131
+ // ...fieldProps,
132
+ // type: 'number',
133
+ // min: columnConfig.record?.options?.min || undefined,
134
+ // max: columnConfig.record?.options?.max || undefined
135
+ // } as OXNumberFieldProps
136
+
137
+ // case 'number':
138
+ // return {
139
+ // ...fieldProps,
140
+ // type: 'number',
141
+ // min: columnConfig.record?.options?.min || undefined,
142
+ // max: columnConfig.record?.options?.max || undefined
143
+ // } as OXNumberFieldProps
144
+
145
+ // case 'float':
146
+ // return {
147
+ // ...fieldProps,
148
+ // type: 'number',
149
+ // min: columnConfig.record?.options?.min || undefined,
150
+ // max: columnConfig.record?.options?.max || undefined
151
+ // } as OXNumberFieldProps
152
+
153
+ // case 'select':
154
+ // return {
155
+ // ...fieldProps,
156
+ // type: 'select',
157
+ // searchEnable: true,
158
+ // options: columnConfig.record?.options.map((option: Record<string, any>) => ({
159
+ // name: option.display,
160
+ // value: option.value
161
+ // }))
162
+ // } as OXSelectFieldProps
163
+
164
+ // case 'boolean':
165
+ // return {
166
+ // ...fieldProps,
167
+ // type: 'checkbox',
168
+ // indeterminate: true
169
+ // } as OXCheckboxFieldProps
170
+
171
+ // case 'checkbox':
172
+ // return {
173
+ // ...fieldProps,
174
+ // type: 'checkbox',
175
+ // indeterminate: true
176
+ // } as OXCheckboxFieldProps
177
+
178
+ // default:
179
+ // throw new Error('Non-supported type of column config')
180
+ // }
181
+ // })
182
+ }
183
+
184
+ get queryFilters(): QueryFilter[] {
185
+ const searchForm: OXSearchForm | null = this.renderRoot.querySelector<OXSearchForm>('ox-search-form')
186
+ if (!searchForm) throw new Error('Failed to find search form')
187
+
188
+ const searchFields: OXSearchFieldTypes[] = searchForm.searchFields
189
+
190
+ return searchFields
191
+ .filter(({ value }: OXSearchFieldTypes) => value !== null && value !== undefined && value !== '')
192
+ .map((searchField: OXSearchFieldTypes) => {
193
+ return {
194
+ name: searchField.field.name,
195
+ operator: searchField.field.operator || this.defaultOperator,
196
+ value: searchField.value
197
+ }
198
+ })
199
+ }
200
+ }