2023-04-04 15:43:43 +03:00
|
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
|
|
|
|
export default class SelectionList {
|
|
|
|
@tracked selectedIds = new Set();
|
|
|
|
@tracked inverted = false;
|
|
|
|
@tracked lastSelectedId = null;
|
|
|
|
@tracked lastShiftSelectionGroup = new Set();
|
|
|
|
|
2023-04-11 17:32:11 +03:00
|
|
|
enabled = true;
|
|
|
|
|
2023-04-04 15:43:43 +03:00
|
|
|
infinityModel;
|
|
|
|
|
2023-04-13 16:04:06 +03:00
|
|
|
#frozen = false;
|
|
|
|
|
2023-04-04 15:43:43 +03:00
|
|
|
constructor(infinityModel) {
|
|
|
|
this.infinityModel = infinityModel ?? {content: []};
|
|
|
|
}
|
|
|
|
|
2023-04-13 16:04:06 +03:00
|
|
|
freeze() {
|
|
|
|
this.#frozen = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
unfreeze() {
|
|
|
|
this.#frozen = false;
|
|
|
|
}
|
|
|
|
|
2023-04-07 12:48:14 +03:00
|
|
|
/**
|
|
|
|
* Returns an NQL filter for all items, not the selection
|
|
|
|
*/
|
|
|
|
get allFilter() {
|
|
|
|
return this.infinityModel.extraParams?.filter ?? '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an NQL filter for the current selection
|
|
|
|
*/
|
|
|
|
get filter() {
|
|
|
|
if (this.inverted) {
|
|
|
|
if (this.allFilter) {
|
|
|
|
if (this.selectedIds.size === 0) {
|
|
|
|
return this.allFilter;
|
|
|
|
}
|
|
|
|
return `(${this.allFilter})+id:-['${[...this.selectedIds].join('\',\'')}']`;
|
|
|
|
}
|
|
|
|
if (this.selectedIds.size === 0) {
|
|
|
|
// Select all
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return `id:-['${[...this.selectedIds].join('\',\'')}']`;
|
|
|
|
}
|
|
|
|
if (this.selectedIds.size === 0) {
|
|
|
|
// Select nothing
|
|
|
|
return 'id:nothing';
|
|
|
|
}
|
|
|
|
// Only based on the ids
|
|
|
|
return `id:['${[...this.selectedIds].join('\',\'')}']`;
|
|
|
|
}
|
|
|
|
|
2023-04-04 15:43:43 +03:00
|
|
|
/**
|
|
|
|
* Create an empty copy
|
|
|
|
*/
|
|
|
|
cloneEmpty() {
|
|
|
|
return new SelectionList(this.infinityModel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a list of models that are already loaded in memory.
|
|
|
|
* Keep in mind that when using CMD + A, we don't have all items in memory!
|
|
|
|
*/
|
|
|
|
get availableModels() {
|
|
|
|
const arr = [];
|
|
|
|
for (const item of this.infinityModel.content) {
|
|
|
|
if (this.isSelected(item.id)) {
|
|
|
|
arr.push(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
2023-04-12 16:53:17 +03:00
|
|
|
get first() {
|
|
|
|
return this.availableModels[0];
|
|
|
|
}
|
|
|
|
|
2023-04-04 15:43:43 +03:00
|
|
|
get isSingle() {
|
|
|
|
return this.selectedIds.size === 1 && !this.inverted;
|
|
|
|
}
|
|
|
|
|
2023-04-11 17:37:42 +03:00
|
|
|
get count() {
|
|
|
|
if (!this.inverted) {
|
|
|
|
return this.selectedIds.size;
|
|
|
|
}
|
|
|
|
return Math.max((this.infinityModel.meta?.pagination?.total ?? 0) - this.selectedIds.size, 1);
|
|
|
|
}
|
|
|
|
|
2023-04-04 15:43:43 +03:00
|
|
|
isSelected(id) {
|
|
|
|
if (this.inverted) {
|
|
|
|
return !this.selectedIds.has(id);
|
|
|
|
}
|
|
|
|
return this.selectedIds.has(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleItem(id) {
|
2023-04-13 16:04:06 +03:00
|
|
|
if (this.#frozen) {
|
|
|
|
return;
|
|
|
|
}
|
2023-04-04 15:43:43 +03:00
|
|
|
this.lastShiftSelectionGroup = new Set();
|
|
|
|
|
|
|
|
if (this.selectedIds.has(id)) {
|
|
|
|
this.selectedIds.delete(id);
|
2023-04-13 11:20:56 +03:00
|
|
|
|
|
|
|
if (!this.inverted) {
|
|
|
|
if (this.lastSelectedId === id) {
|
|
|
|
this.lastSelectedId = null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Shift behaviour in inverted mode needs a review
|
|
|
|
this.lastSelectedId = id;
|
|
|
|
}
|
2023-04-04 15:43:43 +03:00
|
|
|
} else {
|
|
|
|
this.selectedIds.add(id);
|
2023-04-13 11:20:56 +03:00
|
|
|
|
|
|
|
if (!this.inverted) {
|
|
|
|
this.lastSelectedId = id;
|
|
|
|
} else {
|
|
|
|
// Shift behaviour in inverted mode needs a review
|
|
|
|
this.lastSelectedId = id;
|
|
|
|
}
|
2023-04-04 15:43:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Force update
|
|
|
|
// eslint-disable-next-line no-self-assign
|
|
|
|
this.selectedIds = this.selectedIds;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Select all items between the last selection or the first one if none
|
|
|
|
*/
|
|
|
|
shiftItem(id) {
|
2023-04-13 16:04:06 +03:00
|
|
|
if (this.#frozen) {
|
|
|
|
return;
|
|
|
|
}
|
2023-04-04 15:43:43 +03:00
|
|
|
// Unselect last selected items
|
|
|
|
for (const item of this.lastShiftSelectionGroup) {
|
|
|
|
if (this.inverted) {
|
|
|
|
this.selectedIds.add(item);
|
|
|
|
} else {
|
|
|
|
this.selectedIds.delete(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.lastShiftSelectionGroup = new Set();
|
|
|
|
|
|
|
|
// todo
|
|
|
|
let running = false;
|
|
|
|
|
|
|
|
if (this.lastSelectedId === null) {
|
|
|
|
running = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const item of this.infinityModel.content) {
|
|
|
|
// Exlusing the last selected item
|
|
|
|
if (item.id === this.lastSelectedId || item.id === id) {
|
|
|
|
if (!running) {
|
|
|
|
running = true;
|
|
|
|
|
|
|
|
// Skip last selected on its own
|
|
|
|
if (item.id === this.lastSelectedId) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Still include id
|
|
|
|
if (item.id === id) {
|
|
|
|
this.lastShiftSelectionGroup.add(item.id);
|
|
|
|
|
|
|
|
if (this.inverted) {
|
|
|
|
this.selectedIds.delete(item.id);
|
|
|
|
} else {
|
|
|
|
this.selectedIds.add(item.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (running) {
|
|
|
|
this.lastShiftSelectionGroup.add(item.id);
|
|
|
|
if (this.inverted) {
|
|
|
|
this.selectedIds.delete(item.id);
|
|
|
|
} else {
|
|
|
|
this.selectedIds.add(item.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Force update
|
|
|
|
// eslint-disable-next-line no-self-assign
|
|
|
|
this.selectedIds = this.selectedIds;
|
|
|
|
}
|
|
|
|
|
|
|
|
selectAll() {
|
2023-04-13 16:04:06 +03:00
|
|
|
if (this.#frozen) {
|
|
|
|
return;
|
|
|
|
}
|
2023-04-04 15:43:43 +03:00
|
|
|
this.selectedIds = new Set();
|
|
|
|
this.inverted = !this.inverted;
|
2023-04-13 11:20:56 +03:00
|
|
|
this.lastSelectedId = null;
|
2023-04-04 15:43:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
clearSelection() {
|
2023-04-13 16:04:06 +03:00
|
|
|
if (this.#frozen) {
|
|
|
|
return;
|
|
|
|
}
|
2023-04-04 15:43:43 +03:00
|
|
|
this.selectedIds = new Set();
|
|
|
|
this.inverted = false;
|
2023-04-13 11:20:56 +03:00
|
|
|
this.lastSelectedId = null;
|
2023-04-04 15:43:43 +03:00
|
|
|
}
|
|
|
|
}
|