@fluid-topics/ft-filterable-table 1.1.45 → 1.1.46

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.
@@ -9,21 +9,24 @@ export declare class FtFilterableTable<T extends Record<string, any>> extends Ft
9
9
  columns: Array<ColumnConfiguration<T>>;
10
10
  sort?: Sort;
11
11
  stickyHeaders: boolean;
12
+ disableDataManipulation: boolean;
12
13
  currentSort?: Sort;
13
14
  filters: Array<Filter>;
14
- selectData: Array<Array<string>>;
15
+ filterOptions: Array<Array<any>>;
15
16
  static styles: import("lit").CSSResult;
16
17
  init(data: Array<T>, columns: Array<ColumnConfiguration<T>>, sort?: Sort): void;
17
18
  protected render(): import("lit").TemplateResult<1>;
18
19
  private filterData;
19
20
  private sortData;
20
21
  protected update(props: PropertyValues): void;
21
- private updateSelectData;
22
+ private updateFilterOptions;
22
23
  private renderHeader;
23
24
  private renderColumnSort;
25
+ private dispatchChangeEvent;
24
26
  private renderColumnFilter;
25
27
  private columnPart;
26
28
  private renderCell;
27
29
  private getValue;
28
30
  private getValueAsString;
31
+ private stringifyValue;
29
32
  }
@@ -13,7 +13,7 @@ import "@fluid-topics/ft-select";
13
13
  import "@fluid-topics/ft-text-field";
14
14
  import "@fluid-topics/ft-button";
15
15
  import { classMap } from "lit/directives/class-map.js";
16
- import { RowClickEvent } from "./ft-filterable-table.properties";
16
+ import { FtFilterableTableChangeEvent, RowClickEvent } from "./ft-filterable-table.properties";
17
17
  import { styles } from "./ft-filterable-table.styles";
18
18
  const DEFAULT_RENDER = (v) => html `${v}`;
19
19
  const DEFAULT_COMPARATOR = (a, b) => a - b;
@@ -26,8 +26,9 @@ class FtFilterableTable extends FtLitElement {
26
26
  this.data = [];
27
27
  this.columns = [];
28
28
  this.stickyHeaders = false;
29
+ this.disableDataManipulation = false;
29
30
  this.filters = [];
30
- this.selectData = [];
31
+ this.filterOptions = [];
31
32
  }
