diff --git a/src/actions/utilActions.js b/src/actions/utilActions.js index 40f51ba7..ab04db59 100644 --- a/src/actions/utilActions.js +++ b/src/actions/utilActions.js @@ -113,20 +113,6 @@ export function fetchLocationSunburst() { }; } -export function fetchTimezoneList(dispatch) { - dispatch({ type: "FETCH_TIMEZONE_LIST" }); - Server.get(`timezones/`) - .then(response => { - dispatch({ - type: "FETCH_TIMEZONE_LIST_FULFILLED", - payload: response.data, - }); - }) - .catch(err => { - dispatch({ type: "FETCH_TIMEZONE_LIST_REJECTED", payload: err }); - }); -} - export function fetchCountStats() { return function cb(dispatch) { dispatch({ type: "FETCH_COUNT_STATS" }); diff --git a/src/api_client/util.ts b/src/api_client/util.ts new file mode 100644 index 00000000..38d3b80b --- /dev/null +++ b/src/api_client/util.ts @@ -0,0 +1,37 @@ +import { z } from "zod"; + +import { api } from "./api"; + +enum Endpoints { + fetchTimezones = "fetchTimezones", +} + +const TimezonesSchema = z.string().array(); +type Timezones = z.infer; + +const utilApi = api + .injectEndpoints({ + endpoints: builder => ({ + [Endpoints.fetchTimezones]: builder.query({ + query: () => "timezones/", + transformResponse: (response: string) => { + try { + const timezones = JSON.parse(response); + return TimezonesSchema.parse(timezones); + } catch (e) { + return []; + } + }, + }), + }), + }) + .enhanceEndpoints<"Timezones">({ + addTagTypes: ["Timezones"], + endpoints: { + [Endpoints.fetchTimezones]: { + providesTags: ["Timezones"], + }, + }, + }); + +export const { useFetchTimezonesQuery } = utilApi; diff --git a/src/layouts/settings/Settings.tsx b/src/layouts/settings/Settings.tsx index 60a6038d..0bcfb2a1 100644 --- a/src/layouts/settings/Settings.tsx +++ b/src/layouts/settings/Settings.tsx @@ -18,20 +18,20 @@ import { IconSettings as SettingIcon } from "@tabler/icons-react"; import React, { useEffect, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; -import { fetchCountStats, fetchTimezoneList, updateUser } from "../../actions/utilActions"; +import { fetchCountStats, updateUser } from "../../actions/utilActions"; import { api } from "../../api_client/api"; +import { useFetchTimezonesQuery } from "../../api_client/util"; import { ConfigDateTime } from "../../components/settings/ConfigDateTime"; import { useAppDispatch, useAppSelector } from "../../store/store"; export function Settings() { const [isOpenUpdateDialog, setIsOpenUpdateDialog] = useState(false); const userSelfDetailsRedux = useAppSelector(state => state.user.userSelfDetails); - const timezoneListRedux = useAppSelector(state => state.util.timezoneList); const [userSelfDetails, setUserSelfDetails] = useState(userSelfDetailsRedux); - const [timezoneList, setTimezoneList] = useState(timezoneListRedux); const dispatch = useAppDispatch(); const auth = useAppSelector(state => state.auth); const { t } = useTranslation(); + const { data: timezoneList = [] } = useFetchTimezonesQuery(); // open update dialog, when user was edited useEffect(() => { @@ -45,13 +45,8 @@ export function Settings() { useEffect(() => { dispatch(fetchCountStats()); dispatch(api.endpoints.fetchUserSelfDetails.initiate(auth.access.user_id)).refetch(); - fetchTimezoneList(dispatch); }, [auth.access.user_id, dispatch]); - useEffect(() => { - setTimezoneList(timezoneListRedux); - }, [timezoneListRedux]); - useEffect(() => { setUserSelfDetails(userSelfDetailsRedux); }, [userSelfDetailsRedux]); @@ -140,7 +135,7 @@ export function Settings() { searchable title={t("timezoneexplain")} onChange={value => { - setUserSelfDetails({ ...userSelfDetails, default_timezone: value || "UTC" }); + setUserSelfDetails({ ...userSelfDetails, default_timezone: value ?? "UTC" }); }} data={timezoneList} /> diff --git a/src/reducers/utilReducer.js b/src/reducers/utilReducer.js index d2a28200..058747ce 100644 --- a/src/reducers/utilReducer.js +++ b/src/reducers/utilReducer.js @@ -67,8 +67,6 @@ const initialState = { fetchedJobList: false, error: null, - fetchingTimezones: false, - timezoneList: [], }; export default function reducer(state = initialState, action = DEFAULT_ACTION) { @@ -266,19 +264,6 @@ export default function reducer(state = initialState, action = DEFAULT_ACTION) { }; } - case "FETCH_TIMEZONE_LIST": { - return { ...state, fetchingTimezones: true }; - } - case "FETCH_TIMEZONE_LIST_REJECTED": { - return { ...state, fetchingTimezones: false, error: action.payload }; - } - case "FETCH_TIMEZONE_LIST_FULFILLED": { - return { - ...state, - fetchingTimezones: false, - timezoneList: JSON.parse(action.payload), - }; - } case "FETCH_COUNT_STATS": { return { ...state, fetchingCountStats: true }; }