hookshot/web/components/RoomConfigView.tsx
Will Hunt 80c7d35a18
Add an expiry time to inbound webhooks (#984)
* Add logic to enable generic hook expiry

* Add storage for hook expiry warnings.

* Migrate generic hooks / add expiry field

* Allow reporting a specific error and status code for generic webhooks

* Report the specific error when a message fails to send

* Refactor input class to better support datetime

* Remove single use of innerChild

* Add UI support for expiry configuration

* Add new packages

* Add warnings when the timer is about to expire.

* Add send expiry notice config option

* lint

* document new option s

* Fixup test

* Add tests for expiry

* Add textual command for setting a duration on a webhook.

* Add e2e test for inbound hooks.

* changelog

* Add a configuration option to force webhooks to expire.

* update config.sample.yml

* fix field not working
2024-11-18 17:08:52 +00:00

129 lines
4.4 KiB
TypeScript

import { useState } from "preact/hooks"
import { BridgeConfig, EmbedType } from "../BridgeAPI";
import style from "./RoomConfigView.module.scss";
import { ConnectionCard } from "./ConnectionCard";
import { FeedsConfig } from "./roomConfig/FeedsConfig";
import { GenericWebhookConfig } from "./roomConfig/GenericWebhookConfig";
import { OutboundWebhookConfig } from "./roomConfig/OutboundWebhookConfig";
import { GithubRepoConfig } from "./roomConfig/GithubRepoConfig";
import { GitlabRepoConfig } from "./roomConfig/GitlabRepoConfig";
import { JiraProjectConfig } from "./roomConfig/JiraProjectConfig";
import FeedsIcon from "../icons/feeds.png";
import GitHubIcon from "../icons/github.png";
import GitLabIcon from "../icons/gitlab.png";
import JiraIcon from "../icons/jira.png";
import WebhookIcon from "../icons/webhook.png";
import { ChevronLeftIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
interface IProps {
supportedServices: {[service: string]: boolean},
serviceScope?: string,
embedType: EmbedType,
roomId: string,
}
enum ConnectionType {
Feeds = "feeds",
Generic = "generic",
GenericOutbound = "genericOutbound",
Github = "github",
Gitlab = "gitlab",
Jira = "jira",
}
interface IConnectionProps {
displayName: string,
description: string,
icon: string,
darkIcon?: true,
component: BridgeConfig,
}
const connections: Record<ConnectionType, IConnectionProps> = {
[ConnectionType.Feeds]: {
displayName: "RSS/Atom Feeds",
description: "Subscribe to an RSS/Atom feed",
icon: FeedsIcon,
component: FeedsConfig,
},
[ConnectionType.Github]: {
displayName: 'Github',
description: "Connect the room to a GitHub project",
icon: GitHubIcon,
darkIcon: true,
component: GithubRepoConfig,
},
[ConnectionType.Gitlab]: {
displayName: 'Gitlab',
description: "Connect the room to a GitLab project",
icon: GitLabIcon,
component: GitlabRepoConfig,
},
[ConnectionType.Jira]: {
displayName: 'JIRA',
description: "Connect the room to a JIRA project",
icon: JiraIcon,
component: JiraProjectConfig,
},
[ConnectionType.Generic]: {
displayName: 'Inbound (Generic) Webhook',
description: "Create a webhook which can be used to connect any service to Matrix",
icon: WebhookIcon,
darkIcon: true,
component: GenericWebhookConfig,
},
[ConnectionType.GenericOutbound]: {
displayName: 'Outbound Webhook',
description: "Create a webhook which can be used to connect any service to Matrix",
icon: WebhookIcon,
darkIcon: true,
component: OutboundWebhookConfig,
},
};
export default function RoomConfigView(props: IProps) {
const serviceScope = props.serviceScope && props.supportedServices[props.serviceScope] ? props.serviceScope as ConnectionType : null;
const [ activeConnectionType, setActiveConnectionType ] = useState<ConnectionType|null>(serviceScope);
let content;
if (activeConnectionType) {
const ConfigComponent = connections[activeConnectionType].component;
content = <ConfigComponent
roomId={props.roomId}
showHeader={props.embedType !== EmbedType.IntegrationManager}
/>;
} else {
content = <>
<section>
<h2> Integrations </h2>
{(Object.keys(connections) as Array<ConnectionType>).filter(service => props.supportedServices[service]).map((connectionType: ConnectionType) => {
const connection = connections[connectionType];
return <ConnectionCard
serviceName={connection.displayName}
description={connection.description}
key={connectionType}
imageSrc={connection.icon}
darkImage={connection.darkIcon}
onClick={() => setActiveConnectionType(connectionType)}
/>
})}
</section>
</>;
}
return <div className={style.root}>
{!serviceScope && activeConnectionType &&
<header>
<span className={style.backButton} onClick={() => setActiveConnectionType(null)}>
<ChevronLeftIcon /> Browse integrations
</span>
</header>
}
{content}
</div>;
}