Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 31 additions & 56 deletions web/src/elements/table/Table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,37 +337,16 @@ export abstract class Table<T extends object>
*/
#itemKeys = new WeakMap<T, string | number>();

/**
* A mapping of item keys to selected items.
*/
@property({ attribute: false })
public get selectedElements(): T[] {
const items = this.data?.results ?? [];

return items.filter((item) => {
const itemKey = this.#itemKeys.get(item);

if (!itemKey) return false;

return this.#selectedElements.has(itemKey);
});
}
public selectedMap = new Map<string | number, T>();

public set selectedElements(value: Iterable<T>) {
const nextSelected = new Map<string | number, T>();

for (const item of value) {
const itemKey = hasPrimaryKey(item) ? item.pk : JSON.stringify(item);

this.#itemKeys.set(item, itemKey);

if (this.#selectedElements.has(itemKey)) {
nextSelected.set(itemKey, item);
}
}

this.#selectedElements = nextSelected;
public get selectedElements(): T[] {
return Array.from(this.selectedMap.values());
}

#selectedElements = new Map<string | number, T>();

@property({ type: Boolean })
public paginated = true;

Expand Down Expand Up @@ -485,8 +464,8 @@ export abstract class Table<T extends object>
this.expandedElements = nextExpanded;

if (this.clearOnRefresh) {
if (this.#selectedElements.size) {
this.#selectedElements.clear();
if (this.selectedMap.size) {
this.selectedMap = new Map();

const selectAllCheckbox = this.#selectAllCheckboxRef.value;

Expand Down Expand Up @@ -656,9 +635,11 @@ export abstract class Table<T extends object>
this.expandedElements.delete(itemKey);
} else {
this.expandedElements.add(itemKey);

requestAnimationFrame(() => {
currentTarget?.scrollIntoView({
behavior: "smooth",
block: "center",
});
});
}
Expand All @@ -672,7 +653,7 @@ export abstract class Table<T extends object>
const { target } = event ?? {};

const itemKey = this.#itemKeys.get(item);
const selected = !!(itemKey && this.#selectedElements.has(itemKey));
const selected = !!(itemKey && this.selectedMap.has(itemKey));
let checked: boolean;

if (target instanceof HTMLInputElement) {
Expand All @@ -690,22 +671,22 @@ export abstract class Table<T extends object>

if (itemKey) {
if (checked) {
this.#selectedElements.set(itemKey, item);
this.selectedMap.set(itemKey, item);
} else {
this.#selectedElements.delete(itemKey);
this.selectedMap.delete(itemKey);
}

this.requestUpdate("selectedMap");
}

const selectAllCheckbox = this.#selectAllCheckboxRef.value;
const pageItemCount = this.data?.results?.length ?? 0;
const selectedCount = this.#selectedElements.size;
const selectedCount = this.selectedMap.size;

if (selectAllCheckbox) {
selectAllCheckbox.checked = pageItemCount !== 0 && selectedCount !== 0;
selectAllCheckbox.indeterminate = selectedCount !== 0 && selectedCount < pageItemCount;
}

this.requestUpdate();
}

//#region Grouping
Expand All @@ -719,17 +700,16 @@ export abstract class Table<T extends object>

const itemKey = this.#itemKeys.get(item);
const expanded = !!(itemKey && this.expandedElements.has(itemKey));
const selected = !!(itemKey && this.#selectedElements.has(itemKey));
const selected = !!(itemKey && this.selectedMap.has(itemKey));

const rowLabel = this.rowLabel(item) || `#${rowIndex + 1}`;

const selectItem = this.#selectItemListener.bind(this, item);

const renderCheckbox = () => {
const memoizedCheckbox = guard([this.checkbox, item, selected], () => {
if (!this.checkbox) {
return nothing;
}

const rowLabel = this.rowLabel(item) || `#${rowIndex + 1}`;
const selectItem = this.#selectItemListener.bind(this, item);

return html`<td class="pf-c-table__check" role="presentation" @click=${selectItem}>
<label aria-label="${msg(str`Select "${rowLabel}" row`)}"
><input
Expand All @@ -739,14 +719,13 @@ export abstract class Table<T extends object>
@click=${(event: PointerEvent) => event.stopPropagation()}
/></label>
</td>`;
};

const expandItem = this.#toggleExpansion.bind(this, itemKey);
});

const renderExpansion = () => {
const memoizedExpansion = guard([this.expandable, itemKey, expanded], () => {
if (!this.expandable) {
return nothing;
}
const expandItem = this.#toggleExpansion.bind(this, itemKey);

return html`<td
class="pf-c-table__toggle pf-m-pressable"
Expand All @@ -766,7 +745,7 @@ export abstract class Table<T extends object>
</div>
</button>
</td>`;
};
});

let expansionContent: SlottedTemplateResult = nothing;

Expand Down Expand Up @@ -796,8 +775,7 @@ export abstract class Table<T extends object>
"pf-m-hoverable": this.checkbox || this.expandable || this.clickable,
})}"
>
${guard([this.checkbox, selected], renderCheckbox)}
${guard([this.expandable, expanded], renderExpansion)}
${memoizedCheckbox} ${memoizedExpansion}
${this.row(item).map((cell, columnIndex) => {
const columnID = this.#columnIDs.get(this.columns[columnIndex]);

Expand Down Expand Up @@ -926,9 +904,10 @@ export abstract class Table<T extends object>

checkbox.indeterminate = false;

const nextSelected = new Map<string | number, T>();

if (checkbox.checked) {
const items = this.data?.results || [];
const nextSelected = new Map<string | number, T>();

for (const item of items) {
const itemKey = this.#itemKeys.get(item);
Expand All @@ -937,13 +916,9 @@ export abstract class Table<T extends object>
nextSelected.set(itemKey, item);
}
}

this.#selectedElements = nextSelected;
} else {
this.#selectedElements.clear();
}

this.requestUpdate();
this.selectedMap = nextSelected;
};

/**
Expand All @@ -952,7 +927,7 @@ export abstract class Table<T extends object>
* "deactivate all on this page" with a single click.
*/
renderAllOnThisPageCheckbox(): TemplateResult {
const selectedCount = this.#selectedElements.size;
const selectedCount = this.selectedMap.size;
const pageItemCount = this.data?.results?.length ?? 0;

const checked = pageItemCount !== 0 && selectedCount === pageItemCount;
Expand Down Expand Up @@ -991,7 +966,7 @@ export abstract class Table<T extends object>

protected renderChipGroup(): TemplateResult {
return html`<ak-chip-group>
${Array.from(this.#selectedElements.values(), (item) => {
${Array.from(this.selectedMap.values(), (item) => {
return html`<ak-chip>${this.renderSelectedChip(item)}</ak-chip>`;
})}
</ak-chip-group>`;
Expand Down
Loading