Ghost/ghost/admin/app/utils/selection-list.js
Simon Backx 8c046740f0 Added support for selecting posts
refs https://github.com/TryGhost/Team/issues/2906

Adds a way to select posts using CMD, shift and CMD+A. And adds a placeholder context menu.

Behind the making it rain feature flag.
2023-04-05 18:00:08 +02:00

133 lines
3.5 KiB
JavaScript

import {tracked} from '@glimmer/tracking';
export default class SelectionList {
@tracked selectedIds = new Set();
@tracked inverted = false;
@tracked lastSelectedId = null;
@tracked lastShiftSelectionGroup = new Set();
infinityModel;
constructor(infinityModel) {
this.infinityModel = infinityModel ?? {content: []};
}
/**
* 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;
}
get isSingle() {
return this.selectedIds.size === 1 && !this.inverted;
}
isSelected(id) {
if (this.inverted) {
return !this.selectedIds.has(id);
}
return this.selectedIds.has(id);
}
toggleItem(id) {
this.lastShiftSelectionGroup = new Set();
this.lastSelectedId = id;
if (this.selectedIds.has(id)) {
this.selectedIds.delete(id);
} else {
this.selectedIds.add(id);
}
// 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) {
// 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() {
this.selectedIds = new Set();
this.inverted = !this.inverted;
}
clearSelection() {
this.selectedIds = new Set();
this.inverted = false;
}
}