mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-29 18:13:47 +00:00
feat: multi-select scope for referral network graph
Replace single-select scope with multi-select supporting multiple campaigns, partners, and users simultaneously. Chips UI with remove buttons, clear-all, sorted query keys for cache stability.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { create } from 'zustand';
|
||||
import type { SelectedNode, NetworkFilters, ScopeSelection } from '@/types/referralNetwork';
|
||||
|
||||
const MAX_SCOPE_ITEMS = 50;
|
||||
|
||||
const DEFAULT_FILTERS: NetworkFilters = {
|
||||
campaigns: [],
|
||||
partnersOnly: false,
|
||||
@@ -12,14 +14,16 @@ interface ReferralNetworkState {
|
||||
hoveredNodeId: string | null;
|
||||
highlightedNodes: Set<string>;
|
||||
filters: NetworkFilters;
|
||||
scope: ScopeSelection | null;
|
||||
scope: ScopeSelection[];
|
||||
|
||||
setSelectedNode: (node: SelectedNode) => void;
|
||||
setHoveredNode: (id: string | null) => void;
|
||||
setHighlightedNodes: (nodes: Set<string>) => void;
|
||||
updateFilters: (filters: Partial<NetworkFilters>) => void;
|
||||
resetFilters: () => void;
|
||||
setScope: (scope: ScopeSelection | null) => void;
|
||||
addScope: (item: ScopeSelection) => void;
|
||||
removeScope: (type: ScopeSelection['type'], id: number) => void;
|
||||
clearScope: () => void;
|
||||
}
|
||||
|
||||
export const useReferralNetworkStore = create<ReferralNetworkState>()((set) => ({
|
||||
@@ -27,12 +31,10 @@ export const useReferralNetworkStore = create<ReferralNetworkState>()((set) => (
|
||||
hoveredNodeId: null,
|
||||
highlightedNodes: new Set<string>(),
|
||||
filters: { ...DEFAULT_FILTERS },
|
||||
scope: null,
|
||||
scope: [],
|
||||
|
||||
setSelectedNode: (node) => set({ selectedNode: node }),
|
||||
|
||||
setHoveredNode: (id) => set({ hoveredNodeId: id }),
|
||||
|
||||
setHighlightedNodes: (nodes) => set({ highlightedNodes: nodes }),
|
||||
|
||||
updateFilters: (partial) =>
|
||||
@@ -42,9 +44,32 @@ export const useReferralNetworkStore = create<ReferralNetworkState>()((set) => (
|
||||
|
||||
resetFilters: () => set({ filters: { ...DEFAULT_FILTERS } }),
|
||||
|
||||
setScope: (scope) =>
|
||||
addScope: (item) =>
|
||||
set((state) => {
|
||||
const exists = state.scope.some((s) => s.type === item.type && s.id === item.id);
|
||||
if (exists) return state;
|
||||
if (state.scope.length >= MAX_SCOPE_ITEMS) return state;
|
||||
return {
|
||||
scope: [...state.scope, item],
|
||||
selectedNode: null,
|
||||
hoveredNodeId: null,
|
||||
highlightedNodes: new Set<string>(),
|
||||
filters: { ...DEFAULT_FILTERS },
|
||||
};
|
||||
}),
|
||||
|
||||
removeScope: (type, id) =>
|
||||
set((state) => ({
|
||||
scope: state.scope.filter((s) => !(s.type === type && s.id === id)),
|
||||
selectedNode: null,
|
||||
hoveredNodeId: null,
|
||||
highlightedNodes: new Set<string>(),
|
||||
filters: { ...DEFAULT_FILTERS },
|
||||
})),
|
||||
|
||||
clearScope: () =>
|
||||
set({
|
||||
scope,
|
||||
scope: [],
|
||||
selectedNode: null,
|
||||
hoveredNodeId: null,
|
||||
highlightedNodes: new Set<string>(),
|
||||
|
||||
Reference in New Issue
Block a user