@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,33 @@
1
+ import '@operato/input/ox-input-barcode.js'
2
+
3
+ import { html } from 'lit-html'
4
+
5
+ import { FilterConfigObject, FilterSelectRenderer } from '../types.js'
6
+
7
+ export const FilterInputBarcode: FilterSelectRenderer = (column, value, owner) => {
8
+ const filter = column.filter as FilterConfigObject
9
+ const { englishOnly, selectAfterChange } = filter.options || {}
10
+
11
+ return html`
12
+ <ox-input-barcode
13
+ name=${column.name}
14
+ ?english-only=${englishOnly}
15
+ ?select-after-change=${selectAfterChange}
16
+ .value=${value == null ? '' : value}
17
+ @change=${(e: CustomEvent) => {
18
+ const input = e.target as HTMLInputElement
19
+ input.dispatchEvent(
20
+ new CustomEvent('filter-change', {
21
+ bubbles: true,
22
+ composed: true,
23
+ detail: {
24
+ name: column.name,
25
+ operator: filter.operator,
26
+ value: input.value
27
+ }
28
+ })
29
+ )
30
+ }}
31
+ />
32
+ `
33
+ }
@@ -1,7 +1,7 @@
1
- import { FilterConfigObject, FilterSelectRenderer } from '../types'
2
-
3
1
  import { html } from 'lit-html'
4
2
 
