Files
abode/src/react/store/slices/loading.ts
T
codingetandCodex 31d4636dde
CI / install-and-build (pull_request) Successful in 1m29s
CI / format (pull_request) Successful in 51s
CI / typecheck-source (pull_request) Successful in 41s
CI / typecheck-tests (pull_request) Successful in 39s
CI / test (pull_request) Successful in 51s
CI / lint (pull_request) Successful in 21s
ci: add pull request quality gates
Co-Authored-By: gpt-5.6-terra <noreply@openai.com>
2026-07-22 21:50:29 +00:00

65 lines
1.5 KiB
TypeScript

import {
createSlice,
type PayloadAction,
type WithSlice,
} from "@reduxjs/toolkit";
import { clearAll } from "../actions/clearAll.js";
import { reducer } from "../store.js";
import type { ObjectError } from "../../../util/error.js";
export type LoadingSlice = Record<string, LoadingState>;
export type LoadingState = (
| {
status: "loading";
}
| {
status: "refreshing";
}
| {
status: "error";
error: ObjectError;
}
| {
status: "loaded";
}
) & {
type: string;
params: unknown;
};
const initialLoadingSlice: LoadingSlice = {};
const loadingSlice = createSlice({
name: "loading",
initialState: initialLoadingSlice,
selectors: {
getLoading: (state, id: string): LoadingState | null => state[id] ?? null,
getLoadingStatus: (state, id: string): LoadingState["status"] | null =>
state[id]?.status ?? null,
},
reducers: {
setLoading: (
state,
action: PayloadAction<[id: string, state: LoadingState]>,
) => {
state[action.payload[0]] = action.payload[1];
},
clearLoading: (state, action: PayloadAction<string>) => {
delete state[action.payload];
},
},
extraReducers(builder) {
builder.addCase(clearAll, () => initialLoadingSlice);
},
});
declare module "../store.js" {
export interface LazySlices extends WithSlice<typeof loadingSlice> {}
}
export const {
selectors: { getLoading, getLoadingStatus },
actions: { setLoading, clearLoading },
selectSlice: selectLoading,
} = loadingSlice.injectInto(reducer);