@neovici/cosmoz-omnitable 14.12.1 → 14.12.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.
Files changed (35) hide show
  1. package/README.md +1 -2
  2. package/cosmoz-omnitable-column-boolean.js +81 -62
  3. package/cosmoz-omnitable-column-list-data.js +57 -49
  4. package/cosmoz-omnitable-column-list-horizontal.js +42 -26
  5. package/cosmoz-omnitable-group-row.js +10 -2
  6. package/cosmoz-omnitable-item-expand-line.js +1 -1
  7. package/grouped-list/cosmoz-grouped-list-row.js +1 -1
  8. package/grouped-list/use-cosmoz-grouped-list.js +12 -11
  9. package/grouped-list/use-selected-items.js +25 -25
  10. package/grouped-list/use-weak-state.js +2 -2
  11. package/grouped-list/utils.js +11 -9
  12. package/lib/compute-layout.js +2 -1
  13. package/lib/cosmoz-omnitable-amount-range-input.js +100 -97
  14. package/lib/cosmoz-omnitable-date-input-mixin.js +23 -13
  15. package/lib/cosmoz-omnitable-date-range-input.js +85 -78
  16. package/lib/cosmoz-omnitable-datetime-range-input.js +85 -78
  17. package/lib/cosmoz-omnitable-number-range-input.js +34 -27
  18. package/lib/cosmoz-omnitable-range-input-mixin.js +7 -10
  19. package/lib/cosmoz-omnitable-time-range-input.js +54 -30
  20. package/lib/layout.js +12 -14
  21. package/lib/polymer-haunted-render-mixin.js +14 -13
  22. package/lib/save-as-csv-action.js +31 -27
  23. package/lib/save-as-xlsx-action.js +13 -11
  24. package/lib/settings/cosmoz-omnitable-sort-group.js +1 -1
  25. package/lib/settings/drivers/context.js +1 -1
  26. package/lib/use-hash-state.js +1 -1
  27. package/lib/use-processed-items.js +20 -20
  28. package/lib/utils-amount.js +17 -26
  29. package/lib/utils-data.js +24 -24
  30. package/lib/utils-date.js +18 -34
  31. package/lib/utils-datetime.js +10 -15
  32. package/lib/utils-number.js +28 -29
  33. package/lib/utils-time.js +21 -24
  34. package/lib/utils.js +1 -1
  35. package/package.json +8 -2
