Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/assets/image/icons/connections/AzureBot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/image/icons/connections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export { default as LinearIcon } from "@assets/image/icons/connections/linear.sv
export { default as SalesforceIcon } from "@assets/image/icons/connections/Salesforce.svg?react";
// Taken from: https://www.svgrepo.com/svg/452111/teams
export { default as MicrosoftTeamsIcon } from "@assets/image/icons/connections/MicrosoftTeams.svg?react";
export { default as AzureBotIcon } from "@assets/image/icons/connections/AzureBot.svg?react";
2 changes: 1 addition & 1 deletion src/autokitteh
110 changes: 110 additions & 0 deletions src/components/organisms/connections/integrations/azurebot/add.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React, { useEffect, useState } from "react";

import { useTranslation } from "react-i18next";

import { ConnectionAuthType } from "@enums";
import { Integrations } from "@src/enums/components";
import { useConnectionForm } from "@src/hooks";
import { azureBotIntegrationSchema } from "@validations";

import { Button, ErrorMessage, Input, SecretInput, Spinner } from "@components/atoms";

export const AzureBotIntegrationAddForm = ({
connectionId,
triggerParentFormSubmit,
type,
}: {
connectionId?: string;
triggerParentFormSubmit: () => void;
type: string;
}) => {
const { createConnection, errors, handleSubmit, isLoading, register, setValue } = useConnectionForm(
azureBotIntegrationSchema,
"create"
);

const [lockState, setLockState] = useState({
app_password: true,
tenant_id: true,
});

const handleLockAction = (fieldName: string, newLockState: boolean) => {
setLockState((prev) => ({ ...prev, [fieldName]: newLockState }));
};

const configureConnection = async (connectionId: string) => {
await createConnection(connectionId, ConnectionAuthType.Initialized, Integrations.azurebot);
};

useEffect(() => {
setValue("auth_scopes", type);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [type]);

useEffect(() => {
if (connectionId) {
configureConnection(connectionId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [connectionId]);

const { t } = useTranslation("integrations");

return (
<form className="mt-6 flex flex-col gap-6" onSubmit={handleSubmit(triggerParentFormSubmit)}>
<div className="relative">
<Input
{...register("app_id")}
aria-label={t("azurebot.placeholders.appId")}
disabled={isLoading}
isError={!!errors.app_id}
isRequired
label={t("azurebot.placeholders.appId")}
/>
<ErrorMessage>{errors.app_id?.message as string}</ErrorMessage>
</div>

<div className="relative">
<SecretInput
{...register("app_password")}
aria-label={t("azurebot.placeholders.appPassword")}
disabled={isLoading}
handleInputChange={(newValue) => setValue("app_password", newValue)}
handleLockAction={(newLockState) => handleLockAction("app_password", newLockState)}
isError={!!errors.app_password}
isLocked={lockState.app_password}
isRequired
label={t("azurebot.placeholders.appPassword")}
type="password"
/>
<ErrorMessage>{errors.app_password?.message as string}</ErrorMessage>
</div>

<div className="relative">
<SecretInput
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this is a secret

type="password"
{...register("tenant_id")}
aria-label={t("azurebot.placeholders.tenantId")}
disabled={isLoading}
handleInputChange={(newValue) => setValue("tenant_id", newValue)}
handleLockAction={(newLockState) => handleLockAction("tenant_id", newLockState)}
isError={!!errors.tenant_id}
isLocked={lockState.tenant_id}
isRequired
label={t("azurebot.placeholders.tenantId")}
/>
<ErrorMessage>{errors.tenant_id?.message as string}</ErrorMessage>
</div>

<Button
aria-label={t("buttons.saveConnection")}
className="ml-auto w-fit border-black bg-white px-3 font-medium hover:bg-gray-950 hover:text-white"
type="submit"
variant="outline"
>
{isLoading ? <Spinner /> : null}
{t("buttons.saveConnection")}
</Button>
</form>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { useState } from "react";

import { useTranslation } from "react-i18next";

import { useConnectionForm } from "@src/hooks";
import { azureBotIntegrationSchema } from "@validations";

import { Button, ErrorMessage, Input, SecretInput, Spinner } from "@components/atoms";

import { FloppyDiskIcon } from "@assets/image/icons";

const initialLockState: Record<string, boolean> = {
app_password: true,
tenant_id: true,
};

export const AzureBotIntegrationEditForm = () => {
const { t } = useTranslation("integrations");
const [lockState, setLockState] = useState(initialLockState);

const { errors, handleSubmit, isLoading, onSubmitEdit, register, setValue } = useConnectionForm(
azureBotIntegrationSchema,
"edit"
);

const handleLockAction = (fieldName: string, newLockState: boolean) => {
setLockState((prev) => ({ ...prev, [fieldName]: newLockState }));
};

// Removed useEffect to not pre-populate values - just show clean form with labels

return (
<form className="flex flex-col gap-4" onSubmit={handleSubmit(onSubmitEdit)}>
<div className="relative">
<Input
{...register("app_id")}
aria-label={t("azurebot.placeholders.appId")}
disabled={isLoading}
isError={!!errors.app_id}
isRequired
label={t("azurebot.placeholders.appId")}
/>
<ErrorMessage>{errors.app_id?.message as string}</ErrorMessage>
</div>

<div className="relative">
<SecretInput
type="password"
{...register("app_password")}
aria-label={t("azurebot.placeholders.appPassword")}
disabled={isLoading}
handleInputChange={(newValue) => setValue("app_password", newValue)}
handleLockAction={(newLockState) => handleLockAction("app_password", newLockState)}
isError={!!errors.app_password}
isLocked={lockState.app_password}
isRequired
label={t("azurebot.placeholders.appPassword")}
/>
<ErrorMessage>{errors.app_password?.message as string}</ErrorMessage>
</div>

<div className="relative">
<SecretInput
type="password"
{...register("tenant_id")}
aria-label={t("azurebot.placeholders.tenantId")}
disabled={isLoading}
handleInputChange={(newValue) => setValue("tenant_id", newValue)}
handleLockAction={(newLockState) => handleLockAction("tenant_id", newLockState)}
isError={!!errors.tenant_id}
isLocked={lockState.tenant_id}
isRequired
label={t("azurebot.placeholders.tenantId")}
/>
<ErrorMessage>{errors.tenant_id?.message as string}</ErrorMessage>
</div>

<Button
aria-label={t("buttons.saveConnection")}
className="ml-auto w-fit border-white px-3 font-medium text-white hover:bg-black"
disabled={isLoading}
type="submit"
variant="outline"
>
{isLoading ? <Spinner /> : <FloppyDiskIcon className="size-5 fill-white transition" />}
{t("buttons.saveConnection")}
</Button>
</form>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { AzureBotIntegrationAddForm } from "@components/organisms/connections/integrations/azurebot/add";
export { AzureBotIntegrationEditForm } from "@components/organisms/connections/integrations/azurebot/edit";
4 changes: 4 additions & 0 deletions src/components/organisms/connections/integrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ export {
SalesforceIntegrationAddForm,
SalesforceIntegrationEditForm,
} from "@components/organisms/connections/integrations/salesforce";
export {
AzureBotIntegrationAddForm,
AzureBotIntegrationEditForm,
} from "@components/organisms/connections/integrations/azurebot";
2 changes: 2 additions & 0 deletions src/constants/connections/addComponentsMapping.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
HeightIntegrationAddForm,
ZoomIntegrationAddForm,
SalesforceIntegrationAddForm,
AzureBotIntegrationAddForm,
} from "@components/organisms/connections/integrations";
import { MicrosoftTeamsIntegrationAddForm } from "@components/organisms/connections/integrations/microsoft/teams";

Expand Down Expand Up @@ -49,5 +50,6 @@ export const integrationAddFormComponents: Partial<Record<keyof typeof Integrati
linear: LinearIntegrationAddForm,
salesforce: SalesforceIntegrationAddForm,
microsoft_teams: MicrosoftTeamsIntegrationAddForm,
azurebot: AzureBotIntegrationAddForm,
youtube: GoogleYoutubeIntegrationAddForm,
};
2 changes: 2 additions & 0 deletions src/constants/connections/editComponentsMapping.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ZoomIntegrationEditForm,
LinearIntegrationEditForm,
SalesforceIntegrationEditForm,
AzureBotIntegrationEditForm,
} from "@components/organisms/connections/integrations";
import { MicrosoftTeamsIntegrationEditForm } from "@components/organisms/connections/integrations/microsoft/teams";

Expand Down Expand Up @@ -48,4 +49,5 @@ export const integrationToEditComponent: Partial<Record<keyof typeof Integration
[Integrations.linear]: LinearIntegrationEditForm,
[Integrations.salesforce]: SalesforceIntegrationEditForm,
[Integrations.microsoft_teams]: MicrosoftTeamsIntegrationEditForm,
[Integrations.azurebot]: AzureBotIntegrationEditForm,
};
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,9 @@ export const integrationVariablesMapping = {
client_secret: "client_secret",
tenant_id: "tenant_id",
},
[Integrations.azurebot]: {
app_id: "app_id",
app_password: "app_password",
tenant_id: "tenant_id",
},
};
7 changes: 7 additions & 0 deletions src/enums/components/connection.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
ZoomIcon,
SalesforceIcon,
MicrosoftTeamsIcon,
AzureBotIcon,
} from "@assets/image/icons/connections";

export enum ConnectionStatus {
Expand Down Expand Up @@ -67,6 +68,7 @@ export enum Integrations {
salesforce = "salesforce",
// eslint-disable-next-line @typescript-eslint/naming-convention
microsoft_teams = "microsoft_teams",
azurebot = "azurebot",
}

export const defaultGoogleConnectionName = "google";
Expand Down Expand Up @@ -231,6 +233,11 @@ export const IntegrationsMap: Record<Integrations, IntegrationSelectOption> = {
label: "Microsoft Teams",
value: Integrations.microsoft_teams,
},
azurebot: {
icon: AzureBotIcon,
label: "Azure Bot",
value: Integrations.azurebot,
},
};

const shouldHideIntegration: Partial<Record<Integrations, boolean>> = {
Expand Down
1 change: 1 addition & 0 deletions src/hooks/useConnectionForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const useConnectionForm = (validationSchema: ZodObject<ZodRawShape>, mode
[Integrations.chatgpt]: ConnectionAuthType.Initialized,
[Integrations.googlegemini]: ConnectionAuthType.Key,
[Integrations.hubspot]: ConnectionAuthType.OauthDefault,
[Integrations.azurebot]: ConnectionAuthType.Initialized,
};

const defaultAuthType = integrationAuthDefaults[integrationName as string];
Expand Down
13 changes: 13 additions & 0 deletions src/locales/en/dashboard/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,18 @@
"aiPage": {
"requiredMessage": "Please enter a message"
}
},
"welcomeLanding": {
"createNew": "Start",
"creating": "Creating...",
"createFromScratch": "Create from Scratch",
"createFromScratchDesc": "Build a new automation project from the ground up",
"createFromScratchButton": "Create New",
"learnMore": "Learn More",
"newProject": "Quick Tutorial",
"newProjectDesc": "Deploy, execute, and review the output of a simple Python project",
"title": "Welcome to AutoKitteh",
"useTemplate": "Start From Template",
"useTemplateDesc": "Select from a collection of out of the box templates"
}
}
7 changes: 7 additions & 0 deletions src/locales/en/integrations/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -240,5 +240,12 @@
"clientSecret": "Client Secret",
"tenantId": "Tenant ID (multi-tenant = 'common')"
}
},
"azurebot": {
"placeholders": {
"appId": "App ID",
"appPassword": "App Password",
"tenantId": "Tenant ID"
}
}
}
6 changes: 6 additions & 0 deletions src/validations/connection.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,10 @@ export const microsoftTeamsIntegrationSchema = z.object({
tenant_id: z.string().min(1, "Tenant ID is required"),
});

export const azureBotIntegrationSchema = z.object({
app_id: z.string().min(1, "App ID is required"),
app_password: z.string().min(1, "App Password is required"),
tenant_id: z.string().min(1, "Tenant ID is required"),
});

export const oauthSchema = z.object({});
1 change: 1 addition & 0 deletions src/validations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export {
zoomServerToServerIntegrationSchema,
salesforcePrivateAuthIntegrationSchema,
microsoftTeamsIntegrationSchema,
azureBotIntegrationSchema,
linearOauthIntegrationSchema,
} from "@validations/connection.schema";
export { codeAssetsSchema } from "@validations/coseAndAssets.schema";
Expand Down