Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(site): add custom notification settings#19938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletionssite/src/api/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2519,6 +2519,13 @@ class ApiMethods {
return res.data;
};

getCustomNotificationTemplates = async () => {
const res = await this.axios.get<TypesGen.NotificationTemplate[]>(
"/api/v2/notifications/templates/custom",
);
return res.data;
};

getNotificationDispatchMethods = async () => {
const res = await this.axios.get<TypesGen.NotificationMethodsResponse>(
"/api/v2/notifications/dispatch-methods",
Expand Down
44 changes: 29 additions & 15 deletionssite/src/api/queries/notifications.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -62,6 +62,19 @@ export const systemNotificationTemplates = () => {
};
};

export const customNotificationTemplatesKey = [
"notifications",
"templates",
"custom",
];

export const customNotificationTemplates = () => {
return {
queryKey: customNotificationTemplatesKey,
queryFn: () => API.getCustomNotificationTemplates(),
};
};

export function selectTemplatesByGroup(
data: NotificationTemplate[],
): Record<string, NotificationTemplate[]> {
Expand DownExpand Up@@ -106,23 +119,24 @@ export const updateNotificationTemplateMethod = (
mutationFn: (req: UpdateNotificationTemplateMethod) =>
API.updateNotificationTemplateMethod(templateId, req),
onMutate: (data) => {
constprevData =queryClient.getQueryData<NotificationTemplate[]>(
constkeys =[
systemNotificationTemplatesKey,
);
if (!prevData) {
return;
customNotificationTemplatesKey,
];

for (const key of keys) {
const prev = queryClient.getQueryData<NotificationTemplate[]>(key);
if (!prev) {
continue;
}

queryClient.setQueryData(
key,
prev.map((tpl) =>
tpl.id === templateId ? { ...tpl, method: data.method } : tpl,
),
);
}
queryClient.setQueryData(
systemNotificationTemplatesKey,
prevData.map((tpl) =>
tpl.id === templateId
? {
...tpl,
method: data.method,
}
: tpl,
),
);
},
} satisfies UseMutationOptions<
void,
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import {MockNotificationTemplates } from "testHelpers/entities";
import {MockSystemNotificationTemplates } from "testHelpers/entities";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { API } from "api/api";
import { selectTemplatesByGroup } from "api/queries/notifications";
Expand All@@ -13,7 +13,7 @@ const meta: Meta<typeof NotificationEvents> = {
args: {
defaultMethod: "smtp",
availableMethods: ["smtp", "webhook"],
templatesByGroup: selectTemplatesByGroup(MockNotificationTemplates),
templatesByGroup: selectTemplatesByGroup(MockSystemNotificationTemplates),
deploymentConfig: baseMeta.parameters.deploymentValues,
},
...baseMeta,
Expand DownExpand Up@@ -60,7 +60,7 @@ export const Toggle: Story = {
spyOn(API, "updateNotificationTemplateMethod").mockResolvedValue();
const user = userEvent.setup();
const canvas = within(canvasElement);
const tmpl =MockNotificationTemplates[4];
const tmpl =MockSystemNotificationTemplates[4];
const option = await canvas.findByText(tmpl.name);
const li = option.closest("li");
if (!li) {
Expand All@@ -79,7 +79,7 @@ export const ToggleError: Story = {
spyOn(API, "updateNotificationTemplateMethod").mockRejectedValue({});
const user = userEvent.setup();
const canvas = within(canvasElement);
const tmpl =MockNotificationTemplates[4];
const tmpl =MockSystemNotificationTemplates[4];
const option = await canvas.findByText(tmpl.name);
const li = option.closest("li");
if (!li) {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
import {
MockCustomNotificationTemplates,
MockNotificationMethodsResponse,
MockNotificationTemplates,
MockSystemNotificationTemplates,
} from "testHelpers/entities";
import type { Meta, StoryObj } from "@storybook/react-vite";
import {
customNotificationTemplatesKey,
notificationDispatchMethodsKey,
systemNotificationTemplatesKey,
} from "api/queries/notifications";
Expand All@@ -28,6 +30,10 @@ export const LoadingTemplates: Story = {
key: systemNotificationTemplatesKey,
data: undefined,
},
{
key: customNotificationTemplatesKey,
data: undefined,
},
{
key: notificationDispatchMethodsKey,
data: MockNotificationMethodsResponse,
Expand All@@ -39,7 +45,14 @@ export const LoadingTemplates: Story = {
export const LoadingDispatchMethods: Story = {
parameters: {
queries: [
{ key: systemNotificationTemplatesKey, data: MockNotificationTemplates },
{
key: systemNotificationTemplatesKey,
data: MockSystemNotificationTemplates,
},
{
key: customNotificationTemplatesKey,
data: MockCustomNotificationTemplates,
},
{
key: notificationDispatchMethodsKey,
data: undefined,
Expand All@@ -48,7 +61,20 @@ export const LoadingDispatchMethods: Story = {
},
};

export const Events: Story = {};
export const Events: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

// System notification templates
await canvas.findByText("Template Events");
await canvas.findByText("User Events");
await canvas.findByText("Workspace Events");

// Custom notification template
await canvas.findByText("Custom Events");
await canvas.findByText("Custom Notification");
},
};

export const Settings: Story = {
play: async ({ canvasElement }) => {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
import type { Interpolation, Theme } from "@emotion/react";
import {
customNotificationTemplates,
notificationDispatchMethods,
selectTemplatesByGroup,
systemNotificationTemplates,
Expand DownExpand Up@@ -27,21 +28,35 @@ import { Troubleshooting } from "./Troubleshooting";

const NotificationsPage: FC = () => {
const { deploymentConfig } = useDeploymentConfig();
const [templatesByGroup, dispatchMethods] = useQueries({
queries: [
{
...systemNotificationTemplates(),
select: selectTemplatesByGroup,
},
notificationDispatchMethods(),
],
});
const [systemTemplatesByGroup, customTemplatesByGroup, dispatchMethods] =
useQueries({
queries: [
{
...systemNotificationTemplates(),
select: selectTemplatesByGroup,
},
{
...customNotificationTemplates(),
select: selectTemplatesByGroup,
},
notificationDispatchMethods(),
],
});
const tabState = useSearchParamsKey({
key: "tab",
defaultValue: "events",
});

const ready = !!(templatesByGroup.data && dispatchMethods.data);
const ready = !!(
systemTemplatesByGroup.data &&
customTemplatesByGroup.data &&
dispatchMethods.data
);
// Combine system and custom notification templates
const allTemplatesByGroup = {
...systemTemplatesByGroup.data,
...customTemplatesByGroup.data,
};
return (
<>
<Helmet>
Expand DownExpand Up@@ -79,7 +94,7 @@ const NotificationsPage: FC = () => {
{ready ? (
tabState.value === "events" ? (
<NotificationEvents
templatesByGroup={templatesByGroup.data}
templatesByGroup={allTemplatesByGroup}
deploymentConfig={deploymentConfig.config}
defaultMethod={castNotificationMethod(
dispatchMethods.data.default,
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import {
MockCustomNotificationTemplates,
MockNotificationMethodsResponse,
MockNotificationTemplates,
MockSystemNotificationTemplates,
MockUserOwner,
} from "testHelpers/entities";
import {
Expand All@@ -11,6 +12,7 @@ import {
} from "testHelpers/storybook";
import type { Meta } from "@storybook/react-vite";
import {
customNotificationTemplatesKey,
notificationDispatchMethodsKey,
systemNotificationTemplatesKey,
} from "api/queries/notifications";
Expand DownExpand Up@@ -187,7 +189,14 @@ export const baseMeta = {
parameters: {
experiments: ["notifications"],
queries: [
{ key: systemNotificationTemplatesKey, data: MockNotificationTemplates },
{
key: systemNotificationTemplatesKey,
data: MockSystemNotificationTemplates,
},
{
key: customNotificationTemplatesKey,
data: MockCustomNotificationTemplates,
},
{
key: notificationDispatchMethodsKey,
data: MockNotificationMethodsResponse,
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
import {
MockCustomNotificationTemplates,
MockNotificationMethodsResponse,
MockNotificationPreferences,
MockNotificationTemplates,
MockSystemNotificationTemplates,
MockUserOwner,
} from "testHelpers/entities";
import {
Expand All@@ -12,6 +13,7 @@ import {
import type { Meta, StoryObj } from "@storybook/react-vite";
import { API } from "api/api";
import {
customNotificationTemplatesKey,
notificationDispatchMethodsKey,
systemNotificationTemplatesKey,
userNotificationPreferencesKey,
Expand All@@ -32,7 +34,11 @@ const meta = {
},
{
key: systemNotificationTemplatesKey,
data: MockNotificationTemplates,
data: MockSystemNotificationTemplates,
},
{
key: customNotificationTemplatesKey,
data: MockCustomNotificationTemplates,
},
{
key: notificationDispatchMethodsKey,
Expand DownExpand Up@@ -100,7 +106,7 @@ if (!enabledPreference) {
"No enabled notification preference available to test the disabling action.",
);
}
const templateToDisable =MockNotificationTemplates.find(
const templateToDisable =MockSystemNotificationTemplates.find(
(tpl) => tpl.id === enabledPreference.id,
);
if (!templateToDisable) {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,6 +8,7 @@ import ListItemText, { listItemTextClasses } from "@mui/material/ListItemText";
import Switch from "@mui/material/Switch";
import Tooltip from "@mui/material/Tooltip";
import {
customNotificationTemplates,
disableNotification,
notificationDispatchMethods,
selectTemplatesByGroup,
Expand DownExpand Up@@ -38,7 +39,12 @@ import { Section } from "../Section";

const NotificationsPage: FC = () => {
const { user, permissions } = useAuthenticated();
const [disabledPreferences, templatesByGroup, dispatchMethods] = useQueries({
const [
disabledPreferences,
systemTemplatesByGroup,
customTemplatesByGroup,
dispatchMethods,
] = useQueries({
queries: [
{
...userNotificationPreferences(user.id),
Expand All@@ -48,6 +54,10 @@ const NotificationsPage: FC = () => {
...systemNotificationTemplates(),
select: (data: NotificationTemplate[]) => selectTemplatesByGroup(data),
},
{
...customNotificationTemplates(),
select: (data: NotificationTemplate[]) => selectTemplatesByGroup(data),
},
notificationDispatchMethods(),
],
});
Expand DownExpand Up@@ -80,7 +90,15 @@ const NotificationsPage: FC = () => {
}, [searchParams.delete, disabledId, disableMutation]);

const ready =
disabledPreferences.data && templatesByGroup.data && dispatchMethods.data;
disabledPreferences.data &&
systemTemplatesByGroup.data &&
customTemplatesByGroup.data &&
dispatchMethods.data;
// Combine system and custom notification templates
const allTemplatesByGroup = {
...systemTemplatesByGroup.data,
...customTemplatesByGroup.data,
};

return (
<>
Expand All@@ -94,7 +112,7 @@ const NotificationsPage: FC = () => {
>
{ready ? (
<Stack spacing={4}>
{Object.entries(templatesByGroup.data).map(([group, templates]) => {
{Object.entries(allTemplatesByGroup).map(([group, templates]) => {
if (!canSeeNotificationGroup(group, permissions)) {
return null;
}
Expand DownExpand Up@@ -218,6 +236,8 @@ function canSeeNotificationGroup(
return permissions.createTemplates;
case "User Events":
return permissions.createUser;
case "Custom Events":
return true;
default:
return false;
}
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp