Skip to content

Commit

Permalink
add Shift+Click (and Shift+Ctrl+Click) selection
Browse files Browse the repository at this point in the history
Users can select a batch of items starting from one focused item, until the next `Shift+Click` item.
If the user uses a combination of `Shift+Ctrl+Click`, the remainder of the selection persists and is not reset.
  • Loading branch information
ahmedhamidawan committed Mar 4, 2024
1 parent f57504b commit 2331e4d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 22 deletions.
18 changes: 15 additions & 3 deletions client/src/components/History/Content/ContentItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
:data-state="dataState"
tabindex="0"
role="button"
@keydown="onKeyDown">
@keydown="onKeyDown"
@focus="$emit('update:item-focused')">
<div class="p-1 cursor-pointer" draggable @dragstart="onDragStart" @dragend="onDragEnd" @click.stop="onClick">
<div class="d-flex justify-content-between">
<span class="p-1" data-description="content item header info">
Expand Down Expand Up @@ -245,7 +246,10 @@ export default {
this.$emit("shift-select", event.key);
} else if (event.key === "ArrowUp" || event.key === "ArrowDown") {
event.preventDefault();
this.$emit("init-key-selection");
this.$emit("arrow-navigate", event.key);
} else if (event.key === "Tab") {
this.$emit("init-key-selection");
} else if (event.key === "Delete" && !this.selected && !this.item.deleted) {
event.preventDefault();
this.onDelete(event.shiftKey);
Expand All @@ -258,11 +262,17 @@ export default {
}
},
onClick(event) {
if (event && this.isCtrlKey(event)) {
if (event && event.shiftKey && this.isCtrlKey(event)) {
this.$emit("selected-to", false);
} else if (event && this.isCtrlKey(event)) {
this.$emit("init-key-selection");
this.$emit("update:selected", !this.selected);
} else if (event && event.shiftKey) {
this.$emit("selected-to", true);
} else if (this.isPlaceholder) {
return;
this.$emit("init-key-selection");
} else if (this.isDataset) {
this.$emit("init-key-selection");
this.$emit("update:expand-dataset", !this.expandDataset);
} else {
this.$emit("view-collection", this.item, this.name);
Expand All @@ -289,10 +299,12 @@ export default {
onDelete(recursive = false) {
this.$emit("delete", this.item, recursive);
this.$emit("update:selected", false);
this.$emit("init-key-selection");
},
onUndelete() {
this.$emit("undelete");
this.$emit("update:selected", false);
this.$emit("init-key-selection");
},
onDragStart(evt) {
this.$emit("drag-start", evt);
Expand Down
45 changes: 40 additions & 5 deletions client/src/components/History/Content/SelectedItems.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default {
items: new Map(),
showSelection: false,
allSelected: false,
initSelectedKey: null,
initSelectedItem: null,
initDirection: null,
};
},
Expand All @@ -31,6 +31,9 @@ export default {
currentFilters() {
return HistoryFilters.getFiltersForText(this.filterText);
},
initSelectedKey() {
return this.initSelectedItem ? this.getItemKey(this.initSelectedItem) : null;
},
},
methods: {
setShowSelection(val) {
Expand Down Expand Up @@ -59,10 +62,10 @@ export default {
this.items = newSelected;
this.breakQuerySelection();
},
shiftSelect({ item, nextItem, eventKey }) {
shiftSelect(item, nextItem, eventKey) {
const currentItemKey = this.getItemKey(item);
if (!this.initDirection) {
this.initSelectedKey = currentItemKey;
if (!this.initSelectedKey) {
this.initSelectedItem = item;
this.initDirection = eventKey;
this.setSelected(item, true);
}
Expand All @@ -82,8 +85,39 @@ export default {
this.setSelected(nextItem, true);
}
},
selectTo(item, prevItem, allItems, reset = true) {
if (prevItem && item) {
// we are staring a new shift+click selectTo from `prevItem`
if (!this.initSelectedKey) {
this.initSelectedItem = prevItem;
}

// `reset = false` in the case user is holding shift+ctrl key
if (reset) {
// clear this.items of any other selections
this.items = new Map();
}
this.setSelected(this.initSelectedItem, true);

const initItemIndex = allItems.indexOf(this.initSelectedItem);
const currentItemIndex = allItems.indexOf(item);

let selections = [];
// from allItems, get the items between the init item and the current item
if (initItemIndex < currentItemIndex) {
this.initDirection = "ArrowDown";
selections = allItems.slice(initItemIndex + 1, currentItemIndex + 1);
} else if (initItemIndex > currentItemIndex) {
this.initDirection = "ArrowUp";
selections = allItems.slice(currentItemIndex, initItemIndex);
}
this.selectItems(selections);
} else {
this.setSelected(item, true);
}
},
initKeySelection() {
this.initSelectedKey = null;
this.initSelectedItem = null;
this.initDirection = null;
},
selectItems(items = []) {
Expand Down Expand Up @@ -142,6 +176,7 @@ export default {
setShowSelection: this.setShowSelection,
selectAllInCurrentQuery: this.selectAllInCurrentQuery,
selectItems: this.selectItems,
selectTo: this.selectTo,
isSelected: this.isSelected,
setSelected: this.setSelected,
resetSelection: this.reset,
Expand Down
37 changes: 23 additions & 14 deletions client/src/components/History/CurrentHistory/HistoryPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ const contentItemRefs = computed(() => {
return acc;
}, {});
});
const currItemFocused = ref<HistoryItem | null>(null);
const lastItemFocused = ref<HistoryItem | null>(null);
const { currentFilterText, currentHistoryId } = storeToRefs(useHistoryStore());
const { lastCheckedTime, totalMatchesCount, isWatching } = storeToRefs(useHistoryItemsStore());
Expand Down Expand Up @@ -149,6 +151,8 @@ watch(
invisibleHistoryItems.value = {};
offsetQueryParam.value = 0;
loadHistoryItems();
currItemFocused.value = null;
lastItemFocused.value = null;
}
);
Expand Down Expand Up @@ -176,6 +180,8 @@ watch(
(newValue, currentValue) => {
if (newValue !== currentValue) {
operationRunning.value = null;
currItemFocused.value = null;
lastItemFocused.value = null;
}
}
);
Expand All @@ -193,6 +199,15 @@ watch(historyItems, (newHistoryItems) => {
}
});
watch(
() => currItemFocused.value,
(newItem, oldItem) => {
if (newItem) {
lastItemFocused.value = oldItem;
}
}
);
function getHighlight(item: HistoryItem) {
if (unref(isLoading)) {
return undefined;
Expand Down Expand Up @@ -389,15 +404,6 @@ onMounted(async () => {
await loadHistoryItems();
});
function nextSelections(item: HistoryItem, eventKey: string) {
const nextItem = arrowNavigate(item, eventKey);
return {
item,
nextItem,
eventKey,
};
}
function arrowNavigate(item: HistoryItem, eventKey: string) {
let nextItem = null;
if (eventKey === "ArrowDown") {
Expand Down Expand Up @@ -444,6 +450,7 @@ function setItemDragstart(
setShowSelection,
selectAllInCurrentQuery,
isSelected,
selectTo,
setSelected,
shiftSelect,
initKeySelection,
Expand Down Expand Up @@ -574,10 +581,7 @@ function setItemDragstart(
:selected="isSelected(item)"
:selectable="showSelection"
:filterable="filterable"
@arrow-navigate="
arrowNavigate(item, $event);
initKeySelection();
"
@arrow-navigate="arrowNavigate(item, $event)"
@drag-start="
setItemDragstart(
item,
Expand All @@ -588,12 +592,17 @@ function setItemDragstart(
)
"
@hide-selection="setShowSelection(false)"
@shift-select="(eventKey) => shiftSelect(nextSelections(item, eventKey))"
@init-key-selection="initKeySelection"
@shift-select="
(eventKey) => shiftSelect(item, arrowNavigate(item, eventKey), eventKey)
"
@select-all="selectAllInCurrentQuery(historyItems, false)"
@selected-to="(reset) => selectTo(item, lastItemFocused, historyItems, reset)"
@tag-click="updateFilterValue('tag', $event)"
@tag-change="onTagChange"
@toggleHighlights="updateFilterValue('related', item.hid)"
@update:expand-dataset="setExpanded(item, $event)"
@update:item-focused="currItemFocused = item"
@update:selected="setSelected(item, $event)"
@view-collection="$emit('view-collection', item, currentOffset)"
@delete="onDelete"
Expand Down

0 comments on commit 2331e4d

Please sign in to comment.