3
+ import { FilterConfigObject, FilterSelectRenderer } from '../types'
4
+
5
5
  export const FilterInput: FilterSelectRenderer = (column, value, owner) => {
6
6
  const filter = column.filter as FilterConfigObject
7
7
  const type = filter?.type || column.type
@@ -10,7 +10,7 @@ export const FilterInput: FilterSelectRenderer = (column, value, owner) => {
10
10
  <input
11
11
  type=${type}
12
12
  name=${column.name}
13
- .value=${value === undefined ? '' : value}
13
+ .value=${value == null ? '' : value}
14
14
  @change=${(e: CustomEvent) => {
15
15
  const input = e.target as HTMLInputElement
16
16
  input.dispatchEvent(
@@ -26,17 +26,14 @@ export const FilterStyles = css`
26
26
  text-transform: capitalize;
27
27
  }
28
28
 
29
- [filter] input::placeholder,
30
29
  input::placeholder {
31
30
  color: var(--ox-input-placeholder-color);
32
31
  opacity: 0.6;
33
32
  }
34
- [filter] input,
33
+
35
34
  ox-select,
36
- input[type='number'],
37
- input[type='text'],
38
- input[type='datetime-local'] {
39
- padding: var(--ox-input-padding);
35
+ input {
36
+ padding: var(--input-padding);
40
37
  border: none;
41
38
  border-bottom: var(--ox-input-border);
42
39
  font: var(--ox-input-font);
@@ -44,9 +41,7 @@ export const FilterStyles = css`
44
41
  }
45
42
 
46
43
  ox-select:focus,
47
- input[type='number']:focus,
48
- input[type='text']:focus,
49
- input[type='datetime-local']:focus {
44
+ input:focus {
50
45
  outline: none;
51
46
  border-bottom: var(--ox-input-focus-border);
52
47
  color: var(--primary-color);
@@ -55,37 +50,37 @@ export const FilterStyles = css`
55
50
  padding: var(--ox-select-padding);
56
51
  }
57
52
 
58
- [filter] input[type='number'],
59
53
  input[type='number'] {
60
54
  padding-right: var(--padding-narrow);
61
55
  max-width: 90px;
62
56
  }
63
- [filter] input[type='datetime-local'],
64
- input[type='datetime-local'] {
65
- padding-right: var(--padding-narrow);
57
+
58
+ input[type*='date'],
59
+ input[type*='time'],
60
+ input[type='week'],
61
+ input[type='month'] {
62
+ padding: 8px var(--padding-narrow) 8px var(--padding-default);
66
63
  max-width: 170px;
67
64
  }
68
- [filter] input[name='from'] {
69
- margin: 0 0 5px 10px;
70
- }
71
- [filter] input[name='to'] {
72
- margin: 0 10px 5px 0;
73
- }
74
65
 
75
66
  @media only screen and (max-width: 460px) {
76
67
  :host {
77
68
  --ox-filters-form-label-font: bold 13px var(--theme-font);
78
69
  --ox-input-font: normal 16px var(--theme-font);
70
+ --ox-filters-form-gap: var(--margin-narrow);
79
71
  }
72
+
80
73
  ox-checkbox {
81
74
  margin-top: var(--margin-narrow);
82
75
  }
83
- [filter] input[type='number'],
84
- input[type='number'] {
76
+
77
+ input[from],
78
+ input[to] {
85
79
  max-width: 44%;
86
80
  }
87
- [filter] input[type='datetime-local'],
88
- input[type='datetime-local'] {
81
+
82
+ input[type*='datetime'][from],
83
+ input[type*='datetime'][to] {
89
84
  padding-right: var(--padding-narrow);
90
85
  min-width: 91%;
91
86
  }
@@ -77,7 +77,7 @@ export class FiltersForm extends LitElement {
77
77
  this.config = (e as CustomEvent).detail
78
78
  })
79
79
 
80
- grist.addEventListener('filters-change', (e: Event) => {
80
+ grist.addEventListener('fetch-params-change', (e: Event) => {
81
81
  const { filters, from } = (e as CustomEvent).detail || {}
82
82
  if (from === 'filters-form') {
83
83
  return
@@ -88,7 +88,7 @@ export class FiltersForm extends LitElement {
88
88
 
89
89
  this.renderRoot.addEventListener('change', async (e: Event) => {
90
90
  this.dispatchEvent(
91
- new CustomEvent('filters-change', {
91
+ new CustomEvent('fetch-params-change', {
92
92
  bubbles: true,
93
93
  composed: true,
94
94
  detail: {
@@ -137,7 +137,9 @@ export class FiltersForm extends LitElement {
137
137
  >
138
138
  ${this.searchColumns.length === 0
139
139
  ? html``
140
- : html` <ox-input-search name="search" .value=${searchValue}></ox-input-search> `}
140
+ : html`
141
+ <ox-input-search name="search" .value=${searchValue} ?autofocus=${this.autofocus}></ox-input-search>
142
+ `}
141
143
  ${this.filterColumns.map((column: ColumnConfig) => {
142
144
  const { name, header, label, filter } = column
143
145
  const labelText =
@@ -1,9 +1,10 @@
1
- import { FilterSelectRenderer } from '../types'
2
- import { FilterCheckbox } from './filter-checkbox'
3
- import { FilterInput } from './filter-input'
4
- import { FilterRangeDate } from './filter-range-date'
5
- import { FilterRangeNumber } from './filter-range-number'
6
- import { FilterSelect } from './filter-select'
1
+ import { FilterSelectRenderer } from '../types.js'
2
+ import { FilterCheckbox } from './filter-checkbox.js'
3
+ import { FilterInputBarcode } from './filter-input-barcode.js'
4
+ import { FilterInput } from './filter-input.js'
5
+ import { FilterRangeDate } from './filter-range-date.js'
6
+ import { FilterRangeNumber } from './filter-range-number.js'
7
+ import { FilterSelect } from './filter-select.js'
7
8
 
8
9
  var RENDERERS: {
9
10
  [name: string]: FilterSelectRenderer[]
@@ -27,7 +28,9 @@ var RENDERERS: {
27
28
  progress: [FilterInput, FilterRangeNumber],
28
29
  link: [FilterInput],
29
30
  image: [FilterInput],
30
- json5: [FilterInput]
31
+ json5: [FilterInput],
32
+ scanner: [FilterInputBarcode],
33
+ barcode: [FilterInputBarcode]
31
34
  }
32
35
 
33
36
  export function registerFilterRenderer(type: string, renderer: FilterSelectRenderer[]) {
@@ -43,7 +46,7 @@ export function getFilterRenderers(): { [name: string]: FilterSelectRenderer[] }
43
46
  }
44
47
 
45
48
  export function getFilterRenderer(type: string): FilterSelectRenderer[] {
46
- if (typeof type == 'function') {
49
+ if (typeof type === 'function') {
47
50
  return type
48
51
  }
49
52
 
@@ -6,7 +6,7 @@ import { FieldRenderer, HeaderRenderer } from '../types'
6
6
 
7
7
  export class GutterButton {
8
8
  static instance(config: any = {}) {
9
- var { icon = 'edit' } = config
9
+ var { icon = 'edit', title } = config
10
10
 
11
11
  var iconFn = typeof icon == 'function' ? icon : () => icon
12
12
 
@@ -23,17 +23,18 @@ export class GutterButton {
23
23
  sortable: false,
24
24
  header: {
25
25
  renderer: function (column) {
26
- return html` <mwc-icon style=${inlineHeaderStyle}>${iconFn()}</mwc-icon> `
26
+ return html` <mwc-icon style=${inlineHeaderStyle} title=${title}>${iconFn()}</mwc-icon> `
27
27
  } as HeaderRenderer
28
28
  },
29
29
  record: {
30
30
  align: 'center',
31
31
  renderer: function (value, column, record, rowIndex, field) {
32
- return html` <mwc-icon style=${inlineRecordStyle}>${iconFn(record)}</mwc-icon> `
32
+ return html` <mwc-icon style=${inlineRecordStyle} title=${title}>${iconFn(record)}</mwc-icon> `
33
33
  } as FieldRenderer
34
34
  },
35
35
  forGrid: true,
36
- forList: true
36
+ forList: true,
37
+ forCard: true
37
38
  },
38
39
  config
39
40
  )
@@ -1,9 +1,10 @@
1
1
  import '@material/mwc-icon'
2
2
 
3
- import { ColumnConfig, FieldRenderer } from '../types'
4
- import { LitElement, css, html } from 'lit'
3
+ import { css, html, LitElement } from 'lit'
5
4
  import { customElement, property } from 'lit/decorators.js'
6
5
 
6
+ import { ColumnConfig, FieldRenderer, GristEventHandler } from '../types'
7
+
7
8
  @customElement('ox-gutter-dirty-element')
8
9
  class GutterDirtyElement extends LitElement {
9
10
  static styles = css`
@@ -65,7 +66,24 @@ export class GutterDirty {
65
66
  } as FieldRenderer
66
67
  },
67
68
  forGrid: true,
68
- forList: false
69
+ forList: false,
70
+ forCard: false,
71
+ handlers: {
72
+ dblclick: ((columns, data, column, record, rowIndex, target) => {
73
+ target.dispatchEvent(
74
+ new CustomEvent('set-select-block', {
75
+ bubbles: true,
76
+ composed: true,
77
+ detail: {
78
+ startRow: rowIndex,
79
+ startColumn: 0,
80
+ endRow: rowIndex,
81
+ endColumn: -1
82
+ }
83
+ })
84
+ )
85
+ }) as GristEventHandler
86
+ }
69
87
  },
70
88
  config
71
89
  )
@@ -77,7 +77,8 @@ export class GutterRowSelector {
77
77
  } as FieldRenderer
78
78
  },
79
79
  forGrid: true,
80
- forList: true
80
+ forList: true,
81
+ forCard: true
81
82
  },
82
83
  config
83
84
  )