@@ -10,89 +10,96 @@ class DatetimeRangeInput extends dateInputMixin(
10
10
  ) {
11
11
  // eslint-disable-next-line max-lines-per-function
12
12
  render() {
13
- return html`
14
- <style>
15
- paper-dropdown-menu {
16
- --iron-icon-width: 0;
17
- display: block;
18
- text-align: right;
19
- }
13
+ return html`
14
+ <style>
15
+ paper-dropdown-menu {
16
+ --iron-icon-width: 0;
17
+ display: block;
18
+ text-align: right;
19
+ }
20
20
 
21
- .dropdown-content h3 {
22
- font-weight: 500;
23
- font-size: 13px;
24
- margin: 0;
25
- font-family: var(--cosmoz-input-font-family, var(--paper-font-subhead_-_font-family, 'Inter', sans-serif));
26
- }
21
+ .dropdown-content h3 {
22
+ font-weight: 500;
23
+ font-size: 13px;
24
+ margin: 0;
25
+ font-family: var(
26
+ --cosmoz-input-font-family,
27
+ var(--paper-font-subhead_-_font-family, 'Inter', sans-serif)
28
+ );
29
+ }
27
30
 
28
- .dropdown-content {
29
- padding: 10px 10px 10px 10px;
30
- min-width: 120px;
31
- text-align: left;
32
- background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
33
- border-radius: 6px;
34
- backdrop-filter: blur(16px) saturate(180%);
35
- -webkit-backdrop-filter: blur(16px) saturate(180%);
36
- box-shadow: 0 4px 24px 0 rgba(0,0,0,0.18), 0 1.5px 6px 0 rgba(0,0,0,0.1);
37
- }
31
+ .dropdown-content {
32
+ padding: 10px 10px 10px 10px;
33
+ min-width: 120px;
34
+ text-align: left;
35
+ background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
36
+ border-radius: 6px;
37
+ backdrop-filter: blur(16px) saturate(180%);
38
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
39
+ box-shadow:
40
+ 0 4px 24px 0 rgba(0, 0, 0, 0.18),
41
+ 0 1.5px 6px 0 rgba(0, 0, 0, 0.1);
42
+ }
38
43
 
39
- cosmoz-datetime-input {
40
- background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
41
- border-radius: 6px;
42
- border: 1px solid #d1d1d6;
43
- box-shadow: 0 1px 2px 0 rgba(60,60,60,0.04);
44
- padding: 2px 8px;
45
- margin-bottom: 6px;
46
- min-height: 28px;
47
- transition: border-color 0.2s, box-shadow 0.2s;
48
- }
44
+ cosmoz-datetime-input {
45
+ background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
46
+ border-radius: 6px;
47
+ border: 1px solid #d1d1d6;
48
+ box-shadow: 0 1px 2px 0 rgba(60, 60, 60, 0.04);
49
+ padding: 2px 8px;
50
+ margin-bottom: 6px;
51
+ min-height: 28px;
52
+ transition:
53
+ border-color 0.2s,
54
+ box-shadow 0.2s;
55
+ }
49
56
 
50
- cosmoz-datetime-input:focus-within {
51
- border-color: var(--cz-accent-color, #007aff);
52
- box-shadow: 0 0 0 1px rgba(0,122,255,0.15);
53
- background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
54
- }
55
- </style>
57
+ cosmoz-datetime-input:focus-within {
58
+ border-color: var(--cz-accent-color, #007aff);
59
+ box-shadow: 0 0 0 1px rgba(0, 122, 255, 0.15);
60
+ background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
61
+ }
62
+ </style>
56
63
 
57
- <cosmoz-clear-button
58
- @click=${() => this.resetFilter()}
59
- ?visible=${this.hasFilter()}
60
- ></cosmoz-clear-button>
61
- <paper-dropdown-menu
62
- label=${this.title}
63
- placeholder=${ifDefined(this._filterText)}
64
- class="external-values-${this.externalValues}"
65
- title=${this._tooltip}
66
- horizontal-align="right"
67
- ?opened=${this.headerFocused}
68
- @opened-changed=${(event) =>
69
- this.set('headerFocused', event.detail.value)}
70
- >
71
- <div class="dropdown-content" slot="dropdown-content">
72
- <h3 style="margin: 0;">${this.title}</h3>
73
- <cosmoz-datetime-input
74
- date-label=${_('From date')}
75
- time-label=${_('From time')}
76
- min=${this._toInputString(this._limit.fromMin)}
77
- max=${this._toInputString(this._limit.fromMax)}
78
- step=${this.filterStep}
79
- .value=${this._filterInput?.min}
80
- @value-changed=${(event) =>
81
- this.set('_filterInput.min', event.detail.value)}
82
- ></cosmoz-datetime-input>
83
- <cosmoz-datetime-input
84
- date-label=${_('To date')}
85
- time-label=${_('To time')}
86
- min=${this._toInputString(this._limit.toMin)}
87
- max=${this._toInputString(this._limit.toMax)}
88
- step=${this.filterStep}
89
- .value=${this._filterInput?.max}
90
- @value-changed=${(event) =>
91
- this.set('_filterInput.max', event.detail.value)}
92
- ></cosmoz-datetime-input>
93
- </div>
94
- </paper-dropdown-menu>
95
- `;
64
+ <cosmoz-clear-button
65
+ @click=${() => this.resetFilter()}
66
+ ?visible=${this.hasFilter()}
67
+ ></cosmoz-clear-button>
68
+ <paper-dropdown-menu
69
+ label=${this.title}
70
+ placeholder=${ifDefined(this._filterText)}
71
+ class="external-values-${this.externalValues}"
72
+ title=${this._tooltip}
73
+ horizontal-align="right"
74
+ ?opened=${this.headerFocused}
75
+ @opened-changed=${(event) =>
76
+ this.set('headerFocused', event.detail.value)}
77
+ >
78
+ <div class="dropdown-content" slot="dropdown-content">
79
+ <h3 style="margin: 0;">${this.title}</h3>
80
+ <cosmoz-datetime-input
81
+ date-label=${_('From date')}
82
+ time-label=${_('From time')}
83
+ min=${this._toInputString(this._limit.fromMin)}
84
+ max=${this._toInputString(this._limit.fromMax)}
85
+ step=${this.filterStep}
86
+ .value=${this._filterInput?.min}
87
+ @value-changed=${(event) =>
88
+ this.set('_filterInput.min', event.detail.value)}
89
+ ></cosmoz-datetime-input>
90
+ <cosmoz-datetime-input
91
+ date-label=${_('To date')}
92
+ time-label=${_('To time')}
93
+ min=${this._toInputString(this._limit.toMin)}
94
+ max=${this._toInputString(this._limit.toMax)}
95
+ step=${this.filterStep}
96
+ .value=${this._filterInput?.max}
97
+ @value-changed=${(event) =>
98
+ this.set('_filterInput.max', event.detail.value)}
99
+ ></cosmoz-datetime-input>
100
+ </div>
101
+ </paper-dropdown-menu>
102
+ `;
96
103
  }
97
104
 
98
105
  _toInputString(value) {
@@ -45,40 +45,47 @@ class NumberRangeInput extends rangeInputMixin(
45
45
  text-align: right;
46
46
  }
47
47
 
48
- .dropdown-content h3 {
48
+ .dropdown-content h3 {
49
49
  font-weight: 500;
50
50
  font-size: 13px;
51
51
  margin: 0;
52
- font-family: var(--cosmoz-input-font-family, var(--paper-font-subhead_-_font-family, 'Inter', sans-serif));
52
+ font-family: var(
53
+ --cosmoz-input-font-family,
54
+ var(--paper-font-subhead_-_font-family, 'Inter', sans-serif)
55
+ );
53
56
  }
54
57
 
55
- .dropdown-content {
56
- padding: 10px 10px 10px 10px;
57
- min-width: 120px;
58
- text-align: left;
59
- background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
60
- border-radius: 6px;
61
- backdrop-filter: blur(16px) saturate(180%);
62
- -webkit-backdrop-filter: blur(16px) saturate(180%);
63
- box-shadow: 0 4px 24px 0 rgba(0,0,0,0.18), 0 1.5px 6px 0 rgba(0,0,0,0.1);
64
- }
58
+ .dropdown-content {
59
+ padding: 10px 10px 10px 10px;
60
+ min-width: 120px;
61
+ text-align: left;
62
+ background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
63
+ border-radius: 6px;
64
+ backdrop-filter: blur(16px) saturate(180%);
65
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
66
+ box-shadow:
67
+ 0 4px 24px 0 rgba(0, 0, 0, 0.18),
68
+ 0 1.5px 6px 0 rgba(0, 0, 0, 0.1);
69
+ }
65
70
 
66
- cosmoz-input[type="number"] {
67
- background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
68
- border-radius: 6px;
69
- border: 1px solid #d1d1d6;
70
- box-shadow: 0 1px 2px 0 rgba(60,60,60,0.04);
71
- padding: 2px 8px;
72
- margin-bottom: 6px;
73
- min-height: 28px;
74
- transition: border-color 0.2s, box-shadow 0.2s;
75
- }
71
+ cosmoz-input[type='number'] {
72
+ background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
73
+ border-radius: 6px;
74
+ border: 1px solid #d1d1d6;
75
+ box-shadow: 0 1px 2px 0 rgba(60, 60, 60, 0.04);
76
+ padding: 2px 8px;
77
+ margin-bottom: 6px;
78
+ min-height: 28px;
79
+ transition:
80
+ border-color 0.2s,
81
+ box-shadow 0.2s;
82
+ }
76
83
 
77
- cosmoz-input[type="number"]:focus-within {
78
- border-color: var(--cz-accent-color, #007aff);
79
- box-shadow: 0 0 0 1px rgba(0,122,255,0.15);
80
- background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
81
- }
84
+ cosmoz-input[type='number']:focus-within {
85
+ border-color: var(--cz-accent-color, #007aff);
86
+ box-shadow: 0 0 0 1px rgba(0, 122, 255, 0.15);
87
+ background: var(--cosmoz-omnitable-amount-input-background, #ffffff);
88
+ }
82
89
  </style>
83
90
 
84
91
  <cosmoz-clear-button
@@ -108,7 +108,6 @@ export const rangeInputMixin = (
108
108
  };
109
109
  }
110
110
 
111
-
112
111
  static get observers() {
113
112
  return [
114
113
  '_filterInputChanged(_filterInput.*, autoupdate)',
@@ -477,14 +476,12 @@ export const rangeInputMixin = (
477
476
 
478
477
  _updateLimits(limits, headerFocused) {
479
478
  if (!limits) return;
480
- Promise.resolve(invoke(limits, { active: headerFocused })).then(
481
- (res) => {
482
- const {min, max} = res ?? {};
483
- Object.assign(this, {
484
- ...(min != null ? { min } : {}),
485
- ...(max != null ? { max } : {}),
486
- });
487
- },
488
- );
479
+ Promise.resolve(invoke(limits, { active: headerFocused })).then((res) => {
480
+ const { min, max } = res ?? {};
481
+ Object.assign(this, {
482
+ ...(min != null ? { min } : {}),
483
+ ...(max != null ? { max } : {}),
484
+ });
485
+ });
489
486
  }
490
487
  };
@@ -6,7 +6,9 @@ import '@neovici/cosmoz-input';
6
6
  import { dateInputMixin } from './cosmoz-omnitable-date-input-mixin';
7
7
  import { polymerHauntedRender } from './polymer-haunted-render-mixin';
8
8
 
9
- class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)) {
9
+ class TimeRangeInput extends dateInputMixin(
10
+ polymerHauntedRender(PolymerElement),
11
+ ) {
10
12
  // eslint-disable-next-line max-lines-per-function
11
13
  render() {
12
14
  return html`
@@ -17,31 +19,42 @@ class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)
17
19
  }
18
20
  </style>
19
21
 
20
- <cosmoz-clear-button @click=${ () => this.resetFilter() } ?visible=${ this.hasFilter() }></cosmoz-clear-button>
22
+ <cosmoz-clear-button
23
+ @click=${() => this.resetFilter()}
24
+ ?visible=${this.hasFilter()}
25
+ ></cosmoz-clear-button>
21
26
  <paper-dropdown-menu
22
- label=${ this.title }
23
- placeholder=${ ifDefined(this._filterText) }
24
- class="external-values-${ this.externalValues }"
25
- title=${ this._tooltip }
27
+ label=${this.title}
28
+ placeholder=${ifDefined(this._filterText)}
29
+ class="external-values-${this.externalValues}"
30
+ title=${this._tooltip}
26
31
  horizontal-align="right"
27
- ?opened=${ this.headerFocused }
28
- @opened-changed=${ event => this.set('headerFocused', event.detail.value) }>
32
+ ?opened=${this.headerFocused}
33
+ @opened-changed=${(event) =>
34
+ this.set('headerFocused', event.detail.value)}
29
35
  >
30
- <div class="dropdown-content" slot="dropdown-content" style="padding: 15px; min-width: 100px;">
31
- <h3 style="margin: 0;">${ this.title }</h3>
36
+ >
37
+ <div
38
+ class="dropdown-content"
39
+ slot="dropdown-content"
40
+ style="padding: 15px; min-width: 100px;"
41
+ >
42
+ <h3 style="margin: 0;">${this.title}</h3>
32
43
  <cosmoz-input
33
44
  type="time"
34
- label=${ _('From time') }
35
- step=${ this.filterStep }
36
- .value=${ this._filterInput.min }
37
- @value-changed=${ event => this.set('_filterInput.min', event.detail.value) }
45
+ label=${_('From time')}
46
+ step=${this.filterStep}
47
+ .value=${this._filterInput.min}
48
+ @value-changed=${(event) =>
49
+ this.set('_filterInput.min', event.detail.value)}
38
50
  ></cosmoz-input>
39
51
  <cosmoz-input
40
52
  type="time"
41
- label=${ _('Until time') }
42
- step=${ this.filterStep }
43
- .value=${ this._filterInput.max }
44
- @value-changed=${ event => this.set('_filterInput.max', event.detail.value) }
53
+ label=${_('Until time')}
54
+ step=${this.filterStep}
55
+ .value=${this._filterInput.max}
56
+ @value-changed=${(event) =>
57
+ this.set('_filterInput.max', event.detail.value)}
45
58
  ></cosmoz-input>
46
59
  </div>
47
60
  </paper-dropdown-menu>
@@ -64,9 +77,10 @@ class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)
64
77
  // Most browsers use local timezone when no timezone is specified
65
78
  // but Safari uses UTC, so we set it implicitly
66
79
  // TODO: Consider removing this when/if Safari handles local timezone correctly
67
- const date = typeof value === 'string' && value.length > 3 && value.length <= 9
68
- ? this.getAbsoluteISOString(this._fixedDate + 'T' + value)
69
- : value;
80
+ const date =
81
+ typeof value === 'string' && value.length > 3 && value.length <= 9
82
+ ? this.getAbsoluteISOString(this._fixedDate + 'T' + value)
83
+ : value;
70
84
  return super.toDate(date, limit, limitFunc);
71
85
  }
72
86
 
@@ -88,11 +102,15 @@ class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)
88
102
  if (item == null) {
89
103
  return;
90
104
  }
91
- let value = this._toInputString(valuePath == null ? item : this.get(valuePath, item));
105
+ let value = this._toInputString(
106
+ valuePath == null ? item : this.get(valuePath, item),
107
+ );
92
108
  if (value == null) {
93
109
  return;
94
110
  }
95
- value = this.toValue(this.getAbsoluteISOString(this._fixedDate + 'T' + value));
111
+ value = this.toValue(
112
+ this.getAbsoluteISOString(this._fixedDate + 'T' + value),
113
+ );
96
114
  if (value == null) {
97
115
  return;
98
116
  }
@@ -104,15 +122,22 @@ class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)
104
122
  timeString = input.value,
105
123
  item = e.model.item,
106
124
  oldTime = this.toDate(item.date),
107
- newTime = this.toDate(oldTime != null
108
- ? oldTime.toISOString().slice(0, 10) + 'T' + timeString
109
- : timeString),
110
- formatFn = value => value;
125
+ newTime = this.toDate(
126
+ oldTime != null
127
+ ? oldTime.toISOString().slice(0, 10) + 'T' + timeString
128
+ : timeString,
129
+ ),
130
+ formatFn = (value) => value;
111
131
  if (newTime != null) {
112
132
  return;
113
133
  }
114
134
  this.set(this.valuePath, newTime, item);
115
- this._fireItemChangeEvent(item, this.valuePath, oldTime, formatFn.bind(this));
135
+ this._fireItemChangeEvent(
136
+ item,
137
+ this.valuePath,
138
+ oldTime,
139
+ formatFn.bind(this),
140
+ );
116
141
  }
117
142
 
118
143
  // OVERRIDES
@@ -121,11 +146,10 @@ class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)
121
146
  const timeFormatOption = {
122
147
  hour: 'numeric',
123
148
  minute: 'numeric',
124
- second: 'numeric'
149
+ second: 'numeric',
125
150
  };
126
151
  return new Intl.DateTimeFormat(locale || undefined, timeFormatOption);
127
152
  }
128
153
  }
129
154
 
130
-
131
155
  customElements.define('cosmoz-omnitable-time-range-input', TimeRangeInput);
package/lib/layout.js CHANGED
@@ -1,16 +1,12 @@
1
- const finite = num => Number.isFinite(num) ? num : 0;
2
- export const
3
- // eslint-disable-next-line max-lines-per-function, max-statements
1
+ const finite = (num) => (Number.isFinite(num) ? num : 0);
2
+ export const // eslint-disable-next-line max-lines-per-function, max-statements
4
3
  layout = (columns, container) => {
5
4
  const result = [];
6
5
 
7
6
  // eslint-disable-next-line one-var
8
7
  let [widthSum, lots] = columns.reduce(
9
- ([widthSum, lots], { width, flex }) => [
10
- widthSum + width,
11
- lots + flex
12
- ],
13
- [0, 0]
8
+ ([widthSum, lots], { width, flex }) => [widthSum + width, lots + flex],
9
+ [0, 0],
14
10
  ),
15
11
  freeRealEstate = container - widthSum,
16
12
  lotSize = finite(freeRealEstate / lots),
@@ -21,9 +17,10 @@ export const
21
17
  // first pass: apply and drop lots with minWidth or flex 0
22
18
  for (let i = 0; i < columns.length; i++) {
23
19
  const { width, minWidth, flex } = columns[i],
24
- adjustment = freeRealEstate >= 0
25
- ? lotSize * flex
26
- : width * freeRealEstate / widthSum;
20
+ adjustment =
21
+ freeRealEstate >= 0
22
+ ? lotSize * flex
23
+ : (width * freeRealEstate) / widthSum;
27
24
 
28
25
  if (minWidth > width + adjustment) {
29
26
  droppedWidth += width;
@@ -53,9 +50,10 @@ export const
53
50
  }
54
51
 
55
52
  const { width, flex } = columns[i],
56
- adjustment = freeRealEstate >= 0
57
- ? lotSize * flex
58
- : width * freeRealEstate / widthSum;
53
+ adjustment =
54
+ freeRealEstate >= 0
55
+ ? lotSize * flex
56
+ : (width * freeRealEstate) / widthSum;
59
57
 
60
58
  result[i] = width + adjustment;
61
59
  }
@@ -1,18 +1,19 @@
1
1
  import { html } from '@polymer/polymer';
2
2
  import { render } from 'lit-html';
3
3
 
4
- export const polymerHauntedRender = base => class extends base {
5
- static get template() {
6
- return html`<div id="output" style="position:relative;"></div>`;
7
- }
4
+ export const polymerHauntedRender = (base) =>
5
+ class extends base {
6
+ static get template() {
7
+ return html`<div id="output" style="position:relative;"></div>`;
8
+ }
8
9
 
9
- connectedCallback() {
10
- super.connectedCallback();
11
- render(this.render(), this.$.output);
12
- }
10
+ connectedCallback() {
11
+ super.connectedCallback();
12
+ render(this.render(), this.$.output);
13
+ }
13
14
 
14
- _propertiesChanged(currentProps, changedProps, oldProps) {
15
- super._propertiesChanged(currentProps, changedProps, oldProps);
16
- requestAnimationFrame(() => render(this.render(), this.$.output));
17
- }
18
- };
15
+ _propertiesChanged(currentProps, changedProps, oldProps) {
16
+ super._propertiesChanged(currentProps, changedProps, oldProps);
17
+ requestAnimationFrame(() => render(this.render(), this.$.output));
18
+ }
19
+ };
@@ -1,32 +1,36 @@
1
1
  import { saveAs } from 'file-saver-es';
2
2
 
3
- const
4
- makeCsvField = str => {
5
- const result = str.replace(/"/gu, '""');
6
- if (result.search(/("|,|\n)/gu) >= 0) {
7
- return '"' + result + '"';
8
- }
9
- return str;
10
- };
3
+ const makeCsvField = (str) => {
4
+ const result = str.replace(/"/gu, '""');
5
+ if (result.search(/("|,|\n)/gu) >= 0) {
6
+ return '"' + result + '"';
7
+ }
8
+ return str;
9
+ };
11
10
 
12
- export const
13
- saveAsCsvAction = (columns, selectedItems, csvFilename) => {
14
- const separator = ';',
15
- lf = '\n',
16
- header = columns.map(col => makeCsvField(col.title)).join(separator) + lf,
17
- rows = selectedItems.map(item => {
18
- return columns.map(column => {
19
- const cell = column.getString(column, item);
20
- if (cell === undefined || cell === null) {
21
- return '';
22
- }
23
- return makeCsvField(String(cell));
24
- }).join(separator) + lf;
25
- });
11
+ export const saveAsCsvAction = (columns, selectedItems, csvFilename) => {
12
+ const separator = ';',
13
+ lf = '\n',
14
+ header = columns.map((col) => makeCsvField(col.title)).join(separator) + lf,
15
+ rows = selectedItems.map((item) => {
16
+ return (
17
+ columns
18
+ .map((column) => {
19
+ const cell = column.getString(column, item);
20
+ if (cell === undefined || cell === null) {
21
+ return '';
22
+ }
23
+ return makeCsvField(String(cell));
24
+ })
25
+ .join(separator) + lf
26
+ );
27
+ });
26
28
 
27
- rows.unshift(header);
29
+ rows.unshift(header);
28
30
 
29
- saveAs(new File(rows, csvFilename, {
30
- type: 'text/csv;charset=utf-8'
31
- }));
32
- };
31
+ saveAs(
32
+ new File(rows, csvFilename, {
33
+ type: 'text/csv;charset=utf-8',
34
+ }),
35
+ );
36
+ };
@@ -1,25 +1,27 @@
1
1
  import { saveAs } from 'file-saver-es';
2
2
  import { NullXlsx } from '@neovici/nullxlsx';
3
3
 
4
- export const
5
- prepareXlsxData = (columns, selectedItems) => {
6
- const headers = columns.map(col => col.title),
7
- data = selectedItems.map(item =>
8
- columns.map(column => {
4
+ export const prepareXlsxData = (columns, selectedItems) => {
5
+ const headers = columns.map((col) => col.title),
6
+ data = selectedItems.map((item) =>
7
+ columns.map((column) => {
9
8
  const value = column.toXlsxValue(column, item);
10
9
  return value == null ? '' : value;
11
- })
10
+ }),
12
11
  );
13
12
 
14
13
  data.unshift(headers);
15
14
  return data;
16
15
  },
17
-
18
16
  saveAsXlsxAction = (columns, selectedItems, xlsxFilename, xlsxSheetname) => {
19
17
  const data = prepareXlsxData(columns, selectedItems),
20
- xlsx = new NullXlsx(xlsxFilename).addSheetFromData(data, xlsxSheetname).generate();
18
+ xlsx = new NullXlsx(xlsxFilename)
19
+ .addSheetFromData(data, xlsxSheetname)
20
+ .generate();
21
21
 
22
- saveAs(new File([xlsx], xlsxFilename, {
23
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
24
- }));
22
+ saveAs(
23
+ new File([xlsx], xlsxFilename, {
24
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
25
+ }),
26
+ );
25
27
  };
@@ -8,7 +8,7 @@ export const render = ({ column, on, descending, setOn, setDescending }) => {
8
8
  class="sg"
9
9
  title=${title}
10
10
  data-on=${ifDefined(
11
- (name === on && (descending ? 'desc' : 'asc')) || undefined
11
+ (name === on && (descending ? 'desc' : 'asc')) || undefined,
12
12
  )}
13
13
  @click=${(e) => {
14
14
  const on = e.currentTarget?.dataset.on;
@@ -11,6 +11,6 @@ export const DriverContext = createContext(local),
11
11
 
12
12
  customElements.define(
13
13
  'omnitable-settings-driver-provider',
14
- DriverContext.Provider
14
+ DriverContext.Provider,
15
15
  );
16
16
  };
@@ -49,7 +49,7 @@ export const useHashState = (
49
49
  ? [multiLink, multiParse]
50
50
  : [singleLink, singleParse],
51
51
  [state, _setState] = useState(() =>
52
- param == null ? initial : parseHash(param + suffix, read) ?? initial,
52
+ param == null ? initial : (parseHash(param + suffix, read) ?? initial),
53
53
  ),
54
54
  setState = useCallback(
55
55
  (state) =>