mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-20 23:16:55 +00:00
Merge branch 'heads/main' into ENG-3630
This commit is contained in:
@@ -2,7 +2,7 @@ import { useNavigate, useParams, useSearch } from "@tanstack/react-router";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionCommitsActions,
|
||||
ProjectPermissionSub
|
||||
@@ -23,7 +23,7 @@ export const CommitDetailsPage = () => {
|
||||
from: ROUTE_PATHS.SecretManager.CommitDetailsPage.id,
|
||||
select: (el) => el.folderId
|
||||
});
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const navigate = useNavigate();
|
||||
const routerQueryParams: { secretPath?: string } = useSearch({
|
||||
@@ -36,7 +36,7 @@ export const CommitDetailsPage = () => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/commits/$environment/$folderId",
|
||||
params: {
|
||||
projectId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
folderId,
|
||||
environment: envSlug
|
||||
},
|
||||
@@ -51,7 +51,7 @@ export const CommitDetailsPage = () => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore",
|
||||
params: {
|
||||
projectId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
folderId,
|
||||
environment: envSlug,
|
||||
commitId: selectedCommitId
|
||||
@@ -73,7 +73,7 @@ export const CommitDetailsPage = () => {
|
||||
>
|
||||
<CommitDetailsTab
|
||||
selectedCommitId={selectedCommitId}
|
||||
workspaceId={currentWorkspace.id}
|
||||
projectId={currentProject.id}
|
||||
goBackToHistory={handleGoBackToHistory}
|
||||
envSlug={envSlug}
|
||||
goToRollbackPreview={handleGoToRollbackPreview}
|
||||
|
||||
+4
-4
@@ -53,13 +53,13 @@ const formatDisplayDate = (dateString: string): string => {
|
||||
|
||||
export const CommitDetailsTab = ({
|
||||
selectedCommitId,
|
||||
workspaceId,
|
||||
projectId,
|
||||
envSlug,
|
||||
goBackToHistory,
|
||||
goToRollbackPreview
|
||||
}: {
|
||||
selectedCommitId: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
envSlug: string;
|
||||
goBackToHistory: () => void;
|
||||
goToRollbackPreview: () => void;
|
||||
@@ -71,7 +71,7 @@ export const CommitDetailsTab = ({
|
||||
"revertChanges"
|
||||
] as const);
|
||||
|
||||
const { data: commitDetails, isLoading } = useGetCommitDetails(workspaceId, selectedCommitId);
|
||||
const { data: commitDetails, isLoading } = useGetCommitDetails(projectId, selectedCommitId);
|
||||
|
||||
const routerQueryParams: { secretPath?: string } = useSearch({
|
||||
from: ROUTE_PATHS.SecretManager.CommitDetailsPage.id
|
||||
@@ -80,7 +80,7 @@ export const CommitDetailsTab = ({
|
||||
|
||||
const { mutateAsync: revert } = useCommitRevert({
|
||||
commitId: selectedCommitId,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environment: envSlug,
|
||||
directory: secretPath
|
||||
});
|
||||
|
||||
+5
-5
@@ -17,7 +17,7 @@ import {
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionCommitsActions,
|
||||
ProjectPermissionSub
|
||||
@@ -79,7 +79,7 @@ export const RollbackPreviewTab = (): JSX.Element => {
|
||||
const [deepRollback, setDeepRollback] = useState<boolean>(false);
|
||||
const [message, setMessage] = useState<string>("");
|
||||
const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const envSlug = useParams({
|
||||
from: ROUTE_PATHS.SecretManager.RollbackPreviewPage.id,
|
||||
select: (el) => el.environment
|
||||
@@ -104,7 +104,7 @@ export const RollbackPreviewTab = (): JSX.Element => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/commits/$environment/$folderId",
|
||||
params: {
|
||||
projectId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
folderId,
|
||||
environment: envSlug
|
||||
},
|
||||
@@ -120,7 +120,7 @@ export const RollbackPreviewTab = (): JSX.Element => {
|
||||
] as const);
|
||||
|
||||
const { mutateAsync: rollback } = useCommitRollback({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
commitId: selectedCommitId,
|
||||
folderId,
|
||||
deepRollback,
|
||||
@@ -133,7 +133,7 @@ export const RollbackPreviewTab = (): JSX.Element => {
|
||||
folderId,
|
||||
selectedCommitId,
|
||||
envSlug,
|
||||
currentWorkspace.id,
|
||||
currentProject.id,
|
||||
deepRollback,
|
||||
secretPath
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { PageHeader } from "@app/components/v2";
|
||||
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionCommitsActions,
|
||||
ProjectPermissionSub
|
||||
@@ -17,7 +17,7 @@ export const CommitsPage = () => {
|
||||
from: ROUTE_PATHS.SecretManager.CommitsPage.id,
|
||||
select: (el) => el.environment
|
||||
});
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const navigate = useNavigate();
|
||||
const folderId = useParams({
|
||||
from: ROUTE_PATHS.SecretManager.CommitsPage.id,
|
||||
@@ -33,7 +33,7 @@ export const CommitsPage = () => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId",
|
||||
params: {
|
||||
projectId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
folderId,
|
||||
environment: envSlug,
|
||||
commitId
|
||||
@@ -67,7 +67,7 @@ export const CommitsPage = () => {
|
||||
>
|
||||
<CommitHistoryTab
|
||||
onSelectCommit={handleSelectCommit}
|
||||
projectId={currentWorkspace.id}
|
||||
projectId={currentProject.id}
|
||||
environment={envSlug}
|
||||
secretPath={secretPath}
|
||||
/>
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ export const CommitHistoryTab = ({
|
||||
isFetchingNextPage,
|
||||
hasNextPage
|
||||
} = useGetFolderCommitHistory({
|
||||
workspaceId: projectId,
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath,
|
||||
limit,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useAddTrustedIp, useGetMyIp, useUpdateTrustedIp } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -27,7 +27,7 @@ type Props = {
|
||||
export const IPAllowlistModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props) => {
|
||||
const { data, isPending } = useGetMyIp();
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const addTrustedIp = useAddTrustedIp();
|
||||
const updateTrustedIp = useUpdateTrustedIp();
|
||||
|
||||
@@ -65,11 +65,11 @@ export const IPAllowlistModal = ({ popUp, handlePopUpClose, handlePopUpToggle }:
|
||||
|
||||
const onIPAllowlistModalSubmit = async ({ ipAddress, comment }: FormData) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
if (popUp?.trustedIp?.data) {
|
||||
await updateTrustedIp.mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
trustedIpId: (popUp?.trustedIp?.data as { trustedIpId: string })?.trustedIpId,
|
||||
ipAddress,
|
||||
comment,
|
||||
@@ -77,7 +77,7 @@ export const IPAllowlistModal = ({ popUp, handlePopUpClose, handlePopUpToggle }:
|
||||
});
|
||||
} else {
|
||||
await addTrustedIp.mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
ipAddress,
|
||||
comment,
|
||||
isActive: true
|
||||
|
||||
@@ -8,8 +8,8 @@ import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { useDeleteTrustedIp } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
@@ -20,7 +20,7 @@ import { IPAllowlistTable } from "./IPAllowlistTable";
|
||||
export const IPAllowlistSection = () => {
|
||||
const { mutateAsync } = useDeleteTrustedIp();
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||
"trustedIp",
|
||||
@@ -30,10 +30,10 @@ export const IPAllowlistSection = () => {
|
||||
|
||||
const onDeleteTrustedIpSubmit = async (trustedIpId: string) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
await mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
trustedIpId
|
||||
});
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ import {
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { useGetTrustedIps } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -41,8 +41,8 @@ type Props = {
|
||||
|
||||
export const IPAllowlistTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Props) => {
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data, isPending } = useGetTrustedIps(currentWorkspace?.id ?? "");
|
||||
const { currentProject } = useProject();
|
||||
const { data, isPending } = useGetTrustedIps(currentProject?.id ?? "");
|
||||
|
||||
const formatType = (type: string, prefix?: number) => {
|
||||
return `${type.slice(0, 2).toUpperCase() + type.slice(2)} ${
|
||||
@@ -77,10 +77,10 @@ export const IPAllowlistTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }:
|
||||
<Td>{comment}</Td>
|
||||
{/* <Td>
|
||||
<div className="flex items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faCircle}
|
||||
<FontAwesomeIcon
|
||||
icon={faCircle}
|
||||
color="#2ecc71"
|
||||
/>
|
||||
/>
|
||||
<p className="ml-4">Active</p>
|
||||
</div>
|
||||
</Td> */}
|
||||
|
||||
+5
-5
@@ -20,11 +20,11 @@ import {
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useWorkspace } from "@app/context";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useProject } from "@app/context";
|
||||
import { usePopUp, useToggle } from "@app/hooks";
|
||||
import { useGetIntegration } from "@app/hooks/api";
|
||||
import { useDeleteIntegration, useSyncIntegration } from "@app/hooks/api/integrations/queries";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
import { ProjectType } from "@app/hooks/api/projects/types";
|
||||
|
||||
import { IntegrationAuditLogsSection } from "./components/IntegrationAuditLogsSection";
|
||||
import { IntegrationConnectionSection } from "./components/IntegrationConnectionSection";
|
||||
@@ -45,8 +45,8 @@ export const IntegrationDetailsByIDPage = () => {
|
||||
|
||||
const [shouldDeleteSecrets, setShouldDeleteSecrets] = useToggle(false);
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const projectId = currentWorkspace.id;
|
||||
const { currentProject } = useProject();
|
||||
const projectId = currentProject.id;
|
||||
const { mutateAsync: syncIntegration } = useSyncIntegration();
|
||||
const { mutateAsync: deleteIntegration } = useDeleteIntegration();
|
||||
|
||||
@@ -56,7 +56,7 @@ export const IntegrationDetailsByIDPage = () => {
|
||||
try {
|
||||
await deleteIntegration({
|
||||
id: integrationId,
|
||||
workspaceId: currentWorkspace.id,
|
||||
workspaceId: currentProject.id,
|
||||
shouldDeleteIntegrationSecrets
|
||||
});
|
||||
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
import { EmptyState } from "@app/components/v2";
|
||||
import { useSubscription, useWorkspace } from "@app/context";
|
||||
import { useProject, useSubscription } from "@app/context";
|
||||
import { EventType } from "@app/hooks/api/auditLogs/enums";
|
||||
import { TIntegrationWithEnv } from "@app/hooks/api/integrations/types";
|
||||
import { LogsSection } from "@app/pages/organization/AuditLogsPage/components/LogsSection";
|
||||
@@ -15,7 +15,7 @@ type Props = {
|
||||
|
||||
export const IntegrationAuditLogsSection = ({ integration }: Props) => {
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const auditLogsRetentionDays = subscription?.auditLogsRetentionDays ?? 30;
|
||||
|
||||
@@ -31,7 +31,7 @@ export const IntegrationAuditLogsSection = ({ integration }: Props) => {
|
||||
<LogsSection
|
||||
refetchInterval={4000}
|
||||
showFilters={false}
|
||||
project={currentWorkspace}
|
||||
project={currentProject}
|
||||
presets={{
|
||||
eventMetadata: { integrationId: integration.id },
|
||||
startDate: new Date(
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { IntegrationsListPageTabs } from "@app/types/integrations";
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
|
||||
export const IntegrationsListPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { selectedTab } = useSearch({
|
||||
@@ -30,7 +30,7 @@ export const IntegrationsListPage = () => {
|
||||
to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path,
|
||||
search: (prev) => ({ ...prev, selectedTab: tab as IntegrationsListPageTabs }),
|
||||
params: {
|
||||
projectId: currentWorkspace.id
|
||||
projectId: currentProject.id
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
+8
-8
@@ -24,8 +24,8 @@ import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useProjectPermission
|
||||
} from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
@@ -60,7 +60,7 @@ export const CloudIntegrationSection = ({
|
||||
"deleteConfirmation"
|
||||
] as const);
|
||||
const { permission } = useProjectPermission();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isEmpty = !isLoading && !cloudIntegrations?.length;
|
||||
@@ -68,12 +68,12 @@ export const CloudIntegrationSection = ({
|
||||
const sortedCloudIntegrations = useMemo(() => {
|
||||
const sortedIntegrations = cloudIntegrations.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
if (currentWorkspace?.environments.length === 0) {
|
||||
if (currentProject?.environments.length === 0) {
|
||||
return sortedIntegrations.map((integration) => ({ ...integration, isAvailable: false }));
|
||||
}
|
||||
|
||||
return sortedIntegrations;
|
||||
}, [cloudIntegrations, currentWorkspace?.environments]);
|
||||
}, [cloudIntegrations, currentProject?.environments]);
|
||||
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
@@ -83,9 +83,9 @@ export const CloudIntegrationSection = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
{currentWorkspace?.environments.length === 0 && (
|
||||
{currentProject?.environments.length === 0 && (
|
||||
<div className="px-5">
|
||||
<NoEnvironmentsBanner projectId={currentWorkspace.id} />
|
||||
<NoEnvironmentsBanner projectId={currentProject.id} />
|
||||
</div>
|
||||
)}
|
||||
<div className="m-4 mt-0 flex flex-col items-start justify-between px-2 text-xl">
|
||||
@@ -138,7 +138,7 @@ export const CloudIntegrationSection = ({
|
||||
navigate({
|
||||
to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path,
|
||||
params: {
|
||||
projectId: currentWorkspace.id
|
||||
projectId: currentProject.id
|
||||
},
|
||||
search: {
|
||||
selectedTab: IntegrationsListPageTabs.SecretSyncs,
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Badge, IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { TCloudIntegration } from "@app/hooks/api/integrations/types";
|
||||
import { TIntegration } from "@app/hooks/api/types";
|
||||
|
||||
@@ -37,7 +37,7 @@ export const IntegrationRow = ({
|
||||
cloudIntegration
|
||||
}: IProps) => {
|
||||
const navigate = useNavigate();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const { id, secretPath, syncMessage, isSynced } = integration;
|
||||
|
||||
@@ -62,7 +62,7 @@ export const IntegrationRow = ({
|
||||
to: "/projects/secret-management/$projectId/integrations/$integrationId",
|
||||
params: {
|
||||
integrationId: integration.id,
|
||||
projectId: currentWorkspace.id
|
||||
projectId: currentProject.id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@ import { useNavigate } from "@tanstack/react-router";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, Checkbox, DeleteActionModal, Spinner } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { usePopUp, useToggle } from "@app/hooks";
|
||||
import {
|
||||
useDeleteIntegration,
|
||||
@@ -27,8 +27,8 @@ enum IntegrationView {
|
||||
}
|
||||
|
||||
export const NativeIntegrationsTab = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { environments, id: workspaceId } = currentWorkspace;
|
||||
const { currentProject } = useProject();
|
||||
const { environments, id: workspaceId } = currentProject;
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { data: cloudIntegrations, isPending: isCloudIntegrationsLoading } =
|
||||
@@ -91,7 +91,7 @@ export const NativeIntegrationsTab = () => {
|
||||
if (!selectedCloudIntegration) return;
|
||||
|
||||
try {
|
||||
redirectForProviderAuth(currentWorkspace.id, navigate, selectedCloudIntegration);
|
||||
redirectForProviderAuth(currentProject.id, navigate, selectedCloudIntegration);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
+3
-3
@@ -36,7 +36,7 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
@@ -109,7 +109,7 @@ export const SecretSyncsTable = ({ secretSyncs }: Props) => {
|
||||
environmentIds: []
|
||||
});
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const {
|
||||
search,
|
||||
@@ -372,7 +372,7 @@ export const SecretSyncsTable = ({ secretSyncs }: Props) => {
|
||||
<DropdownMenuItem isDisabled>No Secret Syncs Configured</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuLabel>Environment</DropdownMenuLabel>
|
||||
{currentWorkspace.environments.map((env) => (
|
||||
{currentProject.environments.map((env) => (
|
||||
<DropdownMenuItem
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
+45
-7
@@ -1,13 +1,14 @@
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { faArrowUpRightFromSquare, faBookOpen, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { CreateSecretSyncModal } from "@app/components/secret-syncs";
|
||||
import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas";
|
||||
import { Button, Spinner } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useListSecretSyncs } from "@app/hooks/api/secretSyncs";
|
||||
@@ -16,14 +17,15 @@ import { SecretSyncsTable } from "./SecretSyncTable";
|
||||
|
||||
export const SecretSyncsTab = () => {
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["addSync"] as const);
|
||||
const [initialSyncFormData, setInitialSyncFormData] = useState<Partial<TSecretSyncForm>>();
|
||||
|
||||
const { addSync, ...search } = useSearch({
|
||||
const { addSync, connectionId, connectionName, ...search } = useSearch({
|
||||
from: ROUTE_PATHS.SecretManager.IntegrationsListPage.id
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
useEffect(() => {
|
||||
if (!addSync) return;
|
||||
@@ -32,14 +34,46 @@ export const SecretSyncsTab = () => {
|
||||
navigate({
|
||||
to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path,
|
||||
params: {
|
||||
projectId: currentWorkspace.id
|
||||
projectId: currentProject.id
|
||||
},
|
||||
search
|
||||
});
|
||||
}, [addSync]);
|
||||
|
||||
useEffect(() => {
|
||||
if (connectionId && connectionName) {
|
||||
const storedFormData = localStorage.getItem("secretSyncFormData");
|
||||
|
||||
if (!storedFormData) return;
|
||||
|
||||
let form: Partial<TSecretSyncForm> = {};
|
||||
try {
|
||||
form = JSON.parse(storedFormData) as TSecretSyncForm;
|
||||
} catch {
|
||||
return;
|
||||
} finally {
|
||||
localStorage.removeItem("secretSyncFormData");
|
||||
}
|
||||
|
||||
handlePopUpOpen("addSync", form.destination);
|
||||
|
||||
setInitialSyncFormData({
|
||||
...form,
|
||||
connection: { id: connectionId, name: connectionName }
|
||||
});
|
||||
|
||||
navigate({
|
||||
to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path,
|
||||
params: {
|
||||
projectId: currentProject.id
|
||||
},
|
||||
search
|
||||
});
|
||||
}
|
||||
}, [connectionId, connectionName]);
|
||||
|
||||
const { data: secretSyncs = [], isPending: isSecretSyncsPending } = useListSecretSyncs(
|
||||
currentWorkspace.id,
|
||||
currentProject.id,
|
||||
{
|
||||
refetchInterval: 30000
|
||||
}
|
||||
@@ -100,7 +134,11 @@ export const SecretSyncsTab = () => {
|
||||
<CreateSecretSyncModal
|
||||
selectSync={popUp.addSync.data}
|
||||
isOpen={popUp.addSync.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("addSync", isOpen)}
|
||||
initialFormData={initialSyncFormData}
|
||||
onOpenChange={(isOpen) => {
|
||||
if (!isOpen) setInitialSyncFormData(undefined);
|
||||
handlePopUpToggle("addSync", isOpen);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -2,22 +2,24 @@ import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { zodValidator } from "@tanstack/zod-adapter";
|
||||
import { z } from "zod";
|
||||
|
||||
import { workspaceKeys } from "@app/hooks/api";
|
||||
import { projectKeys } from "@app/hooks/api";
|
||||
import { TIntegration } from "@app/hooks/api/integrations/types";
|
||||
import { fetchWorkspaceIntegrations } from "@app/hooks/api/projects/queries";
|
||||
import {
|
||||
fetchSecretSyncsByProjectId,
|
||||
SecretSync,
|
||||
secretSyncKeys,
|
||||
TSecretSync
|
||||
} from "@app/hooks/api/secretSyncs";
|
||||
import { fetchWorkspaceIntegrations } from "@app/hooks/api/workspace/queries";
|
||||
import { IntegrationsListPageTabs } from "@app/types/integrations";
|
||||
|
||||
import { IntegrationsListPage } from "./IntegrationsListPage";
|
||||
|
||||
const IntegrationsListPageQuerySchema = z.object({
|
||||
selectedTab: z.nativeEnum(IntegrationsListPageTabs).optional(),
|
||||
addSync: z.nativeEnum(SecretSync).optional()
|
||||
addSync: z.nativeEnum(SecretSync).optional(),
|
||||
connectionId: z.string().optional(),
|
||||
connectionName: z.string().optional()
|
||||
});
|
||||
|
||||
export const Route = createFileRoute(
|
||||
@@ -57,7 +59,7 @@ export const Route = createFileRoute(
|
||||
let integrations: TIntegration[];
|
||||
try {
|
||||
integrations = await context.queryClient.ensureQueryData({
|
||||
queryKey: workspaceKeys.getWorkspaceIntegrations(projectId),
|
||||
queryKey: projectKeys.getProjectIntegrations(projectId),
|
||||
queryFn: () => fetchWorkspaceIntegrations(projectId)
|
||||
});
|
||||
} catch {
|
||||
|
||||
@@ -63,9 +63,9 @@ import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionDynamicSecretActions,
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionSecretRotationActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import {
|
||||
@@ -92,16 +92,11 @@ import {
|
||||
import { useGetProjectSecretsOverview } from "@app/hooks/api/dashboard/queries";
|
||||
import { DashboardSecretsOrderBy, ProjectSecretsImportedBy } from "@app/hooks/api/dashboard/types";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { ProjectVersion } from "@app/hooks/api/projects/types";
|
||||
import { useUpdateFolderBatch } from "@app/hooks/api/secretFolders/queries";
|
||||
import { TUpdateFolderBatchDTO } from "@app/hooks/api/secretFolders/types";
|
||||
import { TSecretRotationV2 } from "@app/hooks/api/secretRotationsV2";
|
||||
import {
|
||||
SecretType,
|
||||
SecretV3RawSanitized,
|
||||
TSecretFolder,
|
||||
WorkspaceEnv
|
||||
} from "@app/hooks/api/types";
|
||||
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
||||
import { ProjectEnv, SecretType, SecretV3RawSanitized, TSecretFolder } from "@app/hooks/api/types";
|
||||
import {
|
||||
useDynamicSecretOverview,
|
||||
useFolderOverview,
|
||||
@@ -173,10 +168,9 @@ export const OverviewPage = () => {
|
||||
const [debouncedScrollOffset] = useDebounce(scrollOffset);
|
||||
const { permission } = useProjectPermission();
|
||||
const tableRef = useRef<HTMLDivElement>(null);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const isProjectV3 = currentWorkspace?.version === ProjectVersion.V3;
|
||||
const workspaceId = currentWorkspace?.id as string;
|
||||
const projectSlug = currentWorkspace?.slug as string;
|
||||
const { currentProject, projectId } = useProject();
|
||||
const isProjectV3 = currentProject?.version === ProjectVersion.V3;
|
||||
const projectSlug = currentProject?.slug as string;
|
||||
const [searchFilter, setSearchFilter] = useState("");
|
||||
const [debouncedSearchFilter, setDebouncedSearchFilter] = useDebounce(searchFilter);
|
||||
const secretPath = (routerSearch?.secretPath as string) || "/";
|
||||
@@ -246,7 +240,7 @@ export const OverviewPage = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const userAvailableEnvs = currentWorkspace?.environments || [];
|
||||
const userAvailableEnvs = currentProject?.environments || [];
|
||||
const userAvailableDynamicSecretEnvs = userAvailableEnvs.filter((env) =>
|
||||
permission.can(
|
||||
ProjectPermissionDynamicSecretActions.CreateRootCredential,
|
||||
@@ -267,7 +261,7 @@ export const OverviewPage = () => {
|
||||
)
|
||||
);
|
||||
|
||||
const [filteredEnvs, setFilteredEnvs] = useState<WorkspaceEnv[]>([]);
|
||||
const [filteredEnvs, setFilteredEnvs] = useState<ProjectEnv[]>([]);
|
||||
const visibleEnvs = filteredEnvs.length ? filteredEnvs : userAvailableEnvs;
|
||||
|
||||
const {
|
||||
@@ -276,7 +270,7 @@ export const OverviewPage = () => {
|
||||
getImportedSecretByKey,
|
||||
getEnvImportedSecretKeyCount
|
||||
} = useGetImportedSecretsAllEnvs({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
path: secretPath,
|
||||
environments: (userAvailableEnvs || []).map(({ slug }) => slug)
|
||||
});
|
||||
@@ -284,7 +278,7 @@ export const OverviewPage = () => {
|
||||
const isFilteredByResources = Object.values(filter).some(Boolean);
|
||||
const { isPending: isOverviewLoading, data: overview } = useGetProjectSecretsOverview(
|
||||
{
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environments: visibleEnvs.map((env) => env.slug),
|
||||
secretPath,
|
||||
orderDirection,
|
||||
@@ -368,7 +362,7 @@ export const OverviewPage = () => {
|
||||
);
|
||||
|
||||
const { data: tags } = useGetWsTags(
|
||||
permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags) ? workspaceId : ""
|
||||
permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags) ? projectId : ""
|
||||
);
|
||||
|
||||
const { mutateAsync: createSecretV3 } = useCreateSecretV3();
|
||||
@@ -398,7 +392,7 @@ export const OverviewPage = () => {
|
||||
name: folderName,
|
||||
path: secretPath,
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
description
|
||||
});
|
||||
});
|
||||
@@ -456,9 +450,8 @@ export const OverviewPage = () => {
|
||||
|
||||
try {
|
||||
await updateFolderBatch({
|
||||
projectSlug,
|
||||
folders: updatedFolders,
|
||||
projectId: workspaceId
|
||||
projectId
|
||||
});
|
||||
createNotification({
|
||||
type: "success",
|
||||
@@ -491,7 +484,7 @@ export const OverviewPage = () => {
|
||||
);
|
||||
if (folderName && parentPath && canCreateFolder) {
|
||||
await createFolder({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
path: parentPath,
|
||||
environment: env,
|
||||
name: folderName
|
||||
@@ -500,7 +493,7 @@ export const OverviewPage = () => {
|
||||
}
|
||||
const result = await createSecretV3({
|
||||
environment: env,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
secretValue: value,
|
||||
@@ -555,7 +548,7 @@ export const OverviewPage = () => {
|
||||
try {
|
||||
const result = await updateSecretV3({
|
||||
environment: env,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
secretValue,
|
||||
@@ -586,7 +579,7 @@ export const OverviewPage = () => {
|
||||
try {
|
||||
const result = await deleteSecretV3({
|
||||
environment: env,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
secretId,
|
||||
@@ -655,7 +648,7 @@ export const OverviewPage = () => {
|
||||
);
|
||||
if (folderName && parentPath && canCreateFolder) {
|
||||
await createFolder({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environment: slug,
|
||||
path: parentPath,
|
||||
name: folderName
|
||||
@@ -669,7 +662,7 @@ export const OverviewPage = () => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/secrets/$envSlug",
|
||||
params: {
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
envSlug: slug
|
||||
},
|
||||
search: query
|
||||
@@ -1099,7 +1092,7 @@ export const OverviewPage = () => {
|
||||
tags={tags}
|
||||
onChange={setSearchFilter}
|
||||
environments={userAvailableEnvs}
|
||||
projectId={currentWorkspace?.id}
|
||||
projectId={currentProject?.id}
|
||||
/>
|
||||
{userAvailableEnvs.length > 0 && (
|
||||
<div>
|
||||
@@ -1419,7 +1412,7 @@ export const OverviewPage = () => {
|
||||
<Link
|
||||
to="/projects/secret-management/$projectId/settings"
|
||||
params={{
|
||||
projectId: workspaceId
|
||||
projectId
|
||||
}}
|
||||
hash="environments"
|
||||
>
|
||||
|
||||
+10
-11
@@ -19,8 +19,8 @@ import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useProjectPermission
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { getKeyValue } from "@app/helpers/parseEnvVar";
|
||||
@@ -57,16 +57,15 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
formState: { isSubmitting, errors }
|
||||
} = useForm<TFormSchema>({ resolver: zodResolver(typeSchema) });
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject, projectId } = useProject();
|
||||
const { permission } = useProjectPermission();
|
||||
const canReadTags = permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags);
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const environments = currentWorkspace?.environments || [];
|
||||
const environments = currentProject?.environments || [];
|
||||
|
||||
const { mutateAsync: createSecretV3 } = useCreateSecretV3();
|
||||
const { mutateAsync: createFolder } = useCreateFolder();
|
||||
const { data: projectTags, isPending: isTagsLoading } = useGetWsTags(
|
||||
canReadTags ? workspaceId : ""
|
||||
canReadTags ? projectId : ""
|
||||
);
|
||||
|
||||
const secretKeyInputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -93,7 +92,7 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
|
||||
if (folderName && parentPath && canCreateFolder) {
|
||||
await createFolder({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
path: parentPath,
|
||||
environment,
|
||||
name: folderName
|
||||
@@ -106,7 +105,7 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
return {
|
||||
...(await createSecretV3({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
secretValue: value || "",
|
||||
@@ -176,7 +175,7 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
|
||||
if (!secretKey || isWholeKeyHighlighted) {
|
||||
e.preventDefault();
|
||||
const keyStr = currentWorkspace.autoCapitalization ? key.toUpperCase() : key;
|
||||
const keyStr = currentProject.autoCapitalization ? key.toUpperCase() : key;
|
||||
setValue("key", keyStr);
|
||||
if (value) {
|
||||
setValue("value", value);
|
||||
@@ -191,7 +190,7 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
try {
|
||||
const parsedSlug = slugSchema.parse(slug);
|
||||
await createWsTag.mutateAsync({
|
||||
workspaceID: workspaceId,
|
||||
projectId,
|
||||
tagSlug: parsedSlug,
|
||||
tagColor: ""
|
||||
});
|
||||
@@ -220,7 +219,7 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
}}
|
||||
placeholder="Type your secret name"
|
||||
onPaste={handlePaste}
|
||||
autoCapitalization={currentWorkspace?.autoCapitalization}
|
||||
autoCapitalization={currentProject?.autoCapitalization}
|
||||
/>
|
||||
</FormControl>
|
||||
<Controller
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import {
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { getExpandedRowStyle } from "@app/pages/secret-manager/OverviewPage/components/utils";
|
||||
import { HIDDEN_SECRET_VALUE } from "@app/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem";
|
||||
|
||||
@@ -50,7 +50,7 @@ type Props = {
|
||||
getImportedSecretByKey: (
|
||||
env: string,
|
||||
secretName: string
|
||||
) => { secret?: SecretV3RawSanitized; environmentInfo?: WorkspaceEnv } | undefined;
|
||||
) => { secret?: SecretV3RawSanitized; environmentInfo?: ProjectEnv } | undefined;
|
||||
scrollOffset: number;
|
||||
importedBy?: {
|
||||
environment: { name: string; slug: string };
|
||||
|
||||
+4
-5
@@ -10,7 +10,7 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { IconButton, Input, Spinner, Tooltip } from "@app/components/v2";
|
||||
import { ProjectPermissionSub, useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionSub, useProject, useProjectPermission } from "@app/context";
|
||||
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { useUpdateSecretV3 } from "@app/hooks/api";
|
||||
@@ -37,7 +37,7 @@ export const formSchema = z.object({
|
||||
type TFormSchema = z.infer<typeof formSchema>;
|
||||
|
||||
function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }: Props) {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject, projectId } = useProject();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const secrets = environments.map((env) => getSecretByKey(env.slug, secretKey));
|
||||
@@ -68,7 +68,6 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }
|
||||
secret?.overrideAction === SecretActionType.Created ||
|
||||
secret?.overrideAction === SecretActionType.Modified
|
||||
);
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
|
||||
const [isSecNameCopied, setIsSecNameCopied] = useToggle(false);
|
||||
|
||||
@@ -111,7 +110,7 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }
|
||||
|
||||
return updateSecretV3({
|
||||
environment: secret?.env,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: secret.key,
|
||||
secretValue: secret.value || "",
|
||||
@@ -163,7 +162,7 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }
|
||||
<Input
|
||||
autoComplete="off"
|
||||
isReadOnly={isReadOnly || secrets.filter(Boolean).length === 0}
|
||||
autoCapitalization={currentWorkspace?.autoCapitalization}
|
||||
autoCapitalization={currentProject?.autoCapitalization}
|
||||
variant="plain"
|
||||
isDisabled={isOverriden}
|
||||
placeholder={error?.message}
|
||||
|
||||
+2
-2
@@ -33,8 +33,8 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useDebounce } from "@app/hooks";
|
||||
import { useGetProjectSecretsQuickSearch } from "@app/hooks/api/dashboard";
|
||||
import { ProjectEnv } from "@app/hooks/api/projects/types";
|
||||
import { WsTag } from "@app/hooks/api/tags/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/workspace/types";
|
||||
import { QuickSearchSecretRotationItem } from "@app/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretRotationItem";
|
||||
import { RowType } from "@app/pages/secret-manager/SecretDashboardPage/SecretMainPage.types";
|
||||
|
||||
@@ -43,7 +43,7 @@ import { QuickSearchFolderItem } from "./QuickSearchFolderItem";
|
||||
import { QuickSearchSecretItem } from "./QuickSearchSecretItem";
|
||||
|
||||
export type QuickSearchModalProps = {
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
projectId: string;
|
||||
tags?: WsTag[];
|
||||
isSingleEnv?: boolean;
|
||||
|
||||
+2
-2
@@ -28,10 +28,10 @@ import {
|
||||
import { reverseTruncate } from "@app/helpers/reverseTruncate";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import { TDashboardProjectSecretsQuickSearch } from "@app/hooks/api/dashboard/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/workspace/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/projects/types";
|
||||
|
||||
type Props = {
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
secretGroup: TDashboardProjectSecretsQuickSearch["secrets"][string];
|
||||
onClose: () => void;
|
||||
isSingleEnv?: boolean;
|
||||
|
||||
+9
-9
@@ -8,11 +8,11 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, Checkbox, Modal, ModalContent, Spinner } from "@app/components/v2";
|
||||
import { useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { useProject, useProjectPermission } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useGetWorkspaceById, useMigrateProjectToV3, workspaceKeys } from "@app/hooks/api";
|
||||
import { projectKeys, useGetWorkspaceById, useMigrateProjectToV3 } from "@app/hooks/api";
|
||||
import { ProjectVersion } from "@app/hooks/api/projects/types";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
||||
|
||||
enum ProjectUpgradeStatus {
|
||||
InProgress = "IN_PROGRESS",
|
||||
@@ -28,14 +28,14 @@ const formSchema = z.object({
|
||||
|
||||
export const SecretV2MigrationSection = () => {
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["migrationInfo"] as const);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const queryClient = useQueryClient();
|
||||
const { data: workspaceDetails, refetch } = useGetWorkspaceById(
|
||||
// if v3 no need to fetch
|
||||
currentWorkspace?.version === ProjectVersion.V3 ? "" : currentWorkspace?.id || "",
|
||||
currentProject?.version === ProjectVersion.V3 ? "" : currentProject?.id || "",
|
||||
{
|
||||
refetchInterval:
|
||||
currentWorkspace?.upgradeStatus === ProjectUpgradeStatus.InProgress ? 2000 : false
|
||||
currentProject?.upgradeStatus === ProjectUpgradeStatus.InProgress ? 2000 : false
|
||||
}
|
||||
);
|
||||
const { membership } = useProjectPermission();
|
||||
@@ -54,12 +54,12 @@ export const SecretV2MigrationSection = () => {
|
||||
createNotification({ type: "success", text: "Project upgrade completed successfully" });
|
||||
migrateProjectToV3.reset();
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: workspaceKeys.getAllUserWorkspace()
|
||||
queryKey: projectKeys.getAllUserProjects()
|
||||
});
|
||||
}
|
||||
}, [isProjectUpgraded, Boolean(migrateProjectToV3.data)]);
|
||||
|
||||
if (isProjectUpgraded || currentWorkspace?.version === ProjectVersion.V3) return null;
|
||||
if (isProjectUpgraded || currentProject?.version === ProjectVersion.V3) return null;
|
||||
|
||||
const isUpgrading = workspaceDetails?.upgradeStatus === ProjectUpgradeStatus.InProgress;
|
||||
const didProjectUpgradeFailed = workspaceDetails?.upgradeStatus === ProjectUpgradeStatus.Failed;
|
||||
@@ -67,7 +67,7 @@ export const SecretV2MigrationSection = () => {
|
||||
const handleMigrationSecretV2 = async () => {
|
||||
try {
|
||||
handlePopUpToggle("migrationInfo");
|
||||
await migrateProjectToV3.mutateAsync({ workspaceId: currentWorkspace?.id || "" });
|
||||
await migrateProjectToV3.mutateAsync({ projectId: currentProject?.id || "" });
|
||||
refetch();
|
||||
createNotification({
|
||||
text: "Project upgrade started",
|
||||
|
||||
+8
-9
@@ -9,9 +9,9 @@ import { Button, DeleteActionModal, Tooltip } from "@app/components/v2";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
@@ -66,9 +66,8 @@ export const SelectionPanel = ({
|
||||
);
|
||||
const selectedCount = selectedFolderCount + selectedKeysCount;
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const userAvailableEnvs = currentWorkspace?.environments || [];
|
||||
const { currentProject, projectId } = useProject();
|
||||
const userAvailableEnvs = currentProject?.environments || [];
|
||||
const { mutateAsync: deleteBatchSecretV3 } = useDeleteSecretBatch();
|
||||
const { mutateAsync: deleteFolder } = useDeleteFolder();
|
||||
|
||||
@@ -134,7 +133,7 @@ export const SelectionPanel = ({
|
||||
folderId: folder?.id,
|
||||
path: secretPath,
|
||||
environment: env.slug,
|
||||
projectId: workspaceId
|
||||
projectId
|
||||
});
|
||||
}
|
||||
})
|
||||
@@ -173,7 +172,7 @@ export const SelectionPanel = ({
|
||||
processedEntries += secretsToDelete.length;
|
||||
await deleteBatchSecretV3({
|
||||
secretPath,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment: env.slug,
|
||||
secrets: secretsToDelete
|
||||
});
|
||||
@@ -281,8 +280,8 @@ export const SelectionPanel = ({
|
||||
isOpen={popUp.bulkMoveSecrets.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("bulkMoveSecrets", isOpen)}
|
||||
environments={userAvailableEnvs}
|
||||
projectId={workspaceId}
|
||||
projectSlug={currentWorkspace.slug}
|
||||
projectId={projectId}
|
||||
projectSlug={currentProject.slug}
|
||||
sourceSecretPath={secretPath}
|
||||
secrets={selectedEntries[EntryType.SECRET]}
|
||||
onComplete={resetSelectedEntries}
|
||||
|
||||
+2
-4
@@ -30,13 +30,13 @@ import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionCo
|
||||
import { useDebounce } from "@app/hooks";
|
||||
import { useMoveSecrets } from "@app/hooks/api";
|
||||
import { useGetProjectSecretsQuickSearch } from "@app/hooks/api/dashboard";
|
||||
import { ProjectEnv } from "@app/hooks/api/projects/types";
|
||||
import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/workspace/types";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
onOpenChange: (isOpen: boolean) => void;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
projectId: string;
|
||||
projectSlug: string;
|
||||
sourceSecretPath: string;
|
||||
@@ -64,7 +64,6 @@ type MoveResults = {
|
||||
const Content = ({
|
||||
onComplete,
|
||||
secrets,
|
||||
projectSlug,
|
||||
environments,
|
||||
projectId,
|
||||
sourceSecretPath
|
||||
@@ -189,7 +188,6 @@ const Content = ({
|
||||
|
||||
try {
|
||||
const { isDestinationUpdated, isSourceUpdated } = await moveSecrets.mutateAsync({
|
||||
projectSlug,
|
||||
shouldOverwrite,
|
||||
sourceEnvironment: environment.slug,
|
||||
sourceSecretPath,
|
||||
|
||||
@@ -6,7 +6,9 @@ import { OverviewPage } from "./OverviewPage";
|
||||
|
||||
const SecretOverviewPageQuerySchema = z.object({
|
||||
search: z.string().catch(""),
|
||||
secretPath: z.string().catch("/")
|
||||
secretPath: z.string().catch("/"),
|
||||
connectionId: z.string().optional(),
|
||||
connectionName: z.string().optional()
|
||||
});
|
||||
|
||||
export const Route = createFileRoute(
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useGetAccessRequestsCount, useGetSecretApprovalRequestCount } from "@app/hooks/api";
|
||||
|
||||
import { AccessApprovalRequest } from "./components/AccessApprovalRequest";
|
||||
@@ -20,11 +20,10 @@ enum TabSection {
|
||||
|
||||
export const SecretApprovalsPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const projectId = currentWorkspace?.id || "";
|
||||
const projectSlug = currentWorkspace?.slug || "";
|
||||
const { currentProject, projectId } = useProject();
|
||||
const projectSlug = currentProject?.slug || "";
|
||||
const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({
|
||||
workspaceId: projectId
|
||||
projectId
|
||||
});
|
||||
const { data: accessApprovalRequestCount } = useGetAccessRequestsCount({ projectSlug });
|
||||
const defaultTab =
|
||||
@@ -67,7 +66,7 @@ export const SecretApprovalsPage = () => {
|
||||
<AccessApprovalRequest projectId={projectId} projectSlug={projectSlug} />
|
||||
</TabPanel>
|
||||
<TabPanel value={TabSection.Policies}>
|
||||
<ApprovalPolicyList workspaceId={projectId} />
|
||||
<ApprovalPolicyList projectId={projectId} />
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
+5
-5
@@ -39,10 +39,10 @@ import { Badge } from "@app/components/v2/Badge";
|
||||
import {
|
||||
ProjectPermissionMemberActions,
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useUser,
|
||||
useWorkspace
|
||||
useUser
|
||||
} from "@app/context";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
@@ -93,7 +93,7 @@ export const AccessApprovalRequest = ({
|
||||
}) => {
|
||||
const [selectedRequest, setSelectedRequest] = useState<
|
||||
| (TAccessApprovalRequest & {
|
||||
user: { firstName?: string; lastName?: string; email?: string } | null;
|
||||
user: { firstName?: string | null; lastName?: string | null; email?: string | null } | null;
|
||||
isRequestedByCurrentUser: boolean;
|
||||
isSelfApproveAllowed: boolean;
|
||||
isApprover: boolean;
|
||||
@@ -110,7 +110,7 @@ export const AccessApprovalRequest = ({
|
||||
const { permission } = useProjectPermission();
|
||||
const { user } = useUser();
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const { data: members } = useGetWorkspaceUsers(projectId, true);
|
||||
const membersGroupById = members?.reduce<Record<string, TWorkspaceUser>>(
|
||||
@@ -410,7 +410,7 @@ export const AccessApprovalRequest = ({
|
||||
<DropdownMenuLabel className="sticky top-0 bg-mineshaft-900">
|
||||
Select an Environment
|
||||
</DropdownMenuLabel>
|
||||
{currentWorkspace?.environments.map(({ slug, name }) => (
|
||||
{currentProject?.environments.map(({ slug, name }) => (
|
||||
<DropdownMenuItem
|
||||
onClick={() => setEnvFilter((state) => (state === slug ? undefined : slug))}
|
||||
key={`request-filter-${slug}`}
|
||||
|
||||
+4
-4
@@ -25,7 +25,7 @@ import {
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { Badge } from "@app/components/v2/Badge";
|
||||
import { ProjectPermissionActions, useUser, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionActions, useProject, useUser } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useListWorkspaceGroups, useReviewAccessRequest } from "@app/hooks/api";
|
||||
import {
|
||||
@@ -85,7 +85,7 @@ export const ReviewAccessRequestModal = ({
|
||||
isOpen: boolean;
|
||||
onOpenChange: (isOpen: boolean) => void;
|
||||
request: TAccessApprovalRequest & {
|
||||
user: { firstName?: string; lastName?: string; email?: string } | null;
|
||||
user: { firstName?: string | null; lastName?: string | null; email?: string | null } | null;
|
||||
isRequestedByCurrentUser: boolean;
|
||||
isSelfApproveAllowed: boolean;
|
||||
isApprover: boolean;
|
||||
@@ -102,8 +102,8 @@ export const ReviewAccessRequestModal = ({
|
||||
const [bypassApproval, setBypassApproval] = useState(false);
|
||||
|
||||
const [bypassReason, setBypassReason] = useState("");
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: groupMemberships = [] } = useListWorkspaceGroups(currentWorkspace?.id || "");
|
||||
const { currentProject } = useProject();
|
||||
const { data: groupMemberships = [] } = useListWorkspaceGroups(currentProject?.id || "");
|
||||
const { user } = useUser();
|
||||
|
||||
const { popUp, handlePopUpToggle, handlePopUpOpen } = usePopUp(["editRequest"] as const);
|
||||
|
||||
+18
-18
@@ -40,9 +40,9 @@ import {
|
||||
import {
|
||||
ProjectPermissionSub,
|
||||
TProjectPermission,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import {
|
||||
@@ -59,14 +59,14 @@ import {
|
||||
import { useGetAccessApprovalPolicies } from "@app/hooks/api/accessApproval/queries";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { PolicyType } from "@app/hooks/api/policies/enums";
|
||||
import { TAccessApprovalPolicy, Workspace } from "@app/hooks/api/types";
|
||||
import { Project, TAccessApprovalPolicy } from "@app/hooks/api/types";
|
||||
|
||||
import { AccessPolicyForm } from "./components/AccessPolicyModal";
|
||||
import { ApprovalPolicyRow } from "./components/ApprovalPolicyRow";
|
||||
import { RemoveApprovalPolicyModal } from "./components/RemoveApprovalPolicyModal";
|
||||
|
||||
interface IProps {
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
enum PolicyOrderBy {
|
||||
@@ -81,24 +81,24 @@ type PolicyFilters = {
|
||||
environmentIds: string[];
|
||||
};
|
||||
|
||||
const useApprovalPolicies = (permission: TProjectPermission, currentWorkspace?: Workspace) => {
|
||||
const useApprovalPolicies = (permission: TProjectPermission, currentProject?: Project) => {
|
||||
const { data: accessPolicies, isPending: isAccessPoliciesLoading } = useGetAccessApprovalPolicies(
|
||||
{
|
||||
projectSlug: currentWorkspace?.slug as string,
|
||||
projectSlug: currentProject?.slug as string,
|
||||
options: {
|
||||
enabled:
|
||||
permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval) &&
|
||||
!!currentWorkspace?.slug
|
||||
!!currentProject?.slug
|
||||
}
|
||||
}
|
||||
);
|
||||
const { data: secretPolicies, isPending: isSecretPoliciesLoading } = useGetSecretApprovalPolicies(
|
||||
{
|
||||
workspaceId: currentWorkspace?.id as string,
|
||||
projectId: currentProject?.id as string,
|
||||
options: {
|
||||
enabled:
|
||||
permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval) &&
|
||||
!!currentWorkspace?.id
|
||||
!!currentProject?.id
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -118,7 +118,7 @@ const useApprovalPolicies = (permission: TProjectPermission, currentWorkspace?:
|
||||
};
|
||||
};
|
||||
|
||||
export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
|
||||
export const ApprovalPolicyList = ({ projectId }: IProps) => {
|
||||
const { handlePopUpToggle, handlePopUpOpen, popUp } = usePopUp([
|
||||
"policyForm",
|
||||
"deletePolicy",
|
||||
@@ -126,14 +126,14 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
|
||||
] as const);
|
||||
const { permission } = useProjectPermission();
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const { data: members } = useGetWorkspaceUsers(workspaceId, true);
|
||||
const { data: groups } = useListWorkspaceGroups(currentWorkspace?.id || "");
|
||||
const { data: members } = useGetWorkspaceUsers(projectId, true);
|
||||
const { data: groups } = useListWorkspaceGroups(currentProject?.id || "");
|
||||
|
||||
const { policies, isLoading: isPoliciesLoading } = useApprovalPolicies(
|
||||
permission,
|
||||
currentWorkspace
|
||||
currentProject
|
||||
);
|
||||
|
||||
const [filters, setFilters] = useState<PolicyFilters>({
|
||||
@@ -367,7 +367,7 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
|
||||
Change Policy
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuLabel>Environment</DropdownMenuLabel>
|
||||
{currentWorkspace.environments.map((env) => (
|
||||
{currentProject.environments.map((env) => (
|
||||
<DropdownMenuItem
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
@@ -466,7 +466,7 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{!!currentWorkspace &&
|
||||
{!!currentProject &&
|
||||
filteredPolicies
|
||||
?.slice(offset, perPage * page)
|
||||
.map((policy) => (
|
||||
@@ -497,8 +497,8 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
|
||||
</div>
|
||||
</motion.div>
|
||||
<AccessPolicyForm
|
||||
projectId={currentWorkspace.id}
|
||||
projectSlug={currentWorkspace.slug}
|
||||
projectId={currentProject.id}
|
||||
projectSlug={currentProject.slug}
|
||||
isOpen={popUp.policyForm.isOpen}
|
||||
onToggle={(isOpen) => handlePopUpToggle("policyForm", isOpen)}
|
||||
members={members}
|
||||
|
||||
+5
-5
@@ -22,7 +22,7 @@ import {
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { getMemberLabel } from "@app/helpers/members";
|
||||
import { policyDetails } from "@app/helpers/policies";
|
||||
import {
|
||||
@@ -207,10 +207,10 @@ const Form = ({
|
||||
name: "sequenceApprovers"
|
||||
});
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { data: groups } = useListWorkspaceGroups(projectId);
|
||||
|
||||
const availableEnvironments = currentWorkspace?.environments || [];
|
||||
const availableEnvironments = currentProject?.environments || [];
|
||||
const isAccessPolicyType = watch("policyType") === PolicyType.AccessPolicy;
|
||||
|
||||
const { mutateAsync: createAccessApprovalPolicy } = useCreateAccessApprovalPolicy();
|
||||
@@ -246,7 +246,7 @@ const Form = ({
|
||||
approvers: [...userApprovers, ...groupApprovers],
|
||||
bypassers: bypassers.length > 0 ? bypassers : undefined,
|
||||
environments: environments.map((env) => env.slug),
|
||||
workspaceId: currentWorkspace?.id || ""
|
||||
projectId: currentProject?.id || ""
|
||||
});
|
||||
} else {
|
||||
await createAccessApprovalPolicy({
|
||||
@@ -302,7 +302,7 @@ const Form = ({
|
||||
...data,
|
||||
approvers: [...userApprovers, ...groupApprovers],
|
||||
bypassers: bypassers.length > 0 ? bypassers : undefined,
|
||||
workspaceId: currentWorkspace?.id || "",
|
||||
projectId: currentProject?.id || "",
|
||||
environments: environments.map((env) => env.slug)
|
||||
});
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -33,13 +33,13 @@ import { Approver } from "@app/hooks/api/accessApproval/types";
|
||||
import { TGroupMembership } from "@app/hooks/api/groups/types";
|
||||
import { EnforcementLevel, PolicyType } from "@app/hooks/api/policies/enums";
|
||||
import { ApproverType } from "@app/hooks/api/secretApproval/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { TWorkspaceUser } from "@app/hooks/api/users/types";
|
||||
|
||||
interface IPolicy {
|
||||
id: string;
|
||||
name: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
projectId?: string;
|
||||
secretPath?: string;
|
||||
approvals: number;
|
||||
|
||||
+6
-6
@@ -4,7 +4,7 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { DeleteActionModal, Spinner } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import {
|
||||
useDeleteAccessApprovalPolicy,
|
||||
useDeleteSecretApprovalPolicy,
|
||||
@@ -29,18 +29,18 @@ export const RemoveApprovalPolicyModal = ({
|
||||
const { mutateAsync: deleteSecretApprovalPolicy } = useDeleteSecretApprovalPolicy();
|
||||
const { mutateAsync: deleteAccessApprovalPolicy } = useDeleteAccessApprovalPolicy();
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const handleDeletePolicy = async () => {
|
||||
try {
|
||||
if (policyType === PolicyType.ChangePolicy) {
|
||||
await deleteSecretApprovalPolicy({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
id: policyId
|
||||
});
|
||||
} else {
|
||||
await deleteAccessApprovalPolicy({
|
||||
projectSlug: currentWorkspace.slug,
|
||||
projectSlug: currentProject.slug,
|
||||
id: policyId
|
||||
});
|
||||
}
|
||||
@@ -59,14 +59,14 @@ export const RemoveApprovalPolicyModal = ({
|
||||
|
||||
const deleteSecretApprovalData = useGetSecretApprovalRequestCount({
|
||||
policyId,
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
options: {
|
||||
enabled: Boolean(policyId) && policyType === PolicyType.ChangePolicy
|
||||
}
|
||||
});
|
||||
|
||||
const deleteAccessApprovalData = useGetAccessRequestsCount({
|
||||
projectSlug: currentWorkspace.slug,
|
||||
projectSlug: currentProject.slug,
|
||||
policyId,
|
||||
options: {
|
||||
enabled: Boolean(policyId) && policyType === PolicyType.AccessPolicy
|
||||
|
||||
+7
-9
@@ -35,9 +35,9 @@ import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import {
|
||||
ProjectPermissionMemberActions,
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useUser,
|
||||
useWorkspace
|
||||
useUser
|
||||
} from "@app/context";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
@@ -58,8 +58,7 @@ import {
|
||||
} from "./components/SecretApprovalRequestChanges";
|
||||
|
||||
export const SecretApprovalRequest = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const { currentProject, projectId } = useProject();
|
||||
const [selectedApprovalId, setSelectedApprovalId] = useState<string | null>(null);
|
||||
|
||||
// filters
|
||||
@@ -92,7 +91,7 @@ export const SecretApprovalRequest = () => {
|
||||
isPending: isApprovalRequestLoading,
|
||||
refetch
|
||||
} = useGetSecretApprovalRequests({
|
||||
workspaceId,
|
||||
projectId,
|
||||
status: statusFilter,
|
||||
environment: envFilter,
|
||||
committer: committerFilter,
|
||||
@@ -105,14 +104,14 @@ export const SecretApprovalRequest = () => {
|
||||
const secretApprovalRequests = data?.approvals ?? [];
|
||||
|
||||
const { data: secretApprovalRequestCount, isSuccess: isSecretApprovalReqCountSuccess } =
|
||||
useGetSecretApprovalRequestCount({ workspaceId });
|
||||
useGetSecretApprovalRequestCount({ projectId });
|
||||
const { user: userSession } = useUser();
|
||||
const search = useSearch({
|
||||
from: ROUTE_PATHS.SecretManager.ApprovalPage.id
|
||||
});
|
||||
|
||||
const { permission } = useProjectPermission();
|
||||
const { data: members } = useGetWorkspaceUsers(workspaceId);
|
||||
const { data: members } = useGetWorkspaceUsers(projectId);
|
||||
const isSecretApprovalScreen = Boolean(selectedApprovalId);
|
||||
const { requestId } = search;
|
||||
|
||||
@@ -143,7 +142,6 @@ export const SecretApprovalRequest = () => {
|
||||
exit={{ opacity: 0, translateX: 30 }}
|
||||
>
|
||||
<SecretApprovalRequestChanges
|
||||
workspaceId={workspaceId}
|
||||
approvalRequestId={selectedApprovalId || ""}
|
||||
onGoBack={handleGoBackSecretRequestDetail}
|
||||
/>
|
||||
@@ -241,7 +239,7 @@ export const SecretApprovalRequest = () => {
|
||||
<DropdownMenuLabel className="sticky top-0 bg-mineshaft-900">
|
||||
Select an Environment
|
||||
</DropdownMenuLabel>
|
||||
{currentWorkspace?.environments.map(({ slug, name }) => (
|
||||
{currentProject?.environments.map(({ slug, name }) => (
|
||||
<DropdownMenuItem
|
||||
onClick={() => setEnvFilter((state) => (state === slug ? undefined : slug))}
|
||||
key={`request-filter-${slug}`}
|
||||
|
||||
+4
-4
@@ -13,6 +13,7 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, Checkbox, FormControl, Input } from "@app/components/v2";
|
||||
import { useProject } from "@app/context";
|
||||
import {
|
||||
usePerformSecretApprovalRequestMerge,
|
||||
useUpdateSecretApprovalRequestStatus
|
||||
@@ -28,7 +29,6 @@ type Props = {
|
||||
canApprove?: boolean;
|
||||
isBypasser: boolean;
|
||||
statusChangeByEmail?: string;
|
||||
workspaceId: string;
|
||||
enforcementLevel: EnforcementLevel;
|
||||
};
|
||||
|
||||
@@ -39,11 +39,11 @@ export const SecretApprovalRequestAction = ({
|
||||
isMergable,
|
||||
approvals,
|
||||
statusChangeByEmail,
|
||||
workspaceId,
|
||||
enforcementLevel,
|
||||
canApprove,
|
||||
isBypasser
|
||||
}: Props) => {
|
||||
const { projectId } = useProject();
|
||||
const { mutateAsync: performSecretApprovalMerge, isPending: isMerging } =
|
||||
usePerformSecretApprovalRequestMerge();
|
||||
|
||||
@@ -62,7 +62,7 @@ export const SecretApprovalRequestAction = ({
|
||||
try {
|
||||
await performSecretApprovalMerge({
|
||||
id: approvalRequestId,
|
||||
workspaceId,
|
||||
projectId,
|
||||
bypassReason: byPassApproval ? bypassReason : undefined
|
||||
});
|
||||
createNotification({
|
||||
@@ -83,7 +83,7 @@ export const SecretApprovalRequestAction = ({
|
||||
await updateSecretStatusChange({
|
||||
id: approvalRequestId,
|
||||
status: reqState,
|
||||
workspaceId
|
||||
projectId
|
||||
});
|
||||
createNotification({
|
||||
type: "success",
|
||||
|
||||
+4
-10
@@ -33,7 +33,7 @@ import {
|
||||
TextArea,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { useUser, useWorkspace } from "@app/context";
|
||||
import { useProject, useUser } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import {
|
||||
useGetSecretApprovalRequestDetails,
|
||||
@@ -92,7 +92,6 @@ const getReviewedStatusSymbol = (status?: ApprovalStatus) => {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
workspaceId: string;
|
||||
approvalRequestId: string;
|
||||
onGoBack: () => void;
|
||||
};
|
||||
@@ -104,13 +103,9 @@ const reviewFormSchema = z.object({
|
||||
|
||||
type TReviewFormSchema = z.infer<typeof reviewFormSchema>;
|
||||
|
||||
export const SecretApprovalRequestChanges = ({
|
||||
approvalRequestId,
|
||||
onGoBack,
|
||||
workspaceId
|
||||
}: Props) => {
|
||||
export const SecretApprovalRequestChanges = ({ approvalRequestId, onGoBack }: Props) => {
|
||||
const { user: userSession } = useUser();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { projectId } = useProject();
|
||||
const {
|
||||
data: secretApprovalRequestDetails,
|
||||
isSuccess: isSecretApprovalRequestSuccess,
|
||||
@@ -123,7 +118,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
);
|
||||
const { data: secretImports } = useGetSecretImports({
|
||||
environment: secretApprovalRequestDetails?.environment || "",
|
||||
projectId: currentWorkspace.id,
|
||||
projectId,
|
||||
path: approvalSecretPath
|
||||
});
|
||||
|
||||
@@ -526,7 +521,6 @@ export const SecretApprovalRequestChanges = ({
|
||||
isMergable={isMergable}
|
||||
statusChangeByEmail={secretApprovalRequestDetails.statusChangedByUser?.email}
|
||||
enforcementLevel={secretApprovalRequestDetails.policy.enforcementLevel}
|
||||
workspaceId={workspaceId}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,10 +25,11 @@ import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionDynamicSecretActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useProjectPermission
|
||||
} from "@app/context";
|
||||
import {
|
||||
ProjectPermissionCommitsActions,
|
||||
ProjectPermissionSecretActions,
|
||||
ProjectPermissionSecretRotationActions
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -49,10 +50,10 @@ import { useGetProjectSecretsDetails } from "@app/hooks/api/dashboard";
|
||||
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
|
||||
import { useGetFolderCommitsCount } from "@app/hooks/api/folderCommits";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { ProjectVersion } from "@app/hooks/api/projects/types";
|
||||
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||
import { useCreateCommit } from "@app/hooks/api/secrets/mutations";
|
||||
import { SecretV3RawSanitized } from "@app/hooks/api/types";
|
||||
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
||||
import { usePathAccessPolicies } from "@app/hooks/usePathAccessPolicies";
|
||||
import { useResizableColWidth } from "@app/hooks/useResizableColWidth";
|
||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||
@@ -93,7 +94,7 @@ const LOADER_TEXT = [
|
||||
];
|
||||
|
||||
const Page = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const navigate = useNavigate({
|
||||
from: ROUTE_PATHS.SecretManager.SecretDashboardPage.path
|
||||
});
|
||||
@@ -106,7 +107,7 @@ const Page = () => {
|
||||
});
|
||||
|
||||
const { permission } = useProjectPermission();
|
||||
const { mutateAsync: createCommit } = useCreateCommit();
|
||||
const { mutateAsync: createCommit, isPending: isCommitPending } = useCreateCommit();
|
||||
|
||||
const tableRef = useRef<HTMLTableElement>(null);
|
||||
|
||||
@@ -141,15 +142,15 @@ const Page = () => {
|
||||
] as const);
|
||||
|
||||
// env slug
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const projectSlug = currentWorkspace?.slug || "";
|
||||
const projectId = currentProject?.id || "";
|
||||
const projectSlug = currentProject?.slug || "";
|
||||
const secretPath = (routerQueryParams.secretPath as string) || "/";
|
||||
|
||||
useEffect(() => {
|
||||
if (isBatchMode && workspaceId && environment && secretPath) {
|
||||
loadPendingChanges({ workspaceId, environment, secretPath });
|
||||
if (isBatchMode && projectId && environment && secretPath) {
|
||||
loadPendingChanges({ projectId, environment, secretPath });
|
||||
}
|
||||
}, [isBatchMode, workspaceId, environment, secretPath, loadPendingChanges]);
|
||||
}, [isBatchMode, projectId, environment, secretPath, loadPendingChanges]);
|
||||
|
||||
const canReadSecret = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
@@ -213,6 +214,11 @@ const Page = () => {
|
||||
ProjectPermissionSub.SecretRollback
|
||||
);
|
||||
|
||||
const canReadCommits = permission.can(
|
||||
ProjectPermissionCommitsActions.Read,
|
||||
ProjectPermissionSub.Commits
|
||||
);
|
||||
|
||||
const defaultFilterState = {
|
||||
tags: {},
|
||||
searchFilter: (routerQueryParams.search as string) || "",
|
||||
@@ -234,7 +240,7 @@ const Page = () => {
|
||||
const { togglePopUp } = usePopUpAction();
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentWorkspace?.environments.find((env) => env.slug === environment)) {
|
||||
if (!currentProject?.environments.find((env) => env.slug === environment)) {
|
||||
createNotification({
|
||||
text: "No environment found with given slug",
|
||||
type: "error"
|
||||
@@ -242,11 +248,11 @@ const Page = () => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/overview",
|
||||
params: {
|
||||
projectId: workspaceId
|
||||
projectId
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [currentWorkspace, environment]);
|
||||
}, [currentProject, environment]);
|
||||
|
||||
const isResourceTypeFiltered = Object.values(filter.include).some(Boolean);
|
||||
const {
|
||||
@@ -256,7 +262,7 @@ const Page = () => {
|
||||
isFetched
|
||||
} = useGetProjectSecretsDetails({
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
offset,
|
||||
limit,
|
||||
@@ -310,7 +316,7 @@ const Page = () => {
|
||||
|
||||
// fetch imported secrets to show user the overriden ones
|
||||
const { data: importedSecrets } = useGetImportedSecretsSingleEnv({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
path: secretPath,
|
||||
options: {
|
||||
@@ -320,13 +326,13 @@ const Page = () => {
|
||||
|
||||
// fetch tags
|
||||
const { data: tags } = useGetWsTags(
|
||||
permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags) ? workspaceId : ""
|
||||
permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags) ? projectId : ""
|
||||
);
|
||||
|
||||
const { pathPolicies, hasPathPolicies } = usePathAccessPolicies({ secretPath, environment });
|
||||
|
||||
const { data: boardPolicy } = useGetSecretApprovalPolicyOfABoard({
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -335,7 +341,7 @@ const Page = () => {
|
||||
const handleCreateCommit = async (changes: PendingChanges, message: string) => {
|
||||
try {
|
||||
await createCommit({
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath,
|
||||
pendingChanges: changes,
|
||||
@@ -362,7 +368,7 @@ const Page = () => {
|
||||
fetchNextPage: fetchNextSnapshotList,
|
||||
hasNextPage: hasNextSnapshotListPage
|
||||
} = useGetWorkspaceSnapshotList({
|
||||
workspaceId,
|
||||
projectId,
|
||||
directory: secretPath,
|
||||
environment,
|
||||
isPaused: !popUp.snapshots.isOpen || !canDoReadRollback,
|
||||
@@ -375,9 +381,9 @@ const Page = () => {
|
||||
isFetching: isFolderCommitsCountFetching
|
||||
} = useGetFolderCommitsCount({
|
||||
directory: secretPath,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
isPaused: !canDoReadRollback
|
||||
isPaused: !canReadCommits
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -385,13 +391,13 @@ const Page = () => {
|
||||
isPending: isSnapshotCountLoading,
|
||||
isFetching: isSnapshotCountFetching
|
||||
} = useGetWsSnapshotCount({
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath,
|
||||
isPaused: !canDoReadRollback
|
||||
});
|
||||
|
||||
const isPITEnabled = !currentWorkspace?.showSnapshotsLegacy;
|
||||
const isPITEnabled = !currentProject?.showSnapshotsLegacy;
|
||||
|
||||
const changesCount = useMemo(() => {
|
||||
return isPITEnabled ? folderCommitsCount : snapshotCount;
|
||||
@@ -410,7 +416,7 @@ const Page = () => {
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/commits/$environment/$folderId",
|
||||
params: {
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
folderId,
|
||||
environment
|
||||
},
|
||||
@@ -641,7 +647,7 @@ const Page = () => {
|
||||
? change.tags?.map((tag) => ({
|
||||
id: tag.id,
|
||||
slug: tag.slug,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
__v: 0
|
||||
@@ -728,7 +734,7 @@ const Page = () => {
|
||||
const mergedSecrets = getMergedSecretsWithPending();
|
||||
const mergedFolders = getMergedFoldersWithPending();
|
||||
|
||||
if (!(currentWorkspace?.version === ProjectVersion.V3))
|
||||
if (!(currentProject?.version === ProjectVersion.V3))
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center px-6 text-mineshaft-50 dark:[color-scheme:dark]">
|
||||
<SecretV2MigrationSection />
|
||||
@@ -788,8 +794,6 @@ const Page = () => {
|
||||
<>
|
||||
<ActionBar
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectSlug={projectSlug}
|
||||
secretPath={secretPath}
|
||||
isVisible={isVisible}
|
||||
isBatchMode={isBatchMode}
|
||||
@@ -951,7 +955,7 @@ const Page = () => {
|
||||
secretImports={imports}
|
||||
isFetching={isDetailsFetching}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
importedSecrets={importedSecrets}
|
||||
/>
|
||||
@@ -960,7 +964,7 @@ const Page = () => {
|
||||
<FolderListView
|
||||
folders={mergedFolders}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
onNavigateToFolder={handleResetFilter}
|
||||
canNavigate={isFetched}
|
||||
@@ -984,7 +988,7 @@ const Page = () => {
|
||||
tags={tags}
|
||||
isVisible={isVisible}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
isProtectedBranch={isProtectedBranch}
|
||||
importedBy={importedBy}
|
||||
@@ -995,9 +999,9 @@ const Page = () => {
|
||||
<CommitForm
|
||||
onCommit={handleCreateCommit}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
isCommitting={false}
|
||||
isCommitting={isCommitPending}
|
||||
/>
|
||||
)}
|
||||
{noAccessSecretCount > 0 && <SecretNoAccessListView count={noAccessSecretCount} />}
|
||||
@@ -1046,9 +1050,9 @@ const Page = () => {
|
||||
>
|
||||
<CreateSecretForm
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
autoCapitalize={currentWorkspace?.autoCapitalization}
|
||||
autoCapitalize={currentProject?.autoCapitalization}
|
||||
isProtectedBranch={isProtectedBranch}
|
||||
isBatchMode={isBatchMode}
|
||||
/>
|
||||
@@ -1067,10 +1071,10 @@ const Page = () => {
|
||||
)}
|
||||
<SecretDropzone
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
isSmaller={isNotEmpty}
|
||||
environments={currentWorkspace?.environments}
|
||||
environments={currentProject?.environments}
|
||||
isProtectedBranch={isProtectedBranch}
|
||||
/>
|
||||
<PitDrawer
|
||||
@@ -1088,7 +1092,7 @@ const Page = () => {
|
||||
<SnapshotView
|
||||
snapshotId={snapshotId || ""}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
secrets={secrets}
|
||||
folders={folders}
|
||||
|
||||
@@ -97,7 +97,7 @@ export interface PendingChanges {
|
||||
|
||||
// Context interface for batch operations
|
||||
export interface BatchContext {
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
}
|
||||
@@ -257,8 +257,8 @@ type BatchModeState = {
|
||||
};
|
||||
};
|
||||
|
||||
const generateContextKey = (workspaceId: string, environment: string, secretPath: string) => {
|
||||
return `${workspaceId}_${environment}_${secretPath}`;
|
||||
const generateContextKey = (projectId: string, environment: string, secretPath: string) => {
|
||||
return `${projectId}_${environment}_${secretPath}`;
|
||||
};
|
||||
|
||||
const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState> = (set, get) => ({
|
||||
@@ -272,7 +272,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
addPendingChange: (change: PendingChange, context: BatchContext) =>
|
||||
set((state) => {
|
||||
const contextKey = generateContextKey(
|
||||
context.workspaceId,
|
||||
context.projectId,
|
||||
context.environment,
|
||||
context.secretPath
|
||||
);
|
||||
@@ -551,7 +551,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
const currentChanges =
|
||||
contextKey ===
|
||||
generateContextKey(
|
||||
state.currentContext?.workspaceId || context.workspaceId,
|
||||
state.currentContext?.projectId || context.projectId,
|
||||
state.currentContext?.environment || context.environment,
|
||||
state.currentContext?.secretPath || context.secretPath
|
||||
)
|
||||
@@ -568,7 +568,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
removePendingChange: (changeId: string, resourceType: string, context: BatchContext) =>
|
||||
set((state) => {
|
||||
const contextKey = generateContextKey(
|
||||
context.workspaceId,
|
||||
context.projectId,
|
||||
context.environment,
|
||||
context.secretPath
|
||||
);
|
||||
@@ -593,7 +593,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
state.currentContext &&
|
||||
contextKey ===
|
||||
generateContextKey(
|
||||
state.currentContext.workspaceId,
|
||||
state.currentContext.projectId,
|
||||
state.currentContext.environment,
|
||||
state.currentContext.secretPath
|
||||
);
|
||||
@@ -606,7 +606,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
|
||||
loadPendingChanges: (context) => {
|
||||
const contextKey = generateContextKey(
|
||||
context.workspaceId,
|
||||
context.projectId,
|
||||
context.environment,
|
||||
context.secretPath
|
||||
);
|
||||
@@ -626,7 +626,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
|
||||
clearAllPendingChanges: (context) => {
|
||||
const contextKey = generateContextKey(
|
||||
context.workspaceId,
|
||||
context.projectId,
|
||||
context.environment,
|
||||
context.secretPath
|
||||
);
|
||||
@@ -641,7 +641,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
||||
state.currentContext &&
|
||||
contextKey ===
|
||||
generateContextKey(
|
||||
state.currentContext.workspaceId,
|
||||
state.currentContext.projectId,
|
||||
state.currentContext.environment,
|
||||
state.currentContext.secretPath
|
||||
);
|
||||
|
||||
+22
-29
@@ -55,9 +55,9 @@ import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionDynamicSecretActions,
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import {
|
||||
ProjectPermissionCommitsActions,
|
||||
@@ -109,9 +109,6 @@ type TSecOverwriteOpt = { update: TParsedEnv; create: TParsedEnv };
|
||||
type Props = {
|
||||
// switch the secrets type as it gets decrypted after api call
|
||||
environment: string;
|
||||
// @depreciated will be moving all these details to zustand
|
||||
workspaceId: string;
|
||||
projectSlug: string;
|
||||
secretPath?: string;
|
||||
filter: Filter;
|
||||
tags?: WsTag[];
|
||||
@@ -142,8 +139,6 @@ type Props = {
|
||||
|
||||
export const ActionBar = ({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectSlug,
|
||||
secretPath = "/",
|
||||
filter,
|
||||
tags = [],
|
||||
@@ -164,6 +159,7 @@ export const ActionBar = ({
|
||||
hasPathPolicies,
|
||||
onClearFilters
|
||||
}: Props) => {
|
||||
const { projectId, currentProject } = useProject();
|
||||
const { handlePopUpOpen, handlePopUpToggle, handlePopUpClose, popUp } = usePopUp([
|
||||
"addFolder",
|
||||
"addDynamicSecret",
|
||||
@@ -196,7 +192,6 @@ export const ActionBar = ({
|
||||
const { reset: resetSelectedSecret } = useSelectedSecretActions();
|
||||
const isMultiSelectActive = Boolean(Object.keys(selectedSecrets).length);
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const handleFolderCreate = async (folderName: string, description: string | null) => {
|
||||
@@ -214,7 +209,7 @@ export const ActionBar = ({
|
||||
};
|
||||
|
||||
addPendingChange(pendingFolderCreate, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -227,7 +222,7 @@ export const ActionBar = ({
|
||||
name: folderName,
|
||||
path: secretPath,
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
description
|
||||
});
|
||||
handlePopUpClose("addFolder");
|
||||
@@ -247,7 +242,7 @@ export const ActionBar = ({
|
||||
const handleSecretDownload = async () => {
|
||||
try {
|
||||
const { secrets: localSecrets, imports: localImportedSecrets } = await fetchProjectSecrets({
|
||||
workspaceId,
|
||||
projectId,
|
||||
expandSecretReferences: true,
|
||||
includeImports: true,
|
||||
environment,
|
||||
@@ -317,7 +312,7 @@ export const ActionBar = ({
|
||||
try {
|
||||
await deleteBatchSecretV3({
|
||||
secretPath,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secrets: bulkDeletedSecrets.map(({ key }) => ({ secretKey: key, type: SecretType.Shared }))
|
||||
});
|
||||
@@ -348,13 +343,12 @@ export const ActionBar = ({
|
||||
try {
|
||||
const secretsToMove = Object.values(selectedSecrets);
|
||||
const { isDestinationUpdated, isSourceUpdated } = await moveSecrets({
|
||||
projectSlug,
|
||||
shouldOverwrite,
|
||||
sourceEnvironment: environment,
|
||||
sourceSecretPath: secretPath,
|
||||
destinationEnvironment,
|
||||
destinationSecretPath,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
secretIds: secretsToMove.map((sec) => sec.id)
|
||||
});
|
||||
|
||||
@@ -448,7 +442,7 @@ export const ActionBar = ({
|
||||
const { secrets: batchSecrets } = await fetchDashboardProjectSecretsByKeys({
|
||||
secretPath: normalizedPath,
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
keys: batch
|
||||
});
|
||||
|
||||
@@ -566,7 +560,7 @@ export const ActionBar = ({
|
||||
name: folderName,
|
||||
path: parentPath,
|
||||
environment,
|
||||
projectId: workspaceId
|
||||
projectId
|
||||
});
|
||||
|
||||
createdFolders.add(fullPath);
|
||||
@@ -598,7 +592,7 @@ export const ActionBar = ({
|
||||
Object.entries(groupedCreateSecrets).map(([path, secrets]) =>
|
||||
createSecretBatch({
|
||||
secretPath: path,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secrets
|
||||
})
|
||||
@@ -628,7 +622,7 @@ export const ActionBar = ({
|
||||
Object.entries(groupedUpdateSecrets).map(([path, secrets]) =>
|
||||
updateSecretBatch({
|
||||
secretPath: path,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secrets
|
||||
})
|
||||
@@ -638,13 +632,12 @@ export const ActionBar = ({
|
||||
|
||||
// Invalidate appropriate queries to refresh UI
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
|
||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({});
|
||||
dashboardKeys.getDashboardSecrets({ projectId, secretPath });
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: dashboardKeys.getDashboardSecrets({ projectId: workspaceId, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretApprovalRequestKeys.count({ workspaceId })
|
||||
queryKey: secretApprovalRequestKeys.count({ projectId })
|
||||
});
|
||||
|
||||
// Close the modal and show notification
|
||||
@@ -677,8 +670,8 @@ export const ActionBar = ({
|
||||
className="w-2/5"
|
||||
value={filter.searchFilter}
|
||||
onChange={onSearchChange}
|
||||
environments={[currentWorkspace.environments.find((env) => env.slug === environment)!]}
|
||||
projectId={workspaceId}
|
||||
environments={[currentProject.environments.find((env) => env.slug === environment)!]}
|
||||
projectId={projectId}
|
||||
tags={tags}
|
||||
/>
|
||||
<div>
|
||||
@@ -1134,8 +1127,8 @@ export const ActionBar = ({
|
||||
{/* all the side triggers from actions like modals etc */}
|
||||
<CreateSecretImportForm
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
secretPath={secretPath}
|
||||
projectId={projectId}
|
||||
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
|
||||
isOpen={popUp.addSecretImport.isOpen}
|
||||
onClose={() => handlePopUpClose("addSecretImport")}
|
||||
@@ -1144,7 +1137,7 @@ export const ActionBar = ({
|
||||
<CreateDynamicSecretForm
|
||||
isOpen={popUp.addDynamicSecret.isOpen}
|
||||
onToggle={(isOpen) => handlePopUpToggle("addDynamicSecret", isOpen)}
|
||||
projectSlug={projectSlug}
|
||||
projectSlug={currentProject.slug}
|
||||
environments={[{ slug: environment, name: environment, id: "not-used" }]}
|
||||
secretPath={secretPath}
|
||||
isSingleEnvironmentMode
|
||||
@@ -1190,8 +1183,8 @@ export const ActionBar = ({
|
||||
onToggle={(isOpen) => handlePopUpToggle("replicateFolder", isOpen)}
|
||||
onParsedEnv={handleParsedEnvMultiFolder}
|
||||
environment={environment}
|
||||
environments={currentWorkspace.environments}
|
||||
workspaceId={workspaceId}
|
||||
environments={currentProject.environments}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
/>
|
||||
{subscription && (
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
const formSchema = z.object({
|
||||
provider: z.object({
|
||||
@@ -63,7 +63,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import {
|
||||
DynamicSecretAwsIamCredentialType,
|
||||
DynamicSecretProviders
|
||||
} from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
import { MetadataForm } from "../../DynamicSecretListView/MetadataForm";
|
||||
|
||||
@@ -122,7 +122,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import { Tooltip } from "@app/components/v2/Tooltip";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { useGetDynamicSecretProviderData } from "@app/hooks/api/dynamicSecret/queries";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
const formSchema = z.object({
|
||||
selectedUsers: z.array(
|
||||
@@ -66,7 +66,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -66,7 +66,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
// Component for managing scopes and collections within a bucket
|
||||
@@ -265,7 +265,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import { AnimatePresence, motion } from "framer-motion";
|
||||
|
||||
import { Modal, ModalContent } from "@app/components/v2";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
import { AwsElastiCacheInputForm } from "./AwsElastiCacheInputForm";
|
||||
import { AwsIamInputForm } from "./AwsIamInputForm";
|
||||
@@ -51,7 +51,7 @@ type Props = {
|
||||
isOpen?: boolean;
|
||||
onToggle: (isOpen: boolean) => void;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
secretPath: string;
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const authMethods = [
|
||||
@@ -87,7 +87,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FilterableSelect, FormControl, Input } from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
const validateTTL = (val: string, ctx: z.RefinementCtx) => {
|
||||
if (!val) return;
|
||||
@@ -49,7 +49,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
const formSchema = z.object({
|
||||
provider: z.object({
|
||||
@@ -44,7 +44,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import {
|
||||
DynamicSecretProviders,
|
||||
KubernetesDynamicSecretCredentialType
|
||||
} from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
enum RoleType {
|
||||
@@ -150,7 +150,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
enum CredentialType {
|
||||
@@ -89,7 +89,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -77,7 +77,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -67,7 +67,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -71,7 +71,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -64,7 +64,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -62,7 +62,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -64,7 +64,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -62,7 +62,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+27
-3
@@ -19,6 +19,7 @@ import {
|
||||
SecretInput,
|
||||
Select,
|
||||
SelectItem,
|
||||
Switch,
|
||||
TextArea,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
@@ -28,7 +29,7 @@ import {
|
||||
} from "@app/context/OrgPermissionContext/types";
|
||||
import { gatewaysQueryKeys, useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders, SqlProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
import { MetadataForm } from "../../DynamicSecretListView/MetadataForm";
|
||||
@@ -66,6 +67,7 @@ const formSchema = z.object({
|
||||
creationStatement: z.string().min(1),
|
||||
revocationStatement: z.string().min(1),
|
||||
renewStatement: z.string().optional(),
|
||||
sslEnabled: z.boolean().optional(),
|
||||
ca: z.string().optional(),
|
||||
gatewayId: z.string().optional()
|
||||
}),
|
||||
@@ -108,7 +110,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
@@ -200,6 +202,7 @@ export const SqlDatabaseInputForm = ({
|
||||
|
||||
const createDynamicSecret = useCreateDynamicSecret();
|
||||
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
||||
const selectedClient = watch("provider.client");
|
||||
|
||||
const handleCreateDynamicSecret = async ({
|
||||
name,
|
||||
@@ -458,13 +461,34 @@ export const SqlDatabaseInputForm = ({
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{selectedClient === SqlProviders.MsSQL && (
|
||||
<div className="mb-2 mt-2">
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.sslEnabled"
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl isError={Boolean(error?.message)} errorText={error?.message}>
|
||||
<Switch
|
||||
className="bg-mineshaft-400/50 shadow-inner data-[state=checked]:bg-green/80"
|
||||
id="sql-ds-ssl-enabled"
|
||||
thumbClassName="bg-mineshaft-800"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
>
|
||||
Encrypt Connection (SSL)
|
||||
</Switch>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.ca"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isOptional
|
||||
label="CA(SSL)"
|
||||
label="CA (SSL)"
|
||||
isError={Boolean(error?.message)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
enum ConfigType {
|
||||
@@ -66,7 +66,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ import {
|
||||
} from "@app/context/OrgPermissionContext/types";
|
||||
import { gatewaysQueryKeys, useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
|
||||
const passwordRequirementsSchema = z
|
||||
.object({
|
||||
@@ -91,7 +91,7 @@ type Props = {
|
||||
onCancel: () => void;
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
environments: WorkspaceEnv[];
|
||||
environments: ProjectEnv[];
|
||||
isSingleEnvironmentMode?: boolean;
|
||||
};
|
||||
|
||||
|
||||
+6
-6
@@ -14,7 +14,7 @@ import {
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||
import { useSubscription, useWorkspace } from "@app/context";
|
||||
import { useProject, useSubscription } from "@app/context";
|
||||
import { useCreateSecretImport } from "@app/hooks/api";
|
||||
|
||||
const typeSchema = z.object({
|
||||
@@ -32,7 +32,7 @@ type TFormSchema = z.infer<typeof typeSchema>;
|
||||
|
||||
type Props = {
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath?: string;
|
||||
// modal props
|
||||
isOpen?: boolean;
|
||||
@@ -43,7 +43,7 @@ type Props = {
|
||||
|
||||
export const CreateSecretImportForm = ({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath = "/",
|
||||
isOpen,
|
||||
onClose,
|
||||
@@ -57,8 +57,8 @@ export const CreateSecretImportForm = ({
|
||||
watch,
|
||||
formState: { isSubmitting }
|
||||
} = useForm<TFormSchema>({ resolver: zodResolver(typeSchema) });
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const environments = currentWorkspace?.environments || [];
|
||||
const { currentProject } = useProject();
|
||||
const environments = currentProject?.environments || [];
|
||||
const selectedEnvironment = watch("environment");
|
||||
const { subscription } = useSubscription();
|
||||
|
||||
@@ -77,7 +77,7 @@ export const CreateSecretImportForm = ({
|
||||
|
||||
await createSecretImport({
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
path: secretPath,
|
||||
isReplication,
|
||||
import: {
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ import {
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
type Props = {
|
||||
@@ -47,8 +47,8 @@ export const MoveSecretsModal = ({ popUp, handlePopUpToggle, onMoveApproved }: P
|
||||
formState: { isSubmitting }
|
||||
} = useForm<TFormSchema>({ resolver: zodResolver(formSchema) });
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const environments = currentWorkspace?.environments || [];
|
||||
const { currentProject } = useProject();
|
||||
const environments = currentProject?.environments || [];
|
||||
const selectedEnvironment = watch("environment");
|
||||
|
||||
const handleFormSubmit = (data: TFormSchema) => {
|
||||
|
||||
+4
-4
@@ -48,7 +48,7 @@ type Props = {
|
||||
env: Record<string, Record<string, { value: string; comments: string[]; secretPath?: string }>>
|
||||
) => void;
|
||||
environments?: { name: string; slug: string }[];
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
};
|
||||
@@ -64,7 +64,7 @@ type SecretStructure = {
|
||||
|
||||
export const ReplicateFolderFromBoard = ({
|
||||
environments = [],
|
||||
workspaceId,
|
||||
projectId,
|
||||
isOpen,
|
||||
onToggle,
|
||||
onParsedEnv
|
||||
@@ -82,14 +82,14 @@ export const ReplicateFolderFromBoard = ({
|
||||
const [debouncedEnvCopySecretPath] = useDebounce(envCopySecPath);
|
||||
|
||||
const { data: accessibleSecrets } = useGetAccessibleSecrets({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
secretPath: "/",
|
||||
environment: selectedEnvSlug.slug,
|
||||
recursive: true,
|
||||
filterByAction: shouldIncludeValues
|
||||
? ProjectPermissionSecretActions.ReadValue
|
||||
: ProjectPermissionSecretActions.DescribeSecret,
|
||||
options: { enabled: Boolean(workspaceId) && Boolean(selectedEnvSlug) && isOpen }
|
||||
options: { enabled: Boolean(projectId) && Boolean(selectedEnvSlug) && isOpen }
|
||||
});
|
||||
|
||||
const restructureSecrets = useMemo(() => {
|
||||
|
||||
+9
-11
@@ -25,14 +25,14 @@ interface CommitFormProps {
|
||||
onCommit: (changes: PendingChanges, commitMessage: string) => Promise<void>;
|
||||
isCommitting?: boolean;
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath: string;
|
||||
}
|
||||
|
||||
interface ResourceChangeProps {
|
||||
change: PendingChange;
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath: string;
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ const RenderFolderChanges = ({ onDiscard, change }: RenderResourceProps) => {
|
||||
const ResourceChange: React.FC<ResourceChangeProps> = ({
|
||||
change,
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath
|
||||
}) => {
|
||||
const { removePendingChange } = useBatchModeActions();
|
||||
@@ -245,7 +245,7 @@ const ResourceChange: React.FC<ResourceChangeProps> = ({
|
||||
const handleDeletePending = useCallback(
|
||||
(changeType: string, id: string) => {
|
||||
removePendingChange(id, changeType, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -272,7 +272,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
|
||||
onCommit,
|
||||
isCommitting = false,
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath
|
||||
}) => {
|
||||
const { isBatchMode, pendingChanges, totalChangesCount } = useBatchMode();
|
||||
@@ -291,7 +291,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
|
||||
}
|
||||
await onCommit(pendingChanges, commitMessage);
|
||||
clearAllPendingChanges({
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -335,9 +335,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
|
||||
<div className="ml-6 mt-0.5 flex items-center gap-3">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
clearAllPendingChanges({ workspaceId, environment, secretPath })
|
||||
}
|
||||
onClick={() => clearAllPendingChanges({ projectId, environment, secretPath })}
|
||||
isDisabled={totalChangesCount === 0}
|
||||
variant="outline_bg"
|
||||
className="px-4 hover:border-red/40 hover:bg-red/[0.1]"
|
||||
@@ -393,7 +391,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
|
||||
key={change.id}
|
||||
change={change}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
/>
|
||||
))}
|
||||
@@ -414,7 +412,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
|
||||
key={change.id}
|
||||
change={change}
|
||||
environment={environment}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
/>
|
||||
))}
|
||||
|
||||
+15
-15
@@ -38,7 +38,7 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
PreferenceKey,
|
||||
@@ -49,7 +49,7 @@ import { useGetImportedSecretsAllEnvs } from "@app/hooks/api";
|
||||
import { useGetProjectSecretsOverview } from "@app/hooks/api/dashboard";
|
||||
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/workspace/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/projects/types";
|
||||
import { useResizableColWidth } from "@app/hooks/useResizableColWidth";
|
||||
import {
|
||||
useDynamicSecretOverview,
|
||||
@@ -89,10 +89,10 @@ const DEFAULT_FILTER_STATE = {
|
||||
const COL_WIDTH_OFFSET = 220;
|
||||
|
||||
export const CompareEnvironments = ({ secretPath }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const compareEnvironmentsKey = `compare-environments-${currentWorkspace.id}`;
|
||||
const { currentProject } = useProject();
|
||||
const compareEnvironmentsKey = `compare-environments-${currentProject.id}`;
|
||||
|
||||
const [selectedEnvironments, setSelectedEnvironments] = useState<WorkspaceEnv[]>(() => {
|
||||
const [selectedEnvironments, setSelectedEnvironments] = useState<ProjectEnv[]>(() => {
|
||||
try {
|
||||
const storedEnvironments = JSON.parse(localStorage.getItem(compareEnvironmentsKey) ?? "[]");
|
||||
|
||||
@@ -104,12 +104,12 @@ export const CompareEnvironments = ({ secretPath }: Props) => {
|
||||
}
|
||||
});
|
||||
|
||||
return currentWorkspace.environments.filter((env) => potentialEnvs.includes(env.id));
|
||||
return currentProject.environments.filter((env) => potentialEnvs.includes(env.id));
|
||||
}
|
||||
} catch {
|
||||
// do nothing and proceed
|
||||
}
|
||||
return currentWorkspace.environments.slice(0, 2);
|
||||
return currentProject.environments.slice(0, 2);
|
||||
});
|
||||
|
||||
const [filter, setFilter] = useState<Filter>(DEFAULT_FILTER_STATE);
|
||||
@@ -133,7 +133,7 @@ export const CompareEnvironments = ({ secretPath }: Props) => {
|
||||
setUserTablePreference("secretCompareTable", PreferenceKey.PerPage, newPerPage);
|
||||
};
|
||||
|
||||
const workspaceId = currentWorkspace.id;
|
||||
const projectId = currentProject.id;
|
||||
const [searchFilter, setSearchFilter] = useState("");
|
||||
const [debouncedSearchFilter] = useDebounce(searchFilter);
|
||||
const [debouncedSelectedEnvironments] = useDebounce(selectedEnvironments);
|
||||
@@ -151,19 +151,19 @@ export const CompareEnvironments = ({ secretPath }: Props) => {
|
||||
getImportedSecretByKey,
|
||||
getEnvImportedSecretKeyCount
|
||||
} = useGetImportedSecretsAllEnvs({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
path: secretPath,
|
||||
environments: (currentWorkspace.environments || []).map(({ slug }) => slug)
|
||||
environments: (currentProject.environments || []).map(({ slug }) => slug)
|
||||
});
|
||||
|
||||
const compareEnvironments = selectedEnvironments.length
|
||||
? selectedEnvironments
|
||||
: currentWorkspace.environments;
|
||||
: currentProject.environments;
|
||||
|
||||
const isFilteredByResources = Object.values(filter).some(Boolean);
|
||||
const { isPending: isOverviewLoading, data: overview } = useGetProjectSecretsOverview(
|
||||
{
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environments: compareEnvironments.map((env) => env.slug),
|
||||
secretPath,
|
||||
orderDirection,
|
||||
@@ -579,12 +579,12 @@ export const CompareEnvironments = ({ secretPath }: Props) => {
|
||||
<FilterableSelect
|
||||
value={selectedEnvironments}
|
||||
onChange={(value) => {
|
||||
const selected = value as MultiValue<WorkspaceEnv>;
|
||||
const selected = value as MultiValue<ProjectEnv>;
|
||||
|
||||
setSelectedEnvironments((selected as WorkspaceEnv[]) ?? []);
|
||||
setSelectedEnvironments((selected as ProjectEnv[]) ?? []);
|
||||
}}
|
||||
placeholder="Leave blank to compare all environments"
|
||||
options={currentWorkspace.environments}
|
||||
options={currentProject.environments}
|
||||
getOptionValue={(option) => option.slug}
|
||||
getOptionLabel={(option) => option.name}
|
||||
isMulti
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ import {
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/types";
|
||||
import { HIDDEN_SECRET_VALUE } from "@app/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem";
|
||||
|
||||
import { EnvironmentStatus, EnvironmentStatusCell, ResourceNameCell } from "../shared";
|
||||
@@ -32,7 +32,7 @@ type Props = {
|
||||
getImportedSecretByKey: (
|
||||
env: string,
|
||||
secretName: string
|
||||
) => { secret?: SecretV3RawSanitized; environmentInfo?: WorkspaceEnv } | undefined;
|
||||
) => { secret?: SecretV3RawSanitized; environmentInfo?: ProjectEnv } | undefined;
|
||||
colWidth: number;
|
||||
tableWidth: number;
|
||||
};
|
||||
|
||||
+7
-6
@@ -32,7 +32,7 @@ type TFormSchema = z.infer<typeof typeSchema>;
|
||||
|
||||
type Props = {
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath?: string;
|
||||
// modal props
|
||||
autoCapitalize?: boolean;
|
||||
@@ -42,7 +42,7 @@ type Props = {
|
||||
|
||||
export const CreateSecretForm = ({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath = "/",
|
||||
autoCapitalize = true,
|
||||
isProtectedBranch = false,
|
||||
@@ -66,7 +66,7 @@ export const CreateSecretForm = ({
|
||||
const { permission } = useProjectPermission();
|
||||
const canReadTags = permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags);
|
||||
const { data: projectTags, isPending: isTagsLoading } = useGetWsTags(
|
||||
canReadTags ? workspaceId : ""
|
||||
canReadTags ? projectId : ""
|
||||
);
|
||||
|
||||
const secretKeyInputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -80,7 +80,7 @@ export const CreateSecretForm = ({
|
||||
try {
|
||||
const parsedSlug = slugSchema.parse(slug);
|
||||
await createWsTag.mutateAsync({
|
||||
workspaceID: workspaceId,
|
||||
projectId,
|
||||
tagSlug: parsedSlug,
|
||||
tagColor: ""
|
||||
});
|
||||
@@ -106,7 +106,8 @@ export const CreateSecretForm = ({
|
||||
resourceType: "secret"
|
||||
};
|
||||
addPendingChange(pendingSecretCreate, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -116,7 +117,7 @@ export const CreateSecretForm = ({
|
||||
}
|
||||
await createSecretV3({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
secretValue: value || "",
|
||||
|
||||
+25
-1
@@ -18,6 +18,7 @@ import {
|
||||
SecretInput,
|
||||
Select,
|
||||
SelectItem,
|
||||
Switch,
|
||||
TextArea,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
@@ -63,6 +64,7 @@ const formSchema = z.object({
|
||||
creationStatement: z.string().min(1),
|
||||
revocationStatement: z.string().min(1),
|
||||
renewStatement: z.string().optional(),
|
||||
sslEnabled: z.boolean().optional(),
|
||||
ca: z.string().optional(),
|
||||
gatewayId: z.string().optional().nullable()
|
||||
})
|
||||
@@ -151,6 +153,7 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
});
|
||||
|
||||
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
||||
const selectedClient = watch("inputs.client");
|
||||
|
||||
const updateDynamicSecret = useUpdateDynamicSecret();
|
||||
const selectedGatewayId = watch("inputs.gatewayId");
|
||||
@@ -407,13 +410,34 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{selectedClient === SqlProviders.MsSQL && (
|
||||
<div className="mb-2 mt-2">
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.sslEnabled"
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl isError={Boolean(error?.message)} errorText={error?.message}>
|
||||
<Switch
|
||||
className="bg-mineshaft-400/50 shadow-inner data-[state=checked]:bg-green/80"
|
||||
id="sql-ds-ssl-enabled"
|
||||
thumbClassName="bg-mineshaft-800"
|
||||
isChecked={Boolean(value)}
|
||||
onCheckedChange={onChange}
|
||||
>
|
||||
Encrypt Connection (SSL)
|
||||
</Switch>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.ca"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isOptional
|
||||
label="CA(SSL)"
|
||||
label="CA (SSL)"
|
||||
isError={Boolean(error?.message)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
|
||||
+18
-18
@@ -24,12 +24,12 @@ import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { workspaceKeys } from "@app/hooks/api";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/workspace/types";
|
||||
import { projectKeys } from "@app/hooks/api";
|
||||
import { ProjectEnv } from "@app/hooks/api/projects/types";
|
||||
import { AddEnvironmentModal } from "@app/pages/secret-manager/SettingsPage/components/EnvironmentSection/AddEnvironmentModal";
|
||||
|
||||
import { CompareEnvironments } from "../CompareEnvironments";
|
||||
@@ -45,7 +45,7 @@ type Props = {
|
||||
const TABS_TO_SHOW = 5;
|
||||
|
||||
export const EnvironmentTabs = ({ secretPath }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const currentEnv = useParams({
|
||||
from: ROUTE_PATHS.SecretManager.SecretDashboardPage.id,
|
||||
select: (el) => el.envSlug
|
||||
@@ -54,8 +54,8 @@ export const EnvironmentTabs = ({ secretPath }: Props) => {
|
||||
const { subscription } = useSubscription();
|
||||
|
||||
const isMoreEnvironmentsAllowed =
|
||||
subscription?.environmentLimit && currentWorkspace?.environments
|
||||
? currentWorkspace.environments.length < subscription.environmentLimit
|
||||
subscription?.environmentLimit && currentProject?.environments
|
||||
? currentProject.environments.length < subscription.environmentLimit
|
||||
: true;
|
||||
|
||||
const [isNavigating, setIsNavigating] = useState(false);
|
||||
@@ -68,20 +68,20 @@ export const EnvironmentTabs = ({ secretPath }: Props) => {
|
||||
"upgradePlan"
|
||||
] as const);
|
||||
|
||||
const selectedIndex = currentWorkspace.environments.findIndex((env) => env.slug === currentEnv);
|
||||
const selectedIndex = currentProject.environments.findIndex((env) => env.slug === currentEnv);
|
||||
|
||||
let tabEnvironments: WorkspaceEnv[];
|
||||
let dropdownEnvironments: WorkspaceEnv[];
|
||||
let tabEnvironments: ProjectEnv[];
|
||||
let dropdownEnvironments: ProjectEnv[];
|
||||
|
||||
if (selectedIndex < TABS_TO_SHOW) {
|
||||
tabEnvironments = currentWorkspace.environments.slice(0, TABS_TO_SHOW);
|
||||
dropdownEnvironments = currentWorkspace.environments.slice(TABS_TO_SHOW);
|
||||
tabEnvironments = currentProject.environments.slice(0, TABS_TO_SHOW);
|
||||
dropdownEnvironments = currentProject.environments.slice(TABS_TO_SHOW);
|
||||
} else {
|
||||
tabEnvironments = [
|
||||
...currentWorkspace.environments.slice(0, TABS_TO_SHOW - 1),
|
||||
currentWorkspace.environments[selectedIndex]
|
||||
...currentProject.environments.slice(0, TABS_TO_SHOW - 1),
|
||||
currentProject.environments[selectedIndex]
|
||||
];
|
||||
dropdownEnvironments = currentWorkspace.environments
|
||||
dropdownEnvironments = currentProject.environments
|
||||
.slice(TABS_TO_SHOW - 1)
|
||||
.filter((env) => env.slug !== currentEnv);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ export const EnvironmentTabs = ({ secretPath }: Props) => {
|
||||
to: ROUTE_PATHS.SecretManager.SecretDashboardPage.path,
|
||||
params: {
|
||||
envSlug,
|
||||
projectId: currentWorkspace.id
|
||||
projectId: currentProject.id
|
||||
},
|
||||
search: (prev) => prev
|
||||
});
|
||||
@@ -199,7 +199,7 @@ export const EnvironmentTabs = ({ secretPath }: Props) => {
|
||||
</Tooltip>
|
||||
</Tab>
|
||||
)}
|
||||
{currentWorkspace.environments.length > 1 && (
|
||||
{currentProject.environments.length > 1 && (
|
||||
<Tab className="ml-auto" value={COMPARE_ENVIRONMENT_TAB}>
|
||||
<div className="flex items-center gap-x-2 whitespace-nowrap">
|
||||
<FontAwesomeIcon icon={faArrowRightArrowLeft} />
|
||||
@@ -232,7 +232,7 @@ export const EnvironmentTabs = ({ secretPath }: Props) => {
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("createEnvironment", isOpen)}
|
||||
onComplete={async (env) => {
|
||||
await queryClient.refetchQueries({
|
||||
queryKey: workspaceKeys.getWorkspaceById(currentWorkspace.id)
|
||||
queryKey: projectKeys.getProjectById(currentProject.id)
|
||||
});
|
||||
handleSelect(env.slug);
|
||||
}}
|
||||
|
||||
+8
-8
@@ -33,7 +33,7 @@ import { FolderForm } from "../ActionBar/FolderForm";
|
||||
type Props = {
|
||||
folders?: TSecretFolder[];
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath?: string;
|
||||
onNavigateToFolder: (path: string) => void;
|
||||
canNavigate: boolean;
|
||||
@@ -42,7 +42,7 @@ type Props = {
|
||||
export const FolderListView = ({
|
||||
folders = [],
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath = "/",
|
||||
onNavigateToFolder,
|
||||
canNavigate
|
||||
@@ -89,7 +89,7 @@ export const FolderListView = ({
|
||||
};
|
||||
|
||||
addPendingChange(updatedCreate, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -106,7 +106,7 @@ export const FolderListView = ({
|
||||
};
|
||||
|
||||
addPendingChange(updateChange, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -121,7 +121,7 @@ export const FolderListView = ({
|
||||
name: newFolderName,
|
||||
path: secretPath,
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
description: newFolderDescription
|
||||
});
|
||||
handlePopUpClose("updateFolder");
|
||||
@@ -140,7 +140,7 @@ export const FolderListView = ({
|
||||
|
||||
const handleDeletePending = (id: string) => {
|
||||
removePendingChange(id, "folder", {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -161,7 +161,7 @@ export const FolderListView = ({
|
||||
};
|
||||
|
||||
addPendingChange(pendingFolderDelete, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -174,7 +174,7 @@ export const FolderListView = ({
|
||||
folderId: folderData.id,
|
||||
path: secretPath,
|
||||
environment,
|
||||
projectId: workspaceId
|
||||
projectId
|
||||
});
|
||||
|
||||
handlePopUpClose("deleteFolder");
|
||||
|
||||
+4
-4
@@ -46,14 +46,14 @@ type Props = {
|
||||
onToggle: (isOpen: boolean) => void;
|
||||
onParsedEnv: (env: Record<string, { value: string; comments: string[] }>) => void;
|
||||
environments?: { name: string; slug: string }[];
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
};
|
||||
|
||||
export const CopySecretsFromBoard = ({
|
||||
environments = [],
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath,
|
||||
isOpen,
|
||||
@@ -81,7 +81,7 @@ export const CopySecretsFromBoard = ({
|
||||
|
||||
const { data: accessibleSecrets, isPending: isAccessibleSecretsLoading } =
|
||||
useGetAccessibleSecrets({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
secretPath: debouncedEnvCopySecretPath,
|
||||
environment: selectedEnvSlug.slug,
|
||||
filterByAction: shouldIncludeValues
|
||||
@@ -89,7 +89,7 @@ export const CopySecretsFromBoard = ({
|
||||
: ProjectPermissionSecretActions.DescribeSecret,
|
||||
options: {
|
||||
enabled:
|
||||
Boolean(workspaceId) &&
|
||||
Boolean(projectId) &&
|
||||
Boolean(selectedEnvSlug) &&
|
||||
Boolean(debouncedEnvCopySecretPath) &&
|
||||
isOpen
|
||||
|
||||
+9
-9
@@ -53,7 +53,7 @@ type TSecOverwriteOpt = { update: TParsedEnv; create: TParsedEnv };
|
||||
type Props = {
|
||||
isSmaller: boolean;
|
||||
environments?: { name: string; slug: string }[];
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
isProtectedBranch?: boolean;
|
||||
@@ -140,7 +140,7 @@ const MatrixImportModalTableRow = ({
|
||||
export const SecretDropzone = ({
|
||||
isSmaller,
|
||||
environments = [],
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath,
|
||||
isProtectedBranch = false
|
||||
@@ -196,7 +196,7 @@ export const SecretDropzone = ({
|
||||
const { secrets: existingSecrets } = await fetchDashboardProjectSecretsByKeys({
|
||||
secretPath,
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
keys: envSecretKeys
|
||||
});
|
||||
|
||||
@@ -334,7 +334,7 @@ export const SecretDropzone = ({
|
||||
if (Object.keys(create || {}).length) {
|
||||
await createSecretBatch({
|
||||
secretPath,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secrets: Object.entries(create).map(([secretKey, secData]) => ({
|
||||
type: SecretType.Shared,
|
||||
@@ -347,7 +347,7 @@ export const SecretDropzone = ({
|
||||
if (Object.keys(update || {}).length) {
|
||||
await updateSecretBatch({
|
||||
secretPath,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secrets: Object.entries(update).map(([secretKey, secData]) => ({
|
||||
type: SecretType.Shared,
|
||||
@@ -358,13 +358,13 @@ export const SecretDropzone = ({
|
||||
});
|
||||
}
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
|
||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: dashboardKeys.getDashboardSecrets({ projectId: workspaceId, secretPath })
|
||||
queryKey: dashboardKeys.getDashboardSecrets({ projectId, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretApprovalRequestKeys.count({ workspaceId })
|
||||
queryKey: secretApprovalRequestKeys.count({ projectId })
|
||||
});
|
||||
handlePopUpClose("confirmUpload");
|
||||
createNotification({
|
||||
@@ -464,7 +464,7 @@ export const SecretDropzone = ({
|
||||
onParsedEnv={handleParsedEnv}
|
||||
environment={environment}
|
||||
environments={environments}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
secretPath={secretPath}
|
||||
isSmaller={isSmaller}
|
||||
/>
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ import { twMerge } from "tailwind-merge";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { EmptyState, IconButton, SecretInput, TableContainer, Tooltip } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { useResyncSecretReplication } from "@app/hooks/api";
|
||||
import { TSecretImport } from "@app/hooks/api/types";
|
||||
@@ -82,7 +82,7 @@ export const SecretImportItem = ({
|
||||
lastReplicated,
|
||||
importEnv
|
||||
} = secretImport as TSecretImport;
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const [isExpanded, setIsExpanded] = useToggle();
|
||||
const { attributes, listeners, transform, transition, setNodeRef, isDragging } = useSortable({
|
||||
id
|
||||
@@ -118,7 +118,7 @@ export const SecretImportItem = ({
|
||||
id,
|
||||
environment,
|
||||
path: secretPath,
|
||||
projectId: currentWorkspace?.id || ""
|
||||
projectId: currentProject?.id || ""
|
||||
});
|
||||
createNotification({
|
||||
text: "Please refresh the dashboard to view changes",
|
||||
|
||||
+6
-6
@@ -18,7 +18,7 @@ import { usePopUp } from "@app/hooks";
|
||||
import { useDeleteSecretImport, useUpdateSecretImport } from "@app/hooks/api";
|
||||
import { ReservedFolders } from "@app/hooks/api/secretFolders/types";
|
||||
import { TSecretImport } from "@app/hooks/api/secretImports/types";
|
||||
import { SecretV3RawSanitized, WorkspaceEnv } from "@app/hooks/api/types";
|
||||
import { ProjectEnv, SecretV3RawSanitized } from "@app/hooks/api/types";
|
||||
import { formatReservedPaths } from "@app/lib/fn/string";
|
||||
|
||||
import { SecretImportItem } from "./SecretImportItem";
|
||||
@@ -26,7 +26,7 @@ import { SecretImportItem } from "./SecretImportItem";
|
||||
const SECRET_IN_DASHBOARD = "Present In Dashboard";
|
||||
|
||||
type TImportedSecrets = Array<{
|
||||
environmentInfo: WorkspaceEnv;
|
||||
environmentInfo: ProjectEnv;
|
||||
secretPath: string;
|
||||
folderId: string;
|
||||
secrets: SecretV3RawSanitized[];
|
||||
@@ -86,7 +86,7 @@ export const computeImportedSecretRows = (
|
||||
|
||||
type Props = {
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath?: string;
|
||||
secretImports?: TSecretImport[];
|
||||
isFetching?: boolean;
|
||||
@@ -98,7 +98,7 @@ type Props = {
|
||||
export const SecretImportListView = ({
|
||||
secretImports,
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
importedSecrets,
|
||||
// secrets = [],
|
||||
@@ -132,7 +132,7 @@ export const SecretImportListView = ({
|
||||
const { id: secretImportId } = popUp.deleteSecretImport?.data as { id: string };
|
||||
try {
|
||||
await deleteSecretImport({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
path: secretPath,
|
||||
id: secretImportId
|
||||
@@ -158,7 +158,7 @@ export const SecretImportListView = ({
|
||||
const newImportOrder = arrayMove(items, oldIndex, newIndex);
|
||||
setItems(newImportOrder);
|
||||
updateSecretImport({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
path: secretPath,
|
||||
id: active.id as string,
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@ import { faFileImport, faKey, faSync, faWarning } from "@fortawesome/free-solid-
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { Table, TBody, Td, Th, THead, Tooltip, Tr } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { UsedBySecretSyncs } from "@app/hooks/api/dashboard/types";
|
||||
|
||||
enum ItemType {
|
||||
@@ -44,7 +44,7 @@ export const CollapsibleSecretImports: React.FC<CollapsibleSecretImportsProps> =
|
||||
secretsToDelete,
|
||||
onlyReferences
|
||||
}) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const truncatePath = (path: string, maxLength = 24): string => {
|
||||
if (path.length <= maxLength) return path;
|
||||
@@ -62,7 +62,7 @@ export const CollapsibleSecretImports: React.FC<CollapsibleSecretImportsProps> =
|
||||
const handlePathClick = (item: FlatItem) => {
|
||||
if (item.type === ItemType.SecretSync) {
|
||||
window.open(
|
||||
`/secret-manager/${currentWorkspace.id}/integrations/secret-syncs/${item.destination}/${item.id}`,
|
||||
`/secret-manager/${currentProject.id}/integrations/secret-syncs/${item.destination}/${item.id}`,
|
||||
"_blank",
|
||||
"noopener,noreferrer"
|
||||
);
|
||||
@@ -78,7 +78,7 @@ export const CollapsibleSecretImports: React.FC<CollapsibleSecretImportsProps> =
|
||||
}
|
||||
const encodedPath = encodeURIComponent(pathToNavigate);
|
||||
window.open(
|
||||
`/secret-manager/${currentWorkspace.id}/secrets/${item.environment.slug}?secretPath=${encodedPath}`,
|
||||
`/secret-manager/${currentProject.id}/secrets/${item.environment.slug}?secretPath=${encodedPath}`,
|
||||
"_blank"
|
||||
);
|
||||
};
|
||||
|
||||
+7
-7
@@ -21,7 +21,7 @@ import {
|
||||
SelectItem,
|
||||
TextArea
|
||||
} from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useGetWorkspaceUsers } from "@app/hooks/api";
|
||||
import { dashboardKeys } from "@app/hooks/api/dashboard/queries";
|
||||
import { useCreateReminder, useDeleteReminder } from "@app/hooks/api/reminders";
|
||||
@@ -52,7 +52,7 @@ interface ReminderFormProps {
|
||||
isOpen: boolean;
|
||||
reminderId?: string;
|
||||
onOpenChange: () => void;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
secretId: string;
|
||||
@@ -118,8 +118,8 @@ const useReminderForm = (reminderData?: Reminder) => {
|
||||
|
||||
// Custom hook for workspace members
|
||||
const useWorkspaceMembers = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: members = [] } = useGetWorkspaceUsers(currentWorkspace?.id);
|
||||
const { currentProject } = useProject();
|
||||
const { data: members = [] } = useGetWorkspaceUsers(currentProject?.id);
|
||||
|
||||
const memberOptions = useMemo(
|
||||
(): RecipientOption[] =>
|
||||
@@ -137,7 +137,7 @@ const useWorkspaceMembers = () => {
|
||||
export const CreateReminderForm = ({
|
||||
isOpen,
|
||||
onOpenChange,
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath,
|
||||
secretId,
|
||||
@@ -185,12 +185,12 @@ export const CreateReminderForm = ({
|
||||
const invalidateQueries = () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: dashboardKeys.getDashboardSecrets({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
|
||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: reminderKeys.getReminder(secretId)
|
||||
|
||||
+13
-15
@@ -55,8 +55,8 @@ import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useProjectPermission
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { getProjectBaseURL } from "@app/helpers/project";
|
||||
@@ -120,7 +120,7 @@ export const SecretDetailSidebar = ({
|
||||
] as const);
|
||||
|
||||
const { permission } = useProjectPermission();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const tagFields = useFieldArray({
|
||||
control,
|
||||
@@ -187,7 +187,7 @@ export const SecretDetailSidebar = ({
|
||||
});
|
||||
|
||||
const { data: secretAccessList, isPending } = useGetSecretAccessList({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
environment,
|
||||
secretPath,
|
||||
secretKey
|
||||
@@ -252,9 +252,9 @@ export const SecretDetailSidebar = ({
|
||||
) => {
|
||||
switch (actorType) {
|
||||
case ActorType.USER:
|
||||
return `/projects/secret-management/${currentWorkspace.id}/members/${membershipId}`;
|
||||
return `/projects/secret-management/${currentProject.id}/members/${membershipId}`;
|
||||
case ActorType.IDENTITY:
|
||||
return `/projects/secret-management/${currentWorkspace.id}/identities/${actorId}`;
|
||||
return `/projects/secret-management/${currentProject.id}/identities/${actorId}`;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -367,16 +367,14 @@ export const SecretDetailSidebar = ({
|
||||
/>
|
||||
<Tooltip
|
||||
content={
|
||||
!currentWorkspace.secretSharing
|
||||
!currentProject.secretSharing
|
||||
? "This project does not allow secret sharing."
|
||||
: "You don't have permission to view the secret value."
|
||||
}
|
||||
isDisabled={!secret?.secretValueHidden && currentWorkspace.secretSharing}
|
||||
isDisabled={!secret?.secretValueHidden && currentProject.secretSharing}
|
||||
>
|
||||
<Button
|
||||
isDisabled={
|
||||
secret?.secretValueHidden || !currentWorkspace.secretSharing
|
||||
}
|
||||
isDisabled={secret?.secretValueHidden || !currentProject.secretSharing}
|
||||
className="px-2 py-[0.43rem] font-normal"
|
||||
variant="outline_bg"
|
||||
leftIcon={<FontAwesomeIcon icon={faShare} />}
|
||||
@@ -848,10 +846,10 @@ export const SecretDetailSidebar = ({
|
||||
>
|
||||
<Link
|
||||
to={
|
||||
`${getProjectBaseURL(currentWorkspace.type)}/members/$membershipId` as const
|
||||
`${getProjectBaseURL(currentProject.type)}/members/$membershipId` as const
|
||||
}
|
||||
params={{
|
||||
projectId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
membershipId: user.membershipId
|
||||
}}
|
||||
className="text-secondary/80 rounded-md border border-mineshaft-600 bg-mineshaft-700 px-1 py-0.5 text-sm hover:text-mineshaft-100"
|
||||
@@ -882,10 +880,10 @@ export const SecretDetailSidebar = ({
|
||||
>
|
||||
<Link
|
||||
to={
|
||||
`${getProjectBaseURL(currentWorkspace.type)}/identities/$identityId` as const
|
||||
`${getProjectBaseURL(currentProject.type)}/identities/$identityId` as const
|
||||
}
|
||||
params={{
|
||||
projectId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
identityId: identity.id
|
||||
}}
|
||||
className="text-secondary/80 rounded-md border border-mineshaft-600 bg-mineshaft-700 px-1 py-0.5 text-sm hover:text-mineshaft-100"
|
||||
|
||||
+9
-9
@@ -28,7 +28,7 @@ import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
useProject
|
||||
} from "@app/context";
|
||||
import { usePopUp, useToggle } from "@app/hooks";
|
||||
import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||
@@ -75,7 +75,7 @@ type Props = {
|
||||
onCreateTag: () => void;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
handleSecretShare: () => void;
|
||||
onShareSecret: (sec: SecretV3RawSanitized) => void;
|
||||
importedBy?: {
|
||||
environment: { name: string; slug: string };
|
||||
folders: {
|
||||
@@ -102,7 +102,7 @@ export const SecretItem = memo(
|
||||
onToggleSecretSelect,
|
||||
environment,
|
||||
secretPath,
|
||||
handleSecretShare,
|
||||
onShareSecret,
|
||||
importedBy,
|
||||
isPending,
|
||||
pendingAction,
|
||||
@@ -112,7 +112,7 @@ export const SecretItem = memo(
|
||||
"editSecret",
|
||||
"reminder"
|
||||
] as const);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { permission } = useProjectPermission();
|
||||
const { isRotatedSecret } = secret;
|
||||
const { removePendingChange } = useBatchModeActions();
|
||||
@@ -122,7 +122,7 @@ export const SecretItem = memo(
|
||||
|
||||
const handleDeletePending = (pendingSecret: SecretV3RawSanitized) => {
|
||||
removePendingChange(pendingSecret.id, "secret", {
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -393,7 +393,7 @@ export const SecretItem = memo(
|
||||
<Input
|
||||
autoComplete="off"
|
||||
isReadOnly={isReadOnly || isRotatedSecret}
|
||||
autoCapitalization={currentWorkspace?.autoCapitalization}
|
||||
autoCapitalization={currentProject?.autoCapitalization}
|
||||
variant="plain"
|
||||
isDisabled={isOverridden}
|
||||
placeholder={error?.message}
|
||||
@@ -677,12 +677,12 @@ export const SecretItem = memo(
|
||||
)}
|
||||
</ProjectPermissionCan>
|
||||
<IconButton
|
||||
isDisabled={secret.secretValueHidden || !currentWorkspace.secretSharing}
|
||||
isDisabled={secret.secretValueHidden || !currentProject.secretSharing}
|
||||
className="w-0 overflow-hidden p-0 group-hover:w-5"
|
||||
variant="plain"
|
||||
size="md"
|
||||
ariaLabel="share-secret"
|
||||
onClick={handleSecretShare}
|
||||
onClick={() => onShareSecret(secret)}
|
||||
>
|
||||
<Tooltip content="Share Secret">
|
||||
<FontAwesomeSymbol
|
||||
@@ -974,7 +974,7 @@ export const SecretItem = memo(
|
||||
<CreateReminderForm
|
||||
isOpen={popUp.reminder.isOpen}
|
||||
onOpenChange={() => handlePopUpToggle("reminder")}
|
||||
workspaceId={currentWorkspace.id}
|
||||
projectId={currentProject.id}
|
||||
environment={environment}
|
||||
secretPath={secretPath}
|
||||
secretId={secret?.id}
|
||||
|
||||
+63
-40
@@ -1,4 +1,4 @@
|
||||
import { useCallback } from "react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
@@ -37,7 +37,7 @@ import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
|
||||
type Props = {
|
||||
secrets?: SecretV3RawSanitized[];
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath?: string;
|
||||
tags?: WsTag[];
|
||||
isVisible?: boolean;
|
||||
@@ -57,7 +57,7 @@ type Props = {
|
||||
export const SecretListView = ({
|
||||
secrets = [],
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath = "/",
|
||||
tags: wsTags = [],
|
||||
isVisible,
|
||||
@@ -93,13 +93,18 @@ export const SecretListView = ({
|
||||
message:
|
||||
"You have unsaved changes. If you leave now, your work will be lost. Do you want to continue?",
|
||||
context: {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
}
|
||||
});
|
||||
const { addPendingChange } = useBatchModeActions();
|
||||
|
||||
const pendingChangesRef = useRef(pendingChanges);
|
||||
useEffect(() => {
|
||||
pendingChangesRef.current = pendingChanges;
|
||||
}, [pendingChanges]);
|
||||
|
||||
const handleSecretOperation = async (
|
||||
operation: "create" | "update" | "delete",
|
||||
type: SecretType,
|
||||
@@ -135,7 +140,7 @@ export const SecretListView = ({
|
||||
if (operation === "delete") {
|
||||
await deleteSecretV3({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
type,
|
||||
@@ -156,7 +161,7 @@ export const SecretListView = ({
|
||||
|
||||
await updateSecretV3({
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
...(!isRotatedSecret && {
|
||||
@@ -178,7 +183,7 @@ export const SecretListView = ({
|
||||
await createSecretV3(
|
||||
{
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secretKey: key,
|
||||
secretValue: value || "",
|
||||
@@ -332,12 +337,15 @@ export const SecretListView = ({
|
||||
};
|
||||
|
||||
addPendingChange(updatedCreate, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
} else {
|
||||
const trueOriginalSecret = getTrueOriginalSecret(orgSecret, pendingChanges.secrets);
|
||||
const trueOriginalSecret = getTrueOriginalSecret(
|
||||
orgSecret,
|
||||
pendingChangesRef.current.secrets
|
||||
);
|
||||
|
||||
const updateChange: PendingSecretUpdate = {
|
||||
id: orgSecret.id,
|
||||
@@ -361,7 +369,7 @@ export const SecretListView = ({
|
||||
};
|
||||
|
||||
addPendingChange(updateChange, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -392,27 +400,39 @@ export const SecretListView = ({
|
||||
}
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: dashboardKeys.getDashboardSecrets({
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
|
||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretSnapshotKeys.list({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: secretSnapshotKeys.list({
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretSnapshotKeys.count({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: secretSnapshotKeys.count({
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: commitKeys.count({ projectId, environment, directory: secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: commitKeys.history({
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretApprovalRequestKeys.count({ workspaceId })
|
||||
queryKey: secretApprovalRequestKeys.count({ projectId })
|
||||
});
|
||||
if (!isReminderEvent) {
|
||||
handlePopUpClose("secretDetail");
|
||||
@@ -442,15 +462,7 @@ export const SecretListView = ({
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
environment,
|
||||
secretPath,
|
||||
isProtectedBranch,
|
||||
isBatchMode,
|
||||
workspaceId,
|
||||
addPendingChange,
|
||||
pendingChanges.secrets
|
||||
]
|
||||
[environment, secretPath, isProtectedBranch, isBatchMode, projectId, addPendingChange]
|
||||
);
|
||||
|
||||
const handleSecretDelete = useCallback(async () => {
|
||||
@@ -467,7 +479,7 @@ export const SecretListView = ({
|
||||
};
|
||||
|
||||
addPendingChange(deleteChange, {
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -480,25 +492,33 @@ export const SecretListView = ({
|
||||
await handleSecretOperation("delete", SecretType.Shared, key, { secretId });
|
||||
// wrap this in another function and then reuse
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: dashboardKeys.getDashboardSecrets({ projectId: workspaceId, secretPath })
|
||||
queryKey: dashboardKeys.getDashboardSecrets({ projectId, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretKeys.getProjectSecret({ workspaceId, environment, secretPath })
|
||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretSnapshotKeys.list({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: secretSnapshotKeys.list({
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretSnapshotKeys.count({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: secretSnapshotKeys.count({
|
||||
projectId,
|
||||
environment,
|
||||
directory: secretPath
|
||||
})
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: commitKeys.count({ projectId, environment, directory: secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
|
||||
queryKey: commitKeys.history({ projectId, environment, directory: secretPath })
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: secretApprovalRequestKeys.count({ workspaceId })
|
||||
queryKey: secretApprovalRequestKeys.count({ projectId })
|
||||
});
|
||||
handlePopUpClose("deleteSecret");
|
||||
handlePopUpClose("secretDetail");
|
||||
@@ -521,7 +541,7 @@ export const SecretListView = ({
|
||||
secretPath,
|
||||
isProtectedBranch,
|
||||
isBatchMode,
|
||||
workspaceId,
|
||||
projectId,
|
||||
addPendingChange
|
||||
]);
|
||||
|
||||
@@ -535,6 +555,13 @@ export const SecretListView = ({
|
||||
(sec: SecretV3RawSanitized) => handlePopUpOpen("secretDetail", sec),
|
||||
[]
|
||||
);
|
||||
const onShareSecret = useCallback(
|
||||
(sec: SecretV3RawSanitized) =>
|
||||
handlePopUpOpen("createSharedSecret", {
|
||||
value: sec.valueOverride ?? sec.value
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -557,11 +584,7 @@ export const SecretListView = ({
|
||||
onDetailViewSecret={onDetailViewSecret}
|
||||
importedBy={importedBy}
|
||||
onCreateTag={onCreateTag}
|
||||
handleSecretShare={() =>
|
||||
handlePopUpOpen("createSharedSecret", {
|
||||
value: secret.valueOverride ?? secret.value
|
||||
})
|
||||
}
|
||||
onShareSecret={onShareSecret}
|
||||
isPending={secret.isPending}
|
||||
pendingAction={secret.pendingAction}
|
||||
/>
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import { renderIcon, SecretItem, TDiffModes, TDiffView } from "./SecretItem";
|
||||
type Props = {
|
||||
snapshotId: string;
|
||||
environment: string;
|
||||
workspaceId: string;
|
||||
projectId: string;
|
||||
secretPath?: string;
|
||||
secrets?: SecretV3RawSanitized[];
|
||||
folders?: TSecretFolder[];
|
||||
@@ -43,7 +43,7 @@ const deepCompareSecrets = (lhs: SecretV3RawSanitized, rhs: SecretV3RawSanitized
|
||||
export const SnapshotView = ({
|
||||
snapshotId,
|
||||
environment,
|
||||
workspaceId,
|
||||
projectId,
|
||||
secretPath,
|
||||
secrets = [],
|
||||
folders = [],
|
||||
@@ -130,7 +130,7 @@ export const SnapshotView = ({
|
||||
}
|
||||
try {
|
||||
await performRollback({
|
||||
workspaceId,
|
||||
projectId,
|
||||
snapshotId: snapshotData.id,
|
||||
environment,
|
||||
directory: secretPath
|
||||
|
||||
@@ -10,7 +10,9 @@ import { SecretDashboardPage } from "./SecretDashboardPage";
|
||||
const SecretDashboardPageQueryParamsSchema = z.object({
|
||||
secretPath: z.string().catch("/"),
|
||||
search: z.string().catch(""),
|
||||
tags: z.string().catch("")
|
||||
tags: z.string().catch(""),
|
||||
connectionId: z.string().optional(),
|
||||
connectionName: z.string().optional()
|
||||
});
|
||||
export const Route = createFileRoute(
|
||||
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug"
|
||||
|
||||
@@ -40,9 +40,9 @@ import {
|
||||
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
|
||||
import {
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionSecretRotationActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
@@ -56,7 +56,7 @@ import { TSecretRotationProviderTemplate } from "@app/hooks/api/secretRotation/t
|
||||
import { CreateRotationForm } from "@app/pages/secret-manager/SecretRotationPage/components/CreateRotationForm";
|
||||
|
||||
const Page = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const navigate = useNavigate();
|
||||
@@ -68,7 +68,7 @@ const Page = () => {
|
||||
"upgradePlan",
|
||||
"secretRotationV2"
|
||||
] as const);
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const workspaceId = currentProject?.id || "";
|
||||
const canCreateRotation = permission.can(
|
||||
ProjectPermissionSecretRotationActions.Create,
|
||||
ProjectPermissionSub.SecretRotation
|
||||
@@ -173,7 +173,7 @@ const Page = () => {
|
||||
<Link
|
||||
className="text-mineshaft-100 underline decoration-primary underline-offset-2 hover:text-mineshaft-200"
|
||||
to="/projects/secret-management/$projectId/overview"
|
||||
params={{ projectId: currentWorkspace.id }}
|
||||
params={{ projectId: currentProject.id }}
|
||||
>
|
||||
Secret Manager Dashboard
|
||||
</Link>{" "}
|
||||
@@ -408,7 +408,7 @@ const Page = () => {
|
||||
<Link
|
||||
className="text-mineshaft-100 underline decoration-primary underline-offset-2 hover:text-mineshaft-200"
|
||||
to="/projects/secret-management/$projectId/overview"
|
||||
params={{ projectId: currentWorkspace.id }}
|
||||
params={{ projectId: currentProject.id }}
|
||||
>
|
||||
Secret Manager Dashboard
|
||||
</Link>{" "}
|
||||
@@ -425,7 +425,7 @@ const Page = () => {
|
||||
onClick={() =>
|
||||
navigate({
|
||||
to: "/projects/secret-management/$projectId/overview",
|
||||
params: { projectId: currentWorkspace.id }
|
||||
params: { projectId: currentProject.id }
|
||||
})
|
||||
}
|
||||
colorSchema="secondary"
|
||||
|
||||
+5
-5
@@ -4,7 +4,7 @@ import { z } from "zod";
|
||||
|
||||
import { Button, FormControl, Input, Select, SelectItem, Spinner } from "@app/components/v2";
|
||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useGetProjectSecrets } from "@app/hooks/api";
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -22,9 +22,9 @@ type Props = {
|
||||
};
|
||||
|
||||
export const RotationOutputForm = ({ onSubmit, onCancel, outputSchema = {} }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const environments = currentWorkspace?.environments || [];
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const { currentProject } = useProject();
|
||||
const environments = currentProject?.environments || [];
|
||||
const projectId = currentProject?.id || "";
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
@@ -39,7 +39,7 @@ export const RotationOutputForm = ({ onSubmit, onCancel, outputSchema = {} }: Pr
|
||||
const selectedSecrets = watch("secrets");
|
||||
|
||||
const { data: secrets, isPending: isSecretsLoading } = useGetProjectSecrets({
|
||||
workspaceId,
|
||||
projectId,
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@ import { faFingerprint } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
import { useSubscription, useWorkspace } from "@app/context";
|
||||
import { useProject, useSubscription } from "@app/context";
|
||||
import { EventType } from "@app/hooks/api/auditLogs/enums";
|
||||
import { TSecretSync } from "@app/hooks/api/secretSyncs";
|
||||
import { LogsSection } from "@app/pages/organization/AuditLogsPage/components/LogsSection";
|
||||
@@ -19,7 +19,7 @@ type Props = {
|
||||
|
||||
export const SecretSyncAuditLogsSection = ({ secretSync }: Props) => {
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const auditLogsRetentionDays = subscription?.auditLogsRetentionDays ?? 30;
|
||||
|
||||
@@ -37,7 +37,7 @@ export const SecretSyncAuditLogsSection = ({ secretSync }: Props) => {
|
||||
<LogsSection
|
||||
refetchInterval={4000}
|
||||
showFilters={false}
|
||||
project={currentWorkspace}
|
||||
project={currentProject}
|
||||
presets={{
|
||||
eventMetadata: { syncId: secretSync.id },
|
||||
startDate: new Date(
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Helmet } from "react-helmet";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
||||
import { useProject } from "@app/context";
|
||||
import { ProjectVersion } from "@app/hooks/api/projects/types";
|
||||
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
|
||||
|
||||
import { EncryptionTab } from "./components/EncryptionTab";
|
||||
@@ -13,14 +13,14 @@ import { WorkflowIntegrationTab } from "./components/WorkflowIntegrationSection"
|
||||
|
||||
export const SettingsPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const tabs = [
|
||||
{ name: "General", key: "tab-project-general", Component: ProjectGeneralTab },
|
||||
{ name: "Secrets Management", key: "tab-secret-general", Component: SecretSettingsTab },
|
||||
{
|
||||
name: "Encryption",
|
||||
key: "tab-project-encryption",
|
||||
isHidden: currentWorkspace?.version !== ProjectVersion.V3,
|
||||
isHidden: currentProject?.version !== ProjectVersion.V3,
|
||||
Component: EncryptionTab
|
||||
},
|
||||
{
|
||||
|
||||
+8
-8
@@ -3,22 +3,22 @@ import { useTranslation } from "react-i18next";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Checkbox } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { useToggleAutoCapitalization } from "@app/hooks/api";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api";
|
||||
|
||||
export const AutoCapitalizationSection = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { mutateAsync } = useToggleAutoCapitalization();
|
||||
const { currentProject } = useProject();
|
||||
const { mutateAsync } = useUpdateProject();
|
||||
|
||||
const handleToggleCapitalizationToggle = async (state: boolean) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
await mutateAsync({
|
||||
workspaceID: currentWorkspace.id,
|
||||
state
|
||||
projectId: currentProject.id,
|
||||
autoCapitalization: state
|
||||
});
|
||||
|
||||
const text = `Successfully ${state ? "enabled" : "disabled"} auto capitalization`;
|
||||
@@ -44,7 +44,7 @@ export const AutoCapitalizationSection = () => {
|
||||
<Checkbox
|
||||
id="autoCapitalization"
|
||||
isDisabled={!isAllowed}
|
||||
isChecked={currentWorkspace?.autoCapitalization ?? false}
|
||||
isChecked={currentProject?.autoCapitalization ?? false}
|
||||
onCheckedChange={(state) => {
|
||||
handleToggleCapitalizationToggle(state as boolean);
|
||||
}}
|
||||
|
||||
+4
-4
@@ -1,20 +1,20 @@
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button } from "@app/components/v2";
|
||||
import { useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { useProject, useProjectPermission } from "@app/context";
|
||||
import { useBackfillSecretReference } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
|
||||
export const BackfillSecretReferenceSecretion = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { membership } = useProjectPermission();
|
||||
const backfillSecretReferences = useBackfillSecretReference();
|
||||
|
||||
if (!currentWorkspace) return null;
|
||||
if (!currentProject) return null;
|
||||
|
||||
const handleBackfill = async () => {
|
||||
if (backfillSecretReferences.isPending) return;
|
||||
try {
|
||||
await backfillSecretReferences.mutateAsync({ projectId: currentWorkspace.id || "" });
|
||||
await backfillSecretReferences.mutateAsync({ projectId: currentProject.id || "" });
|
||||
createNotification({ text: "Successfully re-indexed secret references", type: "success" });
|
||||
} catch {
|
||||
createNotification({ text: "Failed to re-index secret references", type: "error" });
|
||||
|
||||
+16
-19
@@ -21,7 +21,7 @@ import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useOrganization,
|
||||
useWorkspace
|
||||
useProject
|
||||
} from "@app/context";
|
||||
import { usePopUp, useToggle } from "@app/hooks";
|
||||
import {
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
} from "@app/hooks/api";
|
||||
import { fetchProjectKmsBackup } from "@app/hooks/api/kms/queries";
|
||||
import { INTERNAL_KMS_KEY_ID, KmsType } from "@app/hooks/api/kms/types";
|
||||
import { Organization, Workspace } from "@app/hooks/api/types";
|
||||
import { Organization, Project } from "@app/hooks/api/types";
|
||||
|
||||
const formSchema = z.object({
|
||||
kmsKeyId: z.string()
|
||||
@@ -44,32 +44,29 @@ const BackupConfirmationModal = ({
|
||||
isOpen,
|
||||
onOpenChange,
|
||||
org,
|
||||
workspace
|
||||
project
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
onOpenChange: (state: boolean) => void;
|
||||
org?: Organization;
|
||||
workspace?: Workspace;
|
||||
project?: Project;
|
||||
}) => {
|
||||
const [isGeneratingBackup, setGeneratingBackup] = useToggle();
|
||||
const downloadKmsBackup = async () => {
|
||||
if (!workspace || !org) {
|
||||
if (!project || !org) {
|
||||
return;
|
||||
}
|
||||
|
||||
setGeneratingBackup.on();
|
||||
|
||||
try {
|
||||
const { secretManager } = await fetchProjectKmsBackup(workspace.id);
|
||||
const { secretManager } = await fetchProjectKmsBackup(project.id);
|
||||
|
||||
const [, , kmsFunction] = secretManager.split(".");
|
||||
const file = secretManager;
|
||||
|
||||
const blob = new Blob([file], { type: "text/plain;charset=utf-8" });
|
||||
FileSaver.saveAs(
|
||||
blob,
|
||||
`kms-backup-${org.slug}-${workspace.slug}-${kmsFunction}.infisical.txt`
|
||||
);
|
||||
FileSaver.saveAs(blob, `kms-backup-${org.slug}-${project.slug}-${kmsFunction}.infisical.txt`);
|
||||
|
||||
onOpenChange(false);
|
||||
} catch (err) {
|
||||
@@ -110,20 +107,20 @@ const LoadBackupModal = ({
|
||||
isOpen,
|
||||
onOpenChange,
|
||||
org,
|
||||
workspace
|
||||
workspace: project
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
onOpenChange: (state: boolean) => void;
|
||||
org?: Organization;
|
||||
workspace: Workspace;
|
||||
workspace: Project;
|
||||
}) => {
|
||||
const fileUploadRef = useRef<HTMLInputElement>(null);
|
||||
const { mutateAsync: loadKmsBackup, isPending } = useLoadProjectKmsBackup(workspace.id);
|
||||
const { mutateAsync: loadKmsBackup, isPending } = useLoadProjectKmsBackup(project.id);
|
||||
const [backupContent, setBackupContent] = useState("");
|
||||
const [backupFileName, setBackupFileName] = useState("");
|
||||
|
||||
const uploadKmsBackup = async () => {
|
||||
if (!workspace || !org) {
|
||||
if (!project || !org) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,13 +219,13 @@ const LoadBackupModal = ({
|
||||
|
||||
export const EncryptionTab = () => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
|
||||
const { data: externalKmsList } = useGetExternalKmsList(currentOrg.id);
|
||||
const { data: activeKms } = useGetActiveProjectKms(currentWorkspace.id);
|
||||
const { data: activeKms } = useGetActiveProjectKms(currentProject.id);
|
||||
|
||||
const { mutateAsync: updateProjectKms, isPending: isUpdatingProjectKms } = useUpdateProjectKms(
|
||||
currentWorkspace.id
|
||||
currentProject.id
|
||||
);
|
||||
const { popUp, handlePopUpToggle, handlePopUpOpen } = usePopUp([
|
||||
"createBackupConfirmation",
|
||||
@@ -336,13 +333,13 @@ export const EncryptionTab = () => {
|
||||
isOpen={popUp.createBackupConfirmation.isOpen}
|
||||
onOpenChange={(state: boolean) => handlePopUpToggle("createBackupConfirmation", state)}
|
||||
org={currentOrg}
|
||||
workspace={currentWorkspace}
|
||||
project={currentProject}
|
||||
/>
|
||||
<LoadBackupModal
|
||||
isOpen={popUp.loadBackup.isOpen}
|
||||
onOpenChange={(state: boolean) => handlePopUpToggle("loadBackup", state)}
|
||||
org={currentOrg}
|
||||
workspace={currentWorkspace}
|
||||
workspace={currentProject}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
+7
-7
@@ -4,15 +4,15 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input, Modal, ModalClose, ModalContent } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useCreateWsEnvironment } from "@app/hooks/api";
|
||||
import { WorkspaceEnv } from "@app/hooks/api/workspace/types";
|
||||
import { ProjectEnv } from "@app/hooks/api/projects/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
onOpenChange: (isOpen: boolean) => void;
|
||||
onComplete?: (environment: WorkspaceEnv) => void;
|
||||
onComplete?: (environment: ProjectEnv) => void;
|
||||
};
|
||||
|
||||
const schema = z.object({
|
||||
@@ -25,11 +25,11 @@ const schema = z.object({
|
||||
export type FormData = z.infer<typeof schema>;
|
||||
|
||||
type ContentProps = {
|
||||
onComplete: (environment: WorkspaceEnv) => void;
|
||||
onComplete: (environment: ProjectEnv) => void;
|
||||
};
|
||||
|
||||
const Content = ({ onComplete }: ContentProps) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { mutateAsync, isPending } = useCreateWsEnvironment();
|
||||
const { control, handleSubmit } = useForm<FormData>({
|
||||
resolver: zodResolver(schema)
|
||||
@@ -37,10 +37,10 @@ const Content = ({ onComplete }: ContentProps) => {
|
||||
|
||||
const onFormSubmit = async ({ environmentName, environmentSlug }: FormData) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
const env = await mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
name: environmentName,
|
||||
slug: environmentSlug
|
||||
});
|
||||
|
||||
+7
-7
@@ -8,9 +8,9 @@ import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProject,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { useDeleteWsEnvironment } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
@@ -21,14 +21,14 @@ import { UpdateEnvironmentModal } from "./UpdateEnvironmentModal";
|
||||
|
||||
export const EnvironmentSection = () => {
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const deleteWsEnvironment = useDeleteWsEnvironment();
|
||||
|
||||
const isMoreEnvironmentsAllowed =
|
||||
subscription?.environmentLimit && currentWorkspace?.environments
|
||||
? currentWorkspace.environments.length < subscription.environmentLimit
|
||||
subscription?.environmentLimit && currentProject?.environments
|
||||
? currentProject.environments.length < subscription.environmentLimit
|
||||
: true;
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||
@@ -40,10 +40,10 @@ export const EnvironmentSection = () => {
|
||||
|
||||
const onEnvDeleteSubmit = async (id: string) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
await deleteWsEnvironment.mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
id
|
||||
});
|
||||
|
||||
|
||||
+13
-16
@@ -18,8 +18,8 @@ import {
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useSubscription
|
||||
} from "@app/context";
|
||||
import { useUpdateWsEnvironment } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -40,17 +40,17 @@ type Props = {
|
||||
};
|
||||
|
||||
export const EnvironmentTable = ({ handlePopUpOpen }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { subscription } = useSubscription();
|
||||
|
||||
const updateEnvironment = useUpdateWsEnvironment();
|
||||
|
||||
const handleReorderEnv = async (id: string, position: number) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
await updateEnvironment.mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
id,
|
||||
position
|
||||
});
|
||||
@@ -69,13 +69,13 @@ export const EnvironmentTable = ({ handlePopUpOpen }: Props) => {
|
||||
};
|
||||
|
||||
const isMoreEnvironmentsAllowed =
|
||||
subscription?.environmentLimit && currentWorkspace?.environments
|
||||
? currentWorkspace.environments.length <= subscription.environmentLimit
|
||||
subscription?.environmentLimit && currentProject?.environments
|
||||
? currentProject.environments.length <= subscription.environmentLimit
|
||||
: true;
|
||||
|
||||
const environmentsOverPlanLimit =
|
||||
subscription?.environmentLimit && currentWorkspace?.environments
|
||||
? Math.max(0, currentWorkspace.environments.length - subscription.environmentLimit)
|
||||
subscription?.environmentLimit && currentProject?.environments
|
||||
? Math.max(0, currentProject.environments.length - subscription.environmentLimit)
|
||||
: 0;
|
||||
|
||||
return (
|
||||
@@ -89,7 +89,7 @@ export const EnvironmentTable = ({ handlePopUpOpen }: Props) => {
|
||||
</Tr>
|
||||
</THead>
|
||||
<TBody>
|
||||
{currentWorkspace.environments.map(({ name, slug, id }, pos) => (
|
||||
{currentProject.environments.map(({ name, slug, id }, pos) => (
|
||||
<Tr key={id}>
|
||||
<Td>{name}</Td>
|
||||
<Td>{slug}</Td>
|
||||
@@ -102,15 +102,12 @@ export const EnvironmentTable = ({ handlePopUpOpen }: Props) => {
|
||||
<IconButton
|
||||
className="mr-3 py-2"
|
||||
onClick={() =>
|
||||
handleReorderEnv(
|
||||
id,
|
||||
Math.min(currentWorkspace.environments.length, pos + 2)
|
||||
)
|
||||
handleReorderEnv(id, Math.min(currentProject.environments.length, pos + 2))
|
||||
}
|
||||
colorSchema="primary"
|
||||
variant="plain"
|
||||
ariaLabel="update"
|
||||
isDisabled={pos === currentWorkspace.environments.length - 1 || !isAllowed}
|
||||
isDisabled={pos === currentProject.environments.length - 1 || !isAllowed}
|
||||
>
|
||||
<FontAwesomeIcon icon={faArrowDown} />
|
||||
</IconButton>
|
||||
@@ -183,7 +180,7 @@ export const EnvironmentTable = ({ handlePopUpOpen }: Props) => {
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
{currentWorkspace.environments?.length === 0 && (
|
||||
{currentProject.environments?.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={3}>
|
||||
<EmptyState title="No environments found" />
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useUpdateWsEnvironment } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
@@ -23,7 +23,7 @@ const schema = z.object({
|
||||
export type FormData = z.infer<typeof schema>;
|
||||
|
||||
export const UpdateEnvironmentModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { mutateAsync, isPending } = useUpdateWsEnvironment();
|
||||
const { control, handleSubmit, reset } = useForm<FormData>({
|
||||
resolver: zodResolver(schema),
|
||||
@@ -34,10 +34,10 @@ export const UpdateEnvironmentModal = ({ popUp, handlePopUpClose, handlePopUpTog
|
||||
|
||||
const onFormSubmit = async ({ name, slug }: FormData) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
await mutateAsync({
|
||||
workspaceId: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
name,
|
||||
slug,
|
||||
id: oldEnvId
|
||||
|
||||
+8
-8
@@ -4,9 +4,9 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input } from "@app/components/v2";
|
||||
import { useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { useProject, useProjectPermission } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { useUpdateWorkspaceVersionLimit } from "@app/hooks/api/workspace/queries";
|
||||
|
||||
const formSchema = z.object({
|
||||
pitVersionLimit: z.coerce.number().min(1).max(100)
|
||||
@@ -15,9 +15,9 @@ const formSchema = z.object({
|
||||
type TForm = z.infer<typeof formSchema>;
|
||||
|
||||
export const PointInTimeVersionLimitSection = () => {
|
||||
const { mutateAsync: updatePitVersion } = useUpdateWorkspaceVersionLimit();
|
||||
const { mutateAsync: updateProject } = useUpdateProject();
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject, projectId } = useProject();
|
||||
const { membership } = useProjectPermission();
|
||||
|
||||
const {
|
||||
@@ -27,17 +27,17 @@ export const PointInTimeVersionLimitSection = () => {
|
||||
} = useForm<TForm>({
|
||||
resolver: zodResolver(formSchema),
|
||||
values: {
|
||||
pitVersionLimit: currentWorkspace?.pitVersionLimit || 10
|
||||
pitVersionLimit: currentProject?.pitVersionLimit || 10
|
||||
}
|
||||
});
|
||||
|
||||
if (!currentWorkspace) return null;
|
||||
if (!currentProject) return null;
|
||||
|
||||
const handleVersionLimitSubmit = async ({ pitVersionLimit }: TForm) => {
|
||||
try {
|
||||
await updatePitVersion({
|
||||
await updateProject({
|
||||
pitVersionLimit,
|
||||
projectSlug: currentWorkspace.slug
|
||||
projectId
|
||||
});
|
||||
|
||||
createNotification({
|
||||
|
||||
+6
-6
@@ -7,7 +7,7 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, IconButton, Input } from "@app/components/v2";
|
||||
import { useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { useProject, useProjectPermission } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
|
||||
@@ -23,7 +23,7 @@ const formSchema = z.object({
|
||||
type TForm = z.infer<typeof formSchema>;
|
||||
|
||||
export const SecretDetectionIgnoreValuesSection = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { membership } = useProjectPermission();
|
||||
const { mutateAsync: updateProject } = useUpdateProject();
|
||||
|
||||
@@ -45,19 +45,19 @@ export const SecretDetectionIgnoreValuesSection = () => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const existingIgnoreValues = currentWorkspace?.secretDetectionIgnoreValues || [];
|
||||
const existingIgnoreValues = currentProject?.secretDetectionIgnoreValues || [];
|
||||
reset({
|
||||
ignoreValues:
|
||||
existingIgnoreValues.length > 0
|
||||
? existingIgnoreValues.map((value) => ({ value }))
|
||||
: [{ value: "" }] // Show one empty field by default
|
||||
});
|
||||
}, [currentWorkspace?.secretDetectionIgnoreValues, reset]);
|
||||
}, [currentProject?.secretDetectionIgnoreValues, reset]);
|
||||
|
||||
const handleIgnoreValuesSubmit = async ({ ignoreValues }: TForm) => {
|
||||
try {
|
||||
await updateProject({
|
||||
projectID: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
secretDetectionIgnoreValues: ignoreValues.map((item) => item.value)
|
||||
});
|
||||
|
||||
@@ -75,7 +75,7 @@ export const SecretDetectionIgnoreValuesSection = () => {
|
||||
|
||||
const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin);
|
||||
|
||||
if (!currentWorkspace) return null;
|
||||
if (!currentProject) return null;
|
||||
|
||||
return (
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
|
||||
+6
-6
@@ -3,11 +3,11 @@ import { useState } from "react";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Checkbox } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api/workspace/queries";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api/projects/queries";
|
||||
|
||||
export const SecretSharingSection = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { mutateAsync: updateProject } = useUpdateProject();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -16,13 +16,13 @@ export const SecretSharingSection = () => {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
if (!currentWorkspace?.id) {
|
||||
if (!currentProject?.id) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await updateProject({
|
||||
projectID: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
secretSharing: state
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ export const SecretSharingSection = () => {
|
||||
<Checkbox
|
||||
id="secretSharing"
|
||||
isDisabled={!isAllowed || isLoading}
|
||||
isChecked={currentWorkspace?.secretSharing ?? true}
|
||||
isChecked={currentProject?.secretSharing ?? true}
|
||||
onCheckedChange={(state) => handleToggle(state as boolean)}
|
||||
>
|
||||
This feature enables your project members to securely share secrets.
|
||||
|
||||
+6
-6
@@ -3,11 +3,11 @@ import { useState } from "react";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Checkbox } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api/workspace/queries";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import { useUpdateProject } from "@app/hooks/api/projects/queries";
|
||||
|
||||
export const SecretSnapshotsLegacySection = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { mutateAsync: updateProject } = useUpdateProject();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -16,13 +16,13 @@ export const SecretSnapshotsLegacySection = () => {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
if (!currentWorkspace?.id) {
|
||||
if (!currentProject?.id) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await updateProject({
|
||||
projectID: currentWorkspace.id,
|
||||
projectId: currentProject.id,
|
||||
showSnapshotsLegacy: state
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ export const SecretSnapshotsLegacySection = () => {
|
||||
<Checkbox
|
||||
id="showSnapshotsLegacy"
|
||||
isDisabled={!isAllowed || isLoading}
|
||||
isChecked={currentWorkspace?.showSnapshotsLegacy ?? false}
|
||||
isChecked={currentProject?.showSnapshotsLegacy ?? false}
|
||||
onCheckedChange={(state) => handleToggle(state as boolean)}
|
||||
>
|
||||
This feature enables your project members to view secret snapshots in the legacy
|
||||
|
||||
+5
-5
@@ -4,7 +4,7 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input, Modal, ModalClose, ModalContent } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useProject } from "@app/context";
|
||||
import { useCreateWsTag } from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
@@ -27,7 +27,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const AddSecretTagModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const createWsTag = useCreateWsTag();
|
||||
const {
|
||||
control,
|
||||
@@ -40,10 +40,10 @@ export const AddSecretTagModal = ({ popUp, handlePopUpClose, handlePopUpToggle }
|
||||
|
||||
const onFormSubmit = async ({ slug }: FormData) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) return;
|
||||
if (!currentProject?.id) return;
|
||||
|
||||
await createWsTag.mutateAsync({
|
||||
workspaceID: currentWorkspace?.id,
|
||||
projectId: currentProject?.id,
|
||||
tagSlug: slug,
|
||||
tagColor: ""
|
||||
});
|
||||
@@ -73,7 +73,7 @@ export const AddSecretTagModal = ({ popUp, handlePopUpClose, handlePopUpToggle }
|
||||
}}
|
||||
>
|
||||
<ModalContent
|
||||
title={`Add a tag for ${currentWorkspace?.name ?? ""}`}
|
||||
title={`Add a tag for ${currentProject?.name ?? ""}`}
|
||||
subTitle="Specify your tag name, and the slug will be created automatically."
|
||||
>
|
||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||
|
||||
+4
-4
@@ -7,8 +7,8 @@ import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
useProject,
|
||||
useProjectPermission
|
||||
} from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useDeleteWsTag } from "@app/hooks/api";
|
||||
@@ -23,7 +23,7 @@ export const SecretTagsSection = (): JSX.Element => {
|
||||
"CreateSecretTag",
|
||||
"deleteTagConfirmation"
|
||||
] as const);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentProject } = useProject();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const deleteWsTag = useDeleteWsTag();
|
||||
@@ -31,7 +31,7 @@ export const SecretTagsSection = (): JSX.Element => {
|
||||
const onDeleteApproved = async () => {
|
||||
try {
|
||||
await deleteWsTag.mutateAsync({
|
||||
projectId: currentWorkspace?.id || "",
|
||||
projectId: currentProject?.id || "",
|
||||
tagID: (popUp?.deleteTagConfirmation?.data as DeleteModalData)?.id
|
||||
});
|
||||
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context";
|
||||
import {
|
||||
getUserTablePreference,
|
||||
PreferenceKey,
|
||||
@@ -53,8 +53,8 @@ enum TagsOrderBy {
|
||||
}
|
||||
|
||||
export const SecretTagsTable = ({ handlePopUpOpen }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: tags = [], isPending } = useGetWsTags(currentWorkspace?.id ?? "");
|
||||
const { currentProject } = useProject();
|
||||
const { data: tags = [], isPending } = useGetWsTags(currentProject?.id ?? "");
|
||||
|
||||
const {
|
||||
search,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user