Add required frontend to show results

This commit is contained in:
Half-Shot 2022-09-14 10:15:21 +01:00
parent f7bc38d941
commit 99f6460490
3 changed files with 53 additions and 4 deletions

View File

@ -1,4 +1,9 @@
.resultListItem { .resultListItem {
list-style: none; list-style: none;
padding-bottom: 1rem; padding-bottom: 1rem;
}
.logContainer {
overflow: auto;
max-height: 10rem;
} }

View File

@ -7,6 +7,7 @@ import { GenericHookConnectionState, GenericHookResponseItem } from "../../../sr
import { ConnectionConfigurationProps, RoomConfig } from "./RoomConfig"; import { ConnectionConfigurationProps, RoomConfig } from "./RoomConfig";
import { InputField, ButtonSet, Button } from "../elements"; import { InputField, ButtonSet, Button } from "../elements";
import WebhookIcon from "../../icons/webhook.png"; import WebhookIcon from "../../icons/webhook.png";
import styles from "./FeedConnection.module.scss";
const EXAMPLE_SCRIPT = `if (data.counter === undefined) { const EXAMPLE_SCRIPT = `if (data.counter === undefined) {
result = { result = {
@ -27,8 +28,38 @@ const EXAMPLE_SCRIPT = `if (data.counter === undefined) {
const DOCUMENTATION_LINK = "https://matrix-org.github.io/matrix-hookshot/latest/setup/webhooks.html#script-api"; const DOCUMENTATION_LINK = "https://matrix-org.github.io/matrix-hookshot/latest/setup/webhooks.html#script-api";
const RecentResults: FunctionComponent<{item: GenericHookResponseItem, onRefreshClick: MouseEvent}> = ({ item, onRefreshClick }) => {
if (!item.secrets) {
return null;
}
return <>
<h3>Recent requests</h3>
<Button onClick={onRefreshClick}> Refresh </Button>
{!item.secrets.lastResults.length && <span>There have been no recent requests.</span>}
<ul>
{item.secrets.lastResults.map(item => <li className={styles.resultListItem} key={item.timestamp}>
{new Date(item.timestamp).toLocaleString()}:
{item.ok && ` Successful request`}
{!item.ok && `⚠️ ${item.error}`}
<details>
<summary>Details</summary>
{ item.error && <p>Error: <span>{item.error}</span></p> }
<p>User-Agent: <span>{item.metadata.userAgent || "Unknown"}</span></p>
<p>Content-Type: <span>{item.metadata.contentType || "Unknown"}</span></p>
{ item.logs && <>
<p> Logs </p>
<pre className={styles.logContainer}>
{item.logs}
</pre>
</>}
</details>
</li>
)}
</ul>
</>;
}
const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<ServiceConfig, GenericHookResponseItem, GenericHookConnectionState>> = ({serviceConfig, existingConnection, onSave, onRemove}) => { const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<ServiceConfig, GenericHookResponseItem, GenericHookConnectionState>> = ({serviceConfig, existingConnection, onSave, onRemove, onRefresh}) => {
const [transFn, setTransFn] = useState<string>(existingConnection?.config.transformationFunction as string || EXAMPLE_SCRIPT); const [transFn, setTransFn] = useState<string>(existingConnection?.config.transformationFunction as string || EXAMPLE_SCRIPT);
const [transFnEnabled, setTransFnEnabled] = useState(serviceConfig.allowJsTransformationFunctions && !!existingConnection?.config.transformationFunction); const [transFnEnabled, setTransFnEnabled] = useState(serviceConfig.allowJsTransformationFunctions && !!existingConnection?.config.transformationFunction);
const nameRef = createRef<HTMLInputElement>(); const nameRef = createRef<HTMLInputElement>();
@ -72,6 +103,9 @@ const ConnectionConfiguration: FunctionComponent<ConnectionConfigurationProps<Se
{ canEdit && <Button type="submit">{ existingConnection ? "Save" : "Add webhook" }</Button>} { canEdit && <Button type="submit">{ existingConnection ? "Save" : "Add webhook" }</Button>}
{ canEdit && existingConnection && <Button intent="remove" onClick={onRemove}>Remove webhook</Button>} { canEdit && existingConnection && <Button intent="remove" onClick={onRemove}>Remove webhook</Button>}
</ButtonSet> </ButtonSet>
{ existingConnection && <RecentResults onRefreshClick={onRefresh} item={existingConnection} />}
</form>; </form>;
}; };

View File

@ -11,6 +11,7 @@ export interface ConnectionConfigurationProps<SConfig, ConnectionType extends Ge
onSave: (newConfig: ConnectionState) => void, onSave: (newConfig: ConnectionState) => void,
existingConnection?: ConnectionType; existingConnection?: ConnectionType;
onRemove?: () => void, onRemove?: () => void,
onRefresh?: () => void,
api: BridgeAPI; api: BridgeAPI;
} }
@ -41,6 +42,11 @@ export const RoomConfig = function<SConfig, ConnectionType extends GetConnection
const [ newConnectionKey, incrementConnectionKey ] = useReducer<number, undefined>(n => n+1, 0); const [ newConnectionKey, incrementConnectionKey ] = useReducer<number, undefined>(n => n+1, 0);
useEffect(() => { useEffect(() => {
refreshConnections();
}, [api, roomId, type, newConnectionKey]);
const refreshConnections = useCallback(() => {
api.getConnectionsForService<ConnectionType>(roomId, type).then(res => { api.getConnectionsForService<ConnectionType>(roomId, type).then(res => {
setCanEditRoom(res.canEdit); setCanEditRoom(res.canEdit);
setConnections(res.connections); setConnections(res.connections);
@ -52,10 +58,11 @@ export const RoomConfig = function<SConfig, ConnectionType extends GetConnection
message: ex instanceof BridgeAPIError ? ex.message : "Unknown error" message: ex instanceof BridgeAPIError ? ex.message : "Unknown error"
}); });
}); });
}, [api, roomId, type, newConnectionKey]); }, [api, roomId, type]);
useEffect(() => { useEffect(() => {
api.getServiceConfig<SConfig>(type) if (!serviceConfig) {
api.getServiceConfig<SConfig>(type)
.then(setServiceConfig) .then(setServiceConfig)
.then(() => { .then(() => {
setError(null); setError(null);
@ -67,7 +74,8 @@ export const RoomConfig = function<SConfig, ConnectionType extends GetConnection
message: ex instanceof BridgeAPIError ? ex.message : "Unknown error" message: ex instanceof BridgeAPIError ? ex.message : "Unknown error"
}); });
}) })
}, [api, type]); }
}, [api, type, serviceConfig]);
const handleSaveOnCreation = useCallback((config) => { const handleSaveOnCreation = useCallback((config) => {
api.createConnection(roomId, connectionEventType, config).then(() => { api.createConnection(roomId, connectionEventType, config).then(() => {
@ -98,6 +106,7 @@ export const RoomConfig = function<SConfig, ConnectionType extends GetConnection
api={api} api={api}
serviceConfig={serviceConfig} serviceConfig={serviceConfig}
onSave={handleSaveOnCreation} onSave={handleSaveOnCreation}
onRefresh={refreshConnections}
/>} />}
</section>} </section>}
<section> <section>
@ -107,6 +116,7 @@ export const RoomConfig = function<SConfig, ConnectionType extends GetConnection
api={api} api={api}
serviceConfig={serviceConfig} serviceConfig={serviceConfig}
existingConnection={c} existingConnection={c}
onRefresh={refreshConnections}
onSave={(config) => { onSave={(config) => {
api.updateConnection(roomId, c.id, config).then(() => { api.updateConnection(roomId, c.id, config).then(() => {
// Force reload // Force reload