Skip to content
Snippets Groups Projects
json_viewer.reducer.ts 2.36 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { PayloadAction, createSlice } from '@reduxjs/toolkit'
    
    export enum CollapseValues {
        TOGGLE,
        FALSE,
        TRUE
    }
    
    const CollapseActions = {
        [CollapseValues.TOGGLE]: (collapse: boolean) => { return collapse = !collapse },
        [CollapseValues.FALSE]: () => { return false },
        [CollapseValues.TRUE]: () => { return true },
    }
    
    type Identifier = {
        key: string,
        nested: number
    }
    
    
    // containg object location and collapsed information
    interface CollapsedItem {
        identifier: Identifier
        collapsed: boolean
    }
    
    export interface ReducerState {
        breadcrumbs: Array<string>,
    
        /**
         * Meta container containg identifier of
         * all non collapsed json objects
         */
        collapseContainer: Array<CollapsedItem>
    }
    
    const initialState: ReducerState = {
        breadcrumbs: [],
        collapseContainer: [],
    }
    
    export const compareIdentifier = (a: Identifier, b: Identifier): boolean => {
        return a.key === b.key && a.nested === b.nested;
    }
    
    /**
     * Every component instance has its own id.
     * This id is getting used as key to define the respective object container
     */
    const JsonViewerSlice = createSlice({
        name: 'json_viewer',
        initialState,
        reducers: {
            toggleCollapse: (state, { payload }: PayloadAction<{ identifier: Identifier, collapse: CollapseValues }>) => {
                const { identifier, collapse } = payload
    
                // potentially find already collapsed
    
    Matthias Feyll's avatar
    Matthias Feyll committed
                const i = state.collapseContainer.findIndex(i => compareIdentifier(identifier, i.identifier))
    
    
    
                if (i === -1) {
                    // create new collapse
                    const newItem = { identifier, collapsed: true }
                    state.collapseContainer = [...state.collapseContainer, newItem]
                    return;
                }
    
                // update nested attribute
                state.collapseContainer = state.collapseContainer.map((item, index) => {
                    if (index !== i) {
                        return item
                    }
    
                    return {
                        ...item,
                        collapsed: CollapseActions[collapse](item.collapsed)
                    }
                })
            },
            setBreadcrumbs: (state, { payload }: PayloadAction<Array<string>>) => {
                state.breadcrumbs = payload
            },
        },
    })
    
    export const { toggleCollapse, setBreadcrumbs } = JsonViewerSlice.actions
    
    
    export default JsonViewerSlice.reducer