@@ -1,8 +1,7 @@
1
- import { ColumnWidthCallback, FieldRenderer } from '../types'
2
-
3
1
  import { DataCard } from '../data-card/data-card'
4
2
  import { DataGrid } from '../data-grid/data-grid'
5
3
  import { DataList } from '../data-list/data-list'
4
+ import { ColumnWidthCallback, FieldRenderer, GristEventHandler } from '../types'
6
5
 
7
6
  export class GutterSequence {
8
7
  static instance(config = {} as any) {
@@ -31,6 +30,23 @@ export class GutterSequence {
31
30
  },
32
31
  forGrid: true,
33
32
  forList: false,
33
+ forCard: false,
34
+ handlers: {
35
+ dblclick: ((columns, data, column, record, rowIndex, target) => {
36
+ target.dispatchEvent(
37
+ new CustomEvent('set-select-block', {
38
+ bubbles: true,
39
+ composed: true,
40
+ detail: {
41
+ startRow: rowIndex,
42
+ startColumn: 0,
43
+ endRow: rowIndex,
44
+ endColumn: -1
45
+ }
46
+ })
47
+ )
48
+ }) as GristEventHandler
49
+ },
34
50
  ...config
35
51
  }
36
52
  }
@@ -12,7 +12,7 @@ export function recordViewBodyClickHandler(this: RecordViewBody, e: Event): void
12
12
  /* target should be 'ox-grid-field' */