32
33
  init(data, columns, sort) {
33
34
  this.data = data;
@@ -56,7 +57,7 @@ class FtFilterableTable extends FtLitElement {
56
57
  `;
57
58
  }
58
59
  filterData() {
59
- return this.filters.reduce((data, filter, columnIndex) => {
60
+ return this.disableDataManipulation ? this.data : this.filters.reduce((data, filter, columnIndex) => {
60
61
  var _a;
61
62
  const column = this.columns[columnIndex];
62
63
  if (filter && filter.value) {
@@ -64,7 +65,7 @@ class FtFilterableTable extends FtLitElement {
64
65
  case "text":
65
66
  return data.filter((row) => this.getValueAsString(column, row, columnIndex).toLowerCase().includes(filter.value.toLowerCase()));
66
67
  case "select":
67
- return data.filter((row) => this.getValueAsString(column, row, columnIndex) === filter.value);
68
+ return data.filter((row) => this.getValue(column, row) === filter.value);
68
69
  }
69
70
  }
70
71
  return data;
@@ -72,7 +73,7 @@ class FtFilterableTable extends FtLitElement {
72
73
  }
73
74
  sortData(data) {
74
75
  var _a;
75
- if (this.currentSort) {
76
+ if (this.currentSort && !this.disableDataManipulation) {
76
77
  const column = this.columns[this.currentSort.column];
77
78
  const ascComparator = (_a = column.comparator) !== null && _a !== void 0 ? _a : DEFAULT_COMPARATOR;
78
79
  const comparator = this.currentSort.order === "asc" ? ascComparator : ((a, b) => -ascComparator(a, b));
@@ -86,18 +87,23 @@ class FtFilterableTable extends FtLitElement {
86
87
  this.currentSort = this.sort;
87
88
  }
88
89
  if (props.has("data") || props.has("columns")) {
89
- this.updateSelectData();
90
+ this.updateFilterOptions();
90
91
  }
91
92
  }
92
- updateSelectData() {
93
- this.selectData = [];
93
+ updateFilterOptions() {
94
+ var _a, _b, _c;
95
+ this.filterOptions = [];
94
96
  const data = this.data;
95
97
  const columns = this.columns;
96
98
  for (let index in columns) {
97
99
  const column = columns[index];
98
- if (column.filter === "select") {
99
- this.selectData[index] = [...new Set(data.map((r, i) => this.getValueAsString(column, r, i)))]
100
- .sort((a, b) => a.localeCompare(b));
100
+ const filterType = (_a = column.filter) !== null && _a !== void 0 ? _a : "text";
101
+ if (filterType === "text" || filterType === "select") {
102
+ this.filterOptions[index] = ((_b = column.options) !== null && _b !== void 0 ? _b : [...new Set(data.map((row) => this.getValue(column, row)))])
103
+ .sort((_c = column.comparator) !== null && _c !== void 0 ? _c : DEFAULT_COMPARATOR);
104
+ if (filterType === "text") {
105
+ this.filterOptions[index] = this.filterOptions[index].map(value => this.stringifyValue(column, value, 0));
106
+ }
101
107
  }
102
108
  }
103
109
  this.requestUpdate();
@@ -127,44 +133,44 @@ class FtFilterableTable extends FtLitElement {
127
133
  const sortIcon = isSorted ? (this.currentSort.order === "asc" ? "expand_more" : "expand_less") : "unfold_more";
128
134
  const sort = () => {
129
135
  var _a;
130
- if (isSorted) {
131
- if (((_a = this.currentSort) === null || _a === void 0 ? void 0 : _a.order) === "asc") {
132
- this.currentSort = {
133
- column: index,
134
- order: "desc"
135
- };
136
- }
137
- else {
138
- this.currentSort = undefined;
139
- }
140
- }
141
- else {
142
- this.currentSort = {
143
- column: index,
144
- order: "asc"
145
- };
146
- }
136
+ this.currentSort = {
137
+ column: index,
138
+ order: isSorted && ((_a = this.currentSort) === null || _a === void 0 ? void 0 : _a.order) === "asc" ? "desc" : "asc"
139
+ };
140
+ this.dispatchChangeEvent();
147
141
  };
148
- return html `
142
+ return ((_a = column.sortable) !== null && _a !== void 0 ? _a : true) ? html `
149
143
  <ft-button
150
144
  round
151
145
  dense
152
- class="${((_a = column.sortable) !== null && _a !== void 0 ? _a : true) ? "" : "hidden"}"
153
146
  iconVariant="material"
154
147
  icon="${sortIcon}"
155
148
  label="Sort ${column.title}"
156
149
  @click=${sort}
157
150
  part="${this.columnPart("sort-button", index)}"
158
151
  ></ft-button>
159
- `;
152
+ ` : nothing;
153
+ }
154
+ dispatchChangeEvent() {
155
+ this.dispatchEvent(new FtFilterableTableChangeEvent({
156
+ filters: this.filters
157
+ .map((f, i) => ({
158
+ column: i,
159
+ value: f.value
160
+ }))
161
+ .filter(f => f.value != undefined),
162
+ sort: this.currentSort
163
+ }));
160
164
  }
161
165
  renderColumnFilter(column, index) {
162
- var _a, _b;
166
+ var _a, _b, _c;
163
167
  const onChange = (e) => {
164
168
  this.filters[index] = { value: e.detail };
165
169
  this.requestUpdate();
170
+ this.dispatchChangeEvent();
166
171
  };
167
- switch ((_a = column.filter) !== null && _a !== void 0 ? _a : "text") {
172
+ const options = (_a = this.filterOptions[index]) !== null && _a !== void 0 ? _a : [];
173
+ switch ((_b = column.filter) !== null && _b !== void 0 ? _b : "text") {
168
174
  case "text":
169
175
  return html `
170
176
  <div class="column-filter" part="${this.columnPart("filter-container", index)}">
@@ -172,25 +178,27 @@ class FtFilterableTable extends FtLitElement {
172
178
  label="Search ${column.title}"
173
179
  @live-change="${onChange}"
174
180
  part="${this.columnPart("filter", index)}"
175
- ></ft-text-field>
181
+ >
182
+ ${repeat(options, option => html `
183
+ <ft-text-field-suggestion>${option}</ft-text-field-suggestion>
184
+ `)}
185
+ </ft-text-field>
176
186
  </div>
177
187
  `;
178
188
  case "select":
179
- const values = (_b = this.selectData[index]) !== null && _b !== void 0 ? _b : [];
189
+ const values = (_c = this.filterOptions[index]) !== null && _c !== void 0 ? _c : [];
180
190
  return values.length ? html `
181
191
  <div class="column-filter" part="${this.columnPart("filter-container", index)}">
182
192
  <ft-select label="Filter ${column.title}"
183
193
  @change=${onChange}
184
194
  part="${this.columnPart("filter", index)}">
185
195
  <ft-select-option></ft-select-option>
186
- ${values.map(v => html `
187
- <ft-select-option value="${v}" label="${v}"></ft-select-option>
188
- `)}
196
+ ${repeat(options, option => html `
197
+ <ft-select-option .value=${option} label="${this.stringifyValue(column, option, 0)}"></ft-select-option>
198
+ `)}
189
199
  </ft-select>
190
200
  </div>
191
201
  ` : nothing;
192
- case "date":
193
- break;
194
202
  }
195
203
  return nothing;
196
204
  }
@@ -218,6 +226,9 @@ class FtFilterableTable extends FtLitElement {
218
226
  const value = this.getValue(column, row);
219
227
  return typeof column.stringify === "function" ? column.stringify(value, index) : DEFAULT_STRINGIFY(value);
220
228
  }
229
+ stringifyValue(column, value, index) {
230
+ return typeof column.stringify === "function" ? column.stringify(value, index) : DEFAULT_STRINGIFY(value);
231
+ }
221
232
  }
222
233
  FtFilterableTable.styles = styles;
223
234
  __decorate([
@@ -232,6 +243,9 @@ __decorate([
232
243
  __decorate([
233
244
  property({ type: Boolean })
234
245
  ], FtFilterableTable.prototype, "stickyHeaders", void 0);
246
+ __decorate([
247
+ property({ type: Boolean })
248
+ ], FtFilterableTable.prototype, "disableDataManipulation", void 0);
235
249
  __decorate([
236
250
  state()
237
251
  ], FtFilterableTable.prototype, "currentSort", void 0);