mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
smaller ui improvements
This commit is contained in:
@@ -93,8 +93,6 @@ export const WorkflowIntegrationTab = () => {
|
||||
<THead>
|
||||
<Tr>
|
||||
<Td>Provider</Td>
|
||||
<Td>Access Request Notifications</Td>
|
||||
<Td>Secret Request Notifications</Td>
|
||||
<Td>Access Request Notifications Destination</Td>
|
||||
<Td>Secret Request Notifications Destination</Td>
|
||||
<Td />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import { BsMicrosoftTeams } from "react-icons/bs";
|
||||
import { faCheck, faEllipsis, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faEllipsis } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
@@ -34,10 +35,11 @@ type Props = {
|
||||
|
||||
export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: microsoftTeamsConfig } = useGetWorkspaceWorkflowIntegrationConfig({
|
||||
workspaceId: currentWorkspace?.id ?? "",
|
||||
integration: WorkflowIntegrationPlatform.MICROSOFT_TEAMS
|
||||
});
|
||||
const { data: microsoftTeamsConfig, isPending: isMicrosoftTeamsConfigLoading } =
|
||||
useGetWorkspaceWorkflowIntegrationConfig({
|
||||
workspaceId: currentWorkspace?.id ?? "",
|
||||
integration: WorkflowIntegrationPlatform.MICROSOFT_TEAMS
|
||||
});
|
||||
|
||||
const { data: microsoftTeamsChannels, isPending: isMicrosoftTeamsChannelsLoading } =
|
||||
useGetMicrosoftTeamsIntegrationTeams(microsoftTeamsConfig?.integrationId);
|
||||
@@ -51,6 +53,8 @@ export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isLoadingConfig = isMicrosoftTeamsChannelsLoading || isMicrosoftTeamsConfigLoading;
|
||||
|
||||
return (
|
||||
<Tr>
|
||||
<Td className="flex max-w-xs items-center overflow-hidden text-ellipsis">
|
||||
@@ -60,39 +64,33 @@ export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
{microsoftTeamsConfig.isAccessRequestNotificationEnabled ? (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-green-500" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faXmark} className="text-red-500" />
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
{microsoftTeamsConfig.isSecretRequestNotificationEnabled ? (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-green-500" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faXmark} className="text-red-500" />
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
{isMicrosoftTeamsChannelsLoading ? (
|
||||
<Spinner size="xs" />
|
||||
) : (
|
||||
{microsoftTeamsConfig.isAccessRequestNotificationEnabled &&
|
||||
!isLoadingConfig &&
|
||||
microsoftTeamsConfig.accessRequestChannels?.channelIds?.length > 0 ? (
|
||||
<Badge>
|
||||
{(microsoftTeamsConfig.accessRequestChannels?.channelIds || [])
|
||||
?.map((channel) => microsoftTeamsChannelIdToName[channel])
|
||||
{microsoftTeamsConfig.accessRequestChannels.channelIds
|
||||
.map((channel) => microsoftTeamsChannelIdToName[channel])
|
||||
.join(", ")}
|
||||
</Badge>
|
||||
) : isLoadingConfig ? (
|
||||
<Spinner size="xs" />
|
||||
) : (
|
||||
<Badge variant="danger">Disabled</Badge>
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
{isMicrosoftTeamsChannelsLoading ? (
|
||||
<Spinner size="xs" />
|
||||
) : (
|
||||
{microsoftTeamsConfig.isSecretRequestNotificationEnabled &&
|
||||
!isLoadingConfig &&
|
||||
microsoftTeamsConfig.secretRequestChannels?.channelIds?.length > 0 ? (
|
||||
<Badge>
|
||||
{(microsoftTeamsConfig.secretRequestChannels?.channelIds || [])
|
||||
?.map((channel) => microsoftTeamsChannelIdToName[channel])
|
||||
{microsoftTeamsConfig.secretRequestChannels.channelIds
|
||||
.map((channel) => microsoftTeamsChannelIdToName[channel])
|
||||
.join(", ")}
|
||||
</Badge>
|
||||
) : isLoadingConfig ? (
|
||||
<Spinner size="xs" />
|
||||
) : (
|
||||
<Badge variant="danger">Disabled</Badge>
|
||||
)}
|
||||
</Td>
|
||||
|
||||
@@ -104,6 +102,25 @@ export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} an={OrgPermissionSubjects.Settings}>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
disabled={!isAllowed}
|
||||
className={twMerge(
|
||||
!isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
handlePopUpOpen("editIntegration", {
|
||||
integration: WorkflowIntegrationPlatform.MICROSOFT_TEAMS
|
||||
});
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Delete} an={OrgPermissionSubjects.Settings}>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -124,25 +141,6 @@ export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} an={OrgPermissionSubjects.Settings}>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
disabled={!isAllowed}
|
||||
className={twMerge(
|
||||
!isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
handlePopUpOpen("editIntegration", {
|
||||
integration: WorkflowIntegrationPlatform.MICROSOFT_TEAMS
|
||||
});
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</Td>
|
||||
|
||||
@@ -17,7 +17,8 @@ import {
|
||||
Input,
|
||||
Select,
|
||||
SelectItem,
|
||||
Switch
|
||||
Switch,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import {
|
||||
@@ -37,18 +38,22 @@ const formSchema = z
|
||||
microsoftTeamsIntegrationId: z.string(),
|
||||
isSecretRequestNotificationEnabled: z.boolean(),
|
||||
isAccessRequestNotificationEnabled: z.boolean(),
|
||||
secretRequestChannels: z.object({
|
||||
teamId: z.string(),
|
||||
channelIds: z.string().array()
|
||||
}),
|
||||
accessRequestChannels: z.object({
|
||||
teamId: z.string(),
|
||||
channelIds: z.string().array()
|
||||
})
|
||||
secretRequestChannels: z
|
||||
.object({
|
||||
teamId: z.string(),
|
||||
channelIds: z.string().array()
|
||||
})
|
||||
.optional(),
|
||||
accessRequestChannels: z
|
||||
.object({
|
||||
teamId: z.string(),
|
||||
channelIds: z.string().array()
|
||||
})
|
||||
.optional()
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
if (data.isSecretRequestNotificationEnabled) {
|
||||
if (!data.secretRequestChannels.teamId) {
|
||||
if (!data?.secretRequestChannels?.teamId) {
|
||||
ctx.addIssue({
|
||||
path: ["secretRequestChannels", "teamId"],
|
||||
code: z.ZodIssueCode.custom,
|
||||
@@ -56,7 +61,7 @@ const formSchema = z
|
||||
});
|
||||
}
|
||||
|
||||
if (!data.secretRequestChannels.channelIds.length) {
|
||||
if (!data?.secretRequestChannels?.channelIds?.length) {
|
||||
ctx.addIssue({
|
||||
path: ["secretRequestChannels", "channelIds"],
|
||||
code: z.ZodIssueCode.custom,
|
||||
@@ -66,7 +71,7 @@ const formSchema = z
|
||||
}
|
||||
|
||||
if (data.isAccessRequestNotificationEnabled) {
|
||||
if (!data.accessRequestChannels.teamId) {
|
||||
if (!data?.accessRequestChannels?.teamId) {
|
||||
ctx.addIssue({
|
||||
path: ["accessRequestChannels", "teamId"],
|
||||
code: z.ZodIssueCode.custom,
|
||||
@@ -74,7 +79,7 @@ const formSchema = z
|
||||
});
|
||||
}
|
||||
|
||||
if (!data.accessRequestChannels.channelIds.length) {
|
||||
if (!data?.accessRequestChannels?.channelIds?.length) {
|
||||
ctx.addIssue({
|
||||
path: ["accessRequestChannels", "channelIds"],
|
||||
code: z.ZodIssueCode.custom,
|
||||
@@ -108,7 +113,8 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => {
|
||||
watch,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { isDirty, isSubmitting }
|
||||
getValues,
|
||||
formState: { isDirty, isSubmitting, errors }
|
||||
} = useForm<TMicrosoftTeamsConfigForm>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
@@ -210,13 +216,20 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => {
|
||||
|
||||
if (microsoftTeamsConfig.integration === WorkflowIntegrationPlatform.MICROSOFT_TEAMS) {
|
||||
if (microsoftTeamsConfig.secretRequestChannels) {
|
||||
setValue("secretRequestChannels", microsoftTeamsConfig.secretRequestChannels);
|
||||
setValue("accessRequestChannels", microsoftTeamsConfig.accessRequestChannels);
|
||||
if (Object.entries(microsoftTeamsConfig.accessRequestChannels).length) {
|
||||
setValue("accessRequestChannels", microsoftTeamsConfig.accessRequestChannels);
|
||||
}
|
||||
if (Object.entries(microsoftTeamsConfig.secretRequestChannels).length) {
|
||||
setValue("secretRequestChannels", microsoftTeamsConfig.secretRequestChannels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [microsoftTeamsConfig]);
|
||||
|
||||
console.log("values", getValues());
|
||||
console.log("errors", errors);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(handleIntegrationSave)}>
|
||||
<div className="flex w-full flex-col justify-start">
|
||||
@@ -235,7 +248,20 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => {
|
||||
{...field}
|
||||
isDisabled={!isAllowed}
|
||||
placeholder="None"
|
||||
onValueChange={onChange}
|
||||
onValueChange={(v) => {
|
||||
onChange(v);
|
||||
|
||||
setValue("isAccessRequestNotificationEnabled", false);
|
||||
setValue("isSecretRequestNotificationEnabled", false);
|
||||
setValue("accessRequestChannels", {
|
||||
teamId: "",
|
||||
channelIds: []
|
||||
});
|
||||
setValue("secretRequestChannels", {
|
||||
teamId: "",
|
||||
channelIds: []
|
||||
});
|
||||
}}
|
||||
className="w-full"
|
||||
defaultValue={microsoftTeamsConfig?.integrationId}
|
||||
>
|
||||
@@ -522,6 +548,7 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => {
|
||||
colorSchema="secondary"
|
||||
className="mt-4"
|
||||
type="submit"
|
||||
disabled={!isDirty}
|
||||
isDisabled={!isDirty}
|
||||
isLoading={isSubmitting}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import { BsSlack } from "react-icons/bs";
|
||||
import { faCheck, faEllipsis, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faEllipsis } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
Spinner,
|
||||
Td,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
@@ -33,12 +35,15 @@ type Props = {
|
||||
|
||||
export const SlackConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: slackConfig } = useGetWorkspaceWorkflowIntegrationConfig({
|
||||
workspaceId: currentWorkspace?.id ?? "",
|
||||
integration: WorkflowIntegrationPlatform.SLACK
|
||||
});
|
||||
const { data: slackConfig, isPending: isSlackConfigLoading } =
|
||||
useGetWorkspaceWorkflowIntegrationConfig({
|
||||
workspaceId: currentWorkspace?.id ?? "",
|
||||
integration: WorkflowIntegrationPlatform.SLACK
|
||||
});
|
||||
|
||||
const { data: slackChannels } = useGetSlackIntegrationChannels(slackConfig?.integrationId);
|
||||
const { data: slackChannels, isPending: isSlackChannelsLoading } = useGetSlackIntegrationChannels(
|
||||
slackConfig?.integrationId
|
||||
);
|
||||
const slackChannelIdToName = Object.fromEntries(
|
||||
(slackChannels || []).map((channel) => [channel.id, channel.name])
|
||||
);
|
||||
@@ -47,6 +52,8 @@ export const SlackConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isLoadingConfig = isSlackChannelsLoading || isSlackConfigLoading;
|
||||
|
||||
return (
|
||||
<Tr>
|
||||
<Td className="flex max-w-xs items-center overflow-hidden text-ellipsis">
|
||||
@@ -56,35 +63,37 @@ export const SlackConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
{slackConfig.isAccessRequestNotificationEnabled ? (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-green-500" />
|
||||
{slackConfig.isAccessRequestNotificationEnabled &&
|
||||
!isLoadingConfig &&
|
||||
slackConfig.accessRequestChannels.length > 0 ? (
|
||||
<Badge>
|
||||
{slackConfig.accessRequestChannels
|
||||
.split(", ")
|
||||
.map((channel) => slackChannelIdToName[channel])
|
||||
.join(", ")}
|
||||
</Badge>
|
||||
) : isLoadingConfig ? (
|
||||
<Spinner size="xs" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faXmark} className="text-red-500" />
|
||||
<Badge variant="danger">Disabled</Badge>
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
{slackConfig.isSecretRequestNotificationEnabled ? (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-green-500" />
|
||||
{slackConfig.isSecretRequestNotificationEnabled &&
|
||||
!isLoadingConfig &&
|
||||
slackConfig.secretRequestChannels.length > 0 ? (
|
||||
<Badge>
|
||||
{slackConfig.secretRequestChannels
|
||||
.split(", ")
|
||||
.map((channel) => slackChannelIdToName[channel])
|
||||
.join(", ")}
|
||||
</Badge>
|
||||
) : isLoadingConfig ? (
|
||||
<Spinner size="xs" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faXmark} className="text-red-500" />
|
||||
<Badge variant="danger">Disabled</Badge>
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
<Badge>
|
||||
{slackConfig.accessRequestChannels
|
||||
.split(", ")
|
||||
.map((channel) => slackChannelIdToName[channel])
|
||||
.join(", ")}
|
||||
</Badge>
|
||||
</Td>
|
||||
<Td>
|
||||
<Badge>
|
||||
{slackConfig.secretRequestChannels
|
||||
.split(", ")
|
||||
.map((channel) => slackChannelIdToName[channel])
|
||||
.join(", ")}
|
||||
</Badge>
|
||||
</Td>
|
||||
|
||||
<Td>
|
||||
<DropdownMenu>
|
||||
@@ -94,6 +103,25 @@ export const SlackConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} an={OrgPermissionSubjects.Settings}>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
disabled={!isAllowed}
|
||||
className={twMerge(
|
||||
!isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
handlePopUpOpen("editIntegration", {
|
||||
integration: WorkflowIntegrationPlatform.SLACK
|
||||
});
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Delete} an={OrgPermissionSubjects.Settings}>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -114,25 +142,6 @@ export const SlackConfigRow = ({ handlePopUpOpen }: Props) => {
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Edit} an={OrgPermissionSubjects.Settings}>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
disabled={!isAllowed}
|
||||
className={twMerge(
|
||||
!isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
handlePopUpOpen("editIntegration", {
|
||||
integration: WorkflowIntegrationPlatform.SLACK
|
||||
});
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</Td>
|
||||
|
||||
Reference in New Issue
Block a user