13
13
  var target = e.target as DataGridField
14
14
 
15
- if (!this.onlyForEdit && this.currentTarget) {
15
+ if (this.currentTarget) {
16
16
  this.focus()
17
17
  this.currentTarget.removeAttribute('editing')
18
18
  }
@@ -24,7 +24,5 @@ export function recordViewBodyClickHandler(this: RecordViewBody, e: Event): void
24
24
  }
25
25
 
26
26
  this.currentTarget = target
27
- if (!this.onlyForEdit) {
28
- target.setAttribute('editing', 'true')
29
- }
27
+ target.setAttribute('editing', 'true')
30
28
  }
@@ -12,9 +12,9 @@ export async function recordViewBodyKeydownHandler(this: RecordViewBody, e: Even
12
12
  /* TODO 편집이 취소되어야 한다. */
13
13
  case 'Enter':
14
14
  /* 먼저, focus를 옮겨놓아야, focusout 으로 인해서 popup이 닫히는 것을 방지할 수 있다. */
15
- !this.onlyForEdit && this.focus()
15
+ this.focus()
16
16
 
17
- if (!this.onlyForEdit && this.currentTarget) {
17
+ if (this.currentTarget) {
18
18
  this.currentTarget.removeAttribute('editing')
19
19
  }
20
20
 
@@ -53,7 +53,6 @@ export class RecordCreator extends LitElement {
53
53
  template: html`
54
54
  <div title>${title}</div>
55
55
  <ox-record-view
56
- only-for-edit
57
56
  @field-change=${(e: CustomEvent) => {
58
57
  const view = e.currentTarget as RecordView
59
58
 
@@ -116,7 +115,6 @@ export class RecordCreator extends LitElement {
116
115
 
117
116
  var recordView = document.createElement('ox-record-view') as RecordView
118
117
 
119
- recordView.setAttribute('only-for-edit', '')
120
118
  recordView.columns = columns
121
119
  recordView.record = record
122
120
  recordView.rowIndex = rowIndex
@@ -65,7 +65,6 @@ export class RecordViewBody extends LitElement {
65
65
  @property({ type: Array }) columns: ColumnConfig[] = []
66
66
  @property({ type: Object }) record: GristRecord = ZERO_RECORD
67
67
  @property({ type: Number }) rowIndex: number = -1
68
- @property({ type: Boolean, attribute: 'only-for-edit' }) onlyForEdit: boolean = false
69
68
 
70
69
  public currentTarget: any
71
70
 
@@ -98,7 +97,6 @@ export class RecordViewBody extends LitElement {
98
97
  .record=${record}
99
98
  .value=${record[column.name]}
100
99
  ?dirty=${!!dirtyFields[column.name]}
101
- ?editing=${this.onlyForEdit}
102
100
  ></ox-grid-field>
103
101
  `
104
102
  })}
