fix(ui): integrations update issue, and error handling

This commit is contained in:
Shekar Siri 2024-11-19 11:35:55 +01:00
parent 2ebfd99068
commit 2267ec44c2
6 changed files with 101 additions and 72 deletions

View file

@ -10,7 +10,6 @@ import IntegrationModalCard from 'Components/Client/Integrations/IntegrationModa
import { Loader } from 'UI';
import DocLink from 'Shared/DocLink/DocLink';
import { toast } from ".store/react-toastify-virtual-9dd0f3eae1/package";
interface DatadogConfig {
site: string;

View file

@ -10,7 +10,6 @@ import IntegrationModalCard from 'Components/Client/Integrations/IntegrationModa
import { Loader } from 'UI';
import DocLink from 'Shared/DocLink/DocLink';
import { toast } from ".store/react-toastify-virtual-9dd0f3eae1/package";
interface DynatraceConfig {
environment: string;

View file

@ -10,7 +10,6 @@ import IntegrationModalCard from 'Components/Client/Integrations/IntegrationModa
import { Loader } from 'UI';
import DocLink from 'Shared/DocLink/DocLink';
import { toast } from ".store/react-toastify-virtual-9dd0f3eae1/package";
interface ElasticConfig {
url: string;

View file

@ -26,9 +26,13 @@ function TeamsAddForm({ onClose }: Props) {
const save = () => {
if (instance?.exists()) {
void update();
update().then(() => {
void onClose();
});
} else {
void onSave();
void onSave().then(() => {
void onClose();
});
}
};
@ -37,16 +41,16 @@ function TeamsAddForm({ onClose }: Props) {
await confirm({
header: 'Confirm',
confirmButton: 'Yes, delete',
confirmation: `Are you sure you want to permanently delete this channel?`,
confirmation: `Are you sure you want to permanently delete this channel?`
})
) {
void onRemove(id);
void onRemove(id).then(onClose);
}
};
const write = ({
target: { name, value },
}: {
target: { name, value }
}: {
target: { name: string; value: string };
}) => edit({ [name]: value });

View file

@ -10,9 +10,10 @@ import {
Integration,
IssueTracker,
JiraInt,
SentryInt,
SentryInt
} from './types/integrations/services';
import { serviceNames } from 'App/components/Client/Integrations/apiMethods';
import { toast } from 'react-toastify';
class GenericIntegrationsStore {
list: any[] = [];
@ -82,15 +83,15 @@ class NamedIntegrationStore<T extends Integration> {
setList = (list: T[]): void => {
this.list = list;
}
};
setFetched = (fetched: boolean): void => {
this.fetched = fetched;
}
};
setIssuesFetched = (issuesFetched: boolean): void => {
this.issuesFetched = issuesFetched;
}
};
fetchIntegrations = async (): Promise<void> => {
this.setLoading(true);
@ -134,23 +135,23 @@ class NamedIntegrationStore<T extends Integration> {
siteId
);
return;
}
};
edit = (data: T): void => {
if (!this.instance) {
this.instance = this.namedTypeCreator({});
}
this.instance.edit(data);
}
};
deleteIntegration = async (siteId?: string) => {
if (!this.instance) return;
return integrationsService.removeIntegration(this.name, siteId);
}
};
init = (config: Record<string, any>): void => {
this.instance = this.namedTypeCreator(config);
}
};
}
class MessengerIntegrationStore {
@ -185,19 +186,22 @@ class MessengerIntegrationStore {
};
saveIntegration = async (): Promise<void> => {
// redux todo: errors
if (!this.instance) return;
this.setLoading(true);
try {
await integrationsService.saveIntegration(
const response = await integrationsService.saveIntegration(
this.mName,
this.instance.toData(),
undefined
);
if (response.errors) {
toast.error(response.errors[0] || 'Couldn\'t process the request: check your data.');
return response;
}
this.instance.edit({ webhookId: response.data.webhookId });
this.setList([...this.list, this.instance]);
} catch (e) {
console.log(e);
this.setErrors(["Couldn't process the request: check your data."]);
toast.error('Couldn\'t process the request: check your data.');
} finally {
this.setLoading(false);
}
@ -214,11 +218,11 @@ class MessengerIntegrationStore {
};
sendMessage = ({
integrationId,
entity,
entityId,
data,
}: {
integrationId,
entity,
entityId,
data
}: {
integrationId: string;
entity: string;
entityId: string;
@ -250,21 +254,31 @@ class MessengerIntegrationStore {
};
update = async () => {
// redux todo: errors
if (!this.instance) return;
this.setLoading(true);
await integrationsService.updateMessengerInt(
this.mName,
this.instance.toData()
);
this.setList(
this.list.map((int) =>
int.webhookId === this.instance?.webhookId ? this.instance : int
)
);
this.setLoading(false);
try {
const response = await integrationsService.updateMessengerInt(
this.mName,
this.instance.toData()
);
if (response.errors) {
toast.error(response.errors[0] || 'Couldn\'t process the request: check your data.');
return response;
}
this.setList(
this.list.map((int) =>
int.webhookId === this.instance?.webhookId ? this.instance : int
)
);
} catch (e) {
toast.error('Couldn\'t process the request: check your data.');
} finally {
this.setLoading(false);
}
};
}
export type namedStore = 'sentry'
| 'datadog'
| 'stackdriver'
@ -277,6 +291,7 @@ export type namedStore = 'sentry'
| 'jira'
| 'github'
| 'issues'
export class IntegrationsStore {
sentry = new NamedIntegrationStore('sentry', (d) => new SentryInt(d));
datadog = new NamedIntegrationStore('datadog', (d) => new DatadogInt(d));

View file

@ -1,63 +1,76 @@
import BaseService from "./BaseService";
import BaseService from './BaseService';
export default class IntegrationsService extends BaseService {
fetchList = async (name?: string, siteId?: string) => {
const r = await this.client.get(`${siteId ? `/${siteId}` : ''}/integrations${name ? `/${name}` : ''}`)
const data = await r.json()
const r = await this.client.get(`${siteId ? `/${siteId}` : ''}/integrations${name ? `/${name}` : ''}`);
const data = await r.json();
return data
}
return data;
};
fetchIntegration = async (name: string, siteId: string) => {
const url = siteId && name !== 'github' && name !== 'jira' ? `/${siteId}/integrations/${name}` : `/integrations/${name}`
const r = await this.client.get(url)
const data = await r.json()
const url = siteId && name !== 'github' && name !== 'jira' ? `/${siteId}/integrations/${name}` : `/integrations/${name}`;
const r = await this.client.get(url);
const data = await r.json();
return data
}
return data;
};
saveIntegration = async (name: string, data: any, siteId?: string) => {
const url = (siteId ? `/${siteId}` : '') + `/integrations/${name}`
const r = await this.client.post(url, data)
const res = await r.json()
return res
}
try {
const url = (siteId ? `/${siteId}` : '') + `/integrations/${name}`;
const r = await this.client.post(url, data);
return await r.json();
} catch (e: any) {
if (e.response) {
const errorData = await e.response.json();
return { errors: errorData.errors };
}
return { errors: ['An unexpected error occurred.'] };
}
};
removeIntegration = async (name: string, siteId?: string) => {
const url = (siteId ? `/${siteId}` : '') + `/integrations/${name}`
const r = await this.client.delete(url)
const url = (siteId ? `/${siteId}` : '') + `/integrations/${name}`;
const r = await this.client.delete(url);
return await r.json()
}
return await r.json();
};
fetchMessengerChannels = async (name: string) => {
const r = await this.client.get(`/integrations/${name}/channels`)
const r = await this.client.get(`/integrations/${name}/channels`);
return await r.json()
}
return await r.json();
};
updateMessengerInt = async (name: string, data: any) => {
const r = await this.client.put(`/integrations/${name}/${data.webhookId}`, data)
return await r.json()
}
try {
const r = await this.client.post(`/integrations/${name}/${data.webhookId}`, data);
return await r.json();
} catch (e: any) {
if (e.response) {
const errorData = await e.response.json();
return { errors: errorData.errors };
}
return { errors: ['An unexpected error occurred.'] };
}
};
removeMessengerInt = async (name: string, webhookId: string) => {
const r = await this.client.delete(`/integrations/${name}/${webhookId}`)
const r = await this.client.delete(`/integrations/${name}/${webhookId}`);
return await r.json()
}
return await r.json();
};
sendMsg = async (integrationId, entity, entityId, name, data) => {
const r = await this.client.post(`/integrations/${name}/notify/${integrationId}/${entity}/${entityId}`, data)
const r = await this.client.post(`/integrations/${name}/notify/${integrationId}/${entity}/${entityId}`, data);
return await r.json()
}
return await r.json();
};
testElastic = async (data: any) => {
const r = await this.client.post('/integrations/elasticsearch/test', data)
const r = await this.client.post('/integrations/elasticsearch/test', data);
return r.json();
}
};
}