@gravity-ui/graph
Version:
Modern graph editor component
107 lines (106 loc) • 3.82 kB
JavaScript
import { computed, signal } from "@preact/signals-core";
import groupBy from "lodash/groupBy";
import { Group } from "../../components/canvas/groups";
import { MultipleSelectionBucket } from "../../services/selection/MultipleSelectionBucket";
import { ESelectionStrategy } from "../../services/selection/types";
import { GroupState } from "./Group";
export class GroupsListStore {
constructor(rootStore, graph) {
this.rootStore = rootStore;
this.graph = graph;
this.$groupsMap = signal(new Map());
this.$groups = computed(() => {
return Array.from(this.$groupsMap.value.values());
});
this.$blockGroups = computed(() => {
return groupBy(this.rootStore.blocksList.$blocks.value, (item) => item.$state.value.group);
});
/**
* Bucket for managing group selection state
*/
this.groupSelectionBucket = new MultipleSelectionBucket("group", (payload, defaultAction) => {
this.graph.executеDefaultEventAction("groups-selection-change", payload, defaultAction);
}, (element) => {
return element instanceof Group;
});
this.$selectedGroups = computed(() => {
return Array.from(this.groupSelectionBucket.$selected.value)
.map((id) => this.getGroupState(id))
.filter(Boolean);
});
this.groupSelectionBucket.attachToManager(this.rootStore.selectionService);
}
updateGroupsMap(groups) {
this.$groupsMap.value = new Map(groups);
}
addGroup(group) {
this.$groupsMap.value.set(group.id, this.getOrCreateGroupState(group));
this.updateGroupsMap(this.$groupsMap.value);
return group.id;
}
deleteGroups(groups) {
const map = new Map(this.$groupsMap.value);
groups.forEach((gId) => {
const id = typeof gId === "string" ? gId : gId.id;
map.delete(id);
});
this.updateGroupsMap(map);
}
updateGroups(groups) {
this.updateGroupsMap(groups.reduce((acc, group) => {
const state = this.getOrCreateGroupState(group);
acc.set(group.id, state);
return acc;
}, this.$groupsMap.value));
}
setGroups(groups) {
const groupStates = groups.map((group) => this.getOrCreateGroupState(group));
this.applyGroupsState(groupStates);
}
getOrCreateGroupState(group) {
const groupState = this.$groupsMap.value.get(group.id);
if (groupState) {
groupState.updateGroup(group);
return groupState;
}
return GroupState.fromTGroup(this, group);
}
applyGroupsState(groups) {
this.updateGroupsMap(groups.map((group) => [group.id, group]));
}
getGroupState(id) {
return this.$groupsMap.value.get(id);
}
getGroup(id) {
return this.getGroupState(id)?.asTGroup();
}
reset() {
this.applyGroupsState([]);
}
toJSON() {
return this.$groups.value.map((group) => group.asTGroup());
}
/**
* Updates group selection using the SelectionService
* @param ids Group IDs to update selection for
* @param selected Whether to select or deselect
* @param strategy The selection strategy to apply
*/
updateGroupsSelection(ids, selected, strategy = ESelectionStrategy.REPLACE) {
if (selected) {
this.groupSelectionBucket.select(ids, strategy);
}
else {
this.groupSelectionBucket.deselect(ids);
}
}
/**
* Resets the selection for groups
*/
resetSelection() {
this.groupSelectionBucket.reset();
}
getGroupStates(ids) {
return ids.map((id) => this.getGroupState(id)).filter(Boolean);
}
}