@@ -63,16 +63,10 @@ export class RecordView extends LitElement {
63
63
  @property({ type: Array }) columns: ColumnConfig[] = []
64
64
  @property({ type: Object }) record: GristRecord = ZERO_RECORD
65
65
  @property({ type: Number }) rowIndex: number = -1
66
- @property({ type: Boolean, attribute: 'only-for-edit' }) onlyForEdit: boolean = false
67
66
 
68
67
  render() {
69
68
  return html`
70
- <ox-record-view-body
71
- .columns=${this.columns}
72
- .record=${this.record}
73
- .rowIndex=${this.rowIndex}
74
- ?only-for-edit=${this.onlyForEdit}
75
- >
69
+ <ox-record-view-body .columns=${this.columns} .record=${this.record} .rowIndex=${this.rowIndex}>
76
70
  </ox-record-view-body>
77
71
  <div footer>
78
72
  <button @click=${this.onReset.bind(this)}><mwc-icon>refresh</mwc-icon>Reset</button>
@@ -1,8 +1,9 @@
1
- import { FieldRenderer } from '../types'
2
1
  import { html } from 'lit'
3
2
 
3
+ import { FieldRenderer } from '../types'
4
+
4
5
  export const OxGristRendererColor: FieldRenderer = (value, column, record, rowIndex, field) => {
5
- value = value === undefined ? '#000' : value
6
+ value = value == null ? '#000' : value
6
7
 
7
8
  return html`
8
9
  <div
@@ -1,7 +1,8 @@
1
- import { FieldRenderer } from '../types'
2
1
  import JSON5 from 'json5'
3
2
  import { html } from 'lit'
4
3
 
4
+ import { FieldRenderer } from '../types'
5
+
5
6
  function onmouseover(e: Event) {
6
7
  const element = e.target as HTMLPreElement
7
8
  var parsed
@@ -26,6 +27,6 @@ export const OxGristRendererJson5: FieldRenderer = (value, column, record, rowIn
26
27
  } catch {}
27
28
  }
28
29
 
29
- const text = parsed === undefined || parsed === null ? '' : JSON5.stringify(parsed)
30
+ const text = parsed == null ? '' : JSON5.stringify(parsed)
30
31
  return html`<pre @mouseover=${onmouseover} @mouseout=${onmouseout}>${text}</pre>`
31
32
  }
@@ -1,10 +1,11 @@
1
- import { FieldRenderer } from '../types'
2
1
  import { html } from 'lit'
3
2
 
3
+ import { FieldRenderer } from '../types'
4
+
4
5
  export const OxGristRendererLink: FieldRenderer = (value, column, record, rowIndex, field) => {
5
6
  var { href, target } = column.record.options || {}
6
7
 
7
- value = value === undefined ? '' : value
8
+ value = value == null ? '' : value
8
9
 
9
10
  if (typeof href == 'function') {
10
11
  href = href(value, column, record, rowIndex, field)
@@ -3,7 +3,7 @@ import { html } from 'lit'
3
3
  import { FieldRenderer } from '../types'
4
4
 
5
5
  export const OxGristRendererSelect: FieldRenderer = (value, column, record, rowIndex, field) => {
6
- if (!value) {
6
+ if (value == null) {
7
7
  return ''
8
8
  }
9
9
  var rowOptionField = column.record.rowOptionField && record[column.record.rowOptionField]
@@ -15,7 +15,7 @@ export const OxGristRendererSelect: FieldRenderer = (value, column, record, rowI
15
15
  options = options.call(null, value, column, record, rowIndex, field)
16
16
  }
17
17
 
18
- var res = options ? options.filter((option: any) => option.value == value) : []
18
+ var res = options ? options.filter((option: any) => option.value == String(value == null ? '' : value)) : []
19
19
  if (res.length) {
20
20
  return html`<span>${res[0].display}</span>`
21
21
  }
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit'
2
2
 
3
- import { detectOverflow } from '@operato/utils'
3
+ import { detectOverflow, format as formatter } from '@operato/utils'
4
4
 
5
5
  import { FieldRenderer } from '../types'
6
6
 
@@ -17,6 +17,12 @@ function onmouseout(e: Event) {
17
17
  }
18
18
 
19
19
  export const OxGristRendererText: FieldRenderer = (value, column, record, rowIndex, field) => {
20
- const text = value === undefined ? '' : value
20
+ var { format } = column.record || {}
21
+
22
+ var text = value == null ? '' : value
23
+ if (format) {
24
+ text = formatter(format, text)
25
+ }
26
+
21
27
  return html`<span @mouseover=${onmouseover} @mouseout=${onmouseout}>${text}</span>`
22
28
  }
@@ -1,8 +1,8 @@
1
- import { ColumnConfig, GristConfig, SorterConfig } from '../types'
2
- import { LitElement, PropertyValues, TemplateResult, css, html } from 'lit'
1
+ import { css, html, LitElement, PropertyValues, TemplateResult } from 'lit'
3
2
  import { customElement, state } from 'lit/decorators.js'
4
3
 
5
4
  import { DataGrist } from '../data-grist'
5
+ import { ColumnConfig, GristConfig, SorterConfig } from '../types'
6
6
 
7
7
  @customElement('ox-sorters-control')
8
8
  export class SortersControl extends LitElement {
@@ -55,22 +55,19 @@ export class SortersControl extends LitElement {
55
55
  this.config = (e as CustomEvent).detail
56
56
  })
57
57
 
58
- grist.addEventListener('sorters-change', e => {
58
+ grist.addEventListener('fetch-params-change', e => {
59
59
  const { sorters, from } = (e as CustomEvent).detail || {}
60
60
  if (from === 'sorters-control') {
61
61
  return
62
62
  }
63
63
 
64
- this.sorters = sorters
64
+ sorters && (this.sorters = sorters)
65
65
  })
66
66
  }
67
67
  }
68
68
 
69
69
  updated(changes: PropertyValues<this>) {
70
- // TODO config 에 의한 sorters 설정은 제거해야 한다.
71
70
  if (changes.has('config')) {
72
- const sorters = this.config.sorters || []
73
-
74
71
  this.columns = this.config.columns.filter(column => column.sortable)
75
72
  this.sorters = this.sorters || this.config.sorters || []
76
73
  }
@@ -102,7 +99,7 @@ export class SortersControl extends LitElement {
102
99
  ${desc === null
103
100
  ? html``
104
101
  : html`
105
- <mwc-icon>${desc ? 'keyboard_arrow_up' : 'keyboard_arrow_down'}</mwc-icon>
102
+ <mwc-icon>${desc ? 'keyboard_arrow_down' : 'keyboard_arrow_up'}</mwc-icon>
106
103
  ${rank === 0 ? html`` : html`<sub>${rank}</sub>`}
107
104
  `}
108
105
  </div>
@@ -133,7 +130,7 @@ export class SortersControl extends LitElement {
133
130
  this.sorters = sorters
134
131
 
135
132
  this.dispatchEvent(
136
- new CustomEvent('sorters-change', {
133
+ new CustomEvent('fetch-params-change', {
137
134
  bubbles: true,
138
135
  composed: true,
139
136
  detail: {
package/src/types.ts CHANGED
@@ -1,14 +1,16 @@
1
+ import { TemplateResult } from 'lit-html'
2
+
1
3
  import { DataCardField } from './data-card/data-card-field'
2
4
  import { DataCardGutter } from './data-card/data-card-gutter'
5
+ import { RecordCard } from './data-card/record-card'
3
6
  import { DataGridField } from './data-grid/data-grid-field'
4
7
  import { DataListField } from './data-list/data-list-field'
5
8
  import { DataListGutter } from './data-list/data-list-gutter'
9
+ import { RecordPartial } from './data-list/record-partial'
6
10
  import { DataReportField } from './data-report/data-report-field'
7
11
  import { OxGristEditor } from './editors'
12
+ import { QueryFilter } from './filters'
8
13
  import { OxGristRenderer } from './renderers/ox-grist-renderer'
9
- import { RecordCard } from './data-card/record-card'
10
- import { RecordPartial } from './data-list/record-partial'
11
- import { TemplateResult } from 'lit-html'
12
14
 
13
15
  export type GristConfig = {
14
16
  columns: ColumnConfig[]
@@ -50,6 +52,7 @@ export type FilterConfigObject = {
50
52
  type: string
51
53
  operator?: FilterOperator
52
54
  options?: { [key: string]: any }
55
+ value?: string | number | boolean | string[] | number[] | undefined
53
56
  }
54
57
  export type FilterConfig = FilterConfigObject | FilterOperator | boolean
55
58
 
@@ -70,7 +73,8 @@ export type FetchOption = {
70
73
  page?: number
71
74
  limit?: number
72
75
  sorters?: SortersConfig
73
- filters?: FilterConfigObject[]
76
+ sortings?: SortersConfig
77
+ filters?: QueryFilter[]
74
78
  options?: object
75
79
  }
76
80
  export type FetchResult = {