From 6ace05550c86ffbe2468dfd2a8726f46949acace Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Sat, 28 Sep 2024 18:34:39 +0900 Subject: [PATCH 1/8] =?UTF-8?q?refactor:=20filteredRange=20zustand=20store?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/TemporalFilter/LineChart.ts | 2 +- .../TemporalFilter/TemporalFilter.tsx | 5 +++-- .../view/src/context/GlobalDataProvider.tsx | 7 ++----- packages/view/src/hooks/useGlobalData.ts | 9 --------- packages/view/src/store/filteredRange.ts | 18 ++++++++++++++++++ packages/view/src/store/index.ts | 1 + 6 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 packages/view/src/store/filteredRange.ts diff --git a/packages/view/src/components/TemporalFilter/LineChart.ts b/packages/view/src/components/TemporalFilter/LineChart.ts index 728416ce..d976f88f 100644 --- a/packages/view/src/components/TemporalFilter/LineChart.ts +++ b/packages/view/src/components/TemporalFilter/LineChart.ts @@ -1,7 +1,7 @@ import * as d3 from "d3"; import dayjs from "dayjs"; +import { type DateFilterRange } from "store"; -import type { DateFilterRange } from "hooks"; import "./LineChart.scss"; export type LineChartDatum = { diff --git a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx index d0d58a16..8e9f50a2 100644 --- a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx +++ b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx @@ -6,7 +6,7 @@ import BounceLoader from "react-spinners/BounceLoader"; import { Button } from "@mui/material"; import { useGlobalData } from "hooks"; -import { useLoadingStore } from "store"; +import { useLoadingStore, useFilteredRangeStore } from "store"; import { filterDataByDate, getMinMaxDate, lineChartTimeFormatter, sortBasedOnCommitNode } from "./TemporalFilter.util"; import "./TemporalFilter.scss"; @@ -18,8 +18,9 @@ import { createBrush, drawBrush, resetBrush } from "./LineChartBrush"; import { BRUSH_MARGIN, TEMPORAL_FILTER_LINE_CHART_STYLES } from "./LineChart.const"; const TemporalFilter = () => { - const { data, filteredData, setFilteredData, filteredRange, setFilteredRange, setSelectedData } = useGlobalData(); + const { data, filteredData, setFilteredData, setSelectedData } = useGlobalData(); const { loading } = useLoadingStore((state) => state); + const { filteredRange, setFilteredRange } = useFilteredRangeStore(); const brushGroupRef = useRef(null); const brushRef = useRef>(); diff --git a/packages/view/src/context/GlobalDataProvider.tsx b/packages/view/src/context/GlobalDataProvider.tsx index 7e2cc0dd..5982ca28 100644 --- a/packages/view/src/context/GlobalDataProvider.tsx +++ b/packages/view/src/context/GlobalDataProvider.tsx @@ -1,7 +1,7 @@ import type { PropsWithChildren } from "react"; import { useMemo, useState } from "react"; -import { GlobalDataContext, type DateFilterRange } from "hooks"; +import { GlobalDataContext } from "hooks"; import type { ClusterNode } from "types"; import { useLoadingStore } from "store"; @@ -9,7 +9,6 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { const [data, setData] = useState([]); const [filteredData, setFilteredData] = useState(data); const [selectedData, setSelectedData] = useState([]); - const [filteredRange, setFilteredRange] = useState(undefined); const { setLoading } = useLoadingStore((state) => state); const [branchList, setBranchList] = useState([]); const [selectedBranch, setSelectedBranch] = useState(branchList?.[0]); @@ -31,8 +30,6 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { const value = useMemo( () => ({ data, - filteredRange, - setFilteredRange, filteredData, setFilteredData, selectedData, @@ -48,7 +45,7 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { repo, setRepo, }), - [data, filteredRange, filteredData, selectedData, branchList, selectedBranch, owner, repo] + [data, filteredData, selectedData, branchList, selectedBranch, owner, repo] ); return {children}; diff --git a/packages/view/src/hooks/useGlobalData.ts b/packages/view/src/hooks/useGlobalData.ts index 1d2b96a1..f0a4ef93 100644 --- a/packages/view/src/hooks/useGlobalData.ts +++ b/packages/view/src/hooks/useGlobalData.ts @@ -3,21 +3,12 @@ import { createContext, useContext } from "react"; import type { ClusterNode, IDESentEvents } from "types"; -export type DateFilterRange = - | { - fromDate: string; - toDate: string; - } - | undefined; - type GlobalDataState = { data: ClusterNode[]; - filteredRange: DateFilterRange; filteredData: ClusterNode[]; selectedData: ClusterNode[]; setFilteredData: Dispatch>; setSelectedData: Dispatch>; - setFilteredRange: Dispatch>; branchList: string[]; setBranchList: Dispatch>; selectedBranch: string; diff --git a/packages/view/src/store/filteredRange.ts b/packages/view/src/store/filteredRange.ts new file mode 100644 index 00000000..63729726 --- /dev/null +++ b/packages/view/src/store/filteredRange.ts @@ -0,0 +1,18 @@ +import { create } from "zustand"; + +export type DateFilterRange = + | { + fromDate: string; + toDate: string; + } + | undefined; + +type FilteredRangeStore = { + filteredRange: DateFilterRange; + setFilteredRange: (filteredRange: DateFilterRange) => void; +}; + +export const useFilteredRangeStore = create((set) => ({ + filteredRange: undefined, + setFilteredRange: (filteredRange) => set({ filteredRange }), +})); diff --git a/packages/view/src/store/index.ts b/packages/view/src/store/index.ts index b50fe215..fb2b9871 100644 --- a/packages/view/src/store/index.ts +++ b/packages/view/src/store/index.ts @@ -1 +1,2 @@ export * from "./loading"; +export * from "./filteredRange"; From b8ec9a54c9b5ac92d538337bb5e7829c00419196 Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Sat, 28 Sep 2024 22:58:37 +0900 Subject: [PATCH 2/8] =?UTF-8?q?refactor:=20branch=EA=B4=80=EB=A0=A8=20cont?= =?UTF-8?q?ext=EB=A5=BC=20store=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit type 수정하면서 BranchListPayload의 위치 고민됨 현재는 store쪽에 선언하고 IDESentEvents에서 가져와서 쓰는데 괜찮은지 확인 필요 --- packages/view/src/App.tsx | 5 ++-- .../BranchSelector/BranchSelector.tsx | 5 ++-- .../RefreshButton/RefreshButton.tsx | 5 ++-- .../view/src/context/GlobalDataProvider.tsx | 14 +--------- packages/view/src/hooks/useGlobalData.ts | 9 +++---- packages/view/src/store/branch.ts | 26 +++++++++++++++++++ packages/view/src/store/index.ts | 1 + packages/view/src/types/IDESentEvents.ts | 3 ++- 8 files changed, 40 insertions(+), 28 deletions(-) create mode 100644 packages/view/src/store/branch.ts diff --git a/packages/view/src/App.tsx b/packages/view/src/App.tsx index 19d8af42..0011a3ac 100644 --- a/packages/view/src/App.tsx +++ b/packages/view/src/App.tsx @@ -11,12 +11,13 @@ import { useGlobalData } from "hooks"; import { RefreshButton } from "components/RefreshButton"; import type { IDESentEvents } from "types/IDESentEvents"; import type { RemoteGitHubInfo } from "types/RemoteGitHubInfo"; -import { useLoadingStore } from "store"; +import { useBranchStore, useLoadingStore } from "store"; const App = () => { const initRef = useRef(false); - const { filteredData, handleChangeAnalyzedData, handleChangeBranchList } = useGlobalData(); + const { filteredData, handleChangeAnalyzedData } = useGlobalData(); + const { handleChangeBranchList } = useBranchStore(); const { loading, setLoading } = useLoadingStore((state) => state); const ideAdapter = container.resolve("IDEAdapter"); diff --git a/packages/view/src/components/BranchSelector/BranchSelector.tsx b/packages/view/src/components/BranchSelector/BranchSelector.tsx index 5425f30f..eec0035d 100644 --- a/packages/view/src/components/BranchSelector/BranchSelector.tsx +++ b/packages/view/src/components/BranchSelector/BranchSelector.tsx @@ -3,15 +3,14 @@ import FormControl from "@mui/material/FormControl"; import type { SelectChangeEvent } from "@mui/material/Select"; import Select from "@mui/material/Select"; -import { useGlobalData } from "hooks"; import { sendFetchAnalyzedDataCommand } from "services"; import "./BranchSelector.scss"; -import { useLoadingStore } from "store"; +import { useBranchStore, useLoadingStore } from "store"; import { SLICE_LENGTH } from "./BranchSelector.const"; const BranchSelector = () => { - const { branchList, selectedBranch, setSelectedBranch } = useGlobalData(); + const { branchList, selectedBranch, setSelectedBranch } = useBranchStore(); const { setLoading } = useLoadingStore((state) => state); const handleChangeSelect = (event: SelectChangeEvent) => { diff --git a/packages/view/src/components/RefreshButton/RefreshButton.tsx b/packages/view/src/components/RefreshButton/RefreshButton.tsx index 490bae97..b3845033 100644 --- a/packages/view/src/components/RefreshButton/RefreshButton.tsx +++ b/packages/view/src/components/RefreshButton/RefreshButton.tsx @@ -4,13 +4,12 @@ import ReplayCircleFilledRoundedIcon from "@mui/icons-material/ReplayCircleFille import { IconButton } from "@mui/material"; import { throttle } from "utils"; -import { useGlobalData } from "hooks"; import "./RefreshButton.scss"; import { sendRefreshDataCommand } from "services"; -import { useLoadingStore } from "store"; +import { useBranchStore, useLoadingStore } from "store"; const RefreshButton = () => { - const { selectedBranch } = useGlobalData(); + const { selectedBranch } = useBranchStore(); const { loading, setLoading } = useLoadingStore((state) => state); const refreshHandler = throttle(() => { diff --git a/packages/view/src/context/GlobalDataProvider.tsx b/packages/view/src/context/GlobalDataProvider.tsx index 5982ca28..1210cf84 100644 --- a/packages/view/src/context/GlobalDataProvider.tsx +++ b/packages/view/src/context/GlobalDataProvider.tsx @@ -10,16 +10,9 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { const [filteredData, setFilteredData] = useState(data); const [selectedData, setSelectedData] = useState([]); const { setLoading } = useLoadingStore((state) => state); - const [branchList, setBranchList] = useState([]); - const [selectedBranch, setSelectedBranch] = useState(branchList?.[0]); const [owner, setOwner] = useState(""); const [repo, setRepo] = useState(""); - const handleChangeBranchList = (branches: { branchList: string[]; head: string | null }) => { - setSelectedBranch((prev) => (!prev && branches.head ? branches.head : prev)); - setBranchList(branches.branchList); - }; - const handleChangeAnalyzedData = (analyzedData: ClusterNode[]) => { setData(analyzedData); setFilteredData([...analyzedData.reverse()]); @@ -34,18 +27,13 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { setFilteredData, selectedData, setSelectedData, - branchList, - setBranchList, - selectedBranch, - setSelectedBranch, handleChangeAnalyzedData, - handleChangeBranchList, owner, setOwner, repo, setRepo, }), - [data, filteredData, selectedData, branchList, selectedBranch, owner, repo] + [data, filteredData, selectedData, owner, repo] ); return {children}; diff --git a/packages/view/src/hooks/useGlobalData.ts b/packages/view/src/hooks/useGlobalData.ts index f0a4ef93..16e2793b 100644 --- a/packages/view/src/hooks/useGlobalData.ts +++ b/packages/view/src/hooks/useGlobalData.ts @@ -1,7 +1,7 @@ import type { Dispatch, SetStateAction } from "react"; import { createContext, useContext } from "react"; -import type { ClusterNode, IDESentEvents } from "types"; +import type { ClusterNode } from "types"; type GlobalDataState = { data: ClusterNode[]; @@ -9,15 +9,12 @@ type GlobalDataState = { selectedData: ClusterNode[]; setFilteredData: Dispatch>; setSelectedData: Dispatch>; - branchList: string[]; - setBranchList: Dispatch>; - selectedBranch: string; - setSelectedBranch: Dispatch>; owner: string; setOwner: Dispatch>; repo: string; setRepo: Dispatch>; -} & IDESentEvents; + handleChangeAnalyzedData: (analyzedData: ClusterNode[]) => void; +}; // handleChangeBranchList를 임시로 제외 -> 추후 GlobalDataContext를 삭제할 예정 export const GlobalDataContext = createContext(undefined); diff --git a/packages/view/src/store/branch.ts b/packages/view/src/store/branch.ts new file mode 100644 index 00000000..996a5386 --- /dev/null +++ b/packages/view/src/store/branch.ts @@ -0,0 +1,26 @@ +import { create } from "zustand"; + +export type BranchListPayload = { + branchList: string[]; + head: string | null; +}; + +type BranchStore = { + branchList: string[]; + selectedBranch: string; + setBranchList: (branches: string[]) => void; + setSelectedBranch: (branch: string) => void; + handleChangeBranchList: (branches: BranchListPayload) => void; +}; + +export const useBranchStore = create((set) => ({ + branchList: [], + selectedBranch: "", + setBranchList: (branches) => set({ branchList: branches }), + setSelectedBranch: (branch) => set({ selectedBranch: branch }), + handleChangeBranchList: (branches) => + set((state) => ({ + branchList: branches.branchList, + selectedBranch: !state.selectedBranch && branches.head ? branches.head : state.selectedBranch, + })), +})); diff --git a/packages/view/src/store/index.ts b/packages/view/src/store/index.ts index fb2b9871..f1c226fd 100644 --- a/packages/view/src/store/index.ts +++ b/packages/view/src/store/index.ts @@ -1,2 +1,3 @@ export * from "./loading"; export * from "./filteredRange"; +export * from "./branch"; diff --git a/packages/view/src/types/IDESentEvents.ts b/packages/view/src/types/IDESentEvents.ts index 65def9df..e1420a41 100644 --- a/packages/view/src/types/IDESentEvents.ts +++ b/packages/view/src/types/IDESentEvents.ts @@ -1,7 +1,8 @@ +import type { BranchListPayload } from "store"; import type { ClusterNode } from "types"; // triggered by ide response export type IDESentEvents = { handleChangeAnalyzedData: (analyzedData: ClusterNode[]) => void; - handleChangeBranchList: (branches: { branchList: string[]; head: string | null }) => void; + handleChangeBranchList: (branches: BranchListPayload) => void; }; From 7800d9863e868110dd0baed3f910bca1d893207b Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Sun, 29 Sep 2024 00:09:27 +0900 Subject: [PATCH 3/8] =?UTF-8?q?refactor:=20useLoadingStore=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/view/src/App.tsx | 2 +- packages/view/src/components/BranchSelector/BranchSelector.tsx | 2 +- packages/view/src/components/RefreshButton/RefreshButton.tsx | 2 +- packages/view/src/components/TemporalFilter/TemporalFilter.tsx | 2 +- packages/view/src/context/GlobalDataProvider.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/view/src/App.tsx b/packages/view/src/App.tsx index 0011a3ac..dea87f62 100644 --- a/packages/view/src/App.tsx +++ b/packages/view/src/App.tsx @@ -18,7 +18,7 @@ const App = () => { const { filteredData, handleChangeAnalyzedData } = useGlobalData(); const { handleChangeBranchList } = useBranchStore(); - const { loading, setLoading } = useLoadingStore((state) => state); + const { loading, setLoading } = useLoadingStore(); const ideAdapter = container.resolve("IDEAdapter"); diff --git a/packages/view/src/components/BranchSelector/BranchSelector.tsx b/packages/view/src/components/BranchSelector/BranchSelector.tsx index eec0035d..90ef39bb 100644 --- a/packages/view/src/components/BranchSelector/BranchSelector.tsx +++ b/packages/view/src/components/BranchSelector/BranchSelector.tsx @@ -11,7 +11,7 @@ import { SLICE_LENGTH } from "./BranchSelector.const"; const BranchSelector = () => { const { branchList, selectedBranch, setSelectedBranch } = useBranchStore(); - const { setLoading } = useLoadingStore((state) => state); + const { setLoading } = useLoadingStore(); const handleChangeSelect = (event: SelectChangeEvent) => { setSelectedBranch(event.target.value); diff --git a/packages/view/src/components/RefreshButton/RefreshButton.tsx b/packages/view/src/components/RefreshButton/RefreshButton.tsx index b3845033..ac54eaa3 100644 --- a/packages/view/src/components/RefreshButton/RefreshButton.tsx +++ b/packages/view/src/components/RefreshButton/RefreshButton.tsx @@ -10,7 +10,7 @@ import { useBranchStore, useLoadingStore } from "store"; const RefreshButton = () => { const { selectedBranch } = useBranchStore(); - const { loading, setLoading } = useLoadingStore((state) => state); + const { loading, setLoading } = useLoadingStore(); const refreshHandler = throttle(() => { setLoading(true); diff --git a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx index 8e9f50a2..686e305d 100644 --- a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx +++ b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx @@ -19,7 +19,7 @@ import { BRUSH_MARGIN, TEMPORAL_FILTER_LINE_CHART_STYLES } from "./LineChart.con const TemporalFilter = () => { const { data, filteredData, setFilteredData, setSelectedData } = useGlobalData(); - const { loading } = useLoadingStore((state) => state); + const { loading } = useLoadingStore(); const { filteredRange, setFilteredRange } = useFilteredRangeStore(); const brushGroupRef = useRef(null); const brushRef = useRef>(); diff --git a/packages/view/src/context/GlobalDataProvider.tsx b/packages/view/src/context/GlobalDataProvider.tsx index 1210cf84..e570b240 100644 --- a/packages/view/src/context/GlobalDataProvider.tsx +++ b/packages/view/src/context/GlobalDataProvider.tsx @@ -9,7 +9,7 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { const [data, setData] = useState([]); const [filteredData, setFilteredData] = useState(data); const [selectedData, setSelectedData] = useState([]); - const { setLoading } = useLoadingStore((state) => state); + const { setLoading } = useLoadingStore(); const [owner, setOwner] = useState(""); const [repo, setRepo] = useState(""); From 6cf977b4890e8aba5f379eb7fa241deb2affeb7d Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:17:21 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20repo,=20owner=20context?= =?UTF-8?q?=EB=A5=BC=20store=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/view/src/App.tsx | 6 +++--- packages/view/src/components/Detail/Detail.tsx | 5 +++-- .../VerticalClusterList/Summary/Content/Content.tsx | 5 +++-- packages/view/src/context/GlobalDataProvider.tsx | 8 +------- packages/view/src/hooks/useGlobalData.ts | 4 ---- packages/view/src/store/index.ts | 2 ++ packages/view/src/store/owner.ts | 11 +++++++++++ packages/view/src/store/repo.ts | 11 +++++++++++ 8 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 packages/view/src/store/owner.ts create mode 100644 packages/view/src/store/repo.ts diff --git a/packages/view/src/App.tsx b/packages/view/src/App.tsx index dea87f62..467a6218 100644 --- a/packages/view/src/App.tsx +++ b/packages/view/src/App.tsx @@ -11,7 +11,7 @@ import { useGlobalData } from "hooks"; import { RefreshButton } from "components/RefreshButton"; import type { IDESentEvents } from "types/IDESentEvents"; import type { RemoteGitHubInfo } from "types/RemoteGitHubInfo"; -import { useBranchStore, useLoadingStore } from "store"; +import { useBranchStore, useLoadingStore, useOwnerStore, useRepoStore } from "store"; const App = () => { const initRef = useRef(false); @@ -19,7 +19,8 @@ const App = () => { const { filteredData, handleChangeAnalyzedData } = useGlobalData(); const { handleChangeBranchList } = useBranchStore(); const { loading, setLoading } = useLoadingStore(); - + const { setOwner } = useOwnerStore(); + const { setRepo } = useRepoStore(); const ideAdapter = container.resolve("IDEAdapter"); useEffect(() => { @@ -37,7 +38,6 @@ const App = () => { } }, [handleChangeAnalyzedData, handleChangeBranchList, ideAdapter, setLoading]); - const { setOwner, setRepo } = useGlobalData(); useEffect(() => { const handleMessage = (event: MessageEvent) => { const message = event.data; diff --git a/packages/view/src/components/Detail/Detail.tsx b/packages/view/src/components/Detail/Detail.tsx index dde6c560..010787fb 100644 --- a/packages/view/src/components/Detail/Detail.tsx +++ b/packages/view/src/components/Detail/Detail.tsx @@ -11,7 +11,7 @@ import { import { Tooltip } from "@mui/material"; import { Author } from "components/@common/Author"; -import { useGlobalData } from "hooks"; +import { useOwnerStore, useRepoStore } from "store"; import { useCommitListHide } from "./Detail.hook"; import { getCommitListDetail } from "./Detail.util"; @@ -56,7 +56,8 @@ const Detail = ({ selectedData, clusterId, authSrcMap }: DetailProps) => { const commitNodeListInCluster = selectedData?.filter((selected) => selected.commitNodeList[0].clusterId === clusterId)[0].commitNodeList ?? []; const { commitNodeList, toggle, handleToggle } = useCommitListHide(commitNodeListInCluster); - const { repo, owner } = useGlobalData(); + const { owner } = useOwnerStore(); + const { repo } = useRepoStore(); const isShow = commitNodeListInCluster.length > FIRST_SHOW_NUM; const handleCommitIdCopy = (id: string) => async () => { navigator.clipboard.writeText(id); diff --git a/packages/view/src/components/VerticalClusterList/Summary/Content/Content.tsx b/packages/view/src/components/VerticalClusterList/Summary/Content/Content.tsx index 95b6f3dc..44291936 100644 --- a/packages/view/src/components/VerticalClusterList/Summary/Content/Content.tsx +++ b/packages/view/src/components/VerticalClusterList/Summary/Content/Content.tsx @@ -1,12 +1,13 @@ import React, { useEffect, useState } from "react"; import ArrowDropDownCircleRoundedIcon from "@mui/icons-material/ArrowDropDownCircleRounded"; -import { useGlobalData } from "hooks"; +import { useOwnerStore, useRepoStore } from "store"; import type { ContentProps } from "../Summary.type"; const Content = ({ content, clusterId, selectedClusterId }: ContentProps) => { - const { owner, repo } = useGlobalData(); + const { owner } = useOwnerStore(); + const { repo } = useRepoStore(); const [linkedStr, setLinkedStr] = useState([]); useEffect(() => { diff --git a/packages/view/src/context/GlobalDataProvider.tsx b/packages/view/src/context/GlobalDataProvider.tsx index e570b240..b1b61811 100644 --- a/packages/view/src/context/GlobalDataProvider.tsx +++ b/packages/view/src/context/GlobalDataProvider.tsx @@ -10,8 +10,6 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { const [filteredData, setFilteredData] = useState(data); const [selectedData, setSelectedData] = useState([]); const { setLoading } = useLoadingStore(); - const [owner, setOwner] = useState(""); - const [repo, setRepo] = useState(""); const handleChangeAnalyzedData = (analyzedData: ClusterNode[]) => { setData(analyzedData); @@ -28,12 +26,8 @@ export const GlobalDataProvider = ({ children }: PropsWithChildren) => { selectedData, setSelectedData, handleChangeAnalyzedData, - owner, - setOwner, - repo, - setRepo, }), - [data, filteredData, selectedData, owner, repo] + [data, filteredData, selectedData] ); return {children}; diff --git a/packages/view/src/hooks/useGlobalData.ts b/packages/view/src/hooks/useGlobalData.ts index 16e2793b..45f70a77 100644 --- a/packages/view/src/hooks/useGlobalData.ts +++ b/packages/view/src/hooks/useGlobalData.ts @@ -9,10 +9,6 @@ type GlobalDataState = { selectedData: ClusterNode[]; setFilteredData: Dispatch>; setSelectedData: Dispatch>; - owner: string; - setOwner: Dispatch>; - repo: string; - setRepo: Dispatch>; handleChangeAnalyzedData: (analyzedData: ClusterNode[]) => void; }; // handleChangeBranchList를 임시로 제외 -> 추후 GlobalDataContext를 삭제할 예정 diff --git a/packages/view/src/store/index.ts b/packages/view/src/store/index.ts index f1c226fd..991b1d87 100644 --- a/packages/view/src/store/index.ts +++ b/packages/view/src/store/index.ts @@ -1,3 +1,5 @@ export * from "./loading"; export * from "./filteredRange"; export * from "./branch"; +export * from "./repo"; +export * from "./owner"; diff --git a/packages/view/src/store/owner.ts b/packages/view/src/store/owner.ts new file mode 100644 index 00000000..dbeefc29 --- /dev/null +++ b/packages/view/src/store/owner.ts @@ -0,0 +1,11 @@ +import { create } from "zustand"; + +type OwnerStore = { + owner: string; + setOwner: (owner: string) => void; +}; + +export const useOwnerStore = create((set) => ({ + owner: "", + setOwner: (owner) => set({ owner }), +})); diff --git a/packages/view/src/store/repo.ts b/packages/view/src/store/repo.ts new file mode 100644 index 00000000..d2aac79d --- /dev/null +++ b/packages/view/src/store/repo.ts @@ -0,0 +1,11 @@ +import { create } from "zustand"; + +type RepoStore = { + repo: string; + setRepo: (repo: string) => void; +}; + +export const useRepoStore = create((set) => ({ + repo: "", + setRepo: (repo) => set({ repo }), +})); From d93dda6a3d5554b03980fd0383c0a58c1ad6fa53 Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:08:39 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20data=20=EA=B4=80=EB=A0=A8=20con?= =?UTF-8?q?text=EB=A5=BC=20store=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/view/src/App.tsx | 8 +++--- .../FilteredAuthors/FilteredAuthors.tsx | 4 +-- .../SelectedClusterGroup.tsx | 5 ++-- .../AuthorBarChart/AuthorBarChart.tsx | 4 +-- .../components/Statistics/Statistics.hook.tsx | 4 +-- .../TemporalFilter/TemporalFilter.tsx | 5 ++-- .../ClusterGraph/ClusterGraph.tsx | 4 +-- .../Summary/Summary.hook.tsx | 4 +-- .../VerticalClusterList/Summary/Summary.tsx | 4 +-- .../VerticalClusterList.tsx | 4 +-- packages/view/src/hooks/index.ts | 2 +- packages/view/src/hooks/useAnalayzedData.ts | 16 ++++++++++++ packages/view/src/index.common.tsx | 6 ++--- packages/view/src/store/data.ts | 25 +++++++++++++++++++ packages/view/src/store/index.ts | 1 + 15 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 packages/view/src/hooks/useAnalayzedData.ts create mode 100644 packages/view/src/store/data.ts diff --git a/packages/view/src/App.tsx b/packages/view/src/App.tsx index 467a6218..1e21f10f 100644 --- a/packages/view/src/App.tsx +++ b/packages/view/src/App.tsx @@ -7,16 +7,16 @@ import MonoLogo from "assets/monoLogo.svg"; import { BranchSelector, Statistics, TemporalFilter, ThemeSelector, VerticalClusterList } from "components"; import "./App.scss"; import type IDEPort from "ide/IDEPort"; -import { useGlobalData } from "hooks"; +import { useAnalayzedData } from "hooks"; import { RefreshButton } from "components/RefreshButton"; import type { IDESentEvents } from "types/IDESentEvents"; import type { RemoteGitHubInfo } from "types/RemoteGitHubInfo"; -import { useBranchStore, useLoadingStore, useOwnerStore, useRepoStore } from "store"; +import { useBranchStore, useDataStore, useLoadingStore, useOwnerStore, useRepoStore } from "store"; const App = () => { const initRef = useRef(false); - - const { filteredData, handleChangeAnalyzedData } = useGlobalData(); + const { handleChangeAnalyzedData } = useAnalayzedData(); + const { filteredData } = useDataStore(); const { handleChangeBranchList } = useBranchStore(); const { loading, setLoading } = useLoadingStore(); const { setOwner } = useOwnerStore(); diff --git a/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx b/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx index 0f8d5c4a..e7a0ad08 100644 --- a/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx +++ b/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx @@ -1,12 +1,12 @@ import { Author } from "components/@common/Author"; import { usePreLoadAuthorImg } from "components/VerticalClusterList/Summary/Summary.hook"; import { getInitData } from "components/VerticalClusterList/Summary/Summary.util"; -import { useGlobalData } from "hooks"; +import { useDataStore } from "store"; import "./FilteredAuthors.scss"; const FilteredAuthors = () => { - const { selectedData } = useGlobalData(); + const { selectedData } = useDataStore(); const authSrcMap = usePreLoadAuthorImg(); const selectedClusters = getInitData(selectedData); diff --git a/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx b/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx index ce11e94e..5b9861db 100644 --- a/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx +++ b/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx @@ -4,12 +4,11 @@ import ArrowDropDownRoundedIcon from "@mui/icons-material/ArrowDropDownRounded"; import { selectedDataUpdater } from "components/VerticalClusterList/VerticalClusterList.util"; import { getInitData, getClusterById } from "components/VerticalClusterList/Summary/Summary.util"; -import { useGlobalData } from "hooks"; - import "./SelectedClusterGroup.scss"; +import { useDataStore } from "store"; const SelectedClusterGroup = () => { - const { selectedData, setSelectedData } = useGlobalData(); + const { selectedData, setSelectedData } = useDataStore(); const selectedClusters = getInitData(selectedData); const [isOpen, setIsOpen] = useState(false); diff --git a/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx b/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx index bc81fad1..bb6d3e23 100644 --- a/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx +++ b/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx @@ -4,8 +4,8 @@ import * as d3 from "d3"; import type { SelectChangeEvent } from "@mui/material"; import { FormControl, MenuItem, Select } from "@mui/material"; +import { useDataStore } from "store"; import type { ClusterNode, AuthorInfo } from "types"; -import { useGlobalData } from "hooks"; import { getAuthorProfileImgSrc } from "utils/author"; import { useGetSelectedData } from "../Statistics.hook"; @@ -17,7 +17,7 @@ import { DIMENSIONS, METRIC_TYPE } from "./AuthorBarChart.const"; import "./AuthorBarChart.scss"; const AuthorBarChart = () => { - const { data: totalData, filteredData, setSelectedData, setFilteredData } = useGlobalData(); + const { data: totalData, filteredData, setSelectedData, setFilteredData } = useDataStore(); const rawData = useGetSelectedData(); const svgRef = useRef(null); diff --git a/packages/view/src/components/Statistics/Statistics.hook.tsx b/packages/view/src/components/Statistics/Statistics.hook.tsx index 509b7b88..c478ac3f 100644 --- a/packages/view/src/components/Statistics/Statistics.hook.tsx +++ b/packages/view/src/components/Statistics/Statistics.hook.tsx @@ -1,6 +1,6 @@ -import { useGlobalData } from "hooks"; +import { useDataStore } from "store"; export const useGetSelectedData = () => { - const { filteredData, selectedData } = useGlobalData(); + const { filteredData, selectedData } = useDataStore(); return selectedData.length ? selectedData : filteredData; }; diff --git a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx index 686e305d..98946bd2 100644 --- a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx +++ b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx @@ -5,8 +5,7 @@ import * as d3 from "d3"; import BounceLoader from "react-spinners/BounceLoader"; import { Button } from "@mui/material"; -import { useGlobalData } from "hooks"; -import { useLoadingStore, useFilteredRangeStore } from "store"; +import { useLoadingStore, useFilteredRangeStore, useDataStore } from "store"; import { filterDataByDate, getMinMaxDate, lineChartTimeFormatter, sortBasedOnCommitNode } from "./TemporalFilter.util"; import "./TemporalFilter.scss"; @@ -18,7 +17,7 @@ import { createBrush, drawBrush, resetBrush } from "./LineChartBrush"; import { BRUSH_MARGIN, TEMPORAL_FILTER_LINE_CHART_STYLES } from "./LineChart.const"; const TemporalFilter = () => { - const { data, filteredData, setFilteredData, setSelectedData } = useGlobalData(); + const { data, filteredData, setFilteredData, setSelectedData } = useDataStore(); const { loading } = useLoadingStore(); const { filteredRange, setFilteredRange } = useFilteredRangeStore(); const brushGroupRef = useRef(null); diff --git a/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx b/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx index 108a5771..d22006f1 100644 --- a/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx +++ b/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { useGlobalData } from "hooks"; +import { useDataStore } from "store"; import type { ClusterGraphProps } from "types/ClusterGraphProps"; import { getGraphHeight, getSelectedIndex } from "./ClusterGraph.util"; @@ -10,7 +10,7 @@ import { useHandleClusterGraph } from "./ClusterGraph.hook"; import "./ClusterGraph.scss"; const ClusterGraph: React.FC = ({ data, clusterSizes }) => { - const { selectedData, setSelectedData } = useGlobalData(); + const { selectedData, setSelectedData } = useDataStore(); const selectedIndex = getSelectedIndex(data, selectedData); const graphHeight = getGraphHeight(clusterSizes) + selectedIndex.length * DETAIL_HEIGHT; diff --git a/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx b/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx index 27190177..cc160be3 100644 --- a/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx +++ b/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx @@ -1,12 +1,12 @@ import { useEffect, useState } from "react"; -import { useGlobalData } from "hooks"; +import { useDataStore } from "store"; import { getAuthSrcMap } from "./Summary.util"; import type { AuthSrcMap } from "./Summary.type"; export const usePreLoadAuthorImg = () => { - const { data } = useGlobalData(); + const { data } = useDataStore(); const [authSrcMap, setAuthSrcMap] = useState(null); useEffect(() => { diff --git a/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx b/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx index 3d8a91e0..b2557a5e 100644 --- a/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx +++ b/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx @@ -4,7 +4,7 @@ import { List, AutoSizer } from "react-virtualized"; import type { ClusterNode } from "types"; import { Detail } from "components"; -import { useGlobalData } from "hooks"; +import { useDataStore } from "store"; import "./Summary.scss"; import { Author } from "../../@common/Author"; @@ -21,7 +21,7 @@ const COLLAPSED_ROW_HEIGHT = CLUSTER_HEIGHT + NODE_GAP * 2; const EXPANDED_ROW_HEIGHT = DETAIL_HEIGHT + COLLAPSED_ROW_HEIGHT; const Summary = () => { - const { filteredData: data, selectedData, setSelectedData } = useGlobalData(); + const { filteredData: data, selectedData, setSelectedData } = useDataStore(); const clusters = getInitData(data); const detailRef = useRef(null); const authSrcMap = usePreLoadAuthorImg(); diff --git a/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx b/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx index 892ed2dc..972a820b 100644 --- a/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx +++ b/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx @@ -1,4 +1,4 @@ -import { useGlobalData } from "hooks"; +import { useDataStore } from "store"; import { FilteredAuthors } from "components/FilteredAuthors"; import { SelectedClusterGroup } from "components/SelectedClusterGroup"; @@ -7,7 +7,7 @@ import { Summary } from "./Summary"; import "./VerticalClusterList.scss"; const VerticalClusterList = () => { - const { selectedData } = useGlobalData(); + const { selectedData } = useDataStore(); return (
diff --git a/packages/view/src/hooks/index.ts b/packages/view/src/hooks/index.ts index 10d2f0ec..abc96b1c 100644 --- a/packages/view/src/hooks/index.ts +++ b/packages/view/src/hooks/index.ts @@ -1 +1 @@ -export * from "./useGlobalData"; +export * from "./useAnalayzedData"; diff --git a/packages/view/src/hooks/useAnalayzedData.ts b/packages/view/src/hooks/useAnalayzedData.ts new file mode 100644 index 00000000..e8275a94 --- /dev/null +++ b/packages/view/src/hooks/useAnalayzedData.ts @@ -0,0 +1,16 @@ +import { useDataStore, useLoadingStore } from "store"; +import type { ClusterNode } from "types"; + +export const useAnalayzedData = () => { + const { setData, setFilteredData, setSelectedData } = useDataStore(); + const { setLoading } = useLoadingStore(); + + const handleChangeAnalyzedData = (analyzedData: ClusterNode[]) => { + setData(analyzedData); + setFilteredData([...analyzedData.reverse()]); + setSelectedData([]); + setLoading(false); + }; + + return { handleChangeAnalyzedData }; +}; diff --git a/packages/view/src/index.common.tsx b/packages/view/src/index.common.tsx index 80500cbf..7bd8f6de 100644 --- a/packages/view/src/index.common.tsx +++ b/packages/view/src/index.common.tsx @@ -1,7 +1,7 @@ import ReactDOM from "react-dom/client"; import "./App.scss"; -import { GlobalDataProvider } from "./context/GlobalDataProvider"; + import App from "./App"; export const initRender = () => { @@ -10,9 +10,7 @@ export const initRender = () => { // TODO - StrictMode disabled temporarily to review performance of visualization. ReactDOM.createRoot(rootContainer).render( // - - - + // ); }; diff --git a/packages/view/src/store/data.ts b/packages/view/src/store/data.ts new file mode 100644 index 00000000..97f4e3c6 --- /dev/null +++ b/packages/view/src/store/data.ts @@ -0,0 +1,25 @@ +import { create } from "zustand"; +import type { Dispatch, SetStateAction } from "react"; + +import type { ClusterNode } from "types"; + +interface DataState { + data: ClusterNode[]; + filteredData: ClusterNode[]; + selectedData: ClusterNode[]; + setData: (data: ClusterNode[]) => void; + setFilteredData: (filteredData: ClusterNode[]) => void; + setSelectedData: Dispatch>; +} + +export const useDataStore = create((set) => ({ + data: [], + filteredData: [], + selectedData: [], + setData: (data) => set({ data }), + setFilteredData: (filteredData) => set({ filteredData }), + setSelectedData: (selectedData) => + set((state) => ({ + selectedData: typeof selectedData === "function" ? selectedData(state.selectedData) : selectedData, + })), +})); diff --git a/packages/view/src/store/index.ts b/packages/view/src/store/index.ts index 991b1d87..e9d468f6 100644 --- a/packages/view/src/store/index.ts +++ b/packages/view/src/store/index.ts @@ -3,3 +3,4 @@ export * from "./filteredRange"; export * from "./branch"; export * from "./repo"; export * from "./owner"; +export * from "./data"; From d7257e8c736c4ec7dceb9a0106b67a0870cf0745 Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:09:24 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20=EC=A0=84=EC=97=AD=20context=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/src/context/GlobalDataProvider.tsx | 34 ------------------- packages/view/src/hooks/useGlobalData.ts | 24 ------------- 2 files changed, 58 deletions(-) delete mode 100644 packages/view/src/context/GlobalDataProvider.tsx delete mode 100644 packages/view/src/hooks/useGlobalData.ts diff --git a/packages/view/src/context/GlobalDataProvider.tsx b/packages/view/src/context/GlobalDataProvider.tsx deleted file mode 100644 index b1b61811..00000000 --- a/packages/view/src/context/GlobalDataProvider.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { PropsWithChildren } from "react"; -import { useMemo, useState } from "react"; - -import { GlobalDataContext } from "hooks"; -import type { ClusterNode } from "types"; -import { useLoadingStore } from "store"; - -export const GlobalDataProvider = ({ children }: PropsWithChildren) => { - const [data, setData] = useState([]); - const [filteredData, setFilteredData] = useState(data); - const [selectedData, setSelectedData] = useState([]); - const { setLoading } = useLoadingStore(); - - const handleChangeAnalyzedData = (analyzedData: ClusterNode[]) => { - setData(analyzedData); - setFilteredData([...analyzedData.reverse()]); - setSelectedData([]); - setLoading(false); - }; - - const value = useMemo( - () => ({ - data, - filteredData, - setFilteredData, - selectedData, - setSelectedData, - handleChangeAnalyzedData, - }), - [data, filteredData, selectedData] - ); - - return {children}; -}; diff --git a/packages/view/src/hooks/useGlobalData.ts b/packages/view/src/hooks/useGlobalData.ts deleted file mode 100644 index 45f70a77..00000000 --- a/packages/view/src/hooks/useGlobalData.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { Dispatch, SetStateAction } from "react"; -import { createContext, useContext } from "react"; - -import type { ClusterNode } from "types"; - -type GlobalDataState = { - data: ClusterNode[]; - filteredData: ClusterNode[]; - selectedData: ClusterNode[]; - setFilteredData: Dispatch>; - setSelectedData: Dispatch>; - handleChangeAnalyzedData: (analyzedData: ClusterNode[]) => void; -}; // handleChangeBranchList를 임시로 제외 -> 추후 GlobalDataContext를 삭제할 예정 - -export const GlobalDataContext = createContext(undefined); - -export const useGlobalData = () => { - const globalData = useContext(GlobalDataContext); - if (!globalData) { - throw new Error("Cannot find GlobalDataProvider"); - } - - return globalData; -}; From 67175be061c6ae8d7b2eb2dc3b064ddad5dd7d22 Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:21:47 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20dataStore=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=A0=20=EB=95=8C=20useShallow=EC=99=80=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=EC=A0=81=20=EA=B5=AC=EB=8F=85=EC=9D=84=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=B4=EC=84=9C=20=EB=A6=AC=EB=A0=8C?= =?UTF-8?q?=EB=8D=94=EB=A7=81=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 하나의 상태만 가져오는 경우 선택적 구독 방식 사용 - 여러 상태와 액션 함수를 가져와야하는경우 useShallow를 사용 - useShallow사용시 배열 방식을 이용해서 코드를 간결하게 작성 --- packages/view/src/App.tsx | 3 +-- .../components/FilteredAuthors/FilteredAuthors.tsx | 2 +- .../SelectedClusterGroup/SelectedClusterGroup.tsx | 5 ++++- .../Statistics/AuthorBarChart/AuthorBarChart.tsx | 5 ++++- .../src/components/Statistics/Statistics.hook.tsx | 4 +++- .../components/TemporalFilter/TemporalFilter.tsx | 13 +++++++++---- .../ClusterGraph/ClusterGraph.tsx | 5 ++++- .../VerticalClusterList/Summary/Summary.hook.tsx | 2 +- .../VerticalClusterList/Summary/Summary.tsx | 13 ++++++++----- .../VerticalClusterList/VerticalClusterList.tsx | 2 +- packages/view/src/hooks/useAnalayzedData.ts | 6 +++++- 11 files changed, 41 insertions(+), 19 deletions(-) diff --git a/packages/view/src/App.tsx b/packages/view/src/App.tsx index 1e21f10f..217a7f9d 100644 --- a/packages/view/src/App.tsx +++ b/packages/view/src/App.tsx @@ -16,7 +16,7 @@ import { useBranchStore, useDataStore, useLoadingStore, useOwnerStore, useRepoSt const App = () => { const initRef = useRef(false); const { handleChangeAnalyzedData } = useAnalayzedData(); - const { filteredData } = useDataStore(); + const filteredData = useDataStore((state) => state.filteredData); const { handleChangeBranchList } = useBranchStore(); const { loading, setLoading } = useLoadingStore(); const { setOwner } = useOwnerStore(); @@ -29,7 +29,6 @@ const App = () => { handleChangeAnalyzedData, handleChangeBranchList, }; - setLoading(true); ideAdapter.addIDESentEventListener(callbacks); ideAdapter.sendFetchAnalyzedDataMessage(); diff --git a/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx b/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx index e7a0ad08..82ad83a9 100644 --- a/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx +++ b/packages/view/src/components/FilteredAuthors/FilteredAuthors.tsx @@ -6,7 +6,7 @@ import { useDataStore } from "store"; import "./FilteredAuthors.scss"; const FilteredAuthors = () => { - const { selectedData } = useDataStore(); + const selectedData = useDataStore((state) => state.selectedData); const authSrcMap = usePreLoadAuthorImg(); const selectedClusters = getInitData(selectedData); diff --git a/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx b/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx index 5b9861db..4324cd7e 100644 --- a/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx +++ b/packages/view/src/components/SelectedClusterGroup/SelectedClusterGroup.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; +import { useShallow } from "zustand/react/shallow"; import Chip from "@mui/material/Chip"; import ArrowDropDownRoundedIcon from "@mui/icons-material/ArrowDropDownRounded"; @@ -8,7 +9,9 @@ import "./SelectedClusterGroup.scss"; import { useDataStore } from "store"; const SelectedClusterGroup = () => { - const { selectedData, setSelectedData } = useDataStore(); + const [selectedData, setSelectedData] = useDataStore( + useShallow((state) => [state.selectedData, state.setSelectedData]) + ); const selectedClusters = getInitData(selectedData); const [isOpen, setIsOpen] = useState(false); diff --git a/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx b/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx index bb6d3e23..4a3c4786 100644 --- a/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx +++ b/packages/view/src/components/Statistics/AuthorBarChart/AuthorBarChart.tsx @@ -1,5 +1,6 @@ import type { MouseEvent } from "react"; import { useRef, useEffect, useState } from "react"; +import { useShallow } from "zustand/react/shallow"; import * as d3 from "d3"; import type { SelectChangeEvent } from "@mui/material"; import { FormControl, MenuItem, Select } from "@mui/material"; @@ -17,7 +18,9 @@ import { DIMENSIONS, METRIC_TYPE } from "./AuthorBarChart.const"; import "./AuthorBarChart.scss"; const AuthorBarChart = () => { - const { data: totalData, filteredData, setSelectedData, setFilteredData } = useDataStore(); + const [totalData, filteredData, setSelectedData, setFilteredData] = useDataStore( + useShallow((state) => [state.data, state.filteredData, state.setSelectedData, state.setFilteredData]) + ); const rawData = useGetSelectedData(); const svgRef = useRef(null); diff --git a/packages/view/src/components/Statistics/Statistics.hook.tsx b/packages/view/src/components/Statistics/Statistics.hook.tsx index c478ac3f..01017192 100644 --- a/packages/view/src/components/Statistics/Statistics.hook.tsx +++ b/packages/view/src/components/Statistics/Statistics.hook.tsx @@ -1,6 +1,8 @@ +import { useShallow } from "zustand/react/shallow"; + import { useDataStore } from "store"; export const useGetSelectedData = () => { - const { filteredData, selectedData } = useDataStore(); + const [filteredData, selectedData] = useDataStore(useShallow((state) => [state.filteredData, state.selectedData])); return selectedData.length ? selectedData : filteredData; }; diff --git a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx index 98946bd2..535e11e8 100644 --- a/packages/view/src/components/TemporalFilter/TemporalFilter.tsx +++ b/packages/view/src/components/TemporalFilter/TemporalFilter.tsx @@ -1,8 +1,9 @@ import "reflect-metadata"; import type { CSSProperties } from "react"; import { useEffect, useMemo, useRef } from "react"; -import * as d3 from "d3"; import BounceLoader from "react-spinners/BounceLoader"; +import * as d3 from "d3"; +import { useShallow } from "zustand/react/shallow"; import { Button } from "@mui/material"; import { useLoadingStore, useFilteredRangeStore, useDataStore } from "store"; @@ -17,9 +18,13 @@ import { createBrush, drawBrush, resetBrush } from "./LineChartBrush"; import { BRUSH_MARGIN, TEMPORAL_FILTER_LINE_CHART_STYLES } from "./LineChart.const"; const TemporalFilter = () => { - const { data, filteredData, setFilteredData, setSelectedData } = useDataStore(); - const { loading } = useLoadingStore(); - const { filteredRange, setFilteredRange } = useFilteredRangeStore(); + const [data, filteredData, setFilteredData, setSelectedData] = useDataStore( + useShallow((state) => [state.data, state.filteredData, state.setFilteredData, state.setSelectedData]) + ); + const [loading] = useLoadingStore(useShallow((state) => [state.loading])); + const [filteredRange, setFilteredRange] = useFilteredRangeStore( + useShallow((state) => [state.filteredRange, state.setFilteredRange]) + ); const brushGroupRef = useRef(null); const brushRef = useRef>(); diff --git a/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx b/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx index d22006f1..3666bcdf 100644 --- a/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx +++ b/packages/view/src/components/VerticalClusterList/ClusterGraph/ClusterGraph.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { useShallow } from "zustand/react/shallow"; import { useDataStore } from "store"; import type { ClusterGraphProps } from "types/ClusterGraphProps"; @@ -10,7 +11,9 @@ import { useHandleClusterGraph } from "./ClusterGraph.hook"; import "./ClusterGraph.scss"; const ClusterGraph: React.FC = ({ data, clusterSizes }) => { - const { selectedData, setSelectedData } = useDataStore(); + const [selectedData, setSelectedData] = useDataStore( + useShallow((state) => [state.selectedData, state.setSelectedData]) + ); const selectedIndex = getSelectedIndex(data, selectedData); const graphHeight = getGraphHeight(clusterSizes) + selectedIndex.length * DETAIL_HEIGHT; diff --git a/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx b/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx index cc160be3..c1c1acf7 100644 --- a/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx +++ b/packages/view/src/components/VerticalClusterList/Summary/Summary.hook.tsx @@ -6,7 +6,7 @@ import { getAuthSrcMap } from "./Summary.util"; import type { AuthSrcMap } from "./Summary.type"; export const usePreLoadAuthorImg = () => { - const { data } = useDataStore(); + const data = useDataStore((state) => state.data); const [authSrcMap, setAuthSrcMap] = useState(null); useEffect(() => { diff --git a/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx b/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx index b2557a5e..ce4217f0 100644 --- a/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx +++ b/packages/view/src/components/VerticalClusterList/Summary/Summary.tsx @@ -1,6 +1,7 @@ import { useRef, useEffect } from "react"; import type { ListRowProps } from "react-virtualized"; import { List, AutoSizer } from "react-virtualized"; +import { useShallow } from "zustand/react/shallow"; import type { ClusterNode } from "types"; import { Detail } from "components"; @@ -21,16 +22,18 @@ const COLLAPSED_ROW_HEIGHT = CLUSTER_HEIGHT + NODE_GAP * 2; const EXPANDED_ROW_HEIGHT = DETAIL_HEIGHT + COLLAPSED_ROW_HEIGHT; const Summary = () => { - const { filteredData: data, selectedData, setSelectedData } = useDataStore(); - const clusters = getInitData(data); + const [filteredData, selectedData, setSelectedData] = useDataStore( + useShallow((state) => [state.filteredData, state.selectedData, state.setSelectedData]) + ); + const clusters = getInitData(filteredData); const detailRef = useRef(null); const authSrcMap = usePreLoadAuthorImg(); const selectedClusterId = getClusterIds(selectedData); const listRef = useRef(null); - const clusterSizes = getClusterSizes(data); + const clusterSizes = getClusterSizes(filteredData); const onClickClusterSummary = (clusterId: number) => () => { - const selected = getClusterById(data, clusterId); + const selected = getClusterById(filteredData, clusterId); setSelectedData((prevState: ClusterNode[]) => { return selectedDataUpdater(selected, clusterId)(prevState); }); @@ -63,7 +66,7 @@ const Summary = () => { >
diff --git a/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx b/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx index 972a820b..b3bc1680 100644 --- a/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx +++ b/packages/view/src/components/VerticalClusterList/VerticalClusterList.tsx @@ -7,7 +7,7 @@ import { Summary } from "./Summary"; import "./VerticalClusterList.scss"; const VerticalClusterList = () => { - const { selectedData } = useDataStore(); + const selectedData = useDataStore((state) => state.selectedData); return (
diff --git a/packages/view/src/hooks/useAnalayzedData.ts b/packages/view/src/hooks/useAnalayzedData.ts index e8275a94..0edbbaf8 100644 --- a/packages/view/src/hooks/useAnalayzedData.ts +++ b/packages/view/src/hooks/useAnalayzedData.ts @@ -1,8 +1,12 @@ +import { useShallow } from "zustand/react/shallow"; + import { useDataStore, useLoadingStore } from "store"; import type { ClusterNode } from "types"; export const useAnalayzedData = () => { - const { setData, setFilteredData, setSelectedData } = useDataStore(); + const [setData, setFilteredData, setSelectedData] = useDataStore( + useShallow((state) => [state.setData, state.setFilteredData, state.setSelectedData]) + ); const { setLoading } = useLoadingStore(); const handleChangeAnalyzedData = (analyzedData: ClusterNode[]) => { From 40c1ffa32a0d71a01081f53b47010af71657cc5e Mon Sep 17 00:00:00 2001 From: Sang-minKIM <87116017+Sang-minKIM@users.noreply.github.com> Date: Sat, 5 Oct 2024 21:54:00 +0900 Subject: [PATCH 8/8] =?UTF-8?q?chore:=20interface=EB=A5=BC=20type=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/view/src/store/data.ts | 4 ++-- packages/view/src/store/loading.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/view/src/store/data.ts b/packages/view/src/store/data.ts index 97f4e3c6..55475ab6 100644 --- a/packages/view/src/store/data.ts +++ b/packages/view/src/store/data.ts @@ -3,14 +3,14 @@ import type { Dispatch, SetStateAction } from "react"; import type { ClusterNode } from "types"; -interface DataState { +type DataState = { data: ClusterNode[]; filteredData: ClusterNode[]; selectedData: ClusterNode[]; setData: (data: ClusterNode[]) => void; setFilteredData: (filteredData: ClusterNode[]) => void; setSelectedData: Dispatch>; -} +}; export const useDataStore = create((set) => ({ data: [], diff --git a/packages/view/src/store/loading.ts b/packages/view/src/store/loading.ts index 921810d5..c3e31d28 100644 --- a/packages/view/src/store/loading.ts +++ b/packages/view/src/store/loading.ts @@ -1,9 +1,9 @@ import { create } from "zustand"; -interface LoadingState { +type LoadingState = { loading: boolean; setLoading: (loading: boolean) => void; -} +}; export const useLoadingStore = create((set) => ({ loading: false,