mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
notifications: notification settings page
This commit is contained in:
parent
d77a01d8bc
commit
7135d06673
17 changed files with 319 additions and 35 deletions
|
@ -1,17 +1,22 @@
|
||||||
import { API } from '~/constants/api';
|
import { API } from '~/constants/api';
|
||||||
|
import { NotificationSettings } from '~/types/notifications';
|
||||||
import { api, cleanResult } from '~/utils/api';
|
import { api, cleanResult } from '~/utils/api';
|
||||||
|
import {
|
||||||
|
notificationSettingsFromRequest,
|
||||||
|
notificationSettingsToRequest,
|
||||||
|
} from '~/utils/notifications/notificationSettingsFromRequest';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ApiGetNotificationSettingsResponse,
|
ApiGetNotificationSettingsResponse,
|
||||||
ApiGetNotificationsResponse,
|
ApiGetNotificationsResponse,
|
||||||
ApiUpdateNotificationSettingsResponse,
|
ApiUpdateNotificationSettingsResponse,
|
||||||
ApiUpdateNotificationSettingsRequest,
|
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export const apiGetNotificationSettings = () =>
|
export const apiGetNotificationSettings = (): Promise<NotificationSettings> =>
|
||||||
api
|
api
|
||||||
.get<ApiGetNotificationSettingsResponse>(API.NOTIFICATIONS.SETTINGS)
|
.get<ApiGetNotificationSettingsResponse>(API.NOTIFICATIONS.SETTINGS)
|
||||||
.then(cleanResult);
|
.then(cleanResult)
|
||||||
|
.then(notificationSettingsFromRequest);
|
||||||
|
|
||||||
export const apiGetNotifications = () =>
|
export const apiGetNotifications = () =>
|
||||||
api
|
api
|
||||||
|
@ -19,11 +24,12 @@ export const apiGetNotifications = () =>
|
||||||
.then(cleanResult);
|
.then(cleanResult);
|
||||||
|
|
||||||
export const apiUpdateNotificationSettings = (
|
export const apiUpdateNotificationSettings = (
|
||||||
settings: ApiUpdateNotificationSettingsRequest,
|
settings: Partial<NotificationSettings>,
|
||||||
) =>
|
) =>
|
||||||
api
|
api
|
||||||
.post<ApiUpdateNotificationSettingsResponse>(
|
.post<ApiUpdateNotificationSettingsResponse>(
|
||||||
API.NOTIFICATIONS.SETTINGS,
|
API.NOTIFICATIONS.SETTINGS,
|
||||||
settings,
|
notificationSettingsToRequest(settings),
|
||||||
)
|
)
|
||||||
.then(cleanResult);
|
.then(cleanResult)
|
||||||
|
.then(notificationSettingsFromRequest);
|
||||||
|
|
|
@ -4,6 +4,8 @@ export interface ApiGetNotificationSettingsResponse {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
flow: boolean;
|
flow: boolean;
|
||||||
comments: boolean;
|
comments: boolean;
|
||||||
|
send_telegram: boolean;
|
||||||
|
show_indicator: boolean;
|
||||||
last_seen?: string | null;
|
last_seen?: string | null;
|
||||||
last_date?: string | null;
|
last_date?: string | null;
|
||||||
}
|
}
|
||||||
|
|
19
src/components/input/InputRow/index.tsx
Normal file
19
src/components/input/InputRow/index.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React, { FC, ReactNode } from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
|
interface InputRowProps {
|
||||||
|
className?: string;
|
||||||
|
input?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InputRow: FC<InputRowProps> = ({ children, input, className }) => (
|
||||||
|
<div className={classNames(styles.row, className)}>
|
||||||
|
<div>{children}</div>
|
||||||
|
{!!input && <div>{input}</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export { InputRow };
|
8
src/components/input/InputRow/styles.module.scss
Normal file
8
src/components/input/InputRow/styles.module.scss
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
@import 'src/styles/variables';
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
row-gap: $gap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
|
@ -38,6 +38,10 @@
|
||||||
transition: transform 0.25s, color 0.25s, background-color;
|
transition: transform 0.25s, color 0.25s, background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
&::after {
|
&::after {
|
||||||
transform: translate(24px, 0);
|
transform: translate(24px, 0);
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import React, { FC, useCallback } from 'react';
|
||||||
|
|
||||||
|
import { Group } from '~/components/containers/Group';
|
||||||
|
import { Zone } from '~/components/containers/Zone';
|
||||||
|
import { Button } from '~/components/input/Button';
|
||||||
|
import { InputRow } from '~/components/input/InputRow';
|
||||||
|
import { Toggle } from '~/components/input/Toggle';
|
||||||
|
import { useNotificationSettingsForm } from '~/hooks/notifications/useNotificationSettingsForm';
|
||||||
|
import { NotificationSettings } from '~/types/notifications';
|
||||||
|
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
|
interface NotificationSettingsFormProps {
|
||||||
|
value: NotificationSettings;
|
||||||
|
onSubmit: (val: Partial<NotificationSettings>) => Promise<unknown>;
|
||||||
|
telegramConnected: boolean;
|
||||||
|
onConnectTelegram: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NotificationSettingsForm: FC<NotificationSettingsFormProps> = ({
|
||||||
|
value,
|
||||||
|
onSubmit,
|
||||||
|
telegramConnected,
|
||||||
|
onConnectTelegram,
|
||||||
|
}) => {
|
||||||
|
const { setFieldValue, values } = useNotificationSettingsForm(
|
||||||
|
value,
|
||||||
|
onSubmit,
|
||||||
|
);
|
||||||
|
|
||||||
|
const toggle = useCallback(
|
||||||
|
(key: keyof NotificationSettings, disabled?: boolean) => (
|
||||||
|
<Toggle
|
||||||
|
handler={(val) => setFieldValue(key, val)}
|
||||||
|
value={values[key]}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[setFieldValue, values],
|
||||||
|
);
|
||||||
|
|
||||||
|
const telegramInput = telegramConnected ? (
|
||||||
|
toggle('sendTelegram', !values.enabled)
|
||||||
|
) : (
|
||||||
|
<Button size="micro" onClick={onConnectTelegram}>
|
||||||
|
Подключить
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group>
|
||||||
|
<Zone title="Уведомления">
|
||||||
|
<Group>
|
||||||
|
<InputRow className={styles.row} input={toggle('enabled')}>
|
||||||
|
Включены
|
||||||
|
</InputRow>
|
||||||
|
<InputRow
|
||||||
|
className={styles.row}
|
||||||
|
input={toggle('flow', !values.enabled)}
|
||||||
|
>
|
||||||
|
Новые посты
|
||||||
|
</InputRow>
|
||||||
|
|
||||||
|
<InputRow
|
||||||
|
className={styles.row}
|
||||||
|
input={toggle('comments', !values.enabled)}
|
||||||
|
>
|
||||||
|
Комментарии
|
||||||
|
</InputRow>
|
||||||
|
</Group>
|
||||||
|
</Zone>
|
||||||
|
|
||||||
|
<Zone title="Уведомления">
|
||||||
|
<Group>
|
||||||
|
<InputRow
|
||||||
|
className={styles.row}
|
||||||
|
input={toggle('showIndicator', !values.enabled)}
|
||||||
|
>
|
||||||
|
На иконке профиля
|
||||||
|
</InputRow>
|
||||||
|
|
||||||
|
<InputRow className={styles.row} input={telegramInput}>
|
||||||
|
Телеграм
|
||||||
|
</InputRow>
|
||||||
|
</Group>
|
||||||
|
</Zone>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { NotificationSettingsForm };
|
|
@ -0,0 +1,11 @@
|
||||||
|
@import 'src/styles/variables';
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: row;
|
||||||
|
row-gap: $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
font: $font_14_regular;
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
|
|
||||||
|
import { Padder } from '~/components/containers/Padder';
|
||||||
import { useStackContext } from '~/components/sidebar/SidebarStack';
|
import { useStackContext } from '~/components/sidebar/SidebarStack';
|
||||||
import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard';
|
import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard';
|
||||||
|
import { NotificationSettings } from '~/containers/notifications/NotificationSettings';
|
||||||
import { NotificationList } from '../../../containers/notifications/NotificationList/index';
|
|
||||||
|
|
||||||
interface ProfileSidebarNotificationsProps {}
|
interface ProfileSidebarNotificationsProps {}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ const ProfileSidebarNotifications: VFC<
|
||||||
title="Уведомления"
|
title="Уведомления"
|
||||||
onBackPress={closeAllTabs}
|
onBackPress={closeAllTabs}
|
||||||
>
|
>
|
||||||
<NotificationList />
|
<NotificationSettings />
|
||||||
</SidebarStackCard>
|
</SidebarStackCard>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
30
src/containers/notifications/NotificationSettings/index.tsx
Normal file
30
src/containers/notifications/NotificationSettings/index.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
|
||||||
|
import { Padder } from '~/components/containers/Padder';
|
||||||
|
import { NotificationSettingsForm } from '~/components/notifications/NotificationSettingsForm';
|
||||||
|
import { useOAuth } from '~/hooks/auth/useOAuth';
|
||||||
|
import { useNotificationSettings } from '~/hooks/notifications/useNotificationSettings';
|
||||||
|
|
||||||
|
interface NotificationSettingsProps {}
|
||||||
|
|
||||||
|
const NotificationSettings: FC<NotificationSettingsProps> = () => {
|
||||||
|
const { settings, update } = useNotificationSettings();
|
||||||
|
const { hasTelegram, showTelegramModal } = useOAuth();
|
||||||
|
|
||||||
|
if (!settings) {
|
||||||
|
return <>{null}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Padder>
|
||||||
|
<NotificationSettingsForm
|
||||||
|
value={settings}
|
||||||
|
onSubmit={update}
|
||||||
|
telegramConnected={hasTelegram}
|
||||||
|
onConnectTelegram={showTelegramModal}
|
||||||
|
/>
|
||||||
|
</Padder>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { NotificationSettings };
|
|
@ -15,18 +15,14 @@ import styles from './styles.module.scss';
|
||||||
type ProfileAccountsProps = {};
|
type ProfileAccountsProps = {};
|
||||||
|
|
||||||
const ProfileAccounts: FC<ProfileAccountsProps> = () => {
|
const ProfileAccounts: FC<ProfileAccountsProps> = () => {
|
||||||
const { isLoading, accounts, dropAccount, openOauthWindow } = useOAuth();
|
const {
|
||||||
const { showModal } = useModal();
|
isLoading,
|
||||||
|
accounts,
|
||||||
const hasTelegram = useMemo(
|
dropAccount,
|
||||||
() => accounts.some((acc) => acc.provider === 'telegram'),
|
openOauthWindow,
|
||||||
[accounts],
|
hasTelegram,
|
||||||
);
|
showTelegramModal,
|
||||||
|
} = useOAuth();
|
||||||
const showTelegramModal = useCallback(
|
|
||||||
() => showModal(Dialog.TelegramAttach, {}),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group className={styles.wrap}>
|
<Group className={styles.wrap}>
|
||||||
|
|
|
@ -97,7 +97,19 @@ export const useOAuth = () => {
|
||||||
const accounts = useMemo(() => data || [], [data]);
|
const accounts = useMemo(() => data || [], [data]);
|
||||||
const refresh = useCallback(() => mutate(), []);
|
const refresh = useCallback(() => mutate(), []);
|
||||||
|
|
||||||
|
const hasTelegram = useMemo(
|
||||||
|
() => accounts.some((acc) => acc.provider === 'telegram'),
|
||||||
|
[accounts],
|
||||||
|
);
|
||||||
|
|
||||||
|
const showTelegramModal = useCallback(
|
||||||
|
() => showModal(Dialog.TelegramAttach, {}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
hasTelegram,
|
||||||
|
showTelegramModal,
|
||||||
openOauthWindow,
|
openOauthWindow,
|
||||||
loginWithSocial,
|
loginWithSocial,
|
||||||
createSocialAccount,
|
createSocialAccount,
|
||||||
|
|
|
@ -7,8 +7,7 @@ import { useAuth } from '../auth/useAuth';
|
||||||
import { useNotificationSettingsRequest } from './useNotificationSettingsRequest';
|
import { useNotificationSettingsRequest } from './useNotificationSettingsRequest';
|
||||||
|
|
||||||
export const useNotificationSettings = () => {
|
export const useNotificationSettings = () => {
|
||||||
// TODO: remove isTester
|
const { isUser } = useAuth();
|
||||||
const { isUser, isTester } = useAuth();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
error: settingsError,
|
error: settingsError,
|
||||||
|
@ -18,16 +17,15 @@ export const useNotificationSettings = () => {
|
||||||
isLoading: isLoadingSettings,
|
isLoading: isLoadingSettings,
|
||||||
update,
|
update,
|
||||||
refresh,
|
refresh,
|
||||||
|
settings,
|
||||||
} = useNotificationSettingsRequest();
|
} = useNotificationSettingsRequest();
|
||||||
|
|
||||||
const enabled =
|
const enabled = !isLoadingSettings && !settingsError && settingsEnabled;
|
||||||
!isLoadingSettings && !settingsError && settingsEnabled && isTester;
|
|
||||||
|
|
||||||
const hasNew =
|
const hasNew =
|
||||||
enabled && !!lastDate && (!lastSeen || isAfter(lastDate, lastSeen));
|
enabled && !!lastDate && (!lastSeen || isAfter(lastDate, lastSeen));
|
||||||
|
|
||||||
// TODO: store `indicator` as option and include it here
|
const indicatorEnabled = enabled && !!settings?.showIndicator;
|
||||||
const indicatorEnabled = enabled && true;
|
|
||||||
|
|
||||||
const markAsRead = useCallback(() => {
|
const markAsRead = useCallback(() => {
|
||||||
if (
|
if (
|
||||||
|
@ -37,7 +35,7 @@ export const useNotificationSettings = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
update({ last_seen: lastDate.toISOString() });
|
update({ lastSeen: lastDate.toISOString() });
|
||||||
}, [update, lastDate, lastSeen]);
|
}, [update, lastDate, lastSeen]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -45,7 +43,9 @@ export const useNotificationSettings = () => {
|
||||||
hasNew,
|
hasNew,
|
||||||
indicatorEnabled,
|
indicatorEnabled,
|
||||||
available: isUser,
|
available: isUser,
|
||||||
|
settings,
|
||||||
markAsRead,
|
markAsRead,
|
||||||
refresh,
|
refresh,
|
||||||
|
update,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
46
src/hooks/notifications/useNotificationSettingsForm.ts
Normal file
46
src/hooks/notifications/useNotificationSettingsForm.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { FormikConfig, useFormik } from 'formik';
|
||||||
|
import { Asserts, boolean, object } from 'yup';
|
||||||
|
|
||||||
|
import { showErrorToast } from '~/utils/errors/showToast';
|
||||||
|
|
||||||
|
import { useFormAutoSubmit } from '../useFormAutosubmit';
|
||||||
|
|
||||||
|
const validationSchema = object({
|
||||||
|
enabled: boolean().default(false),
|
||||||
|
flow: boolean().default(false),
|
||||||
|
comments: boolean().default(false),
|
||||||
|
sendTelegram: boolean().default(false),
|
||||||
|
showIndicator: boolean().default(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Values = Asserts<typeof validationSchema>;
|
||||||
|
|
||||||
|
export const useNotificationSettingsForm = (
|
||||||
|
initialValues: Values,
|
||||||
|
submit: (val: Values) => void,
|
||||||
|
) => {
|
||||||
|
const onSubmit = useCallback<FormikConfig<Values>['onSubmit']>(
|
||||||
|
async (values, { setSubmitting }) => {
|
||||||
|
try {
|
||||||
|
await submit(values);
|
||||||
|
} catch (error) {
|
||||||
|
showErrorToast(error);
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[submit],
|
||||||
|
);
|
||||||
|
|
||||||
|
const formik = useFormik<Values>({
|
||||||
|
initialValues,
|
||||||
|
validationSchema,
|
||||||
|
onSubmit,
|
||||||
|
});
|
||||||
|
|
||||||
|
useFormAutoSubmit(formik.values, formik.handleSubmit);
|
||||||
|
|
||||||
|
return formik;
|
||||||
|
};
|
|
@ -7,8 +7,8 @@ import {
|
||||||
apiGetNotificationSettings,
|
apiGetNotificationSettings,
|
||||||
apiUpdateNotificationSettings,
|
apiUpdateNotificationSettings,
|
||||||
} from '~/api/notifications/settings';
|
} from '~/api/notifications/settings';
|
||||||
import { ApiUpdateNotificationSettingsRequest } from '~/api/notifications/types';
|
|
||||||
import { API } from '~/constants/api';
|
import { API } from '~/constants/api';
|
||||||
|
import { NotificationSettings } from '~/types/notifications';
|
||||||
import { getErrorMessage } from '~/utils/errors/getErrorMessage';
|
import { getErrorMessage } from '~/utils/errors/getErrorMessage';
|
||||||
import { showErrorToast } from '~/utils/errors/showToast';
|
import { showErrorToast } from '~/utils/errors/showToast';
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ export const useNotificationSettingsRequest = () => {
|
||||||
mutate,
|
mutate,
|
||||||
} = useSWR(
|
} = useSWR(
|
||||||
isUser ? API.NOTIFICATIONS.SETTINGS : null,
|
isUser ? API.NOTIFICATIONS.SETTINGS : null,
|
||||||
async () => apiGetNotificationSettings(),
|
apiGetNotificationSettings,
|
||||||
{ refreshInterval },
|
{ refreshInterval },
|
||||||
);
|
);
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
async (settings: ApiUpdateNotificationSettingsRequest) => {
|
async (settings: Partial<NotificationSettings>) => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -69,14 +69,15 @@ export const useNotificationSettingsRequest = () => {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
lastSeen:
|
lastSeen:
|
||||||
data?.last_seen && isValid(parseISO(data.last_seen))
|
data?.lastSeen && isValid(parseISO(data.lastSeen))
|
||||||
? parseISO(data?.last_seen)
|
? parseISO(data?.lastSeen)
|
||||||
: undefined,
|
: undefined,
|
||||||
lastDate:
|
lastDate:
|
||||||
data?.last_date && isValid(parseISO(data.last_date))
|
data?.lastDate && isValid(parseISO(data.lastDate))
|
||||||
? parseISO(data?.last_date)
|
? parseISO(data?.lastDate)
|
||||||
: undefined,
|
: undefined,
|
||||||
enabled: !!data?.enabled && (data.flow || data.comments),
|
enabled: !!data?.enabled && (data.flow || data.comments),
|
||||||
|
settings: data,
|
||||||
refresh,
|
refresh,
|
||||||
update,
|
update,
|
||||||
updateError,
|
updateError,
|
||||||
|
|
20
src/hooks/useFormAutosubmit.ts
Normal file
20
src/hooks/useFormAutosubmit.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
export const useFormAutoSubmit = <T>(
|
||||||
|
values: T,
|
||||||
|
onSubmit: () => void,
|
||||||
|
delay = 1000,
|
||||||
|
) => {
|
||||||
|
const prevValue = useRef<T>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!prevValue.current) {
|
||||||
|
prevValue.current = values;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeout = setTimeout(onSubmit, delay);
|
||||||
|
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}, [values]);
|
||||||
|
};
|
|
@ -14,3 +14,13 @@ export enum NotificationType {
|
||||||
Node = 'node',
|
Node = 'node',
|
||||||
Comment = 'comment',
|
Comment = 'comment',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NotificationSettings {
|
||||||
|
enabled: boolean;
|
||||||
|
flow: boolean;
|
||||||
|
comments: boolean;
|
||||||
|
sendTelegram: boolean;
|
||||||
|
showIndicator: boolean;
|
||||||
|
lastSeen: string | null;
|
||||||
|
lastDate: string | null;
|
||||||
|
}
|
||||||
|
|
28
src/utils/notifications/notificationSettingsFromRequest.ts
Normal file
28
src/utils/notifications/notificationSettingsFromRequest.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { ApiGetNotificationSettingsResponse } from '~/api/notifications/types';
|
||||||
|
import { NotificationSettings } from '~/types/notifications';
|
||||||
|
|
||||||
|
import { ApiUpdateNotificationSettingsRequest } from '../../api/notifications/types';
|
||||||
|
|
||||||
|
export const notificationSettingsFromRequest = (
|
||||||
|
req: ApiGetNotificationSettingsResponse,
|
||||||
|
): NotificationSettings => ({
|
||||||
|
enabled: req.enabled,
|
||||||
|
flow: req.flow,
|
||||||
|
comments: req.comments,
|
||||||
|
sendTelegram: req.send_telegram,
|
||||||
|
showIndicator: req.show_indicator,
|
||||||
|
lastDate: req.last_date ?? null,
|
||||||
|
lastSeen: req.last_seen ?? null,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const notificationSettingsToRequest = (
|
||||||
|
req: Partial<NotificationSettings>,
|
||||||
|
): ApiUpdateNotificationSettingsRequest => ({
|
||||||
|
enabled: req.enabled,
|
||||||
|
flow: req.flow,
|
||||||
|
comments: req.comments,
|
||||||
|
send_telegram: req.sendTelegram,
|
||||||
|
show_indicator: req.showIndicator,
|
||||||
|
last_date: req.lastDate,
|
||||||
|
last_seen: req.lastSeen,
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue