mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-13 14:39:52 +03:00
8c046740f0
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.
133 lines
3.5 KiB
JavaScript
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;
|
|
}
|
|
}
|