@neovici/cosmoz-omnitable 7.1.1 → 8.0.0-beta.2
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.
- package/README.md +23 -0
- package/cosmoz-omnitable-column-amount.js +89 -320
- package/cosmoz-omnitable-column-autocomplete.js +36 -47
- package/cosmoz-omnitable-column-boolean.js +107 -209
- package/cosmoz-omnitable-column-date.js +89 -102
- package/cosmoz-omnitable-column-datetime.js +86 -119
- package/cosmoz-omnitable-column-list-data.js +4 -1
- package/cosmoz-omnitable-column-list-horizontal.js +20 -38
- package/cosmoz-omnitable-column-list-mixin.js +133 -140
- package/cosmoz-omnitable-column-list.js +19 -28
- package/cosmoz-omnitable-column-mixin.js +69 -447
- package/cosmoz-omnitable-column-number.js +91 -183
- package/cosmoz-omnitable-column-time.js +77 -162
- package/cosmoz-omnitable-column.js +49 -93
- package/cosmoz-omnitable-group-row.js +1 -5
- package/cosmoz-omnitable-header-row.js +9 -6
- package/cosmoz-omnitable-item-expand.js +0 -3
- package/cosmoz-omnitable-item-row.js +5 -8
- package/cosmoz-omnitable-styles.js +1 -5
- package/cosmoz-omnitable.js +73 -811
- package/lib/cosmoz-omnitable-amount-range-input.js +295 -0
- package/{cosmoz-omnitable-column-date-mixin.js → lib/cosmoz-omnitable-date-input-mixin.js} +4 -26
- package/lib/cosmoz-omnitable-date-range-input.js +81 -0
- package/lib/cosmoz-omnitable-datetime-range-input.js +75 -0
- package/lib/cosmoz-omnitable-number-range-input.js +159 -0
- package/{cosmoz-omnitable-column-range-mixin.js → lib/cosmoz-omnitable-range-input-mixin.js} +45 -129
- package/lib/cosmoz-omnitable-settings.js +22 -4
- package/lib/cosmoz-omnitable-time-range-input.js +130 -0
- package/lib/generic-sorter.js +35 -0
- package/lib/invoke.js +1 -0
- package/lib/memoize.js +54 -0
- package/lib/polymer-haunted-render-mixin.js +19 -0
- package/lib/save-as-csv-action.js +32 -0
- package/lib/save-as-xlsx-action.js +25 -0
- package/lib/use-canvas-width.js +1 -1
- package/lib/use-dom-columns.js +138 -0
- package/lib/use-hash-state.js +59 -0
- package/lib/use-layout.js +1 -1
- package/lib/use-omnitable.js +31 -4
- package/lib/use-processed-items.js +132 -0
- package/lib/use-saved-settings.js +2 -2
- package/lib/use-sort-and-group-options.js +30 -0
- package/lib/utils-amount.js +147 -0
- package/lib/utils-data.js +36 -0
- package/lib/utils-date.js +204 -0
- package/lib/utils-datetime.js +71 -0
- package/lib/utils-number.js +112 -0
- package/lib/utils-time.js +115 -0
- package/package.json +1 -1
- package/lib/use-force-render.js +0 -8
- package/lib/use-render-on-column-updates.js +0 -18
|
@@ -5,222 +5,130 @@ import './ui-helpers/cosmoz-clear-button';
|
|
|
5
5
|
import { PolymerElement } from '@polymer/polymer/polymer-element';
|
|
6
6
|
import { html } from 'lit-html';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
translatable, _
|
|
10
|
-
} from '@neovici/cosmoz-i18next';
|
|
11
8
|
import { columnMixin } from './cosmoz-omnitable-column-mixin';
|
|
12
|
-
|
|
13
|
-
import
|
|
9
|
+
|
|
10
|
+
import './lib/cosmoz-omnitable-number-range-input';
|
|
11
|
+
import { valuesFrom } from './lib/utils-data';
|
|
12
|
+
import { applySingleFilter, getComparableValue, getInputString, getString, toHashString, toNumber } from './lib/utils-number';
|
|
13
|
+
import { get } from '@polymer/polymer/lib/utils/path';
|
|
14
|
+
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* @polymer
|
|
17
18
|
* @customElement
|
|
18
|
-
* @appliesMixin rangeColumnMixin
|
|
19
19
|
* @appliesMixin columnMixin
|
|
20
20
|
*/
|
|
21
|
-
class OmnitableColumnNumber extends
|
|
22
|
-
columnMixin(
|
|
23
|
-
translatable(
|
|
24
|
-
PolymerElement
|
|
25
|
-
)
|
|
26
|
-
)
|
|
27
|
-
) {
|
|
28
|
-
static get is() {
|
|
29
|
-
return 'cosmoz-omnitable-column-number';
|
|
30
|
-
}
|
|
31
|
-
|
|
21
|
+
class OmnitableColumnNumber extends columnMixin(PolymerElement) {
|
|
32
22
|
static get properties() {
|
|
33
23
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
value: '30px'
|
|
45
|
-
},
|
|
46
|
-
editWidth: {
|
|
47
|
-
type: String,
|
|
48
|
-
value: '30px'
|
|
49
|
-
},
|
|
50
|
-
headerCellClass: {
|
|
51
|
-
type: String,
|
|
52
|
-
value: 'number-header-cell'
|
|
53
|
-
},
|
|
54
|
-
maximumFractionDigits: {
|
|
55
|
-
type: Number,
|
|
56
|
-
value: null
|
|
57
|
-
},
|
|
58
|
-
minimumFractionDigits: {
|
|
59
|
-
type: Number,
|
|
60
|
-
value: null // browser default 0 for numbers, currency-specific or 2 for currency
|
|
61
|
-
},
|
|
62
|
-
formatter: {
|
|
63
|
-
type: Object,
|
|
64
|
-
computed: '_computeFormatter(locale, minimumFractionDigits, maximumFractionDigits)'
|
|
65
|
-
},
|
|
66
|
-
// trigger filter updates manually
|
|
67
|
-
autoupdate: {
|
|
68
|
-
type: String,
|
|
69
|
-
value: false
|
|
70
|
-
},
|
|
71
|
-
_filterText: {
|
|
72
|
-
type: String,
|
|
73
|
-
computed: '_computeFilterText(filter.*, formatter)'
|
|
74
|
-
}
|
|
24
|
+
min: { type: Number, value: null, notify: true },
|
|
25
|
+
max: { type: Number, value: null, notify: true },
|
|
26
|
+
locale: { type: String, value: null, notify: true },
|
|
27
|
+
autoupdate: { type: Boolean, value: false, notify: true },
|
|
28
|
+
cellClass: { type: String, value: 'number-cell align-right' },
|
|
29
|
+
width: { type: String, value: '30px' },
|
|
30
|
+
minWidth: { type: String, value: '30px' },
|
|
31
|
+
headerCellClass: { type: String, value: 'number-header-cell' },
|
|
32
|
+
maximumFractionDigits: { type: Number, value: null },
|
|
33
|
+
minimumFractionDigits: { type: Number, value: null } // browser default 0 for numbers, currency-specific or 2 for currency
|
|
75
34
|
};
|
|
76
35
|
}
|
|
77
36
|
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (minimumFractionDigits !== null) {
|
|
83
|
-
options.minimumFractionDigits = minimumFractionDigits;
|
|
84
|
-
}
|
|
85
|
-
if (maximumFractionDigits !== null) {
|
|
86
|
-
options.maximumFractionDigits = maximumFractionDigits;
|
|
87
|
-
}
|
|
88
|
-
return new Intl.NumberFormat(locale || undefined, options);
|
|
89
|
-
}
|
|
37
|
+
getFilterFn(column, filter) {
|
|
38
|
+
const
|
|
39
|
+
min = getComparableValue(filter, 'min', column),
|
|
40
|
+
max = getComparableValue(filter, 'max', column);
|
|
90
41
|
|
|
91
|
-
|
|
92
|
-
* Check if label should float based on validity
|
|
93
|
-
*
|
|
94
|
-
* Number inputs can have allowed characters that aren't numbers (-,e) and won't
|
|
95
|
-
* trigger a value change and thus not float the label.
|
|
96
|
-
* However, the validity will report badInput so we can trigger a label float by
|
|
97
|
-
* setting it to something truthy but still not visible.
|
|
98
|
-
* Fixed in paper-input 3.x
|
|
99
|
-
*
|
|
100
|
-
* @param {Event} event KeyboardEvent
|
|
101
|
-
* @returns {void}
|
|
102
|
-
*/
|
|
103
|
-
onBadInputFloatLabel(event) {
|
|
104
|
-
const paperInput = event.currentTarget;
|
|
105
|
-
if (paperInput == null || paperInput.tagName !== 'PAPER-INPUT') {
|
|
42
|
+
if (min == null && max == null) {
|
|
106
43
|
return;
|
|
107
44
|
}
|
|
108
|
-
|
|
45
|
+
return applySingleFilter(column, filter);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getString(column, item) {
|
|
49
|
+
return getString(column, item);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
toXlsxValue({ valuePath }, item) {
|
|
53
|
+
return get(item, valuePath);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
cellTitleFn(column, item) {
|
|
57
|
+
return getString(column, item);
|
|
109
58
|
}
|
|
110
59
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
*/
|
|
118
|
-
getComparableValue(item, valuePath) {
|
|
119
|
-
if (item == null) {
|
|
60
|
+
getComparableValue(item, valuePath, column) {
|
|
61
|
+
return getComparableValue(item, valuePath, column);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
serializeFilter(column, filter) {
|
|
65
|
+
if (filter == null) {
|
|
120
66
|
return;
|
|
121
67
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
value = this.toValue(value);
|
|
127
|
-
if (value == null) {
|
|
68
|
+
const min = toNumber(filter.min),
|
|
69
|
+
max = toNumber(filter.max);
|
|
70
|
+
|
|
71
|
+
if (min == null && max == null) {
|
|
128
72
|
return;
|
|
129
73
|
}
|
|
74
|
+
return toHashString(min) + '~' + toHashString(max);
|
|
75
|
+
}
|
|
130
76
|
|
|
131
|
-
|
|
132
|
-
if (
|
|
133
|
-
return
|
|
77
|
+
deserializeFilter(column, filter) {
|
|
78
|
+
if (filter == null || filter === '') {
|
|
79
|
+
return null;
|
|
134
80
|
}
|
|
135
|
-
|
|
136
|
-
}
|
|
81
|
+
const matches = filter.match(/^([^~]+)?~([^~]+)?/iu);
|
|
137
82
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (number == null) {
|
|
141
|
-
return;
|
|
83
|
+
if (!Array.isArray(matches)) {
|
|
84
|
+
return null;
|
|
142
85
|
}
|
|
143
|
-
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
min: toNumber(matches[1]),
|
|
89
|
+
max: toNumber(matches[2])
|
|
90
|
+
};
|
|
144
91
|
}
|
|
145
92
|
|
|
146
93
|
renderCell(column, { item }) {
|
|
147
|
-
return html`<div class="omnitable-cell-number">${
|
|
94
|
+
return html`<div class="omnitable-cell-number">${ getString(column, item) }</div>`;
|
|
148
95
|
}
|
|
149
96
|
|
|
150
|
-
renderEditCell(column, { item }) {
|
|
151
|
-
const onChange = event =>
|
|
152
|
-
event.model = { item };
|
|
153
|
-
return column._valueChanged(event);
|
|
154
|
-
};
|
|
97
|
+
renderEditCell(column, { item }, onItemChange) {
|
|
98
|
+
const onChange = event => onItemChange(event.target.value);
|
|
155
99
|
|
|
156
|
-
return html`<paper-input no-label-float type="number" @change=${ onChange } .value=${
|
|
100
|
+
return html`<paper-input no-label-float type="number" @change=${ onChange } .value=${ getInputString(column, item) }></paper-input>`;
|
|
157
101
|
}
|
|
158
102
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
103
|
+
renderHeader(
|
|
104
|
+
{ title,
|
|
105
|
+
min,
|
|
106
|
+
max,
|
|
107
|
+
locale,
|
|
108
|
+
maximumFractionDigits,
|
|
109
|
+
minimumFractionDigits,
|
|
110
|
+
autoupdate },
|
|
111
|
+
{ filter },
|
|
112
|
+
setState,
|
|
113
|
+
source
|
|
114
|
+
) {
|
|
115
|
+
return html`<cosmoz-omnitable-number-range-input
|
|
116
|
+
.title=${ title }
|
|
117
|
+
.filter=${ filter }
|
|
118
|
+
.values=${ source }
|
|
119
|
+
.min=${ min }
|
|
120
|
+
.max=${ max }
|
|
121
|
+
.locale=${ locale }
|
|
122
|
+
.maximumFractionDigits=${ maximumFractionDigits }
|
|
123
|
+
.minimumFractionDigsits=${ minimumFractionDigits }
|
|
124
|
+
.autoupdate=${ autoupdate }
|
|
125
|
+
@filter-changed=${ ({ detail: { value }}) => setState(state => ({ ...state, filter: value })) }
|
|
126
|
+
@header-focused-changed=${ ({ detail: { value }}) => setState(state => ({ ...state, headerFocused: value })) }
|
|
127
|
+
></cosmoz-omnitable-number-range-input>`;
|
|
128
|
+
}
|
|
165
129
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
paper-input > iron-icon {
|
|
169
|
-
display: none;
|
|
170
|
-
cursor: pointer;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
paper-input.has-value > iron-icon {
|
|
174
|
-
display: block;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
paper-dropdown-menu {
|
|
178
|
-
--iron-icon-width: 0;
|
|
179
|
-
}
|
|
180
|
-
</style>
|
|
181
|
-
<cosmoz-clear-button @click=${ event => column.resetFilter(event) } ?visible=${ column.hasFilter() }></cosmoz-clear-button>
|
|
182
|
-
<paper-dropdown-menu
|
|
183
|
-
label=${ column.title }
|
|
184
|
-
placeholder=${ ifDefined(column._filterText) }
|
|
185
|
-
class="external-values-${ column.externalValues }"
|
|
186
|
-
title=${ column._tooltip }
|
|
187
|
-
horizontal-align=${ column.preferredDropdownHorizontalAlign }
|
|
188
|
-
?opened=${ column.headerFocused }
|
|
189
|
-
@opened-changed=${ onOpenedChanged }
|
|
190
|
-
>
|
|
191
|
-
<div class="dropdown-content" slot="dropdown-content" style="padding: 15px; min-width: 100px;">
|
|
192
|
-
<h3 style="margin: 0;">${ column.title }</h3>
|
|
193
|
-
<paper-input
|
|
194
|
-
class=${ column._fromClasses }
|
|
195
|
-
type="number"
|
|
196
|
-
label=${ _('From') }
|
|
197
|
-
.value=${ column._filterInput.min }
|
|
198
|
-
@value-changed=${ event => column.set('_filterInput.min', event.detail.value) }
|
|
199
|
-
@input=${ event => column.onBadInputFloatLabel(event) }
|
|
200
|
-
@blur=${ event => column._onBlur(event) }
|
|
201
|
-
@keydown=${ event => column._onKeyDown(event) }
|
|
202
|
-
min=${ column._toInputString(column._limit.fromMin) }
|
|
203
|
-
max=${ column._toInputString(column._limit.fromMax) }
|
|
204
|
-
>
|
|
205
|
-
<iron-icon icon="clear" slot="suffix" @tap=${ event => column._clearFrom(event) }></iron-icon>
|
|
206
|
-
</paper-input>
|
|
207
|
-
<paper-input
|
|
208
|
-
class=${ column._toClasses }
|
|
209
|
-
type="number"
|
|
210
|
-
label=${ _('To') }
|
|
211
|
-
.value=${ column._filterInput.max }
|
|
212
|
-
@value-changed=${ event => column.set('_filterInput.max', event.detail.value) }
|
|
213
|
-
@input=${ event => column.onBadInputFloatLabel(event) }
|
|
214
|
-
@blur=${ event => column._onBlur(event) }
|
|
215
|
-
@keydown=${ event => column._onKeyDown(event) }
|
|
216
|
-
min=${ column._toInputString(column._limit.toMin) }
|
|
217
|
-
max=${ column._toInputString(column._limit.toMax) }
|
|
218
|
-
>
|
|
219
|
-
<iron-icon icon="clear" slot="suffix" @tap=${ event => column._clearTo(event) }></iron-icon>
|
|
220
|
-
</paper-input>
|
|
221
|
-
</div>
|
|
222
|
-
</paper-dropdown-menu>
|
|
223
|
-
`;
|
|
130
|
+
computeSource({ valuePath }, data) {
|
|
131
|
+
return valuesFrom(data, valuePath);
|
|
224
132
|
}
|
|
225
133
|
}
|
|
226
|
-
customElements.define(
|
|
134
|
+
customElements.define('cosmoz-omnitable-column-number', OmnitableColumnNumber);
|
|
@@ -7,210 +7,125 @@ import './ui-helpers/cosmoz-clear-button';
|
|
|
7
7
|
import { PolymerElement } from '@polymer/polymer/polymer-element';
|
|
8
8
|
import { html } from 'lit-html';
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
translatable, _
|
|
12
|
-
} from '@neovici/cosmoz-i18next';
|
|
13
10
|
import { columnMixin } from './cosmoz-omnitable-column-mixin';
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
11
|
+
import { getComparableValue, getString, toXlsxValue, applySingleFilter, toDate, toHashString, fromHashString } from './lib/utils-time';
|
|
12
|
+
import './lib/cosmoz-omnitable-time-range-input';
|
|
13
|
+
import { valuesFrom } from './lib/utils-data';
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* @polymer
|
|
19
17
|
* @customElement
|
|
20
|
-
* @appliesMixin dateColumnMixin
|
|
21
18
|
* @appliesMixin columnMixin
|
|
22
19
|
*/
|
|
23
|
-
class OmnitableColumnTime extends
|
|
24
|
-
dateColumnMixin(
|
|
25
|
-
columnMixin(
|
|
26
|
-
translatable(PolymerElement)
|
|
27
|
-
)
|
|
28
|
-
) {
|
|
29
|
-
static get is() {
|
|
30
|
-
return 'cosmoz-omnitable-column-time';
|
|
31
|
-
}
|
|
32
|
-
|
|
20
|
+
class OmnitableColumnTime extends columnMixin(PolymerElement) {
|
|
33
21
|
static get properties() {
|
|
34
22
|
return {
|
|
23
|
+
min: { type: Number, value: null, notify: true },
|
|
24
|
+
max: { type: Number, value: null, notify: true },
|
|
25
|
+
locale: { type: String, value: null, notify: true },
|
|
26
|
+
headerCellClass: { type: String, value: 'time-header-cell' },
|
|
27
|
+
minWidth: { type: String, value: '63px' },
|
|
28
|
+
width: { type: String, value: '210px' },
|
|
29
|
+
flex: { type: String, value: '0' },
|
|
35
30
|
/*
|
|
36
31
|
* Specifies the value granularity of the time input's value in the filter.
|
|
37
32
|
* 1 => full seconds
|
|
38
33
|
* 0.1 => milliseconds
|
|
39
34
|
*/
|
|
40
|
-
filterStep: {
|
|
41
|
-
type: String,
|
|
42
|
-
value: '1'
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
headerCellClass: {
|
|
46
|
-
type: String,
|
|
47
|
-
value: 'time-header-cell'
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
minWidth: {
|
|
51
|
-
type: String,
|
|
52
|
-
value: '63px'
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
editMinWidth: {
|
|
56
|
-
type: String,
|
|
57
|
-
value: '63px'
|
|
58
|
-
}
|
|
35
|
+
filterStep: { type: String, value: '1' }
|
|
59
36
|
};
|
|
60
37
|
}
|
|
61
38
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
renderEditCell(column, { item }) {
|
|
67
|
-
const onChange = event => {
|
|
68
|
-
event.model = { item };
|
|
69
|
-
return column._timeValueChanged(event);
|
|
70
|
-
};
|
|
39
|
+
getFilterFn(column, filter) {
|
|
40
|
+
const
|
|
41
|
+
min = getComparableValue(filter, 'min', column),
|
|
42
|
+
max = getComparableValue(filter, 'max', column);
|
|
71
43
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.value=${ column.getInputString(item, column.valuePath) }
|
|
77
|
-
></paper-input>`;
|
|
44
|
+
if (min == null && max == null) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
return applySingleFilter(column, filter);
|
|
78
48
|
}
|
|
79
49
|
|
|
80
|
-
|
|
81
|
-
return
|
|
82
|
-
<cosmoz-clear-button @click=${ event => column.resetFilter(event) } ?visible=${ column.hasFilter() }></cosmoz-clear-button>
|
|
83
|
-
<paper-dropdown-menu
|
|
84
|
-
label=${ column.title }
|
|
85
|
-
placeholder=${ ifDefined(column._filterText) }
|
|
86
|
-
class="external-values-${ column.externalValues }"
|
|
87
|
-
title=${ column._tooltip }
|
|
88
|
-
horizontal-align=${ column.preferredDropdownHorizontalAlign }
|
|
89
|
-
?opened=${ column.headerFocused }
|
|
90
|
-
@opened-changed=${ event => column.headerFocused = event.detail.value }>
|
|
91
|
-
>
|
|
92
|
-
<div class="dropdown-content" slot="dropdown-content" style="padding: 15px; min-width: 100px;">
|
|
93
|
-
<h3 style="margin: 0;">${ column.title }</h3>
|
|
94
|
-
<paper-input
|
|
95
|
-
type="time"
|
|
96
|
-
label=${ _('From time') }
|
|
97
|
-
step=${ column.filterStep }
|
|
98
|
-
.value=${ column._filterInput.min }
|
|
99
|
-
@value-changed=${ event => column.set('_filterInput.min', event.detail.value) }
|
|
100
|
-
></paper-input>
|
|
101
|
-
<paper-input
|
|
102
|
-
type="time"
|
|
103
|
-
label=${ _('Until time') }
|
|
104
|
-
step=${ column.filterStep }
|
|
105
|
-
.value=${ column._filterInput.max }
|
|
106
|
-
@value-changed=${ event => column.set('_filterInput.max', event.detail.value) }
|
|
107
|
-
></paper-input>
|
|
108
|
-
</div>
|
|
109
|
-
</paper-dropdown-menu>
|
|
110
|
-
`;
|
|
50
|
+
getString(column, item) {
|
|
51
|
+
return getString(column, item);
|
|
111
52
|
}
|
|
112
53
|
|
|
113
|
-
|
|
114
|
-
return
|
|
54
|
+
toXlsxValue(column, item) {
|
|
55
|
+
return toXlsxValue(column, item);
|
|
115
56
|
}
|
|
116
57
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
*
|
|
120
|
-
* @param {Date|Number} value Date or Timestamp ( miliseconds since property _fixedDate ) to be converted
|
|
121
|
-
* @param {Date|Number} limit Optional value to limit the date.
|
|
122
|
-
* @param {Function} limitFunc Function used to limit the date (Math.min|Math.max)
|
|
123
|
-
* @returns {Date|void} Value converted to date optionaly limitated
|
|
124
|
-
*/
|
|
125
|
-
toDate(value, limit, limitFunc) {
|
|
126
|
-
// Most browsers use local timezone when no timezone is specified
|
|
127
|
-
// but Safari uses UTC, so we set it implicitly
|
|
128
|
-
// TODO: Consider removing this when/if Safari handles local timezone correctly
|
|
129
|
-
const date = typeof value === 'string' && value.length > 3 && value.length <= 9
|
|
130
|
-
? this.getAbsoluteISOString(this._fixedDate + 'T' + value)
|
|
131
|
-
: value;
|
|
132
|
-
return super.toDate(date, limit, limitFunc);
|
|
58
|
+
cellTitleFn(column, item) {
|
|
59
|
+
return getString(column, item);
|
|
133
60
|
}
|
|
134
61
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (date == null) {
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
return this._toLocalISOString(date).slice(11, 19);
|
|
62
|
+
getComparableValue(item, valuePath, column) {
|
|
63
|
+
return getComparableValue(item, valuePath, column);
|
|
141
64
|
}
|
|
142
65
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return '';
|
|
66
|
+
serializeFilter(column, filter) {
|
|
67
|
+
if (filter == null) {
|
|
68
|
+
return;
|
|
147
69
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
70
|
+
const min = toDate(filter.min),
|
|
71
|
+
max = toDate(filter.max);
|
|
151
72
|
|
|
152
|
-
|
|
153
|
-
if (value == null || value === '') {
|
|
73
|
+
if (min == null && max == null) {
|
|
154
74
|
return;
|
|
155
75
|
}
|
|
156
|
-
|
|
157
|
-
return this.toValue(value.replace(/\./gu, ':') + 'Z');
|
|
76
|
+
return toHashString(min) + '~' + toHashString(max);
|
|
158
77
|
}
|
|
159
78
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* @param {Object} item Item to be processed
|
|
164
|
-
* @param {String} valuePath Property path
|
|
165
|
-
* @returns {Number|void} Valid value or void
|
|
166
|
-
*/
|
|
167
|
-
getComparableValue(item, valuePath) {
|
|
168
|
-
if (item == null) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
let value = this._toInputString(valuePath == null ? item : this.get(valuePath, item));
|
|
172
|
-
if (value == null) {
|
|
173
|
-
return;
|
|
79
|
+
deserializeFilter(column, filter) {
|
|
80
|
+
if (filter == null || filter === '') {
|
|
81
|
+
return null;
|
|
174
82
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
83
|
+
const matches = filter.match(/^([^~]+)?~([^~]+)?/iu);
|
|
84
|
+
|
|
85
|
+
if (!Array.isArray(matches)) {
|
|
86
|
+
return null;
|
|
178
87
|
}
|
|
179
|
-
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
min: fromHashString(matches[1]),
|
|
91
|
+
max: fromHashString(matches[2])
|
|
92
|
+
};
|
|
180
93
|
}
|
|
181
94
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return '';
|
|
185
|
-
}
|
|
186
|
-
return this.getString(item, valuePath);
|
|
95
|
+
renderCell(column, { item }) {
|
|
96
|
+
return getString(column, item);
|
|
187
97
|
}
|
|
188
98
|
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
item = e.model.item,
|
|
193
|
-
oldTime = this.toDate(item.date),
|
|
194
|
-
newTime = this.toDate(oldTime != null
|
|
195
|
-
? oldTime.toISOString().slice(0, 10) + 'T' + timeString
|
|
196
|
-
: timeString),
|
|
197
|
-
formatFn = value => value;
|
|
198
|
-
if (newTime != null) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
this.set(this.valuePath, newTime, item);
|
|
202
|
-
this._fireItemChangeEvent(item, this.valuePath, oldTime, formatFn.bind(this));
|
|
99
|
+
renderEditCell(column, { item }, onItemChange) {
|
|
100
|
+
const onChange = event => onItemChange(event.target.value);
|
|
101
|
+
return html`<paper-input no-label-float type="text" @change=${ onChange } .value=${ getString(column, item) }></paper-input>`;
|
|
203
102
|
}
|
|
204
103
|
|
|
205
|
-
|
|
104
|
+
renderHeader(
|
|
105
|
+
{ title,
|
|
106
|
+
min,
|
|
107
|
+
max,
|
|
108
|
+
locale,
|
|
109
|
+
filterStep },
|
|
110
|
+
{ filter },
|
|
111
|
+
setState,
|
|
112
|
+
source
|
|
113
|
+
) {
|
|
114
|
+
return html`<cosmoz-omnitable-time-range-input
|
|
115
|
+
.title=${ title }
|
|
116
|
+
.filter=${ filter }
|
|
117
|
+
.values=${ source }
|
|
118
|
+
.min=${ min }
|
|
119
|
+
.max=${ max }
|
|
120
|
+
.locale=${ locale }
|
|
121
|
+
.filterStep=${ filterStep }
|
|
122
|
+
@filter-changed=${ ({ detail: { value }}) => setState(state => ({ ...state, filter: value })) }
|
|
123
|
+
@header-focused-changed=${ ({ detail: { value }}) => setState(state => ({ ...state, headerFocused: value })) }
|
|
124
|
+
></cosmoz-omnitable-time-range-input>`;
|
|
125
|
+
}
|
|
206
126
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
hour: 'numeric',
|
|
210
|
-
minute: 'numeric',
|
|
211
|
-
second: 'numeric'
|
|
212
|
-
};
|
|
213
|
-
return new Intl.DateTimeFormat(locale || undefined, timeFormatOption);
|
|
127
|
+
computeSource({ valuePath }, data) {
|
|
128
|
+
return valuesFrom(data, valuePath);
|
|
214
129
|
}
|
|
215
130
|
}
|
|
216
|
-
customElements.define(
|
|
131
|
+
customElements.define('cosmoz-omnitable-column-time', OmnitableColumnTime);
|