From 68aa15a00ea40280548edb598d53cc75f0935793 Mon Sep 17 00:00:00 2001 From: Kariamos Date: Fri, 19 Jan 2024 14:52:29 +0100 Subject: [PATCH 1/8] wip: refactor rtk --- .../ExperiencePointsFilters.tsx | 117 ++++++++++++++++-- src/pages/ExperiencePoints/index.tsx | 116 +++++++++++------ 2 files changed, 181 insertions(+), 52 deletions(-) diff --git a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx index b7b5f35a4..fb7d18080 100644 --- a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx +++ b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx @@ -13,30 +13,123 @@ import { setSelectedDate, } from "../../redux/experiencePoints/actionCreator"; import { useAppDispatch } from "../../redux/provider"; +import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; interface ExperiencePointsFiltersProps { - campaigns: SelectType.Option[]; + /* campaigns: SelectType.Option[]; activities: SelectType.Option[]; - dates: SelectType.Option[]; + dates: SelectType.Option[]; */ selectedCampaign?: SelectType.Option; selectedActivity?: SelectType.Option; selectedDate?: SelectType.Option; - search?: string; } +const useSelectValues = ({ + selectedCampaign, + selectedActivity, + selectedDate, +}: { + selectedCampaign?: SelectType.Option; + selectedActivity?: SelectType.Option; + selectedDate?: SelectType.Option; + search?: string; +}) => { + const { data, isLoading } = useGetUsersMeExperienceQuery({ + filterBy: { + campaign: selectedCampaign?.value, + activity: selectedActivity?.value, + date: selectedDate?.value, + }, + }); + if (isLoading || !data) return { campaigns: [], activities: [], dates: [] }; + + const campaigns: SelectType.Option[] = data.results + .filter( + ( + r + ): r is { + id: number; + activity: { id: number }; + campaign: { id: number; title?: string | undefined }; + date: string; + amount: number; + note?: string | undefined; + } => typeof r.campaign !== "undefined" + ) + .map((r) => { + return { + value: r.campaign.id.toString(), + label: `CP${r.campaign.id} - ${r.campaign.title}`, + }; + }) + .filter( + (value, index, self) => + index === self.findIndex((t) => t.value === value.value) + ); + + const activities: SelectType.Option[] = data.results + .filter( + ( + r + ): r is { + id: number; + activity: { id: number }; + campaign: { id: number; title?: string | undefined }; + date: string; + amount: number; + note?: string | undefined; + } => typeof r.activity !== "undefined" + ) + .map((r) => { + return { + value: r.activity.id.toString(), + label: r.activity.id.toString(), + }; + }) + .filter( + (value, index, self) => + index === self.findIndex((t) => t.value === value.value) + ); + + const dates: SelectType.Option[] = data.results + .filter( + ( + r + ): r is { + id: number; + activity: { id: number }; + campaign: { id: number; title?: string | undefined }; + date: string; + amount: number; + note?: string | undefined; + } => typeof r.date !== "undefined" + ) + .map((r) => { + return { value: r.date, label: r.date }; + }) + .filter( + (value, index, self) => + index === self.findIndex((t) => t.value === value.value) + ); + + return { campaigns, activities, dates }; +}; + const ExperiencePointsFilters = ({ - search, - campaigns, - dates, - activities, selectedCampaign, selectedActivity, selectedDate, }: ExperiencePointsFiltersProps) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); - const [currentSearch, setCurrentSearch] = useState(search); - const debouncedSearch = useDebounce(currentSearch, 500); + /* const [currentSearch, setCurrentSearch] = useState(""); + const debouncedSearch = useDebounce(currentSearch, 500); */ + + const { campaigns, activities, dates } = useSelectValues({ + selectedCampaign, + selectedActivity, + selectedDate, + }); const allCampaign = t("All", { context: "female" }); const allActivities = t("All", { context: "female" }); @@ -61,12 +154,12 @@ const ExperiencePointsFilters = ({ dateValue = selectedDate; } - useEffect(() => { + /* useEffect(() => { dispatch({ type: "experiencePoints/setSearch", payload: debouncedSearch, }); - }, [debouncedSearch]); + }, [debouncedSearch]); */ return (
@@ -76,7 +169,7 @@ const ExperiencePointsFilters = ({ placeholder={t("Search here")} type="search" id="search" - onChange={setCurrentSearch} + //onChange={setCurrentSearch} />
diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index a2e16bc06..3bbd28cb6 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -21,6 +21,7 @@ import dateFormatter from "../../utils/dateFormatter"; import { ExperiencePointsColumns } from "./columns"; import ExperiencePointsFilters from "./ExperiencePointsFilters"; import ExperiencePointsTable from "./ExperiencePointsTable"; +import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; export default function ExperiencePoints() { const { t } = useTranslation(); @@ -30,22 +31,45 @@ export default function ExperiencePoints() { ); const [rows, setRows] = useState([]); - const { + /* const { expList, - campaigns, - activities, - dates, - selectedCampaign, - selectedActivity, - selectedDate, - search, - isLoading, + //campaigns, + //activities, + //dates, + //selectedCampaign, + //selectedActivity, + //selectedDate, + //search, + //isLoading, } = useSelector( (state: GeneralState) => state.experiencePoints, shallowEqual + ); */ + + const { selectedActivity, selectedCampaign, selectedDate } = useSelector( + (state: GeneralState) => state.experiencePoints, + shallowEqual + ); + const { limit, start, order, orderBy } = useSelector( + (state: GeneralState) => state.experiencePoints.expList ); - const { results, limit, total, start, order, orderBy } = expList; + const { data, isLoading } = useGetUsersMeExperienceQuery({ + limit: limit, + start: start, + order: order, + orderBy: orderBy, + filterBy: { + campaign: selectedCampaign?.value, + activity: selectedActivity?.value, + dates: selectedDate?.value, + }, + }); + const { results, total } = data || {}; + + const search = useSelector( + (state: GeneralState) => state.experiencePoints.search + ); const changePagination = (newPage: number) => { const newStart = limit * (newPage - 1); @@ -53,31 +77,32 @@ export default function ExperiencePoints() { }; useEffect(() => { - setRows( - results.map((res) => { - return { - key: res.id, - amount: { - title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, - content: - res.amount === 0 ? ( - {res.amount}pts - ) : res.amount > 0 ? ( - +{res.amount}pts - ) : ( - {res.amount}pts - ), - }, - date: dateFormatter(res.date), - activity: mapActivityName(res.activity.id, t), - campaign: - res.campaign.title && res.campaign.id > 0 - ? `CP${res.campaign.id}` - : `-`, - note: res.note?.replace(/\\(.)/gm, "$1"), - }; - }) - ); + if (results) + setRows( + results.map((res) => { + return { + key: res.id, + amount: { + title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, + content: + res.amount === 0 ? ( + {res.amount}pts + ) : res.amount > 0 ? ( + +{res.amount}pts + ) : ( + {res.amount}pts + ), + }, + date: dateFormatter(res.date), + activity: mapActivityName(res.activity.id, t), + campaign: + res.campaign.title && res.campaign.id > 0 + ? `CP${res.campaign.id}` + : `-`, + note: res.note?.replace(/\\(.)/gm, "$1"), + }; + }) + ); }, [results]); useEffect(() => { @@ -91,7 +116,7 @@ export default function ExperiencePoints() { changePagination(1); dispatch(fetchExperiencePointsFilters(t)); } - }, [selectedCampaign, selectedActivity, selectedDate, search]); + }, [selectedCampaign, selectedActivity, selectedDate]); useEffect(() => { dispatch(fetchExperiencePoints()); @@ -111,7 +136,7 @@ export default function ExperiencePoints() { data={rows} page={(start || 0) / limit + 1} setPage={changePagination} - totalEntries={total} + totalEntries={total || 0} limit={limit} loading={isLoading} columns={columns} @@ -124,10 +149,10 @@ export default function ExperiencePoints() {
); } + +function useInputValues( + arg0: (state: GeneralState) => { + selectedActivity: any; + selectedCampaign: any; + selectedDate: any; + }, + shallowEqual: (left: T, right: any) => boolean +): { selectedActivity: any; selectedCampaign: any; selectedDate: any } { + throw new Error("Function not implemented."); +} From 00b5d6af7d1b1db55ef42bd43b59ed3c8906222e Mon Sep 17 00:00:00 2001 From: Kariamos Date: Mon, 22 Jan 2024 13:59:37 +0100 Subject: [PATCH 2/8] wip: updated select filters and removed some unused actions and dispatch --- .../ExperiencePointsFilters.tsx | 27 ++++---- src/pages/ExperiencePoints/index.tsx | 62 ++++--------------- src/redux/experiencePoints/actionCreator.ts | 4 +- 3 files changed, 30 insertions(+), 63 deletions(-) diff --git a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx index fb7d18080..7d4e45078 100644 --- a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx +++ b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx @@ -14,14 +14,14 @@ import { } from "../../redux/experiencePoints/actionCreator"; import { useAppDispatch } from "../../redux/provider"; import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; +import { mapActivityName } from "src/redux/experiencePoints/utils"; +import dateFormatter from "src/utils/dateFormatter"; interface ExperiencePointsFiltersProps { - /* campaigns: SelectType.Option[]; - activities: SelectType.Option[]; - dates: SelectType.Option[]; */ selectedCampaign?: SelectType.Option; selectedActivity?: SelectType.Option; selectedDate?: SelectType.Option; + search: string | undefined; } const useSelectValues = ({ @@ -32,8 +32,8 @@ const useSelectValues = ({ selectedCampaign?: SelectType.Option; selectedActivity?: SelectType.Option; selectedDate?: SelectType.Option; - search?: string; }) => { + const { t } = useTranslation(); const { data, isLoading } = useGetUsersMeExperienceQuery({ filterBy: { campaign: selectedCampaign?.value, @@ -54,7 +54,7 @@ const useSelectValues = ({ date: string; amount: number; note?: string | undefined; - } => typeof r.campaign !== "undefined" + } => typeof r.campaign.title !== "undefined" ) .map((r) => { return { @@ -83,7 +83,7 @@ const useSelectValues = ({ .map((r) => { return { value: r.activity.id.toString(), - label: r.activity.id.toString(), + label: mapActivityName(r.activity.id, t) || " ", }; }) .filter( @@ -105,7 +105,10 @@ const useSelectValues = ({ } => typeof r.date !== "undefined" ) .map((r) => { - return { value: r.date, label: r.date }; + return { + value: r.date, + label: dateFormatter(r.date), + }; }) .filter( (value, index, self) => @@ -122,8 +125,8 @@ const ExperiencePointsFilters = ({ }: ExperiencePointsFiltersProps) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); - /* const [currentSearch, setCurrentSearch] = useState(""); - const debouncedSearch = useDebounce(currentSearch, 500); */ + const [currentSearch, setCurrentSearch] = useState(""); + const debouncedSearch = useDebounce(currentSearch, 500); const { campaigns, activities, dates } = useSelectValues({ selectedCampaign, @@ -154,12 +157,12 @@ const ExperiencePointsFilters = ({ dateValue = selectedDate; } - /* useEffect(() => { + useEffect(() => { dispatch({ type: "experiencePoints/setSearch", payload: debouncedSearch, }); - }, [debouncedSearch]); */ + }, [debouncedSearch]); return (
@@ -169,7 +172,7 @@ const ExperiencePointsFilters = ({ placeholder={t("Search here")} type="search" id="search" - //onChange={setCurrentSearch} + onChange={setCurrentSearch} />
diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index 3bbd28cb6..5e25a0674 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -10,11 +10,7 @@ import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { shallowEqual, useSelector } from "react-redux"; import { PageTemplate } from "src/features/PageTemplate"; -import { - fetchExperiencePoints, - fetchExperiencePointsFilters, - updateExperiencePointsPagination, -} from "../../redux/experiencePoints/actionCreator"; +import { updateExperiencePointsPagination } from "../../redux/experiencePoints/actionCreator"; import { mapActivityName } from "../../redux/experiencePoints/utils"; import { useAppDispatch } from "../../redux/provider"; import dateFormatter from "../../utils/dateFormatter"; @@ -31,26 +27,12 @@ export default function ExperiencePoints() { ); const [rows, setRows] = useState([]); - /* const { - expList, - //campaigns, - //activities, - //dates, - //selectedCampaign, - //selectedActivity, - //selectedDate, - //search, - //isLoading, - } = useSelector( - (state: GeneralState) => state.experiencePoints, - shallowEqual - ); */ + const limit = 25; - const { selectedActivity, selectedCampaign, selectedDate } = useSelector( - (state: GeneralState) => state.experiencePoints, - shallowEqual - ); - const { limit, start, order, orderBy } = useSelector( + const { selectedActivity, selectedCampaign, selectedDate, search } = + useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); + + const { start, order, orderBy } = useSelector( (state: GeneralState) => state.experiencePoints.expList ); @@ -59,18 +41,16 @@ export default function ExperiencePoints() { start: start, order: order, orderBy: orderBy, + search: search, + searchBy: search && "note", filterBy: { campaign: selectedCampaign?.value, activity: selectedActivity?.value, - dates: selectedDate?.value, + date: selectedDate?.value, }, }); const { results, total } = data || {}; - const search = useSelector( - (state: GeneralState) => state.experiencePoints.search - ); - const changePagination = (newPage: number) => { const newStart = limit * (newPage - 1); dispatch(updateExperiencePointsPagination(newStart)); @@ -114,15 +94,9 @@ export default function ExperiencePoints() { search === "" ) { changePagination(1); - dispatch(fetchExperiencePointsFilters(t)); } }, [selectedCampaign, selectedActivity, selectedDate]); - useEffect(() => { - dispatch(fetchExperiencePoints()); - dispatch(fetchExperiencePointsFilters(t)); - }, []); - return ( ); } - -function useInputValues( - arg0: (state: GeneralState) => { - selectedActivity: any; - selectedCampaign: any; - selectedDate: any; - }, - shallowEqual: (left: T, right: any) => boolean -): { selectedActivity: any; selectedCampaign: any; selectedDate: any } { - throw new Error("Function not implemented."); -} diff --git a/src/redux/experiencePoints/actionCreator.ts b/src/redux/experiencePoints/actionCreator.ts index 43c4b37a8..da7e75589 100644 --- a/src/redux/experiencePoints/actionCreator.ts +++ b/src/redux/experiencePoints/actionCreator.ts @@ -107,7 +107,7 @@ export const updateExperiencePointsSortingOptions = return dispatch(fetchExperiencePoints()); }; -export const fetchExperiencePointsFilters = +/* export const fetchExperiencePointsFilters = ( t: TFunction ): ThunkAction< @@ -205,7 +205,7 @@ export const fetchExperiencePointsFilters = type: "experiencePoints/setIsLoading", payload: false, }); - }; + }; */ export const setSelectedCampaign = ( From a718bdaf83f92bad740fbd733f8fba2f915d2f79 Mon Sep 17 00:00:00 2001 From: Kariamos Date: Mon, 22 Jan 2024 17:34:08 +0100 Subject: [PATCH 3/8] wip: worked on search input and removed/modified other actions --- .../ExperiencePointsFilters.tsx | 11 +- src/pages/ExperiencePoints/index.tsx | 17 +- src/redux/experiencePoints/actionCreator.ts | 173 ------------------ 3 files changed, 17 insertions(+), 184 deletions(-) diff --git a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx index 7d4e45078..07d28e421 100644 --- a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx +++ b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx @@ -16,6 +16,7 @@ import { useAppDispatch } from "../../redux/provider"; import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; import { mapActivityName } from "src/redux/experiencePoints/utils"; import dateFormatter from "src/utils/dateFormatter"; +import { shallowEqual, useSelector } from "react-redux"; interface ExperiencePointsFiltersProps { selectedCampaign?: SelectType.Option; @@ -34,6 +35,7 @@ const useSelectValues = ({ selectedDate?: SelectType.Option; }) => { const { t } = useTranslation(); + const { data, isLoading } = useGetUsersMeExperienceQuery({ filterBy: { campaign: selectedCampaign?.value, @@ -122,10 +124,17 @@ const ExperiencePointsFilters = ({ selectedCampaign, selectedActivity, selectedDate, + search, }: ExperiencePointsFiltersProps) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); - const [currentSearch, setCurrentSearch] = useState(""); + + search = useSelector( + (state: GeneralState) => state.experiencePoints.search, + shallowEqual + ); + + const [currentSearch, setCurrentSearch] = useState(search); const debouncedSearch = useDebounce(currentSearch, 500); const { campaigns, activities, dates } = useSelectValues({ diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index 5e25a0674..e6d4f6651 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -32,8 +32,9 @@ export default function ExperiencePoints() { const { selectedActivity, selectedCampaign, selectedDate, search } = useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); - const { start, order, orderBy } = useSelector( - (state: GeneralState) => state.experiencePoints.expList + const { order, orderBy, start } = useSelector( + (state: GeneralState) => state.experiencePoints.expList, + shallowEqual ); const { data, isLoading } = useGetUsersMeExperienceQuery({ @@ -42,14 +43,14 @@ export default function ExperiencePoints() { order: order, orderBy: orderBy, search: search, - searchBy: search && "note", + searchBy: "note", filterBy: { campaign: selectedCampaign?.value, activity: selectedActivity?.value, date: selectedDate?.value, }, }); - const { results, total } = data || {}; + const { results, total } = data ?? {}; const changePagination = (newPage: number) => { const newStart = limit * (newPage - 1); @@ -108,9 +109,9 @@ export default function ExperiencePoints() { , - GeneralState, - unknown, - ExperiencePointsActions - > => - async (dispatch, getState) => { - const { - experiencePoints: { - expList, - selectedCampaign, - selectedActivity, - selectedDate, - search, - }, - } = getState(); - dispatch({ - type: "experiencePoints/setIsLoading", - payload: true, - }); - try { - const query: ApiOperations["get-users-me-experience"]["parameters"]["query"] = - { - order: expList.order, - orderBy: expList.orderBy, - limit: expList.limit, - start: expList.start, - filterBy: { - ...(selectedCampaign?.value && { - campaign: selectedCampaign.value, - }), - ...(selectedActivity?.value && { - activity: selectedActivity.value, - }), - ...(selectedDate?.value && { date: selectedDate.value }), - }, - search: search, - searchBy: search && "note", - }; - const data = await API.experiencePoints({ query }); - dispatch({ - type: "experiencePoints/updateExpList", - payload: data, - }); - } catch (e) { - const error = e as HttpError; - if (error.statusCode === 404) { - const { start, limit, size } = expList; - if ((start || 0) - limit >= 0) { - dispatch(updateExperiencePointsPagination((start || 0) - limit)); - } - dispatch({ - type: "experiencePoints/updateExpList", - payload: { - size: size, - start: start, - results: [], - }, - }); - } else { - addMessage(error.message, "danger", false); - } - } - }; export const updateExperiencePointsPagination = ( @@ -86,7 +15,6 @@ export const updateExperiencePointsPagination = type: "experiencePoints/updateExpListQuery", payload: { start: newStart }, }); - return dispatch(fetchExperiencePoints()); }; export const updateExperiencePointsSortingOptions = @@ -104,109 +32,8 @@ export const updateExperiencePointsSortingOptions = type: "experiencePoints/updateExpListQuery", payload: { order: order, orderBy: orderBy }, }); - return dispatch(fetchExperiencePoints()); }; -/* export const fetchExperiencePointsFilters = - ( - t: TFunction - ): ThunkAction< - Promise, - GeneralState, - unknown, - ExperiencePointsActions - > => - async (dispatch, getState) => { - const { - experiencePoints: { - expList, - selectedCampaign, - selectedActivity, - selectedDate, - search, - }, - } = getState(); - dispatch({ - type: "experiencePoints/setIsLoading", - payload: true, - }); - try { - const query: ApiOperations["get-users-me-experience"]["parameters"]["query"] = - { - orderBy: "id", - order: "DESC", - filterBy: { - ...(selectedCampaign?.value && { - campaign: selectedCampaign.value, - }), - ...(selectedActivity?.value && { - activity: selectedActivity.value, - }), - ...(selectedDate?.value && { date: selectedDate.value }), - }, - search: search, - searchBy: search && "note", - }; - const data = await API.experiencePoints({ query }); - - let _campaigns: SelectType.Option[] = []; - let _activities: SelectType.Option[] = []; - let _dates: SelectType.Option[] = []; - - data.results.forEach((res: any) => { - if ( - typeof res.campaign === "undefined" || - typeof res.activity === "undefined" || - typeof res.date === "undefined" - ) - return; - if (res.campaign?.id && res.campaign?.title) { - _campaigns[res.campaign.id] = { - label: `CP${res.campaign?.id} - ${res.campaign?.title}` || "", - value: res.campaign.id.toString(), - }; - } - if (res.activity?.id) { - _activities[res.activity.id] = { - label: mapActivityName(res.activity.id, t) || "", - value: res.activity.id.toString(), - }; - } - if (res.date) { - let d = new Date(res.date); - _dates[d.getTime()] = { - label: dateFormatter(res.date) || "", - value: res.date, - }; - } - }); - - let datesFilter = Object.values(_dates).filter((el) => el != null); - if (expList.orderBy === "date" && expList.order === "ASC") - datesFilter = datesFilter.reverse(); - - dispatch({ - type: "experiencePoints/setCampaigns", - payload: _campaigns.filter((el) => el != null).reverse(), - }); - dispatch({ - type: "experiencePoints/setActivities", - payload: _activities.filter((el) => el != null), - }); - dispatch({ - type: "experiencePoints/setDates", - payload: datesFilter, - }); - } catch (e) { - const error = e as HttpError; - console.log(error); - } - dispatch({ - type: "experiencePoints/setIsLoading", - payload: false, - }); - }; */ - export const setSelectedCampaign = ( campaign: SelectType.Option From b144bf9c8e15e93c6188bf7cad76f379dbfa4148 Mon Sep 17 00:00:00 2001 From: Kariamos Date: Wed, 24 Jan 2024 17:33:03 +0100 Subject: [PATCH 4/8] wip: worked on search filter --- src/pages/ExperiencePoints/ExperiencePointsFilters.tsx | 7 +++++++ src/pages/ExperiencePoints/index.tsx | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx index 07d28e421..34c4992c8 100644 --- a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx +++ b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx @@ -36,7 +36,14 @@ const useSelectValues = ({ }) => { const { t } = useTranslation(); + const { search } = useSelector( + (state: GeneralState) => state.experiencePoints, + shallowEqual + ); + const { data, isLoading } = useGetUsersMeExperienceQuery({ + searchBy: "note", + search: search, filterBy: { campaign: selectedCampaign?.value, activity: selectedActivity?.value, diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index e6d4f6651..1e957673c 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -37,7 +37,7 @@ export default function ExperiencePoints() { shallowEqual ); - const { data, isLoading } = useGetUsersMeExperienceQuery({ + const { data, error, isLoading } = useGetUsersMeExperienceQuery({ limit: limit, start: start, order: order, @@ -50,6 +50,7 @@ export default function ExperiencePoints() { date: selectedDate?.value, }, }); + const { results, total } = data ?? {}; const changePagination = (newPage: number) => { @@ -58,7 +59,7 @@ export default function ExperiencePoints() { }; useEffect(() => { - if (results) + if (!error && results) setRows( results.map((res) => { return { @@ -84,7 +85,8 @@ export default function ExperiencePoints() { }; }) ); - }, [results]); + else setRows([]); + }, [results, error, t]); useEffect(() => { if ( From b25fa5a9dd2142abb9309e080ce8993c237915b8 Mon Sep 17 00:00:00 2001 From: Kariamos Date: Mon, 29 Jan 2024 12:36:31 +0100 Subject: [PATCH 5/8] refactor: removed unnecessary useEffect --- .../ExperiencePointsFilters.tsx | 5 -- src/pages/ExperiencePoints/index.tsx | 60 +++++++++---------- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx index 34c4992c8..11721dba4 100644 --- a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx +++ b/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx @@ -136,11 +136,6 @@ const ExperiencePointsFilters = ({ const { t } = useTranslation(); const dispatch = useAppDispatch(); - search = useSelector( - (state: GeneralState) => state.experiencePoints.search, - shallowEqual - ); - const [currentSearch, setCurrentSearch] = useState(search); const debouncedSearch = useDebounce(currentSearch, 500); diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index 1e957673c..c723aaca0 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -25,7 +25,6 @@ export default function ExperiencePoints() { const [columns, setcolumns] = useState( ExperiencePointsColumns(dispatch, t) ); - const [rows, setRows] = useState([]); const limit = 25; @@ -58,35 +57,29 @@ export default function ExperiencePoints() { dispatch(updateExperiencePointsPagination(newStart)); }; - useEffect(() => { - if (!error && results) - setRows( - results.map((res) => { - return { - key: res.id, - amount: { - title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, - content: - res.amount === 0 ? ( - {res.amount}pts - ) : res.amount > 0 ? ( - +{res.amount}pts - ) : ( - {res.amount}pts - ), - }, - date: dateFormatter(res.date), - activity: mapActivityName(res.activity.id, t), - campaign: - res.campaign.title && res.campaign.id > 0 - ? `CP${res.campaign.id}` - : `-`, - note: res.note?.replace(/\\(.)/gm, "$1"), - }; - }) - ); - else setRows([]); - }, [results, error, t]); + const rows = (results ?? []).map((res) => { + return { + key: res.id, + amount: { + title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, + content: + res.amount === 0 ? ( + {res.amount}pts + ) : res.amount > 0 ? ( + +{res.amount}pts + ) : ( + {res.amount}pts + ), + }, + date: dateFormatter(res.date), + activity: mapActivityName(res.activity.id, t), + campaign: + res.campaign.title && res.campaign.id > 0 + ? `CP${res.campaign.id}` + : `-`, + note: res.note?.replace(/\\(.)/gm, "$1"), + }; + }); useEffect(() => { if ( @@ -94,7 +87,8 @@ export default function ExperiencePoints() { selectedActivity || selectedDate || search || - search === "" + search === "" || + error ) { changePagination(1); } @@ -110,10 +104,10 @@ export default function ExperiencePoints() { Date: Mon, 29 Jan 2024 14:29:14 +0100 Subject: [PATCH 6/8] refaxtor: added dependency --- src/pages/ExperiencePoints/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index c723aaca0..a0d64f463 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -92,7 +92,7 @@ export default function ExperiencePoints() { ) { changePagination(1); } - }, [selectedCampaign, selectedActivity, selectedDate]); + }, [selectedCampaign, selectedActivity, selectedDate, search]); return ( Date: Mon, 29 Jan 2024 15:01:35 +0100 Subject: [PATCH 7/8] refactor: modified variables --- src/pages/ExperiencePoints/index.tsx | 54 +++++++++++++++------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index a0d64f463..c883e806a 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -57,29 +57,33 @@ export default function ExperiencePoints() { dispatch(updateExperiencePointsPagination(newStart)); }; - const rows = (results ?? []).map((res) => { - return { - key: res.id, - amount: { - title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, - content: - res.amount === 0 ? ( - {res.amount}pts - ) : res.amount > 0 ? ( - +{res.amount}pts - ) : ( - {res.amount}pts - ), - }, - date: dateFormatter(res.date), - activity: mapActivityName(res.activity.id, t), - campaign: - res.campaign.title && res.campaign.id > 0 - ? `CP${res.campaign.id}` - : `-`, - note: res.note?.replace(/\\(.)/gm, "$1"), - }; - }); + const rows = error + ? [] + : (results ?? []).map((res) => { + return { + key: res.id, + amount: { + title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, + content: + res.amount === 0 ? ( + {res.amount}pts + ) : res.amount > 0 ? ( + +{res.amount}pts + ) : ( + {res.amount}pts + ), + }, + date: dateFormatter(res.date), + activity: mapActivityName(res.activity.id, t), + campaign: + res.campaign.title && res.campaign.id > 0 + ? `CP${res.campaign.id}` + : `-`, + note: res.note?.replace(/\\(.)/gm, "$1"), + }; + }); + + const totalResults = error ? 1 : total ?? 0; useEffect(() => { if ( @@ -104,10 +108,10 @@ export default function ExperiencePoints() { Date: Mon, 29 Jan 2024 15:34:55 +0100 Subject: [PATCH 8/8] rework: Split exp tables hooks --- .../index.tsx} | 46 ++------ .../ExperiencePointsTable.tsx | 65 ----------- .../ExperiencePointsTable/index.tsx | 66 +++++++++++ .../useResetPaginationOnFilterChange.tsx | 25 +++++ .../ExperiencePointsTable/useRows.tsx | 77 +++++++++++++ src/pages/ExperiencePoints/columns.ts | 10 +- src/pages/ExperiencePoints/index.tsx | 105 +----------------- 7 files changed, 186 insertions(+), 208 deletions(-) rename src/pages/ExperiencePoints/{ExperiencePointsFilters.tsx => ExperiencePointsFilters/index.tsx} (86%) delete mode 100644 src/pages/ExperiencePoints/ExperiencePointsTable.tsx create mode 100644 src/pages/ExperiencePoints/ExperiencePointsTable/index.tsx create mode 100644 src/pages/ExperiencePoints/ExperiencePointsTable/useResetPaginationOnFilterChange.tsx create mode 100644 src/pages/ExperiencePoints/ExperiencePointsTable/useRows.tsx diff --git a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx b/src/pages/ExperiencePoints/ExperiencePointsFilters/index.tsx similarity index 86% rename from src/pages/ExperiencePoints/ExperiencePointsFilters.tsx rename to src/pages/ExperiencePoints/ExperiencePointsFilters/index.tsx index 11721dba4..70587ffb0 100644 --- a/src/pages/ExperiencePoints/ExperiencePointsFilters.tsx +++ b/src/pages/ExperiencePoints/ExperiencePointsFilters/index.tsx @@ -6,40 +6,23 @@ import { } from "@appquality/appquality-design-system"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; +import { shallowEqual, useSelector } from "react-redux"; import useDebounce from "src/hooks/useDebounce"; import { setSelectedActivity, setSelectedCampaign, setSelectedDate, -} from "../../redux/experiencePoints/actionCreator"; -import { useAppDispatch } from "../../redux/provider"; -import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; +} from "src/redux/experiencePoints/actionCreator"; import { mapActivityName } from "src/redux/experiencePoints/utils"; +import { useAppDispatch } from "src/redux/provider"; +import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; import dateFormatter from "src/utils/dateFormatter"; -import { shallowEqual, useSelector } from "react-redux"; -interface ExperiencePointsFiltersProps { - selectedCampaign?: SelectType.Option; - selectedActivity?: SelectType.Option; - selectedDate?: SelectType.Option; - search: string | undefined; -} - -const useSelectValues = ({ - selectedCampaign, - selectedActivity, - selectedDate, -}: { - selectedCampaign?: SelectType.Option; - selectedActivity?: SelectType.Option; - selectedDate?: SelectType.Option; -}) => { +const useSelectValues = () => { const { t } = useTranslation(); - const { search } = useSelector( - (state: GeneralState) => state.experiencePoints, - shallowEqual - ); + const { selectedActivity, selectedCampaign, selectedDate, search } = + useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); const { data, isLoading } = useGetUsersMeExperienceQuery({ searchBy: "note", @@ -127,23 +110,16 @@ const useSelectValues = ({ return { campaigns, activities, dates }; }; -const ExperiencePointsFilters = ({ - selectedCampaign, - selectedActivity, - selectedDate, - search, -}: ExperiencePointsFiltersProps) => { +const ExperiencePointsFilters = () => { const { t } = useTranslation(); const dispatch = useAppDispatch(); + const { selectedActivity, selectedCampaign, selectedDate, search } = + useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); const [currentSearch, setCurrentSearch] = useState(search); const debouncedSearch = useDebounce(currentSearch, 500); - const { campaigns, activities, dates } = useSelectValues({ - selectedCampaign, - selectedActivity, - selectedDate, - }); + const { campaigns, activities, dates } = useSelectValues(); const allCampaign = t("All", { context: "female" }); const allActivities = t("All", { context: "female" }); diff --git a/src/pages/ExperiencePoints/ExperiencePointsTable.tsx b/src/pages/ExperiencePoints/ExperiencePointsTable.tsx deleted file mode 100644 index fe21e680a..000000000 --- a/src/pages/ExperiencePoints/ExperiencePointsTable.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { - Table, - Pagination, - TableType, - SortTableSelect, -} from "@appquality/appquality-design-system"; -import { useTranslation } from "react-i18next"; - -interface ExperiencePointsTableProps { - data: TableType.Row[]; - page: number; - setPage: (page: number) => void; - totalEntries: number; - limit: number; - loading: boolean; - columns: TableType.Column[]; - order: ApiComponents["parameters"]["order"]; - orderBy: string; -} - -const ExperiencePointsTable = ({ - data, - page, - setPage, - totalEntries, - limit, - loading, - order, - orderBy, - columns, -}: ExperiencePointsTableProps) => { - const { t } = useTranslation(); - - return ( - <> - - - - t(`Page %current% / %total%`) - .replace("%current%", current.toString()) - .replace("%total%", total ? total.toString() : "0") - } - /> - - ); -}; - -export default ExperiencePointsTable; diff --git a/src/pages/ExperiencePoints/ExperiencePointsTable/index.tsx b/src/pages/ExperiencePoints/ExperiencePointsTable/index.tsx new file mode 100644 index 000000000..75d258ab9 --- /dev/null +++ b/src/pages/ExperiencePoints/ExperiencePointsTable/index.tsx @@ -0,0 +1,66 @@ +import { + Pagination, + SortTableSelect, + Table, +} from "@appquality/appquality-design-system"; +import { useTranslation } from "react-i18next"; +import { shallowEqual, useSelector } from "react-redux"; +import { updateExperiencePointsPagination } from "src/redux/experiencePoints/actionCreator"; +import { useAppDispatch } from "src/store"; +import { useExperiencePointsColumns } from "../columns"; +import { useResetPaginationOnFilterChange } from "./useResetPaginationOnFilterChange"; +import { useRows } from "./useRows"; + +const ExperiencePointsTable = () => { + const limit = 25; + const { t } = useTranslation(); + const dispatch = useAppDispatch(); + const { rows, loading, totalEntries } = useRows(); + const columns = useExperiencePointsColumns(); + + const setPage = (newPage: number) => { + const newStart = limit * (newPage - 1); + dispatch(updateExperiencePointsPagination(newStart)); + }; + + useResetPaginationOnFilterChange({ setPage }); + + const { order, orderBy, start } = useSelector( + (state: GeneralState) => state.experiencePoints.expList, + shallowEqual + ); + + const page = (start ?? 0) / limit + 1; + + return ( + <> + +
+ + t(`Page %current% / %total%`) + .replace("%current%", current.toString()) + .replace("%total%", total ? total.toString() : "0") + } + /> + + ); +}; + +export default ExperiencePointsTable; diff --git a/src/pages/ExperiencePoints/ExperiencePointsTable/useResetPaginationOnFilterChange.tsx b/src/pages/ExperiencePoints/ExperiencePointsTable/useResetPaginationOnFilterChange.tsx new file mode 100644 index 000000000..b4d584989 --- /dev/null +++ b/src/pages/ExperiencePoints/ExperiencePointsTable/useResetPaginationOnFilterChange.tsx @@ -0,0 +1,25 @@ +import { useEffect } from "react"; +import { shallowEqual, useSelector } from "react-redux"; + +const useResetPaginationOnFilterChange = ({ + setPage, +}: { + setPage: (newPage: number) => void; +}) => { + const { selectedActivity, selectedCampaign, selectedDate, search } = + useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); + + useEffect(() => { + if ( + selectedCampaign || + selectedActivity || + selectedDate || + search || + search === "" + ) { + setPage(1); + } + }, [selectedCampaign, selectedActivity, selectedDate, search]); +}; + +export { useResetPaginationOnFilterChange }; diff --git a/src/pages/ExperiencePoints/ExperiencePointsTable/useRows.tsx b/src/pages/ExperiencePoints/ExperiencePointsTable/useRows.tsx new file mode 100644 index 000000000..963208216 --- /dev/null +++ b/src/pages/ExperiencePoints/ExperiencePointsTable/useRows.tsx @@ -0,0 +1,77 @@ +import { useTranslation } from "react-i18next"; +import { shallowEqual, useSelector } from "react-redux"; +import { mapActivityName } from "src/redux/experiencePoints/utils"; +import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; +import dateFormatter from "src/utils/dateFormatter"; + +const useRows = () => { + const limit = 25; + const { t } = useTranslation(); + + const { order, orderBy, start } = useSelector( + (state: GeneralState) => state.experiencePoints.expList, + shallowEqual + ); + const { selectedActivity, selectedCampaign, selectedDate, search } = + useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); + + const { + data, + error, + isLoading: loading, + } = useGetUsersMeExperienceQuery({ + limit: limit, + start: start, + order: order, + orderBy: orderBy, + search: search, + searchBy: "note", + filterBy: { + campaign: selectedCampaign?.value, + activity: selectedActivity?.value, + date: selectedDate?.value, + }, + }); + + if (error) { + return { + rows: [], + loading: false, + totalEntries: 0, + }; + } + + const { results, total } = data ?? {}; + + const rows = (results ?? []).map((res) => { + return { + key: res.id, + amount: { + title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, + content: + res.amount === 0 ? ( + {res.amount}pts + ) : res.amount > 0 ? ( + +{res.amount}pts + ) : ( + {res.amount}pts + ), + }, + date: dateFormatter(res.date), + activity: mapActivityName(res.activity.id, t), + campaign: + res.campaign.title && res.campaign.id > 0 + ? `CP${res.campaign.id}` + : `-`, + note: res.note?.replace(/\\(.)/gm, "$1"), + }; + }); + + return { + rows, + loading, + totalEntries: total ?? 0, + }; +}; + +export { useRows }; diff --git a/src/pages/ExperiencePoints/columns.ts b/src/pages/ExperiencePoints/columns.ts index b571d50f8..382e88237 100644 --- a/src/pages/ExperiencePoints/columns.ts +++ b/src/pages/ExperiencePoints/columns.ts @@ -1,11 +1,11 @@ import { Column } from "@appquality/appquality-design-system/dist/stories/table/_types"; -import { TFunction } from "react-i18next"; +import { useTranslation } from "react-i18next"; +import { useAppDispatch } from "src/store"; import { updateExperiencePointsSortingOptions } from "../../redux/experiencePoints/actionCreator"; -export const ExperiencePointsColumns = ( - dispatch: AppDispatch, - t: TFunction<"translation"> -): Column[] => { +export const useExperiencePointsColumns = (): Column[] => { + const { t } = useTranslation("translation"); + const dispatch = useAppDispatch(); return [ { title: t("Points"), diff --git a/src/pages/ExperiencePoints/index.tsx b/src/pages/ExperiencePoints/index.tsx index c883e806a..c57893201 100644 --- a/src/pages/ExperiencePoints/index.tsx +++ b/src/pages/ExperiencePoints/index.tsx @@ -3,101 +3,15 @@ import { BSGrid, Button, Card, - TableType, Text, } from "@appquality/appquality-design-system"; -import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import { shallowEqual, useSelector } from "react-redux"; import { PageTemplate } from "src/features/PageTemplate"; -import { updateExperiencePointsPagination } from "../../redux/experiencePoints/actionCreator"; -import { mapActivityName } from "../../redux/experiencePoints/utils"; -import { useAppDispatch } from "../../redux/provider"; -import dateFormatter from "../../utils/dateFormatter"; -import { ExperiencePointsColumns } from "./columns"; import ExperiencePointsFilters from "./ExperiencePointsFilters"; import ExperiencePointsTable from "./ExperiencePointsTable"; -import { useGetUsersMeExperienceQuery } from "src/services/tryberApi"; export default function ExperiencePoints() { const { t } = useTranslation(); - const dispatch = useAppDispatch(); - const [columns, setcolumns] = useState( - ExperiencePointsColumns(dispatch, t) - ); - - const limit = 25; - - const { selectedActivity, selectedCampaign, selectedDate, search } = - useSelector((state: GeneralState) => state.experiencePoints, shallowEqual); - - const { order, orderBy, start } = useSelector( - (state: GeneralState) => state.experiencePoints.expList, - shallowEqual - ); - - const { data, error, isLoading } = useGetUsersMeExperienceQuery({ - limit: limit, - start: start, - order: order, - orderBy: orderBy, - search: search, - searchBy: "note", - filterBy: { - campaign: selectedCampaign?.value, - activity: selectedActivity?.value, - date: selectedDate?.value, - }, - }); - - const { results, total } = data ?? {}; - - const changePagination = (newPage: number) => { - const newStart = limit * (newPage - 1); - dispatch(updateExperiencePointsPagination(newStart)); - }; - - const rows = error - ? [] - : (results ?? []).map((res) => { - return { - key: res.id, - amount: { - title: `${res.amount > 0 ? `+${res.amount}` : res.amount}pts`, - content: - res.amount === 0 ? ( - {res.amount}pts - ) : res.amount > 0 ? ( - +{res.amount}pts - ) : ( - {res.amount}pts - ), - }, - date: dateFormatter(res.date), - activity: mapActivityName(res.activity.id, t), - campaign: - res.campaign.title && res.campaign.id > 0 - ? `CP${res.campaign.id}` - : `-`, - note: res.note?.replace(/\\(.)/gm, "$1"), - }; - }); - - const totalResults = error ? 1 : total ?? 0; - - useEffect(() => { - if ( - selectedCampaign || - selectedActivity || - selectedDate || - search || - search === "" || - error - ) { - changePagination(1); - } - }, [selectedCampaign, selectedActivity, selectedDate, search]); - return ( - +
- +