mirror of
https://github.com/docmost/docmost.git
synced 2026-08-20 00:01:37 +10:00
feat(integrations): one-step install for workspace-scoped providers
This commit is contained in:
@@ -19,6 +19,7 @@ export default function ConnectionRow({
|
||||
isDisconnecting,
|
||||
}: ConnectionRowProps) {
|
||||
const { t } = useTranslation();
|
||||
const isWorkspaceScoped = definition.oauth?.connectionScope === 'workspace';
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -42,30 +43,47 @@ export default function ConnectionRow({
|
||||
</Group>
|
||||
|
||||
<Group gap="sm" wrap="nowrap" style={{ flexShrink: 0 }}>
|
||||
{connection ? (
|
||||
{isWorkspaceScoped ? (
|
||||
<>
|
||||
<Text size="xs" c="green">
|
||||
{t("Connected")}
|
||||
{connection.providerUserId && ` (${connection.providerUserId})`}
|
||||
</Text>
|
||||
<Button
|
||||
size="xs"
|
||||
variant="subtle"
|
||||
color="red"
|
||||
onClick={() => onDisconnect(connection.integrationId)}
|
||||
loading={isDisconnecting}
|
||||
>
|
||||
{t("Disconnect")}
|
||||
</Button>
|
||||
{connection ? (
|
||||
<Text size="xs" c="green">
|
||||
{t("Linked")}
|
||||
{connection.providerUserId && ` as @${connection.providerUserId}`}
|
||||
</Text>
|
||||
) : (
|
||||
<Text size="xs" c="dimmed">
|
||||
{t("Use")} <code>/docmost help</code> {t("in")} {definition.name} {t("to link your account.")}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={() => onConnect(definition.type)}
|
||||
>
|
||||
{t("Connect")}
|
||||
</Button>
|
||||
<>
|
||||
{connection ? (
|
||||
<>
|
||||
<Text size="xs" c="green">
|
||||
{t("Connected")}
|
||||
{connection.providerUserId && ` (${connection.providerUserId})`}
|
||||
</Text>
|
||||
<Button
|
||||
size="xs"
|
||||
variant="subtle"
|
||||
color="red"
|
||||
onClick={() => onDisconnect(connection.integrationId)}
|
||||
loading={isDisconnecting}
|
||||
>
|
||||
{t("Disconnect")}
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={() => onConnect(definition.type)}
|
||||
>
|
||||
{t("Connect")}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
useUpdateIntegrationSettings,
|
||||
} from "../queries/integration-query";
|
||||
import { Integration } from "../types/integration.types";
|
||||
import { getOAuthAuthorizeUrl } from "../services/integration-service";
|
||||
|
||||
export default function Integrations() {
|
||||
const { t } = useTranslation();
|
||||
@@ -28,10 +29,21 @@ export default function Integrations() {
|
||||
const [configuring, setConfiguring] = useState<Integration | null>(null);
|
||||
|
||||
const handleInstall = useCallback(
|
||||
(type: string) => {
|
||||
installMutation.mutate({ type });
|
||||
async (type: string) => {
|
||||
const definition = available?.find((d) => d.type === type);
|
||||
try {
|
||||
const integration = await installMutation.mutateAsync({ type });
|
||||
if (definition?.oauth?.connectionScope === 'workspace') {
|
||||
const { authorizationUrl } = await getOAuthAuthorizeUrl({
|
||||
integrationId: integration.id,
|
||||
});
|
||||
window.location.href = authorizationUrl;
|
||||
}
|
||||
} catch (err) {
|
||||
// installMutation's onError already shows a notification
|
||||
}
|
||||
},
|
||||
[installMutation],
|
||||
[installMutation, available],
|
||||
);
|
||||
|
||||
const handleUninstall = useCallback(
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
export type IntegrationCapability = "oauth" | "unfurl" | "actions" | "webhooks";
|
||||
|
||||
export type OAuthConfig = {
|
||||
authUrl: string;
|
||||
tokenUrl: string;
|
||||
scopes: string[];
|
||||
connectionScope?: 'workspace' | 'user';
|
||||
};
|
||||
|
||||
export type IntegrationDefinition = {
|
||||
type: string;
|
||||
name: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
capabilities: IntegrationCapability[];
|
||||
oauth?: OAuthConfig;
|
||||
};
|
||||
|
||||
export type Integration = {
|
||||
|
||||
Reference in New Issue
Block a user