revert fb8e77bb68
Local Build and Deploy / deploy (push) Successful in 1m11s
Local Build and Deploy / deploy (push) Successful in 1m11s
revert style: clean up code with prettier and eslint
This commit is contained in:
1 parent
27de078f54
commit
e85e4d74ea
378 files changed
+20710
-22428
No files matched your search
@@ -1,34 +1,34 @@
|
||||
"use client";
|
||||
'use client'
|
||||
|
||||
import { createContext, type Dispatch, type ReactNode, useContext, useReducer } from "react";
|
||||
import type { RootTab, TreeNodeData, TreeNodeUpdate } from "@/types/catalog";
|
||||
import { createContext, type Dispatch, type ReactNode, useContext, useReducer } from 'react'
|
||||
import type { RootTab, TreeNodeData, TreeNodeUpdate } from '@/types/catalog'
|
||||
|
||||
// ── State ─────────────────────────────────────────────────────
|
||||
|
||||
export interface CatalogManagerState {
|
||||
// Root tabs
|
||||
rootPages: RootTab[];
|
||||
activeTabId: number | null;
|
||||
loadingRoot: boolean;
|
||||
rootPages: RootTab[]
|
||||
activeTabId: number | null
|
||||
loadingRoot: boolean
|
||||
|
||||
// Tree
|
||||
nodes: Map<number, TreeNodeData>;
|
||||
childrenMap: Map<number, number[]>;
|
||||
expandedIds: Set<number>;
|
||||
loadingIds: Set<number>;
|
||||
selectedPageId: number | null;
|
||||
multiSelectedIds: Set<number>;
|
||||
focusedId: number | null;
|
||||
sortMode: boolean;
|
||||
searchQuery: string;
|
||||
searchResults: TreeNodeData[] | null;
|
||||
searching: boolean;
|
||||
nodes: Map<number, TreeNodeData>
|
||||
childrenMap: Map<number, number[]>
|
||||
expandedIds: Set<number>
|
||||
loadingIds: Set<number>
|
||||
selectedPageId: number | null
|
||||
multiSelectedIds: Set<number>
|
||||
focusedId: number | null
|
||||
sortMode: boolean
|
||||
searchQuery: string
|
||||
searchResults: TreeNodeData[] | null
|
||||
searching: boolean
|
||||
|
||||
// Editor
|
||||
editorDirty: boolean;
|
||||
editorDirty: boolean
|
||||
|
||||
// Breadcrumb
|
||||
ancestors: Array<{ id: number; caption: string }>;
|
||||
ancestors: Array<{ id: number; caption: string }>
|
||||
}
|
||||
|
||||
const initialState: CatalogManagerState = {
|
||||
@@ -43,51 +43,51 @@ const initialState: CatalogManagerState = {
|
||||
multiSelectedIds: new Set(),
|
||||
focusedId: null,
|
||||
sortMode: false,
|
||||
searchQuery: "",
|
||||
searchQuery: '',
|
||||
searchResults: null,
|
||||
searching: false,
|
||||
editorDirty: false,
|
||||
ancestors: [],
|
||||
};
|
||||
}
|
||||
|
||||
// ── Actions ───────────────────────────────────────────────────
|
||||
|
||||
export type CatalogAction =
|
||||
| { type: "SET_ROOT_PAGES"; pages: RootTab[] }
|
||||
| { type: "SET_LOADING_ROOT"; loading: boolean }
|
||||
| { type: "SET_ACTIVE_TAB"; id: number | null }
|
||||
| { type: "SELECT_PAGE"; id: number | null }
|
||||
| { type: "TOGGLE_EXPAND"; id: number }
|
||||
| { type: "SET_EXPANDED"; id: number; expanded: boolean }
|
||||
| { type: "EXPAND_PATH"; ids: number[] }
|
||||
| { type: "COLLAPSE_ALL" }
|
||||
| { type: "SET_NODES"; nodes: TreeNodeData[] }
|
||||
| { type: "SET_CHILDREN"; parentId: number; children: TreeNodeData[] }
|
||||
| { type: "UPDATE_NODE"; update: TreeNodeUpdate }
|
||||
| { type: "REMOVE_NODE"; id: number }
|
||||
| { type: "SET_LOADING_IDS"; ids: Set<number> }
|
||||
| { type: "SET_SEARCH_QUERY"; query: string }
|
||||
| { type: "SET_SEARCH_RESULTS"; results: TreeNodeData[] | null }
|
||||
| { type: "SET_SEARCHING"; searching: boolean }
|
||||
| { type: "TOGGLE_SORT_MODE" }
|
||||
| { type: "TOGGLE_MULTI_SELECT"; id: number }
|
||||
| { type: "RANGE_SELECT"; from: number; to: number; flatIds: number[] }
|
||||
| { type: "CLEAR_MULTI_SELECT" }
|
||||
| { type: "SET_FOCUSED"; id: number | null }
|
||||
| { type: "SET_DIRTY"; dirty: boolean }
|
||||
| { type: "SET_ANCESTORS"; ancestors: Array<{ id: number; caption: string }> }
|
||||
| { type: "ON_DIALOG_CLOSE" }
|
||||
| { type: "CLEAR_TREE" };
|
||||
| { type: 'SET_ROOT_PAGES'; pages: RootTab[] }
|
||||
| { type: 'SET_LOADING_ROOT'; loading: boolean }
|
||||
| { type: 'SET_ACTIVE_TAB'; id: number | null }
|
||||
| { type: 'SELECT_PAGE'; id: number | null }
|
||||
| { type: 'TOGGLE_EXPAND'; id: number }
|
||||
| { type: 'SET_EXPANDED'; id: number; expanded: boolean }
|
||||
| { type: 'EXPAND_PATH'; ids: number[] }
|
||||
| { type: 'COLLAPSE_ALL' }
|
||||
| { type: 'SET_NODES'; nodes: TreeNodeData[] }
|
||||
| { type: 'SET_CHILDREN'; parentId: number; children: TreeNodeData[] }
|
||||
| { type: 'UPDATE_NODE'; update: TreeNodeUpdate }
|
||||
| { type: 'REMOVE_NODE'; id: number }
|
||||
| { type: 'SET_LOADING_IDS'; ids: Set<number> }
|
||||
| { type: 'SET_SEARCH_QUERY'; query: string }
|
||||
| { type: 'SET_SEARCH_RESULTS'; results: TreeNodeData[] | null }
|
||||
| { type: 'SET_SEARCHING'; searching: boolean }
|
||||
| { type: 'TOGGLE_SORT_MODE' }
|
||||
| { type: 'TOGGLE_MULTI_SELECT'; id: number }
|
||||
| { type: 'RANGE_SELECT'; from: number; to: number; flatIds: number[] }
|
||||
| { type: 'CLEAR_MULTI_SELECT' }
|
||||
| { type: 'SET_FOCUSED'; id: number | null }
|
||||
| { type: 'SET_DIRTY'; dirty: boolean }
|
||||
| { type: 'SET_ANCESTORS'; ancestors: Array<{ id: number; caption: string }> }
|
||||
| { type: 'ON_DIALOG_CLOSE' }
|
||||
| { type: 'CLEAR_TREE' }
|
||||
|
||||
// ── Reducer ───────────────────────────────────────────────────
|
||||
|
||||
function reducer(state: CatalogManagerState, action: CatalogAction): CatalogManagerState {
|
||||
switch (action.type) {
|
||||
case "SET_ROOT_PAGES":
|
||||
return { ...state, rootPages: action.pages, loadingRoot: false };
|
||||
case "SET_LOADING_ROOT":
|
||||
return { ...state, loadingRoot: action.loading };
|
||||
case "SET_ACTIVE_TAB":
|
||||
case 'SET_ROOT_PAGES':
|
||||
return { ...state, rootPages: action.pages, loadingRoot: false }
|
||||
case 'SET_LOADING_ROOT':
|
||||
return { ...state, loadingRoot: action.loading }
|
||||
case 'SET_ACTIVE_TAB':
|
||||
return {
|
||||
...state,
|
||||
activeTabId: action.id,
|
||||
@@ -95,55 +95,55 @@ function reducer(state: CatalogManagerState, action: CatalogAction): CatalogMana
|
||||
multiSelectedIds: new Set(),
|
||||
focusedId: null,
|
||||
ancestors: [],
|
||||
};
|
||||
case "SELECT_PAGE":
|
||||
}
|
||||
case 'SELECT_PAGE':
|
||||
return {
|
||||
...state,
|
||||
selectedPageId: action.id,
|
||||
multiSelectedIds: new Set(),
|
||||
focusedId: action.id,
|
||||
};
|
||||
|
||||
case "TOGGLE_EXPAND": {
|
||||
const next = new Set(state.expandedIds);
|
||||
if (next.has(action.id)) next.delete(action.id);
|
||||
else next.add(action.id);
|
||||
return { ...state, expandedIds: next };
|
||||
}
|
||||
case "SET_EXPANDED": {
|
||||
const next = new Set(state.expandedIds);
|
||||
if (action.expanded) next.add(action.id);
|
||||
else next.delete(action.id);
|
||||
return { ...state, expandedIds: next };
|
||||
}
|
||||
case "EXPAND_PATH": {
|
||||
const next = new Set(state.expandedIds);
|
||||
for (const id of action.ids) next.add(id);
|
||||
return { ...state, expandedIds: next };
|
||||
}
|
||||
case "COLLAPSE_ALL":
|
||||
return { ...state, expandedIds: new Set() };
|
||||
|
||||
case "SET_NODES": {
|
||||
const next = new Map(state.nodes);
|
||||
for (const n of action.nodes) next.set(n.id, n);
|
||||
return { ...state, nodes: next };
|
||||
}
|
||||
case "SET_CHILDREN": {
|
||||
const nextNodes = new Map(state.nodes);
|
||||
const nextChildren = new Map(state.childrenMap);
|
||||
const childIds: number[] = [];
|
||||
for (const child of action.children) {
|
||||
nextNodes.set(child.id, child);
|
||||
childIds.push(child.id);
|
||||
}
|
||||
nextChildren.set(action.parentId, childIds);
|
||||
return { ...state, nodes: nextNodes, childrenMap: nextChildren };
|
||||
|
||||
case 'TOGGLE_EXPAND': {
|
||||
const next = new Set(state.expandedIds)
|
||||
if (next.has(action.id)) next.delete(action.id)
|
||||
else next.add(action.id)
|
||||
return { ...state, expandedIds: next }
|
||||
}
|
||||
case "UPDATE_NODE": {
|
||||
const existing = state.nodes.get(action.update.id);
|
||||
if (!existing) return state;
|
||||
const nextNodes = new Map(state.nodes);
|
||||
case 'SET_EXPANDED': {
|
||||
const next = new Set(state.expandedIds)
|
||||
if (action.expanded) next.add(action.id)
|
||||
else next.delete(action.id)
|
||||
return { ...state, expandedIds: next }
|
||||
}
|
||||
case 'EXPAND_PATH': {
|
||||
const next = new Set(state.expandedIds)
|
||||
for (const id of action.ids) next.add(id)
|
||||
return { ...state, expandedIds: next }
|
||||
}
|
||||
case 'COLLAPSE_ALL':
|
||||
return { ...state, expandedIds: new Set() }
|
||||
|
||||
case 'SET_NODES': {
|
||||
const next = new Map(state.nodes)
|
||||
for (const n of action.nodes) next.set(n.id, n)
|
||||
return { ...state, nodes: next }
|
||||
}
|
||||
case 'SET_CHILDREN': {
|
||||
const nextNodes = new Map(state.nodes)
|
||||
const nextChildren = new Map(state.childrenMap)
|
||||
const childIds: number[] = []
|
||||
for (const child of action.children) {
|
||||
nextNodes.set(child.id, child)
|
||||
childIds.push(child.id)
|
||||
}
|
||||
nextChildren.set(action.parentId, childIds)
|
||||
return { ...state, nodes: nextNodes, childrenMap: nextChildren }
|
||||
}
|
||||
case 'UPDATE_NODE': {
|
||||
const existing = state.nodes.get(action.update.id)
|
||||
if (!existing) return state
|
||||
const nextNodes = new Map(state.nodes)
|
||||
nextNodes.set(action.update.id, {
|
||||
...existing,
|
||||
...(action.update.caption !== undefined && { caption: action.update.caption }),
|
||||
@@ -151,77 +151,77 @@ function reducer(state: CatalogManagerState, action: CatalogAction): CatalogMana
|
||||
...(action.update.visible !== undefined && { visible: action.update.visible }),
|
||||
...(action.update.pageLayout !== undefined && { pageLayout: action.update.pageLayout }),
|
||||
...(action.update.iconImage !== undefined && { iconImage: action.update.iconImage }),
|
||||
});
|
||||
return { ...state, nodes: nextNodes };
|
||||
})
|
||||
return { ...state, nodes: nextNodes }
|
||||
}
|
||||
case "REMOVE_NODE": {
|
||||
const nextNodes = new Map(state.nodes);
|
||||
nextNodes.delete(action.id);
|
||||
const nextChildren = new Map(state.childrenMap);
|
||||
case 'REMOVE_NODE': {
|
||||
const nextNodes = new Map(state.nodes)
|
||||
nextNodes.delete(action.id)
|
||||
const nextChildren = new Map(state.childrenMap)
|
||||
// Remove from parent's children list
|
||||
for (const [parentId, children] of nextChildren) {
|
||||
const idx = children.indexOf(action.id);
|
||||
const idx = children.indexOf(action.id)
|
||||
if (idx !== -1) {
|
||||
nextChildren.set(
|
||||
parentId,
|
||||
children.filter((cid) => cid !== action.id),
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
// Remove this node's children entry
|
||||
nextChildren.delete(action.id);
|
||||
const nextSelected = state.selectedPageId === action.id ? null : state.selectedPageId;
|
||||
return { ...state, nodes: nextNodes, childrenMap: nextChildren, selectedPageId: nextSelected };
|
||||
nextChildren.delete(action.id)
|
||||
const nextSelected = state.selectedPageId === action.id ? null : state.selectedPageId
|
||||
return { ...state, nodes: nextNodes, childrenMap: nextChildren, selectedPageId: nextSelected }
|
||||
}
|
||||
case "SET_LOADING_IDS":
|
||||
return { ...state, loadingIds: action.ids };
|
||||
case 'SET_LOADING_IDS':
|
||||
return { ...state, loadingIds: action.ids }
|
||||
|
||||
case "SET_SEARCH_QUERY":
|
||||
return { ...state, searchQuery: action.query };
|
||||
case "SET_SEARCH_RESULTS":
|
||||
return { ...state, searchResults: action.results, searching: false };
|
||||
case "SET_SEARCHING":
|
||||
return { ...state, searching: action.searching };
|
||||
case "TOGGLE_SORT_MODE":
|
||||
return { ...state, sortMode: !state.sortMode, multiSelectedIds: new Set() };
|
||||
case 'SET_SEARCH_QUERY':
|
||||
return { ...state, searchQuery: action.query }
|
||||
case 'SET_SEARCH_RESULTS':
|
||||
return { ...state, searchResults: action.results, searching: false }
|
||||
case 'SET_SEARCHING':
|
||||
return { ...state, searching: action.searching }
|
||||
case 'TOGGLE_SORT_MODE':
|
||||
return { ...state, sortMode: !state.sortMode, multiSelectedIds: new Set() }
|
||||
|
||||
case "TOGGLE_MULTI_SELECT": {
|
||||
const next = new Set(state.multiSelectedIds);
|
||||
if (next.has(action.id)) next.delete(action.id);
|
||||
else next.add(action.id);
|
||||
return { ...state, multiSelectedIds: next, focusedId: action.id };
|
||||
case 'TOGGLE_MULTI_SELECT': {
|
||||
const next = new Set(state.multiSelectedIds)
|
||||
if (next.has(action.id)) next.delete(action.id)
|
||||
else next.add(action.id)
|
||||
return { ...state, multiSelectedIds: next, focusedId: action.id }
|
||||
}
|
||||
case "RANGE_SELECT": {
|
||||
const { flatIds, from, to } = action;
|
||||
const fromIdx = flatIds.indexOf(from);
|
||||
const toIdx = flatIds.indexOf(to);
|
||||
if (fromIdx === -1 || toIdx === -1) return state;
|
||||
const lo = Math.min(fromIdx, toIdx);
|
||||
const hi = Math.max(fromIdx, toIdx);
|
||||
const next = new Set(state.multiSelectedIds);
|
||||
for (let i = lo; i <= hi; i++) next.add(flatIds[i]);
|
||||
return { ...state, multiSelectedIds: next, focusedId: action.to };
|
||||
case 'RANGE_SELECT': {
|
||||
const { flatIds, from, to } = action
|
||||
const fromIdx = flatIds.indexOf(from)
|
||||
const toIdx = flatIds.indexOf(to)
|
||||
if (fromIdx === -1 || toIdx === -1) return state
|
||||
const lo = Math.min(fromIdx, toIdx)
|
||||
const hi = Math.max(fromIdx, toIdx)
|
||||
const next = new Set(state.multiSelectedIds)
|
||||
for (let i = lo; i <= hi; i++) next.add(flatIds[i])
|
||||
return { ...state, multiSelectedIds: next, focusedId: action.to }
|
||||
}
|
||||
case "CLEAR_MULTI_SELECT":
|
||||
return { ...state, multiSelectedIds: new Set() };
|
||||
case "SET_FOCUSED":
|
||||
return { ...state, focusedId: action.id };
|
||||
case 'CLEAR_MULTI_SELECT':
|
||||
return { ...state, multiSelectedIds: new Set() }
|
||||
case 'SET_FOCUSED':
|
||||
return { ...state, focusedId: action.id }
|
||||
|
||||
case "SET_DIRTY":
|
||||
return { ...state, editorDirty: action.dirty };
|
||||
case "SET_ANCESTORS":
|
||||
return { ...state, ancestors: action.ancestors };
|
||||
case 'SET_DIRTY':
|
||||
return { ...state, editorDirty: action.dirty }
|
||||
case 'SET_ANCESTORS':
|
||||
return { ...state, ancestors: action.ancestors }
|
||||
|
||||
case "ON_DIALOG_CLOSE":
|
||||
case 'ON_DIALOG_CLOSE':
|
||||
return {
|
||||
...state,
|
||||
selectedPageId: null,
|
||||
editorDirty: false,
|
||||
multiSelectedIds: new Set(),
|
||||
ancestors: [],
|
||||
};
|
||||
}
|
||||
|
||||
case "CLEAR_TREE":
|
||||
case 'CLEAR_TREE':
|
||||
return {
|
||||
...state,
|
||||
nodes: new Map(),
|
||||
@@ -231,34 +231,36 @@ function reducer(state: CatalogManagerState, action: CatalogAction): CatalogMana
|
||||
selectedPageId: null,
|
||||
multiSelectedIds: new Set(),
|
||||
focusedId: null,
|
||||
searchQuery: "",
|
||||
searchQuery: '',
|
||||
searchResults: null,
|
||||
ancestors: [],
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
// ── Context ───────────────────────────────────────────────────
|
||||
|
||||
interface CatalogManagerContextValue {
|
||||
state: CatalogManagerState;
|
||||
dispatch: Dispatch<CatalogAction>;
|
||||
state: CatalogManagerState
|
||||
dispatch: Dispatch<CatalogAction>
|
||||
}
|
||||
|
||||
const CatalogManagerContext = createContext<CatalogManagerContextValue | null>(null);
|
||||
const CatalogManagerContext = createContext<CatalogManagerContextValue | null>(null)
|
||||
|
||||
export function CatalogManagerProvider({ children }: { children: ReactNode }) {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const [state, dispatch] = useReducer(reducer, initialState)
|
||||
return (
|
||||
<CatalogManagerContext.Provider value={{ state, dispatch }}>{children}</CatalogManagerContext.Provider>
|
||||
);
|
||||
<CatalogManagerContext.Provider value={{ state, dispatch }}>
|
||||
{children}
|
||||
</CatalogManagerContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useCatalogManager() {
|
||||
const ctx = useContext(CatalogManagerContext);
|
||||
if (!ctx) throw new Error("useCatalogManager must be used within CatalogManagerProvider");
|
||||
return ctx;
|
||||
const ctx = useContext(CatalogManagerContext)
|
||||
if (!ctx) throw new Error('useCatalogManager must be used within CatalogManagerProvider')
|
||||
return ctx
|
||||
}
|
||||
Reference in new issue
Block a user