mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 06:45:28 +00:00
feat: admin slack configuration
This commit is contained in:
@@ -25,6 +25,7 @@ import { useOrganization, useServerConfig, useUser } from "@app/context";
|
||||
import { useGetOrganizations, useUpdateServerConfig } from "@app/hooks/api";
|
||||
|
||||
import { AuthPanel } from "./AuthPanel";
|
||||
import { IntegrationPanel } from "./IntegrationPanel";
|
||||
import { RateLimitPanel } from "./RateLimitPanel";
|
||||
import { UserPanel } from "./UserPanel";
|
||||
|
||||
@@ -32,6 +33,7 @@ enum TabSections {
|
||||
Settings = "settings",
|
||||
Auth = "auth",
|
||||
RateLimit = "rate-limit",
|
||||
Integrations = "integrations",
|
||||
Users = "users"
|
||||
}
|
||||
|
||||
@@ -137,6 +139,7 @@ export const AdminDashboardPage = () => {
|
||||
<Tab value={TabSections.Settings}>General</Tab>
|
||||
<Tab value={TabSections.Auth}>Authentication</Tab>
|
||||
<Tab value={TabSections.RateLimit}>Rate Limit</Tab>
|
||||
<Tab value={TabSections.Integrations}>Integrations</Tab>
|
||||
<Tab value={TabSections.Users}>Users</Tab>
|
||||
</div>
|
||||
</TabList>
|
||||
@@ -323,6 +326,9 @@ export const AdminDashboardPage = () => {
|
||||
<TabPanel value={TabSections.RateLimit}>
|
||||
<RateLimitPanel />
|
||||
</TabPanel>
|
||||
<TabPanel value={TabSections.Integrations}>
|
||||
<IntegrationPanel />
|
||||
</TabPanel>
|
||||
<TabPanel value={TabSections.Users}>
|
||||
<UserPanel />
|
||||
</TabPanel>
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input } from "@app/components/v2";
|
||||
import {
|
||||
useGetAdminSlackConfig,
|
||||
useGetCustomSlackAppCreationUrl,
|
||||
useUpdateAdminSlackConfig
|
||||
} from "@app/hooks/api";
|
||||
|
||||
const slackFormSchema = z.object({
|
||||
clientId: z.string(),
|
||||
clientSecret: z.string()
|
||||
});
|
||||
|
||||
type TSlackForm = z.infer<typeof slackFormSchema>;
|
||||
|
||||
export const IntegrationPanel = () => {
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { isSubmitting, isDirty }
|
||||
} = useForm<TSlackForm>({
|
||||
resolver: zodResolver(slackFormSchema)
|
||||
});
|
||||
|
||||
const { data: customSlackAppCreationUrl } = useGetCustomSlackAppCreationUrl();
|
||||
const { data: adminSlackConfig } = useGetAdminSlackConfig();
|
||||
|
||||
const { mutateAsync: updateAdminSlackConfig } = useUpdateAdminSlackConfig();
|
||||
|
||||
useEffect(() => {
|
||||
if (adminSlackConfig) {
|
||||
setValue("clientId", adminSlackConfig.clientId);
|
||||
setValue("clientSecret", adminSlackConfig.clientSecret);
|
||||
}
|
||||
}, [adminSlackConfig]);
|
||||
|
||||
const onSlackFormSubmit = async (data: TSlackForm) => {
|
||||
await updateAdminSlackConfig(data);
|
||||
|
||||
createNotification({
|
||||
text: "Updated admin slack configuration",
|
||||
type: "success"
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4"
|
||||
onSubmit={handleSubmit(onSlackFormSubmit)}
|
||||
>
|
||||
<div className="flex flex-col justify-start">
|
||||
<div className="mb-2 text-xl font-semibold text-mineshaft-100">Slack Integration</div>
|
||||
<div className="mb-4 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 1: Create your Infisical Slack App
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<Button colorSchema="secondary" onClick={() => window.open(customSlackAppCreationUrl)}>
|
||||
Create Slack App
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-4 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 2: Configure your instance-wide settings to enable integration with Slack. Copy the
|
||||
values from the App Credentials page of your custom Slack App.
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="clientId"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Client ID"
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="clientSecret"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Client Secret"
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
className="mt-2"
|
||||
type="submit"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting || !isDirty}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user