From a9537c7961a05970c68d591a8e404c5034c246e2 Mon Sep 17 00:00:00 2001
From: Will Hunt
Date: Fri, 21 Apr 2023 11:47:29 +0100
Subject: [PATCH] Add option to enable/disable feed failure notices. (#716)
* Add new notifyOnFailure option
* Disable state buttons when updating is set
* Linting
---
changelog.d/716.feature | 1 +
src/Connections/FeedConnection.ts | 5 +++++
src/FormatUtil.ts | 2 +-
src/Notifications/GitLabWatcher.ts | 3 ---
src/Widgets/GoNebMigrator.ts | 2 +-
tests/FeedReader.spec.ts | 8 +++----
web/components/elements/Button.module.scss | 4 ++++
web/components/roomConfig/FeedsConfig.tsx | 22 ++++++++++++-------
.../roomConfig/GenericWebhookConfig.tsx | 6 ++---
.../roomConfig/GithubRepoConfig.tsx | 6 ++---
.../roomConfig/GitlabRepoConfig.tsx | 6 ++---
.../roomConfig/JiraProjectConfig.tsx | 6 ++---
web/components/roomConfig/RoomConfig.tsx | 13 +++++++++++
13 files changed, 55 insertions(+), 29 deletions(-)
create mode 100644 changelog.d/716.feature
diff --git a/changelog.d/716.feature b/changelog.d/716.feature
new file mode 100644
index 00000000..958c5451
--- /dev/null
+++ b/changelog.d/716.feature
@@ -0,0 +1 @@
+Notifications for RSS feed failures can now be toggled on and off. The feature is now **off** by default.
\ No newline at end of file
diff --git a/src/Connections/FeedConnection.ts b/src/Connections/FeedConnection.ts
index 7a561ee7..ed403834 100644
--- a/src/Connections/FeedConnection.ts
+++ b/src/Connections/FeedConnection.ts
@@ -25,6 +25,7 @@ export interface FeedConnectionState extends IConnectionState {
url: string;
label?: string;
template?: string;
+ notifyOnFailure?: boolean;
}
export interface FeedConnectionSecrets {
@@ -225,6 +226,10 @@ export class FeedConnection extends BaseConnection implements IConnection {
// To avoid short term failures bubbling up, if the error is serious, we still bubble.
return;
}
+ if (!this.state.notifyOnFailure) {
+ // User hasn't opted into notifications on failure
+ return;
+ }
if (!this.hasError) {
await this.intent.sendEvent(this.roomId, {
msgtype: 'm.notice',
diff --git a/src/FormatUtil.ts b/src/FormatUtil.ts
index c2532ce0..f0424b39 100644
--- a/src/FormatUtil.ts
+++ b/src/FormatUtil.ts
@@ -4,7 +4,7 @@ import emoji from "node-emoji";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { JiraIssue } from './Jira/Types';
-import { formatLabels, getPartialBodyForJiraIssue, hashId, getPartialBodyForGithubIssue, getPartialBodyForGithubRepo, MinimalGitHubRepo, MinimalGitHubIssue } from "./libRs";
+import { formatLabels, getPartialBodyForJiraIssue, hashId, getPartialBodyForGithubIssue, getPartialBodyForGithubRepo, MinimalGitHubIssue } from "./libRs";
interface IMinimalPR {
html_url: string;
diff --git a/src/Notifications/GitLabWatcher.ts b/src/Notifications/GitLabWatcher.ts
index 264294ec..f18f5e9f 100644
--- a/src/Notifications/GitLabWatcher.ts
+++ b/src/Notifications/GitLabWatcher.ts
@@ -29,8 +29,5 @@ export class GitLabWatcher extends EventEmitter implements NotificationWatcherTa
private async getNotifications() {
log.info(`Fetching events from GitLab for ${this.userId}`);
- const events = await this.client.getEvents({
- after: new Date(this.since)
- });
}
}
\ No newline at end of file
diff --git a/src/Widgets/GoNebMigrator.ts b/src/Widgets/GoNebMigrator.ts
index aacceaf8..67539a3e 100644
--- a/src/Widgets/GoNebMigrator.ts
+++ b/src/Widgets/GoNebMigrator.ts
@@ -2,7 +2,7 @@ import { Logger } from "matrix-appservice-bridge";
import axios from "axios";
import { FeedConnection, FeedConnectionState, GitHubRepoConnection, GitHubRepoConnectionState } from "../Connections";
-import { AllowedEvents as GitHubAllowedEvents, AllowedEventsNames as GitHubAllowedEventsNames } from "../Connections/GithubRepo";
+import { AllowedEventsNames as GitHubAllowedEventsNames } from "../Connections/GithubRepo";
const log = new Logger("GoNebMigrator");
diff --git a/tests/FeedReader.spec.ts b/tests/FeedReader.spec.ts
index ed4feeae..153be2fd 100644
--- a/tests/FeedReader.spec.ts
+++ b/tests/FeedReader.spec.ts
@@ -14,7 +14,7 @@ class MockConnectionManager extends EventEmitter {
super();
}
- getAllConnectionsOfType(type: unknown) {
+ getAllConnectionsOfType() {
return this.connections;
}
}
@@ -32,7 +32,7 @@ class MockMessageQueue extends EventEmitter implements MessageQueue {
this.emit('pushed', data, single);
}
- async pushWait(data: MessageQueueMessage, timeout?: number, single?: boolean): Promise {
+ async pushWait(): Promise {
throw new Error('Not yet implemented');
}
}
@@ -73,13 +73,13 @@ describe("FeedReader", () => {
config, cm, mq,
{
getAccountData: () => Promise.resolve({ 'http://test/': [] } as unknown as T),
- setAccountData: () => Promise.resolve(),
+ setAccountData: () => Promise.resolve(),
},
new MockHttpClient({ headers: {}, data: feedContents } as AxiosResponse) as unknown as AxiosStatic,
);
const event: any = await new Promise((resolve) => {
- mq.on('pushed', (data, _) => { resolve(data); feedReader.stop() });
+ mq.on('pushed', (data) => { resolve(data); feedReader.stop() });
});
expect(event.eventName).to.equal('feed.entry');
diff --git a/web/components/elements/Button.module.scss b/web/components/elements/Button.module.scss
index 5dcc6450..26fadb5e 100644
--- a/web/components/elements/Button.module.scss
+++ b/web/components/elements/Button.module.scss
@@ -22,4 +22,8 @@
.remove {
color: #FF5B55;
background-color: transparent;
+
+ &:disabled {
+ background-color: transparent;
+ }
}
\ No newline at end of file
diff --git a/web/components/roomConfig/FeedsConfig.tsx b/web/components/roomConfig/FeedsConfig.tsx
index b64639af..e4663dab 100644
--- a/web/components/roomConfig/FeedsConfig.tsx
+++ b/web/components/roomConfig/FeedsConfig.tsx
@@ -28,10 +28,11 @@ const FeedRecentResults: FunctionComponent<{item: FeedResponseItem}> = ({ item }
}
const DOCUMENTATION_LINK = "https://matrix-org.github.io/matrix-hookshot/latest/setup/feeds.html#feed-templates";
-const ConnectionConfiguration: FunctionComponent> = ({existingConnection, onSave, onRemove, isMigrationCandidate}) => {
+const ConnectionConfiguration: FunctionComponent> = ({existingConnection, onSave, onRemove, isMigrationCandidate, isUpdating}) => {
const urlRef = createRef();
const labelRef = createRef();
const templateRef = createRef();
+ const notifyRef = createRef();
const canSave = !existingConnection?.id || (existingConnection?.canEdit ?? false);
const canEdit = canSave && !isMigrationCandidate;
const handleSave = useCallback((evt: Event) => {
@@ -45,10 +46,13 @@ const ConnectionConfiguration: FunctionComponent
{ existingConnection && }
@@ -58,14 +62,16 @@ const ConnectionConfiguration: FunctionComponent
-
+
+
+
+
See the documentation for help writing templates.
-
- { canSave && }
- { canEdit && existingConnection?.id && }
+ { canSave && }
+ { canEdit && existingConnection?.id && }
;
diff --git a/web/components/roomConfig/GenericWebhookConfig.tsx b/web/components/roomConfig/GenericWebhookConfig.tsx
index a91cfce8..7a6648c6 100644
--- a/web/components/roomConfig/GenericWebhookConfig.tsx
+++ b/web/components/roomConfig/GenericWebhookConfig.tsx
@@ -28,7 +28,7 @@ const EXAMPLE_SCRIPT = `if (data.counter === undefined) {
const DOCUMENTATION_LINK = "https://matrix-org.github.io/matrix-hookshot/latest/setup/webhooks.html#script-api";
const CODE_MIRROR_EXTENSIONS = [javascript({})];
-const ConnectionConfiguration: FunctionComponent> = ({serviceConfig, existingConnection, onSave, onRemove}) => {
+const ConnectionConfiguration: FunctionComponent> = ({serviceConfig, existingConnection, onSave, onRemove, isUpdating}) => {
const [transFn, setTransFn] = useState(existingConnection?.config.transformationFunction as string || EXAMPLE_SCRIPT);
const [transFnEnabled, setTransFnEnabled] = useState(serviceConfig.allowJsTransformationFunctions && !!existingConnection?.config.transformationFunction);
const nameRef = createRef();
@@ -67,8 +67,8 @@ const ConnectionConfiguration: FunctionComponent See the documentation for help writing transformation functions
- { canEdit && }
- { canEdit && existingConnection && }
+ { canEdit && }
+ { canEdit && existingConnection && }
;
};
diff --git a/web/components/roomConfig/GithubRepoConfig.tsx b/web/components/roomConfig/GithubRepoConfig.tsx
index 48a7045c..eb749c44 100644
--- a/web/components/roomConfig/GithubRepoConfig.tsx
+++ b/web/components/roomConfig/GithubRepoConfig.tsx
@@ -18,7 +18,7 @@ function getRepoFullName(state: GitHubRepoConnectionState) {
}
const ConnectionConfiguration: FunctionComponent> = ({
- showAuthPrompt, loginLabel, serviceConfig, api, existingConnection, onSave, onRemove
+ showAuthPrompt, loginLabel, serviceConfig, api, existingConnection, onSave, onRemove, isUpdating
}) => {
// Assume true if we have no auth prompt.
const [authedResponse, setAuthResponse] = useState(null);
@@ -159,8 +159,8 @@ const ConnectionConfiguration: FunctionComponent
- { canEdit && consideredAuthenticated && }
- { canEdit && existingConnection?.id && }
+ { canEdit && consideredAuthenticated && }
+ { canEdit && existingConnection?.id && }
;
};
diff --git a/web/components/roomConfig/GitlabRepoConfig.tsx b/web/components/roomConfig/GitlabRepoConfig.tsx
index e2876e01..084b0068 100644
--- a/web/components/roomConfig/GitlabRepoConfig.tsx
+++ b/web/components/roomConfig/GitlabRepoConfig.tsx
@@ -10,7 +10,7 @@ import { DropItem } from "../elements/DropdownSearch";
import { ConnectionSearch } from "../elements/ConnectionSearch";
const EventType = "uk.half-shot.matrix-hookshot.gitlab.repository";
-const ConnectionConfiguration: FunctionComponent> = ({api, existingConnection, onSave, onRemove }) => {
+const ConnectionConfiguration: FunctionComponent> = ({api, existingConnection, onSave, onRemove, isUpdating }) => {
const [enabledHooks, setEnabledHooks] = useState(existingConnection?.config.enableHooks || []);
const toggleEnabledHook = useCallback((evt: any) => {
@@ -107,8 +107,8 @@ const ConnectionConfiguration: FunctionComponent
- { canEdit && }
- { canEdit && existingConnection && }
+ { canEdit && }
+ { canEdit && existingConnection && }
;
};
diff --git a/web/components/roomConfig/JiraProjectConfig.tsx b/web/components/roomConfig/JiraProjectConfig.tsx
index ed048c6c..2261e3df 100644
--- a/web/components/roomConfig/JiraProjectConfig.tsx
+++ b/web/components/roomConfig/JiraProjectConfig.tsx
@@ -11,7 +11,7 @@ import { DropItem } from "../elements/DropdownSearch";
const EventType = "uk.half-shot.matrix-hookshot.jira.project";
-const ConnectionConfiguration: FunctionComponent> = ({api, existingConnection, onSave, onRemove }) => {
+const ConnectionConfiguration: FunctionComponent> = ({api, existingConnection, onSave, onRemove, isUpdating }) => {
const [allowedEvents, setAllowedEvents] = useState(existingConnection?.config.events || ['issue_created']);
const toggleEvent = useCallback((evt: Event) => {
@@ -93,8 +93,8 @@ const ConnectionConfiguration: FunctionComponent
- { canEdit && }
- { canEdit && existingConnection && }
+ { canEdit && }
+ { canEdit && existingConnection && }
;
};
diff --git a/web/components/roomConfig/RoomConfig.tsx b/web/components/roomConfig/RoomConfig.tsx
index 03da44d2..b9f8294a 100644
--- a/web/components/roomConfig/RoomConfig.tsx
+++ b/web/components/roomConfig/RoomConfig.tsx
@@ -13,6 +13,8 @@ export interface ConnectionConfigurationProps void,
+ isUpdating: boolean,
+ isMigrationCandidate?: boolean,
existingConnection?: ConnectionType;
onRemove?: () => void,
api: BridgeAPI;
@@ -64,6 +66,7 @@ export const RoomConfig = function(false);
// We need to increment this every time we create a connection in order to properly reset the state.
const [ newConnectionKey, incrementConnectionKey ] = useReducer(n => n+1, 0);
+ const [ updatingConnection, isUpdatingConnection ] = useState(false);
const clearCurrentError = () => {
setError(error => error?.forPrevious ? error : null);
@@ -125,6 +128,7 @@ export const RoomConfig = function {
+ isUpdatingConnection(true);
api.createConnection(roomId, connectionEventType, config).then(result => {
// Force reload
incrementConnectionKey(undefined);
@@ -140,6 +144,8 @@ export const RoomConfig = function {
+ isUpdatingConnection(false);
});
}, [api, roomId, connectionEventType]);
@@ -167,6 +173,7 @@ export const RoomConfig = function}
}
{ !error && connections === null && }
@@ -178,6 +185,7 @@ export const RoomConfig = function {
+ isUpdatingConnection(true);
api.updateConnection(roomId, c.id, config).then(() => {
c.config = config;
// Force reload
@@ -189,6 +197,8 @@ export const RoomConfig = function {
+ isUpdatingConnection(false);
});
}}
onRemove={() => {
@@ -203,6 +213,7 @@ export const RoomConfig = function
)
}
@@ -214,6 +225,8 @@ export const RoomConfig = function
) }