Skip to content

Commit 11e5d9d

Browse files
committed
🎉 Added support for selection mode.
1 parent 9f4e4a8 commit 11e5d9d

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

src/businessLogic/contracts/types.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,23 @@ export interface ItemTypeCustomisations {
1414

1515
export interface TreeViewCreatedEventPayload {
1616
itemCustomisations: ItemTypeCustomisations;
17-
eventManager: EventManager
17+
eventManager: EventManager;
1818
}
1919

2020
export interface EventManager {
2121
subscribeToItemChecked(type: string, callback: (item: TreeViewItem[]) => void): void;
2222
subscribeToItemUnchecked(type: string, callback: (item: TreeViewItem[]) => void): void;
2323
}
2424

25+
export interface EventHub {
26+
onItemChecked(item: TreeViewItem): void;
27+
onItemUnChecked(item: TreeViewItem): void;
28+
onFolderChecked(folder: TreeViewItem): void
29+
onFolderUnChecked(folder: TreeViewItem): void;
30+
setSelectionMode(mode: string): void;
31+
readonly selectedItems: TreeViewItem[];
32+
}
33+
2534
export interface TreeViewViewModel {
2635
loadNodes(nodes: TreeViewItem[]): void;
2736
getNodes(): { [id: string]: TreeViewItem };
@@ -32,6 +41,7 @@ export interface TreeViewViewModel {
3241
checkedStatusChanged(item: TreeViewItem): void;
3342
setSelectionMode(mode: SelectionMode): void;
3443
selectedItems: TreeViewItem[];
44+
readonly selectedItems: TreeViewItem[];
3545
}
3646

3747
export interface Customisations {
Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import { EventManager, TreeViewItem } from "../contracts/types"
1+
import { EventHub, EventManager, SelectionMode, TreeViewItem } from "../contracts/types"
22
import { findChildrenOfType } from "../hierachyTraversal/hierachyTraversal";
33

4-
const onCheckedSubscribers: {[type: string]: ((items: TreeViewItem[]) => void)[] } = {}
5-
const onUnCheckedSubscribers: {[type: string]: ((items: TreeViewItem[]) => void)[] } = {}
6-
4+
let selectedItems: TreeViewItem[] = [];
75
export const eventManager: EventManager = {
86
// Add subscriber for item hecked to collection of subscribers
97
subscribeToItemChecked(type: string, callback: (item: TreeViewItem[]) => void): void {
108
onCheckedSubscribers[type] = onCheckedSubscribers[type] ?? [];
11-
129
onCheckedSubscribers[type].push(callback);
1310
},
1411

1512
// Add subscriber for item unchecked to collection of subscribers
1613
subscribeToItemUnchecked(type: string, callback: (item: TreeViewItem[]) => void): void {
1714
onUnCheckedSubscribers[type] = onUnCheckedSubscribers[type] ?? [];
18-
1915
onUnCheckedSubscribers[type].push(callback);
2016
},
2117
}
2218

23-
export const eventHub = {
19+
export const eventHub: EventHub = {
2420
// Publish events if any subscriber listening for item checked
2521
onItemChecked(item: TreeViewItem): void {
22+
if (selectionMode == 'Single') RemovePreviousSelectedItems();
23+
24+
selectedItems.push(item);
25+
2626
if (item.type == 'folder') {
2727
this.onFolderChecked(item);
2828
} else {
@@ -35,15 +35,20 @@ export const eventHub = {
3535

3636
// Publish events if any subscriber listening for item unchecked
3737
onItemUnChecked(item: TreeViewItem): void {
38+
remove(item, selectedItems);
3839
const subscribers = onUnCheckedSubscribers[item.type.toString()];
3940
if (subscribers) {
4041
subscribers.forEach(callback => callback([item]));
4142
}
4243
},
4344

4445
/// Premise: Whenever a folder is checked, it automatically checks all it's decendants.
45-
/// Expected action: When a folder is checked, traverse it's tree to get see if any item has also been checked for which a listener needs to be updated
46+
/// Expected action: When a folder is checked, traverse it's tree to get see if any item has also been checked
47+
// for which a callback listener needs to be called
4648
onFolderChecked(folder: TreeViewItem): void {
49+
if (selectionMode == 'Single') RemovePreviousSelectedItems();
50+
selectedItems.push(folder);
51+
4752
if (folder.type != 'folder') return;
4853

4954
const itemTypesWithListeners = Object.keys(onCheckedSubscribers);
@@ -54,14 +59,38 @@ export const eventHub = {
5459
},
5560

5661
/// Premise: Whenever a folder is checked, it automatically checks all it's decendants.
57-
/// Expected action: When a folder is un-checked, traverse it's tree to get see if any item has also been checked for which a listener needs to be updated
62+
/// Expected action: When a folder is un-checked, traverse it's tree to get see if any item
63+
// has also been checked for which a listener needs to be called
5864
onFolderUnChecked(folder: TreeViewItem): void {
65+
remove(folder, selectedItems);
5966
if (folder.type != 'folder') return;
6067

6168
const itemTypesWithListeners = Object.keys(onUnCheckedSubscribers);
6269
itemTypesWithListeners.forEach(itemType => {
6370
const itemsToPublish = findChildrenOfType(folder, itemType);
6471
onUnCheckedSubscribers[itemType].forEach(subscriber => subscriber(itemsToPublish));
6572
});
66-
}
73+
},
74+
75+
setSelectionMode(mode: SelectionMode): void {
76+
selectionMode = mode;
77+
},
78+
79+
selectedItems
80+
}
81+
82+
83+
function RemovePreviousSelectedItems() {
84+
selectedItems.forEach(item => item.checkedStatus = 'False');
85+
selectedItems = [];
86+
}
87+
88+
function remove(item: TreeViewItem, collection: TreeViewItem[]) {
89+
const index = collection.indexOf(item);
90+
if (index > -1) collection.splice(index, 1);
6791
}
92+
93+
const onCheckedSubscribers: {[type: string]: ((items: TreeViewItem[]) => void)[] } = {};
94+
const onUnCheckedSubscribers: {[type: string]: ((items: TreeViewItem[]) => void)[] } = {};
95+
96+
let selectionMode: SelectionMode = 'Multiple';

src/components/treeView.vue/treeView.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { eventManager } from '@/businessLogic/eventHub/explorerEventPublisher';
4343
export default class TreeView extends Vue {
4444
@Prop({ default: () => { return [] }}) treeViewItems!: TreeViewItem[];
4545
viewModel = TreeViewViewModel;
46+
@Prop({ default: 'Multiple' }) selectionMode!: SelectionMode;
4647
itemCustomisations = ItemCustomisations;
4748
4849
created(): void {
@@ -109,6 +110,7 @@ export default class TreeView extends Vue {
109110
}
110111
111112
mounted(): void {
113+
this.viewModel.setSelectionMode(this.selectionMode);
112114
const isRootNode = !('nested' in this.$attrs);
113115
if (isRootNode) {
114116
this.viewModel.loadNodes(this.treeViewItems);
@@ -124,6 +126,11 @@ export default class TreeView extends Vue {
124126
target.classList.toggle('rotate-90');
125127
element[0].classList.toggle('hide');
126128
}
129+
130+
@Watch("selectionMode")
131+
onSelectionModeChanged(newMode: SelectionMode): void {
132+
this.viewModel.setSelectionMode(newMode);
133+
}
127134
}
128135
</script>
129136

0 commit comments

Comments
 (0)