# All files / src/store/slices namespacesSlice.ts

75.78% Statements 72/95
80% Branches 8/10
100% Functions 2/2
75.78% Lines 72/95

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    961x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    20x
    20x
    20x
    1x
    1x
    1x
    1x
    1x

    1x
    1x
    1x
    1x
    1x

    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    37x
    37x
    20x
    20x
    20x
    37x
    20x
    20x
    20x
    1x
    1x
    1x
    20x
    37x

    37x

    37x

    37x
    1x
    1x
    1x
    1x
    1x
     import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'
    import { Namespace } from '@/lib/types'
    import {
      getAllNamespaces,
      createNamespace as createNamespaceDB,
      deleteNamespace as deleteNamespaceDB,
      ensureDefaultNamespace,
    } from '@/lib/db'

    interface NamespacesState {
      items: Namespace[]
      selectedId: string | null
      loading: boolean
      error: string | null
    }

    const initialState: NamespacesState = {
      items: [],
      selectedId: null,
      loading: false,
      error: null,
    }

    export const fetchNamespaces = createAsyncThunk(
      'namespaces/fetchAll',
      async () => {
        await ensureDefaultNamespace()
        return await getAllNamespaces()
      }
    )

    export const createNamespace = createAsyncThunk(
      'namespaces/create',
      async (name: string) => {
        const namespace: Namespace = {
          id: Date.now().toString(),
          name,
          createdAt: Date.now(),
          isDefault: false,
        }
        await createNamespaceDB(namespace)
        return namespace
      }
    )

    export const deleteNamespace = createAsyncThunk(
      'namespaces/delete',
      async (id: string) => {
        await deleteNamespaceDB(id)
        return id
      }
    )

    const namespacesSlice = createSlice({
      name: 'namespaces',
      initialState,
      reducers: {
        setSelectedNamespace: (state, action: PayloadAction<string>) => {
          state.selectedId = action.payload
        },
      },
      extraReducers: (builder) => {
        builder
          .addCase(fetchNamespaces.pending, (state) => {
            state.loading = true
            state.error = null
          })
          .addCase(fetchNamespaces.fulfilled, (state, action) => {
            state.loading = false
            state.items = action.payload || []
            if (!state.selectedId && state.items.length > 0) {
              const defaultNamespace = state.items.find(n => n.isDefault)
              state.selectedId = defaultNamespace?.id || state.items[0].id
            }
          })
          .addCase(fetchNamespaces.rejected, (state, action) => {
            state.loading = false
            state.error = action.error.message || 'Failed to fetch namespaces'
          })
          .addCase(createNamespace.fulfilled, (state, action) => {
            state.items.push(action.payload)
          })
          .addCase(deleteNamespace.fulfilled, (state, action) => {
            state.items = state.items.filter(n => n.id !== action.payload)
            if (state.selectedId === action.payload) {
              const defaultNamespace = state.items.find(n => n.isDefault)
              state.selectedId = defaultNamespace?.id || state.items[0]?.id || null
            }
          })
      },
    })

    export const { setSelectedNamespace } = namespacesSlice.actions

    export default namespacesSlice.reducer