Fix possible 404 when obtaining calendar busy lists (#3345)
parent
48916cf85e
commit
4c2f6df94d
|
@ -153,6 +153,7 @@ function ConnectedCalendarsList(props: Props) {
|
||||||
actions={
|
actions={
|
||||||
<DisconnectIntegration
|
<DisconnectIntegration
|
||||||
id={item.credentialId}
|
id={item.credentialId}
|
||||||
|
externalId={item.primary?.externalId}
|
||||||
render={(btnProps) => (
|
render={(btnProps) => (
|
||||||
<Button {...btnProps} color="warn" data-testid="integration-connection-button">
|
<Button {...btnProps} color="warn" data-testid="integration-connection-button">
|
||||||
{t("disconnect")}
|
{t("disconnect")}
|
||||||
|
|
|
@ -13,10 +13,11 @@ import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogCont
|
||||||
export default function DisconnectIntegration(props: {
|
export default function DisconnectIntegration(props: {
|
||||||
/** Integration credential id */
|
/** Integration credential id */
|
||||||
id: number;
|
id: number;
|
||||||
|
externalId?: string;
|
||||||
render: (renderProps: ButtonBaseProps) => JSX.Element;
|
render: (renderProps: ButtonBaseProps) => JSX.Element;
|
||||||
onOpenChange: (isOpen: boolean) => unknown | Promise<unknown>;
|
onOpenChange: (isOpen: boolean) => unknown | Promise<unknown>;
|
||||||
}) {
|
}) {
|
||||||
const { id } = props;
|
const { id, externalId = "" } = props;
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ export default function DisconnectIntegration(props: {
|
||||||
confirmBtnText={t("yes_remove_app")}
|
confirmBtnText={t("yes_remove_app")}
|
||||||
cancelBtnText="Cancel"
|
cancelBtnText="Cancel"
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
mutation.mutate({ id });
|
mutation.mutate({ id, externalId });
|
||||||
}}>
|
}}>
|
||||||
{t("are_you_sure_you_want_to_remove_this_app")}
|
{t("are_you_sure_you_want_to_remove_this_app")}
|
||||||
</ConfirmationDialogContent>
|
</ConfirmationDialogContent>
|
||||||
|
|
|
@ -991,9 +991,10 @@ const loggedInViewerRouter = createProtectedRouter()
|
||||||
.mutation("deleteCredential", {
|
.mutation("deleteCredential", {
|
||||||
input: z.object({
|
input: z.object({
|
||||||
id: z.number(),
|
id: z.number(),
|
||||||
|
externalId: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
async resolve({ input, ctx }) {
|
async resolve({ input, ctx }) {
|
||||||
const { id } = input;
|
const { id, externalId } = input;
|
||||||
|
|
||||||
const credential = await prisma.credential.findFirst({
|
const credential = await prisma.credential.findFirst({
|
||||||
where: {
|
where: {
|
||||||
|
@ -1060,14 +1061,41 @@ const loggedInViewerRouter = createProtectedRouter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's a calendar, remove the destination claendar from the event type
|
// If it's a calendar, remove the destination calendar from the event type
|
||||||
if (credential.app?.categories.includes(AppCategories.calendar)) {
|
if (credential.app?.categories.includes(AppCategories.calendar)) {
|
||||||
if (eventType.destinationCalendar?.integration === credential.type) {
|
if (eventType.destinationCalendar?.integration === credential.type) {
|
||||||
await prisma.destinationCalendar.delete({
|
const destinationCalendar = await prisma.destinationCalendar.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: eventType.destinationCalendar.id,
|
id: eventType.destinationCalendar?.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
if (destinationCalendar) {
|
||||||
|
await prisma.destinationCalendar.delete({
|
||||||
|
where: {
|
||||||
|
id: destinationCalendar.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (externalId) {
|
||||||
|
const existingSelectedCalendar = await prisma.selectedCalendar.findFirst({
|
||||||
|
where: {
|
||||||
|
externalId: externalId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// @TODO: SelectedCalendar doesn't have unique ID so we should only delete one item
|
||||||
|
if (existingSelectedCalendar) {
|
||||||
|
await prisma.selectedCalendar.delete({
|
||||||
|
where: {
|
||||||
|
userId_integration_externalId: {
|
||||||
|
userId: existingSelectedCalendar.userId,
|
||||||
|
externalId: existingSelectedCalendar.externalId,
|
||||||
|
integration: existingSelectedCalendar.integration,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,16 +140,18 @@ export default class Office365CalendarService implements Calendar {
|
||||||
});
|
});
|
||||||
const responseBody = await handleErrorsJson(response);
|
const responseBody = await handleErrorsJson(response);
|
||||||
return responseBody.responses.reduce(
|
return responseBody.responses.reduce(
|
||||||
(acc: BufferedBusyTime[], subResponse: { body: { value: any[] } }) =>
|
(acc: BufferedBusyTime[], subResponse: { body: { value?: any[] } }) =>
|
||||||
acc.concat(
|
acc.concat(
|
||||||
subResponse.body.value
|
subResponse.body?.value
|
||||||
.filter((evt) => evt.showAs !== "free" && evt.showAs !== "workingElsewhere")
|
? subResponse.body.value
|
||||||
.map((evt) => {
|
.filter((evt) => evt.showAs !== "free" && evt.showAs !== "workingElsewhere")
|
||||||
return {
|
.map((evt) => {
|
||||||
start: evt.start.dateTime + "Z",
|
return {
|
||||||
end: evt.end.dateTime + "Z",
|
start: evt.start.dateTime + "Z",
|
||||||
};
|
end: evt.end.dateTime + "Z",
|
||||||
})
|
};
|
||||||
|
})
|
||||||
|
: []
|
||||||
),
|
),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue