@neovici/cosmoz-omnitable 7.2.1 → 8.0.0-beta.3

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 (50) hide show
  1. package/README.md +25 -0
  2. package/cosmoz-omnitable-column-amount.js +89 -320
  3. package/cosmoz-omnitable-column-autocomplete.js +36 -47
  4. package/cosmoz-omnitable-column-boolean.js +107 -209
  5. package/cosmoz-omnitable-column-date.js +89 -102
  6. package/cosmoz-omnitable-column-datetime.js +86 -119
  7. package/cosmoz-omnitable-column-list-data.js +4 -1
  8. package/cosmoz-omnitable-column-list-horizontal.js +20 -38
  9. package/cosmoz-omnitable-column-list-mixin.js +133 -140
  10. package/cosmoz-omnitable-column-list.js +19 -28
  11. package/cosmoz-omnitable-column-mixin.js +69 -447
  12. package/cosmoz-omnitable-column-number.js +91 -183
  13. package/cosmoz-omnitable-column-time.js +77 -162
  14. package/cosmoz-omnitable-column.js +49 -93
  15. package/cosmoz-omnitable-group-row.js +1 -5
  16. package/cosmoz-omnitable-header-row.js +9 -6
  17. package/cosmoz-omnitable-item-expand.js +0 -3
  18. package/cosmoz-omnitable-item-row.js +5 -8
  19. package/cosmoz-omnitable-styles.js +4 -8
  20. package/cosmoz-omnitable.js +72 -764
  21. package/lib/cosmoz-omnitable-amount-range-input.js +295 -0
  22. package/{cosmoz-omnitable-column-date-mixin.js → lib/cosmoz-omnitable-date-input-mixin.js} +4 -26
  23. package/lib/cosmoz-omnitable-date-range-input.js +81 -0
  24. package/lib/cosmoz-omnitable-datetime-range-input.js +75 -0
  25. package/lib/cosmoz-omnitable-number-range-input.js +159 -0
  26. package/{cosmoz-omnitable-column-range-mixin.js → lib/cosmoz-omnitable-range-input-mixin.js} +45 -123
  27. package/lib/cosmoz-omnitable-settings.js +8 -5
  28. package/lib/cosmoz-omnitable-time-range-input.js +130 -0
  29. package/lib/generic-sorter.js +2 -2
  30. package/lib/invoke.js +1 -0
  31. package/lib/memoize.js +54 -0
  32. package/lib/polymer-haunted-render-mixin.js +19 -0
  33. package/lib/save-as-csv-action.js +32 -0
  34. package/lib/save-as-xlsx-action.js +25 -0
  35. package/lib/use-canvas-width.js +1 -1
  36. package/lib/use-dom-columns.js +138 -0
  37. package/lib/use-hash-state.js +59 -0
  38. package/lib/use-layout.js +1 -1
  39. package/lib/use-omnitable.js +26 -14
  40. package/lib/use-processed-items.js +132 -0
  41. package/lib/use-sort-and-group-options.js +30 -0
  42. package/lib/utils-amount.js +147 -0
  43. package/lib/utils-data.js +36 -0
  44. package/lib/utils-date.js +204 -0
  45. package/lib/utils-datetime.js +71 -0
  46. package/lib/utils-number.js +112 -0
  47. package/lib/utils-time.js +115 -0
  48. package/package.json +1 -2
  49. package/lib/use-force-render.js +0 -8
  50. package/lib/use-render-on-column-updates.js +0 -18
@@ -3,121 +3,77 @@ import '@polymer/iron-icon/iron-icon';
3
3
  import '@polymer/paper-input/paper-input';
4
4
  import './ui-helpers/cosmoz-clear-button';
5
5
 
6
- import { columnMixin } from './cosmoz-omnitable-column-mixin';
6
+ import { applySingleFilter, columnMixin, getString } from './cosmoz-omnitable-column-mixin';
7
7
  import { PolymerElement } from '@polymer/polymer/polymer-element';
8
- import { timeOut } from '@polymer/polymer/lib/utils/async.js';
9
- import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
10
- import { enqueueDebouncer } from '@polymer/polymer/lib/utils/flush.js';
11
8
  import { html } from 'lit-html';
12
9
 
10
+ const
11
+ onChange = setState => event => setState(state => {
12
+ clearInterval(state.t);
13
+ const t = setTimeout(() => setState(state => ({ ...state, filter: state.inputValue })), 1000);
14
+ return { ...state, inputValue: event.target.value, t };
15
+ }),
16
+
17
+ onBlur = setState => () =>
18
+ setState(state => ({ ...state, filter: state.inputValue })),
19
+
20
+ onKeyDown = setState => event => {
21
+ if (event.keyCode === 13) {
22
+ event.preventDefault();
23
+ setState(state => ({ ...state, filter: state.inputValue }));
24
+ }
25
+ },
26
+
27
+ onFocus = setState => event =>
28
+ setState(state => ({ ...state, headerFocused: event.detail.value })),
29
+
30
+ resetFilter = setState => () =>
31
+ setState(state => ({ ...state, filter: undefined, inputValue: undefined })),
32
+
33
+ hasFilter = filter => filter != null && filter !== '';
34
+
13
35
  /**
14
36
  * @polymer
15
37
  * @customElement
16
38
  * @appliesMixin columnMixin
17
39
  */
18
40
  class OmnitableColumn extends columnMixin(PolymerElement) {
19
- static get is() {
20
- return 'cosmoz-omnitable-column';
21
- }
22
-
23
41
  static get properties() {
24
42
  return {
25
- minWidth: {
26
- type: String,
27
- value: '55px'
28
- },
29
-
30
- editMinWidth: {
31
- type: String,
32
- value: '55px'
33
- },
34
-
35
- inputValue: {
36
- type: Object,
37
- notify: true,
38
- value() {
39
- return this._getDefaultFilter();
40
- },
41
- observer: '_inputValueValueChanged'
42
- },
43
-
44
- _timeForNoInput: {
45
- type: Number,
46
- value: 1000
47
- }
43
+ minWidth: { type: String, value: '55px' },
44
+ editMinWidth: { type: String, value: '55px' },
45
+ inputValue: { type: Object, notify: true }
48
46
  };
49
47
  }
50
48
 
49
+ getFilterFn(column, filter) {
50
+ if (filter == null || filter === '') {
51
+ return;
52
+ }
53
+ return applySingleFilter(column, filter);
54
+ }
55
+
51
56
  renderCell(column, { item }) {
52
- return html`<span class="default-column">${ column.getString(item, column.valuePath) }</span>`;
57
+ return html`<span class="default-column">${ getString(column, item) }</span>`;
53
58
  }
54
59
 
55
- renderEditCell(column, { item }) {
56
- const onChange = event => {
57
- event.model = { item };
58
- return column._valueChanged(event);
59
- };
60
- return html`<paper-input no-label-float type="text" @change=${ onChange } .value=${ column.getString(item, column.valuePath) }></paper-input>`;
60
+ renderEditCell(column, { item }, onItemChange) {
61
+ const onChange = event => onItemChange(event.target.value);
62
+ return html`<paper-input no-label-float type="text" @change=${ onChange } .value=${ getString(column, item) }></paper-input>`;
61
63
  }
62
64
 
63
- renderHeader(column) {
65
+ renderHeader(column, { filter, inputValue, headerFocused }, setState) {
64
66
  return html`<paper-input
65
67
  label=${ column.title }
66
- .value=${ column.inputValue }
67
- @value-changed=${ event => column.inputValue = event.target.value }
68
- focused=${ column.headerFocused }
69
- @focused-changed=${ event => column.headerFocused = event.detail.value }
70
- @keydown=${ column._onKeyDown }
71
- @blur=${ column._onBlur }
68
+ .value=${ inputValue ?? filter }
69
+ @value-changed=${ onChange(setState) }
70
+ focused=${ headerFocused }
71
+ @focused-changed=${ onFocus(setState) }
72
+ @keydown=${ onKeyDown(setState) }
73
+ @blur=${ onBlur(setState) }
72
74
  >
73
- <cosmoz-clear-button suffix slot="suffix" ?visible=${ column.hasFilter() } light @click=${ () => column.resetFilter() }></cosmoz-clear-button>
75
+ <cosmoz-clear-button suffix slot="suffix" ?visible=${ hasFilter(filter) } light @click=${ resetFilter(setState) }></cosmoz-clear-button>
74
76
  </paper-input>`;
75
77
  }
76
-
77
- _serializeFilter(filter = this.filter) {
78
- return filter || null;
79
- }
80
-
81
- _deserializeFilter(obj) {
82
- return obj || null;
83
- }
84
-
85
- resetFilter() {
86
- this.filter = null;
87
- this.inputValue = null;
88
- }
89
-
90
- __filterChanged(change) {
91
- super.__filterChanged(change);
92
- if (change.value != null && change.value !== this.inputValue) {
93
- this.inputValue = change.value;
94
- }
95
- }
96
-
97
- _onBlur() {
98
- this.filter = this.inputValue;
99
- }
100
-
101
- _onKeyDown(event) {
102
- switch (event.keyCode) {
103
- case 13: // Enter
104
- event.preventDefault();
105
- this.filter = this.inputValue;
106
- break;
107
- }
108
- }
109
-
110
- _inputValueValueChanged() {
111
- if (this.inputValue === '') {
112
- this.filter = this.inputValue;
113
- return;
114
- }
115
- this._debouncer = Debouncer.debounce(this._debouncer,
116
- timeOut.after(this._timeForNoInput),
117
- () => {
118
- this.filter = this.inputValue;
119
- });
120
- enqueueDebouncer(this._debouncer);
121
- }
122
78
  }
123
- customElements.define(OmnitableColumn.is, OmnitableColumn);
79
+ customElements.define('cosmoz-omnitable-column', OmnitableColumn);
@@ -1,11 +1,7 @@
1
- import { component, useMemo } from 'haunted';
1
+ import { component } from 'haunted';
2
2
  import { nothing } from 'lit-html';
3
- import { useRenderOnColumnUpdates } from './lib/use-render-on-column-updates';
4
3
 
5
4
  const GroupRow = ({ column, item, selected, folded }) => {
6
- const columns = useMemo(() => column ? [column] : [], [column]);
7
- useRenderOnColumnUpdates(columns);
8
-
9
5
  if (!column) {
10
6
  return nothing;
11
7
  }
@@ -1,18 +1,22 @@
1
1
  /* eslint-disable object-curly-newline */
2
2
  import { html, component } from 'haunted';
3
3
  import { repeat } from 'lit-html/directives/repeat';
4
- import { useRenderOnColumnUpdates } from './lib/use-render-on-column-updates';
5
4
  import './lib/cosmoz-omnitable-resize-nub';
6
5
 
7
6
  const
8
- renderHeaderRow = ({ columns, groupOnColumn }) => {
7
+ renderHeaderRow = ({ data, columns, groupOnColumn, filters, setFilterState }) => {
9
8
  return repeat(columns, column => column.name, column => [
10
9
  html`<div
11
10
  class="cell ${ column.headerCellClass } header-cell"
12
11
  ?hidden=${ column === groupOnColumn }
13
12
  title=${ column.title }
14
13
  name=${ column.name }
15
- >${ column.renderHeader(column) }</div>`,
14
+ >${ column.renderHeader(
15
+ column,
16
+ filters[column.name] ?? {},
17
+ state => setFilterState(column.name, state),
18
+ column.source(column, data)
19
+ ) }</div>`,
16
20
  html`<cosmoz-omnitable-resize-nub
17
21
  .column=${ column }
18
22
  name=${ column.name }
@@ -20,9 +24,8 @@ const
20
24
  ]);
21
25
  },
22
26
 
23
- HeaderRow = ({ columns, groupOnColumn, content }) => {
24
- useRenderOnColumnUpdates(columns);
25
- return [columns && renderHeaderRow({ columns, groupOnColumn }), content];
27
+ HeaderRow = ({ data, columns, groupOnColumn, content, filters, setFilterState }) => {
28
+ return [columns && renderHeaderRow({ data, columns, groupOnColumn, filters, setFilterState }), content];
26
29
  };
27
30
 
28
31
  customElements.define('cosmoz-omnitable-header-row', component(HeaderRow, { useShadowDOM: false }));
@@ -3,7 +3,6 @@ import { component, useEffect } from 'haunted';
3
3
  import {
4
4
  html, nothing
5
5
  } from 'lit-html';
6
- import { useRenderOnColumnUpdates } from './lib/use-render-on-column-updates';
7
6
  import './cosmoz-omnitable-item-expand-line';
8
7
 
9
8
  const
@@ -15,8 +14,6 @@ const
15
14
  >${ column.renderCell(column, { item, selected, expanded }) }</cosmoz-omnitable-item-expand-line>`),
16
15
 
17
16
  ExpandList = host => {
18
- useRenderOnColumnUpdates(host.columns);
19
-
20
17
  useEffect(() => {
21
18
  if (host.columns?.length > 0) {
22
19
  return;
@@ -1,22 +1,19 @@
1
1
  import { component, html } from 'haunted';
2
2
  import { repeat } from 'lit-html/directives/repeat';
3
- import { useRenderOnColumnUpdates } from './lib/use-render-on-column-updates';
4
3
 
5
4
  const
6
- renderCell = (column, data) => column.editable
7
- ? column.renderEditCell(column, data)
5
+ renderCell = (column, data, onItemChange) => column.editable
6
+ ? column.renderEditCell(column, data, onItemChange(column, data.item))
8
7
  : column.renderCell(column, data),
9
- ItemRow = ({ columns, groupOnColumn, item, selected, expanded }) => {
10
- useRenderOnColumnUpdates(columns);
11
-
8
+ ItemRow = ({ columns, groupOnColumn, item, selected, expanded, onItemChange }) => {
12
9
  return repeat(columns, column => column.name, column => {
13
10
  return html`<div
14
11
  class="cell itemRow-cell ${ column.cellClass ?? '' }"
15
12
  ?hidden=${ column === groupOnColumn }
16
13
  ?editable=${ column.editable }
17
- title=${ column.cellTitleFn(item, column.valuePath) }
14
+ title=${ column.cellTitleFn(column, item) }
18
15
  name=${ column.name }
19
- >${ renderCell(column, { item, selected, expanded }) }</div>`;
16
+ >${ renderCell(column, { item, selected, expanded }, onItemChange) }</div>`;
20
17
  });
21
18
  };
22
19
 
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-lines */
1
2
  const checkbox = `
2
3
  .checkbox {
3
4
  box-sizing: border-box;
@@ -21,7 +22,7 @@ const checkbox = `
21
22
  }
22
23
 
23
24
  .checkbox:checked {
24
- background-color: var(--paper-checkbox-checked-color, var(--primary-color));
25
+ background-color: var(--cosmoz-omnitable-checkbox-checked-color, var(--primary-color));
25
26
  box-shadow: none;
26
27
  }
27
28
 
@@ -62,7 +63,7 @@ const checkbox = `
62
63
  height: 2px;
63
64
  left: 4px;
64
65
  top: 8px;
65
- background-color: var(--paper-checkbox-checked-color, var(--primary-color));
66
+ background-color: var(--cosmoz-omnitable-checkbox-checked-color, var(--primary-color));
66
67
  }
67
68
  `;
68
69
 
@@ -281,7 +282,7 @@ export default `<style>
281
282
  display: flex;
282
283
  align-items: center;
283
284
  border-top: solid 1px #e8e8e8;
284
- background-color: #f5f5f5;
285
+ background-color: var(--cosmoz-omnitable-footer-bg-color, #f5f5f5);
285
286
  min-height: 25px;
286
287
  height: 63px;
287
288
  margin-bottom: 1px; /* Chrome overflow rendering bug? When only component in a view */
@@ -336,11 +337,6 @@ export default `<style>
336
337
  @apply --cosmoz-omnitable-selected-row;
337
338
  }
338
339
 
339
- .itemRow[highlighted] {
340
- background-color: rgba(195, 212, 248, 0.5);
341
- @apply --cosmoz-omnitable-hightlighted-row;
342
- }
343
-
344
340
  .tableContent .itemRow-cell paper-dropdown-menu {
345
341
  margin-top:-20px;
346
342
  }