diff --git a/frontend/src/pages/project/[id]/secrets/overview.tsx b/frontend/src/pages/project/[id]/secrets/overview.tsx
index eaf915120..69e2bc196 100644
--- a/frontend/src/pages/project/[id]/secrets/overview.tsx
+++ b/frontend/src/pages/project/[id]/secrets/overview.tsx
@@ -2,7 +2,6 @@ import { useTranslation } from "react-i18next";
import Head from "next/head";
import { SecretOverviewPage } from "@app/views/SecretOverviewPage";
-import { StoreProvider } from "@app/views/SecretOverviewPage/SecretOverviewPage.store";
const Dashboard = () => {
const { t } = useTranslation();
@@ -17,9 +16,7 @@ const Dashboard = () => {
-
-
-
+
>
);
diff --git a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.store.tsx b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.store.tsx
deleted file mode 100644
index db544c7e8..000000000
--- a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.store.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import { createContext, ReactNode, useContext, useEffect, useRef } from "react";
-import { useRouter } from "next/router";
-import { createStore, StateCreator, StoreApi, useStore } from "zustand";
-
-export enum EntryType {
- FOLDER = "folder",
- SECRET = "secret"
-}
-
-type SelectedEntriesState = {
- selectedEntries: {
- [EntryType.FOLDER]: Record;
- [EntryType.SECRET]: Record;
- };
- action: {
- toggle: (type: EntryType, key: string) => void;
- reset: () => void;
- };
-};
-
-const createSelectedSecretStore: StateCreator = (set) => ({
- selectedEntries: {
- [EntryType.FOLDER]: {},
- [EntryType.SECRET]: {}
- },
- action: {
- toggle: (type: EntryType, key: string) =>
- set((state) => {
- const isChecked = Boolean(state.selectedEntries[type]?.[key]);
- const newChecks = { ...state.selectedEntries };
- // remove selection if its present else add it
- if (isChecked) delete newChecks[type][key];
- else newChecks[type][key] = true;
- return { selectedEntries: newChecks };
- }),
- reset: () =>
- set({
- selectedEntries: {
- [EntryType.FOLDER]: {},
- [EntryType.SECRET]: {}
- }
- })
- }
-});
-
-const StoreContext = createContext | null>(null);
-export const StoreProvider = ({ children }: { children: ReactNode }) => {
- const storeRef = useRef>();
- const router = useRouter();
- if (!storeRef.current) {
- storeRef.current = createStore((...a) => ({
- ...createSelectedSecretStore(...a)
- }));
- }
-
- useEffect(() => {
- const onRouteChangeStart = () => {
- const state = storeRef.current?.getState();
- state?.action.reset();
- };
-
- router.events.on("routeChangeStart", onRouteChangeStart);
- return () => {
- router.events.off("routeChangeStart", onRouteChangeStart);
- };
- }, []);
-
- return {children};
-};
-
-const useStoreContext = (selector: (state: SelectedEntriesState) => T): T => {
- const ctx = useContext(StoreContext);
- if (!ctx) throw new Error("Missing context provider");
- return useStore(ctx, selector);
-};
-
-export const useSelectedEntries = () => useStoreContext((state) => state.selectedEntries);
-export const useSelectedEntryActions = () => useStoreContext((state) => state.action);
diff --git a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx
index cd00af883..fab7ebecf 100644
--- a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx
+++ b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useRef, useState } from "react";
+import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { useRouter } from "next/router";
@@ -71,7 +71,11 @@ import { SecretOverviewDynamicSecretRow } from "./components/SecretOverviewDynam
import { SecretOverviewFolderRow } from "./components/SecretOverviewFolderRow";
import { SecretOverviewTableRow } from "./components/SecretOverviewTableRow";
import { SelectionPanel } from "./components/SelectionPanel/SelectionPanel";
-import { EntryType, useSelectedEntries, useSelectedEntryActions } from "./SecretOverviewPage.store";
+
+export enum EntryType {
+ FOLDER = "folder",
+ SECRET = "secret"
+}
export const SecretOverviewPage = () => {
const { t } = useTranslation();
@@ -84,15 +88,6 @@ export const SecretOverviewPage = () => {
const [expandableTableWidth, setExpandableTableWidth] = useState(0);
const [sortDir, setSortDir] = useState<"asc" | "desc">("asc");
- useEffect(() => {
- const handleParentTableWidthResize = () => {
- setExpandableTableWidth(parentTableRef.current?.clientWidth || 0);
- };
-
- window.addEventListener("resize", handleParentTableWidthResize);
- return () => window.removeEventListener("resize", handleParentTableWidthResize);
- }, []);
-
useEffect(() => {
if (parentTableRef.current) {
setExpandableTableWidth(parentTableRef.current.clientWidth);
@@ -107,8 +102,55 @@ export const SecretOverviewPage = () => {
const [searchFilter, setSearchFilter] = useState("");
const secretPath = (router.query?.secretPath as string) || "/";
- const selectedEntries = useSelectedEntries();
- const { toggle: toggleSelectedEntry } = useSelectedEntryActions();
+ const [selectedEntries, setSelectedEntries] = useState<{
+ [EntryType.FOLDER]: Record;
+ [EntryType.SECRET]: Record;
+ }>({
+ [EntryType.FOLDER]: {},
+ [EntryType.SECRET]: {}
+ });
+
+ const toggleSelectedEntry = useCallback(
+ (type: EntryType, key: string) => {
+ const isChecked = Boolean(selectedEntries[type]?.[key]);
+ const newChecks = { ...selectedEntries };
+
+ // remove selection if its present else add it
+ if (isChecked) {
+ delete newChecks[type][key];
+ } else {
+ newChecks[type][key] = true;
+ }
+
+ setSelectedEntries(newChecks);
+ },
+ [selectedEntries]
+ );
+
+ const resetSelectedEntries = useCallback(() => {
+ setSelectedEntries({
+ [EntryType.FOLDER]: {},
+ [EntryType.SECRET]: {}
+ });
+ }, []);
+
+ useEffect(() => {
+ const handleParentTableWidthResize = () => {
+ setExpandableTableWidth(parentTableRef.current?.clientWidth || 0);
+ };
+
+ const onRouteChangeStart = () => {
+ resetSelectedEntries();
+ };
+
+ router.events.on("routeChangeStart", onRouteChangeStart);
+
+ window.addEventListener("resize", handleParentTableWidthResize);
+ return () => {
+ window.removeEventListener("resize", handleParentTableWidthResize);
+ router.events.off("routeChangeStart", onRouteChangeStart);
+ };
+ }, []);
useEffect(() => {
if (!isWorkspaceLoading && !workspaceId && router.isReady) {
@@ -553,6 +595,8 @@ export const SecretOverviewPage = () => {
secretPath={secretPath}
getSecretByKey={getSecretByKey}
getFolderByNameAndEnv={getFolderByNameAndEnv}
+ selectedEntries={selectedEntries}
+ resetSelectedEntries={resetSelectedEntries}
/>
diff --git a/frontend/src/views/SecretOverviewPage/components/SelectionPanel/SelectionPanel.tsx b/frontend/src/views/SecretOverviewPage/components/SelectionPanel/SelectionPanel.tsx
index 89fcef58c..6a2fe9bf6 100644
--- a/frontend/src/views/SecretOverviewPage/components/SelectionPanel/SelectionPanel.tsx
+++ b/frontend/src/views/SecretOverviewPage/components/SelectionPanel/SelectionPanel.tsx
@@ -15,23 +15,35 @@ import { usePopUp } from "@app/hooks";
import { useDeleteFolder, useDeleteSecretBatch } from "@app/hooks/api";
import { DecryptedSecret, TDeleteSecretBatchDTO, TSecretFolder } from "@app/hooks/api/types";
-import { useSelectedEntries, useSelectedEntryActions } from "../../SecretOverviewPage.store";
+export enum EntryType {
+ FOLDER = "folder",
+ SECRET = "secret"
+}
type Props = {
secretPath: string;
getSecretByKey: (slug: string, key: string) => DecryptedSecret | undefined;
getFolderByNameAndEnv: (name: string, env: string) => TSecretFolder | undefined;
+ resetSelectedEntries: () => void;
+ selectedEntries: {
+ [EntryType.FOLDER]: Record;
+ [EntryType.SECRET]: Record;
+ };
};
-export const SelectionPanel = ({ getFolderByNameAndEnv, getSecretByKey, secretPath }: Props) => {
+export const SelectionPanel = ({
+ getFolderByNameAndEnv,
+ getSecretByKey,
+ secretPath,
+ resetSelectedEntries,
+ selectedEntries
+}: Props) => {
const { permission } = useProjectPermission();
const { handlePopUpOpen, handlePopUpToggle, handlePopUpClose, popUp } = usePopUp([
"bulkDeleteEntries"
] as const);
- const selectedEntries = useSelectedEntries();
- const { reset: resetSelectedEntries } = useSelectedEntryActions();
const selectedCount =
Object.keys(selectedEntries.folder).length + Object.keys(selectedEntries.secret).length;