mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-09 23:48:05 -05:00
improvement: native integration legacy details and sync redirects
This commit is contained in:
@@ -31,6 +31,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
|
||||
.object({
|
||||
name: z.string(),
|
||||
slug: z.string(),
|
||||
syncSlug: z.string().optional(),
|
||||
clientSlug: z.string().optional(),
|
||||
image: z.string(),
|
||||
isAvailable: z.boolean().optional(),
|
||||
|
||||
@@ -195,6 +195,7 @@ export const getIntegrationOptions = async () => {
|
||||
{
|
||||
name: "AWS Secrets Manager",
|
||||
slug: "aws-secret-manager",
|
||||
syncSlug: "aws-secrets-manager",
|
||||
image: "Amazon Web Services.png",
|
||||
isAvailable: true,
|
||||
type: "custom",
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "AWS Parameter Store"
|
||||
description: "Learn how to sync secrets from Infisical to AWS Parameter Store."
|
||||
---
|
||||
|
||||
<Note>
|
||||
The AWS Parameter Store Native Integration will be deprecated in 2026. Please migrate to our new [AWS Parameter Store Sync](../secret-syncs/aws-parameter-store).
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Assume Role (Recommended)">
|
||||
Infisical will assume the provided role in your AWS account securely, without the need to share any credentials.
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "AWS Secrets Manager"
|
||||
description: "Learn how to sync secrets from Infisical to AWS Secrets Manager."
|
||||
---
|
||||
|
||||
<Note>
|
||||
The AWS Secrets Manager Native Integration will be deprecated in 2026. Please migrate to our new [AWS Secrets Manager Sync](../secret-syncs/aws-secrets-manager).
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Assume Role (Recommended)">
|
||||
Infisical will assume the provided role in your AWS account securely, without the need to share any credentials.
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "Azure App Configuration"
|
||||
description: "How to sync secrets from Infisical to Azure App Configuration"
|
||||
---
|
||||
|
||||
<Note>
|
||||
The Azure App Configuration Native Integration will be deprecated in 2026. Please migrate to our new [Azure App Configuration Sync](../secret-syncs/azure-app-configuration).
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Usage">
|
||||
**Prerequisites:**
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "Azure Key Vault"
|
||||
description: "How to sync secrets from Infisical to Azure Key Vault"
|
||||
---
|
||||
|
||||
<Note>
|
||||
The Azure Key Vault Native Integration will be deprecated in 2026. Please migrate to our new [Azure Key Vault Sync](../secret-syncs/azure-key-vault).
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Usage">
|
||||
Prerequisites:
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "Databricks"
|
||||
description: "Learn how to sync secrets from Infisical to Databricks."
|
||||
---
|
||||
|
||||
<Note>
|
||||
The Databricks Native Integration will be deprecated in 2026. Please migrate to our new [Databricks Sync](../secret-syncs/databricks).
|
||||
</Note>
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Set up and add secrets to [Infisical Cloud](https://app.infisical.com)
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "GCP Secret Manager"
|
||||
description: "How to sync secrets from Infisical to GCP Secret Manager"
|
||||
---
|
||||
|
||||
<Note>
|
||||
The GCP Secret Manager Native Integration will be deprecated in 2026. Please migrate to our new [GCP Secret Manager Sync](../secret-syncs/gcp-secret-manager).
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Usage">
|
||||
<AccordionGroup>
|
||||
|
||||
@@ -3,6 +3,10 @@ title: "Terraform Cloud"
|
||||
description: "How to sync secrets from Infisical to Terraform Cloud"
|
||||
---
|
||||
|
||||
<Note>
|
||||
The Terraform Cloud Native Integration will be deprecated in 2026. Please migrate to our new [Terraform Cloud Sync](../secret-syncs/terraform-cloud).
|
||||
</Note>
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Set up and add envars to [Infisical Cloud](https://app.infisical.com)
|
||||
|
||||
@@ -3,6 +3,11 @@ title: "Vercel"
|
||||
description: "How to sync secrets from Infisical to Vercel"
|
||||
---
|
||||
|
||||
<Note>
|
||||
The Vercel Native Integration will be deprecated in 2026. Please migrate to our new [Vercel Sync](../secret-syncs/vercel).
|
||||
</Note>
|
||||
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Usage">
|
||||
Prerequisites:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { Modal, ModalContent } from "@app/components/v2";
|
||||
import { SecretSync, TSecretSync } from "@app/hooks/api/secretSyncs";
|
||||
@@ -10,6 +10,7 @@ import { SecretSyncSelect } from "./SecretSyncSelect";
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
onOpenChange: (isOpen: boolean) => void;
|
||||
selectSync?: SecretSync | null;
|
||||
};
|
||||
|
||||
type ContentProps = {
|
||||
@@ -32,8 +33,12 @@ const Content = ({ onComplete, setSelectedSync, selectedSync }: ContentProps) =>
|
||||
return <SecretSyncSelect onSelect={setSelectedSync} />;
|
||||
};
|
||||
|
||||
export const CreateSecretSyncModal = ({ onOpenChange, ...props }: Props) => {
|
||||
const [selectedSync, setSelectedSync] = useState<SecretSync | null>(null);
|
||||
export const CreateSecretSyncModal = ({ onOpenChange, selectSync = null, ...props }: Props) => {
|
||||
const [selectedSync, setSelectedSync] = useState<SecretSync | null>(selectSync);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedSync(selectSync);
|
||||
}, [selectSync]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export type TCloudIntegration = {
|
||||
name: string;
|
||||
slug: string;
|
||||
syncSlug?: string;
|
||||
image: string;
|
||||
isAvailable: boolean;
|
||||
type: string;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Badge, PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { Badge, PageHeader, Tab, TabList, TabPanel, Tabs, Tooltip } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
@@ -51,46 +51,19 @@ export const IntegrationsListPage = () => {
|
||||
title="Integrations"
|
||||
description="Manage integrations with third-party services."
|
||||
/>
|
||||
<div className="mb-4 mt-4 flex flex-col rounded-r border-l-2 border-l-primary bg-mineshaft-300/5 px-4 py-2.5">
|
||||
<div className="mb-1 flex items-center text-sm">
|
||||
<FontAwesomeIcon icon={faInfoCircle} size="sm" className="mr-1.5 text-primary" />
|
||||
Integrations Update
|
||||
</div>
|
||||
<p className="mb-2 mt-1 text-sm text-bunker-300">
|
||||
Infisical is excited to announce{" "}
|
||||
<a
|
||||
className="text-bunker-200 underline decoration-primary-700 underline-offset-4 duration-200 hover:text-mineshaft-100 hover:decoration-primary-600"
|
||||
href="https://infisical.com/docs/integrations/secret-syncs/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Secret Syncs
|
||||
</a>
|
||||
, a new way to sync your secrets to third-party services using{" "}
|
||||
<a
|
||||
className="text-bunker-200 underline decoration-primary-700 underline-offset-4 duration-200 hover:text-mineshaft-100 hover:decoration-primary-600"
|
||||
href="https://infisical.com/docs/integrations/app-connections/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
App Connections
|
||||
</a>
|
||||
, offering deeper customization and re-configurability.
|
||||
</p>
|
||||
<p className="text-sm text-bunker-300">
|
||||
Existing integrations (now called Native Integrations) will continue to be supported
|
||||
as we build out our Secret Sync library.
|
||||
</p>
|
||||
</div>
|
||||
<Tabs value={selectedTab} onValueChange={updateSelectedTab}>
|
||||
<TabList>
|
||||
<Tab value={IntegrationsListPageTabs.SecretSyncs}>
|
||||
Secret Syncs
|
||||
<Badge variant="primary" className="ml-1 cursor-pointer text-xs">
|
||||
New
|
||||
</Badge>
|
||||
<Tab value={IntegrationsListPageTabs.SecretSyncs}>Secret Syncs</Tab>
|
||||
<Tab value={IntegrationsListPageTabs.NativeIntegrations}>
|
||||
Native Integrations
|
||||
<Tooltip content="Native Integrations will be deprecated in 2026. Please migrate to Secret Syncs as they become available.">
|
||||
<div>
|
||||
<Badge variant="primary" className="ml-1 cursor-pointer text-xs">
|
||||
Legacy
|
||||
</Badge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Tab>
|
||||
<Tab value={IntegrationsListPageTabs.NativeIntegrations}>Native Integrations</Tab>
|
||||
<Tab value={IntegrationsListPageTabs.FrameworkIntegrations}>
|
||||
Framework Integrations
|
||||
</Tab>
|
||||
@@ -108,6 +81,26 @@ export const IntegrationsListPage = () => {
|
||||
</ProjectPermissionCan>
|
||||
</TabPanel>
|
||||
<TabPanel value={IntegrationsListPageTabs.NativeIntegrations}>
|
||||
<div className="mb-5 flex flex-col rounded-r border-l-2 border-l-primary bg-mineshaft-300/5 px-4 py-2.5">
|
||||
<div className="mb-1 flex items-center text-sm">
|
||||
<FontAwesomeIcon icon={faInfoCircle} size="sm" className="mr-1.5 text-primary" />
|
||||
Native Integrations Transitioning to Legacy Status
|
||||
</div>
|
||||
<p className="mb-2 mt-1 text-sm text-bunker-300">
|
||||
Native integrations are now a legacy feature and will begin deprecation in 2026.
|
||||
We recommend migrating to our new{" "}
|
||||
<a
|
||||
className="text-bunker-200 underline decoration-primary-700 underline-offset-4 duration-200 hover:text-mineshaft-100 hover:decoration-primary-600"
|
||||
href="https://infisical.com/docs/integrations/secret-syncs/overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Secret Syncs
|
||||
</a>{" "}
|
||||
feature which offers the same functionality as Native Integrations with improved
|
||||
stability, insights, re-configurability, and customization.
|
||||
</p>
|
||||
</div>
|
||||
<ProjectPermissionCan
|
||||
renderGuardBanner
|
||||
I={ProjectPermissionActions.Read}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
|
||||
import { NoEnvironmentsBanner } from "@app/components/integrations/NoEnvironmentsBanner";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
Skeleton,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -26,7 +28,9 @@ import {
|
||||
useWorkspace
|
||||
} from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
import { IntegrationAuth, TCloudIntegration } from "@app/hooks/api/types";
|
||||
import { IntegrationsListPageTabs } from "@app/types/integrations";
|
||||
|
||||
type Props = {
|
||||
isLoading?: boolean;
|
||||
@@ -40,6 +44,10 @@ type Props = {
|
||||
|
||||
type TRevokeIntegrationPopUp = { provider: string };
|
||||
|
||||
const SECRET_SYNCS = Object.values(SecretSync) as string[];
|
||||
// this assumes sync and integration will have same name which looks like it will be the case
|
||||
const isSecretSyncAvailable = (type: string) => SECRET_SYNCS.includes(type);
|
||||
|
||||
export const CloudIntegrationSection = ({
|
||||
isLoading,
|
||||
cloudIntegrations = [],
|
||||
@@ -54,6 +62,7 @@ export const CloudIntegrationSection = ({
|
||||
] as const);
|
||||
const { permission } = useProjectPermission();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isEmpty = !isLoading && !cloudIntegrations?.length;
|
||||
|
||||
@@ -111,73 +120,104 @@ export const CloudIntegrationSection = ({
|
||||
))}
|
||||
|
||||
{!isLoading && filteredIntegrations.length ? (
|
||||
filteredIntegrations.map((cloudIntegration) => (
|
||||
<div
|
||||
onKeyDown={() => null}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className={`group relative ${
|
||||
cloudIntegration.isAvailable
|
||||
? "cursor-pointer duration-200 hover:bg-mineshaft-700"
|
||||
: "opacity-50"
|
||||
} flex h-32 flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4`}
|
||||
onClick={() => {
|
||||
if (!cloudIntegration.isAvailable) return;
|
||||
if (
|
||||
permission.cannot(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.Integrations
|
||||
)
|
||||
) {
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "You do not have permission to create an integration"
|
||||
});
|
||||
return;
|
||||
}
|
||||
onIntegrationStart(cloudIntegration.slug);
|
||||
}}
|
||||
key={cloudIntegration.slug}
|
||||
>
|
||||
<img
|
||||
src={`/images/integrations/${cloudIntegration.image}`}
|
||||
height={60}
|
||||
width={60}
|
||||
className="mt-auto"
|
||||
alt="integration logo"
|
||||
/>
|
||||
<div className="mt-auto max-w-xs text-center text-sm font-semibold text-gray-300 duration-200 group-hover:text-gray-200">
|
||||
{cloudIntegration.name}
|
||||
</div>
|
||||
{cloudIntegration.isAvailable &&
|
||||
Boolean(integrationAuths?.[cloudIntegration.slug]) && (
|
||||
<div className="absolute right-0 top-0 z-30 h-full">
|
||||
<div className="relative h-full">
|
||||
<div className="absolute right-0 top-0 w-24 flex-row items-center overflow-hidden whitespace-nowrap rounded-bl-md rounded-tr-md bg-primary px-2 py-0.5 text-xs text-black opacity-80 transition-all duration-300 group-hover:w-0 group-hover:p-0">
|
||||
<FontAwesomeIcon icon={faCheck} className="mr-2 text-xs" />
|
||||
Authorized
|
||||
</div>
|
||||
<Tooltip content="Revoke Access">
|
||||
<div
|
||||
onKeyDown={() => null}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={async (event) => {
|
||||
event.stopPropagation();
|
||||
handlePopUpOpen("deleteConfirmation", {
|
||||
provider: cloudIntegration.slug
|
||||
});
|
||||
}}
|
||||
className="absolute right-0 top-0 flex h-0 w-12 cursor-pointer items-center justify-center overflow-hidden rounded-r-md bg-red text-xs opacity-50 transition-all duration-300 hover:opacity-100 group-hover:h-full"
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} size="xl" />
|
||||
filteredIntegrations.map((cloudIntegration) => {
|
||||
const syncSlug = cloudIntegration.syncSlug ?? cloudIntegration.slug;
|
||||
const isSyncAvailable = isSecretSyncAvailable(syncSlug);
|
||||
|
||||
return (
|
||||
<div
|
||||
onKeyDown={() => null}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className={`group relative ${
|
||||
cloudIntegration.isAvailable
|
||||
? "cursor-pointer duration-200 hover:bg-mineshaft-700"
|
||||
: "opacity-50"
|
||||
} flex h-36 flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-3`}
|
||||
onClick={() => {
|
||||
if (isSyncAvailable) {
|
||||
navigate({
|
||||
to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path,
|
||||
params: {
|
||||
projectId: currentWorkspace.id
|
||||
},
|
||||
search: {
|
||||
selectedTab: IntegrationsListPageTabs.SecretSyncs,
|
||||
addSync: syncSlug as SecretSync
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!cloudIntegration.isAvailable) return;
|
||||
if (
|
||||
permission.cannot(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.Integrations
|
||||
)
|
||||
) {
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "You do not have permission to create an integration"
|
||||
});
|
||||
return;
|
||||
}
|
||||
onIntegrationStart(cloudIntegration.slug);
|
||||
}}
|
||||
key={cloudIntegration.slug}
|
||||
>
|
||||
<div className="m-auto flex flex-col items-center">
|
||||
<img
|
||||
src={`/images/integrations/${cloudIntegration.image}`}
|
||||
height={60}
|
||||
width={60}
|
||||
className="mt-auto"
|
||||
alt="integration logo"
|
||||
/>
|
||||
<div
|
||||
className={`mt-2 max-w-xs text-center text-sm font-semibold text-gray-300 duration-200 group-hover:text-gray-200 ${isSyncAvailable ? "mb-4" : ""}`}
|
||||
>
|
||||
{cloudIntegration.name}
|
||||
</div>
|
||||
</div>
|
||||
{cloudIntegration.isAvailable &&
|
||||
Boolean(integrationAuths?.[cloudIntegration.slug]) && (
|
||||
<div className="absolute right-0 top-0 z-30 h-full">
|
||||
<div className="relative h-full">
|
||||
<div className="absolute right-0 top-0 w-24 flex-row items-center overflow-hidden whitespace-nowrap rounded-bl-md rounded-tr-md bg-primary px-2 py-0.5 text-xs text-black opacity-80 transition-all duration-300 group-hover:w-0 group-hover:p-0">
|
||||
<FontAwesomeIcon icon={faCheck} className="mr-2 text-xs" />
|
||||
Authorized
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip content="Revoke Access">
|
||||
<div
|
||||
onKeyDown={() => null}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={async (event) => {
|
||||
event.stopPropagation();
|
||||
handlePopUpOpen("deleteConfirmation", {
|
||||
provider: cloudIntegration.slug
|
||||
});
|
||||
}}
|
||||
className="absolute right-0 top-0 flex h-0 w-12 cursor-pointer items-center justify-center overflow-hidden rounded-r-md bg-red text-xs opacity-50 transition-all duration-300 hover:opacity-100 group-hover:h-full"
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} size="xl" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isSyncAvailable && (
|
||||
<div className="absolute bottom-0 left-0 z-30 h-full w-full">
|
||||
<div className="relative h-full">
|
||||
<div className="absolute bottom-0 left-0 w-full flex-row overflow-hidden whitespace-nowrap rounded-bl-md rounded-br-md bg-yellow/20 px-2 py-0.5 text-center text-xs text-yellow">
|
||||
Secret Sync Available
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<EmptyState
|
||||
className="col-span-full h-32 w-full rounded-md bg-transparent pt-14"
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { useEffect } 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 { Button, Spinner } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
@@ -14,8 +17,27 @@ import { SecretSyncsTable } from "./SecretSyncTable";
|
||||
export const SecretSyncsTab = () => {
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["addSync"] as const);
|
||||
|
||||
const { addSync, ...search } = useSearch({
|
||||
from: ROUTE_PATHS.SecretManager.IntegrationsListPage.id
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
|
||||
useEffect(() => {
|
||||
if (!addSync) return;
|
||||
|
||||
handlePopUpOpen("addSync", addSync);
|
||||
navigate({
|
||||
to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path,
|
||||
params: {
|
||||
projectId: currentWorkspace.id
|
||||
},
|
||||
search
|
||||
});
|
||||
}, [addSync]);
|
||||
|
||||
const { data: secretSyncs = [], isPending: isSecretSyncsPending } = useListSecretSyncs(
|
||||
currentWorkspace.id,
|
||||
{
|
||||
@@ -76,6 +98,7 @@ export const SecretSyncsTab = () => {
|
||||
<SecretSyncsTable secretSyncs={secretSyncs} />
|
||||
</div>
|
||||
<CreateSecretSyncModal
|
||||
selectSync={popUp.addSync.data}
|
||||
isOpen={popUp.addSync.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("addSync", isOpen)}
|
||||
/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { workspaceKeys } from "@app/hooks/api";
|
||||
import { TIntegration } from "@app/hooks/api/integrations/types";
|
||||
import {
|
||||
fetchSecretSyncsByProjectId,
|
||||
SecretSync,
|
||||
secretSyncKeys,
|
||||
TSecretSync
|
||||
} from "@app/hooks/api/secretSyncs";
|
||||
@@ -15,7 +16,8 @@ import { IntegrationsListPageTabs } from "@app/types/integrations";
|
||||
import { IntegrationsListPage } from "./IntegrationsListPage";
|
||||
|
||||
const IntegrationsListPageQuerySchema = z.object({
|
||||
selectedTab: z.nativeEnum(IntegrationsListPageTabs).optional()
|
||||
selectedTab: z.nativeEnum(IntegrationsListPageTabs).optional(),
|
||||
addSync: z.nativeEnum(SecretSync).optional()
|
||||
});
|
||||
|
||||
export const Route = createFileRoute(
|
||||
|
||||
Reference in New Issue
Block a user