diff --git a/src/locales/en.ts b/src/locales/en.ts index c723011..84db484 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -29,6 +29,8 @@ const en = { realmUrlPH: 'https://your.oidp.server.com/realms/frigate-realm', adminRole: 'Select admin role', birdseyeRole: 'Select birds eye role user', + emptyRolesNotify: 'List of roles are empty. You can manually start updating on server:', + updateRoles: 'Update Roles', }, systemPage: { cameraStats: 'Cameras stats', @@ -128,6 +130,7 @@ const en = { youCanRetryOrGoToMain: "You can retry or return to the main page", successfully: "Sucessfully", successfullySaved: "Sucessfully saved", + successfullyUpdated: "Sucessfully updated", error: "Error", errors: { emptyResponse: 'Empty response', diff --git a/src/locales/ru.ts b/src/locales/ru.ts index 0e59497..d4e7178 100644 --- a/src/locales/ru.ts +++ b/src/locales/ru.ts @@ -6,7 +6,7 @@ const ru = { cameraConfigNotExist: 'Конфиг. камеры не найден', width: 'Ширина', height: 'Высота', - points: 'Точки', + points: 'Точки', }, frigateConfigPage: { copyConfig: 'Копировать Конфиг.', @@ -26,7 +26,10 @@ const ru = { realmUrl: 'OIDP realm URL путь', realmUrlPH: 'https://your.oidp.server.com/realms/frigate-realm', adminRole: 'Выбери роль администратора', - birdseyeRole: 'Выбери роль birdseye пользователя',}, + birdseyeRole: 'Выбери роль birdseye пользователя', + emptyRolesNotify: 'Список ролей пуст. Вы можете вручную запустить обновление на сервере:', + updateRoles: 'Обновить роли', + }, systemPage: { cameraStats: 'Статистика Камер', storageStats: 'Статистика Хранения', @@ -60,7 +63,7 @@ const ru = { restart: 'Перезагрузка', system: 'Система', storage: 'Хранилище', - }, + }, header: { home: 'Главная', settings: 'Настройки', @@ -106,7 +109,7 @@ const ru = { second: 'Час', events: 'События', notHaveEvents: 'Событий нет', - selectHost:'Выбери хост', + selectHost: 'Выбери хост', selectCamera: 'Выбери камеру', selectRange: 'Выбери период', changeTheme: "Изменить тему", @@ -125,6 +128,7 @@ const ru = { youCanRetryOrGoToMain: "Вы можете повторить или вернуться на главную", successfully: "Успешно", successfullySaved: "Успешно сохранено", + successfullyUpdated: "Успешно обновлено", error: "Ошибка", errors: { emptyResponse: 'Пустой ответ', diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index c6b8780..4030478 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -6,7 +6,7 @@ import { useContext, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Context } from '..'; import { useAdminRole } from '../hooks/useAdminRole'; -import { frigateApi } from '../services/frigate.proxy/frigate.api'; +import { frigateApi, frigateQueryKeys } from '../services/frigate.proxy/frigate.api'; import { GetRole } from '../services/frigate.proxy/frigate.schema'; import CenterLoader from '../shared/components/loaders/CenterLoader'; import { dimensions } from '../shared/dimensions/dimensions'; @@ -35,7 +35,8 @@ const SettingsPage = () => { const isMobile = useMediaQuery(dimensions.mobileSize) - const mutation = useMutation({ + const getRoles = useMutation({ + mutationKey: [frigateQueryKeys.getRoles], mutationFn: frigateApi.getRoles, onSuccess: (data) => { setAllRoles(data) @@ -44,7 +45,7 @@ const SettingsPage = () => { const handleOIDPConfigValid = (valid: boolean) => { setShowRoles(valid) - mutation.mutate() + getRoles.mutate() } if (!isAdmin) return @@ -59,8 +60,11 @@ const SettingsPage = () => { { - showRoles && allRoles && allRoles.length > 0 ? - + showRoles && allRoles ? + getRoles.mutate()} + /> : null } diff --git a/src/services/frigate.proxy/frigate.api.ts b/src/services/frigate.proxy/frigate.api.ts index 7a3f03f..c89d4c0 100644 --- a/src/services/frigate.proxy/frigate.api.ts +++ b/src/services/frigate.proxy/frigate.api.ts @@ -55,6 +55,7 @@ export const frigateApi = { return res.data }), getRoles: () => instanceApi.get('apiv1/roles').then(res => res.data), + putRoles: () => instanceApi.put('apiv1/roles').then(res => res.data), putRoleWCameras: (roleId: string, cameraIDs: string[]) => instanceApi.put(`apiv1/roles/${roleId}/cameras`, { cameraIDs: cameraIDs @@ -237,6 +238,7 @@ export const frigateQueryKeys = { getRecordings: 'recordings-frigate', getEvents: 'events-frigate', getRoles: 'roles', + putRoles: 'putRoles', getRoleWCameras: 'roles-cameras', getUsersByRole: 'users-role', getAdminRole: 'admin-role', diff --git a/src/widgets/RolesSettingsForm.tsx b/src/widgets/RolesSettingsForm.tsx index 69342cc..6ecef8a 100644 --- a/src/widgets/RolesSettingsForm.tsx +++ b/src/widgets/RolesSettingsForm.tsx @@ -7,7 +7,7 @@ import RoleSelectFilter from '../shared/components/filters/RoleSelectFilter'; import CogwheelLoader from '../shared/components/loaders/CogwheelLoader'; import { GetRole } from '../services/frigate.proxy/frigate.schema'; import { isProduction } from '../shared/env.const'; -import { Flex, Button } from '@mantine/core'; +import { Flex, Button, Text } from '@mantine/core'; import { notifications } from '@mantine/notifications'; import { IconCircleCheck, IconAlertCircle } from '@tabler/icons-react'; import { v4 } from 'uuid'; @@ -24,11 +24,13 @@ interface Roles { } interface RolesSettingsFormProps { - allRoles: GetRole[] + allRoles: GetRole[], + refetchRoles?: () => void, } const RolesSettingsForm: React.FC = ({ - allRoles + allRoles, + refetchRoles }) => { const [roles, setRoles] = useState() const { t } = useTranslation() @@ -56,6 +58,39 @@ const RolesSettingsForm: React.FC = ({ }, }) + const updateRoles = useMutation({ + mutationFn: async () => frigateApi.putRoles().catch(error => { + if (error.response && error.response.data) { + return Promise.reject(error.response.data) + } + return Promise.reject(error) + }), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: [frigateQueryKeys.getRoles] }) + notifications.show({ + id: v4(), + withCloseButton: true, + autoClose: 5000, + title: t('successfully'), + message: t('successfullyUpdated'), + color: 'green', + icon: + }) + if (refetchRoles) refetchRoles() + }, + onError: (e) => { + notifications.show({ + id: e.message, + withCloseButton: true, + autoClose: false, + title: t('error'), + message: e.message, + color: 'red', + icon: , + }) + } + }) + const save = useMutation({ mutationFn: async () => { if (roles?.adminRole?.name) { @@ -141,6 +176,12 @@ const RolesSettingsForm: React.FC = ({ if (isPending) return if (isError) return + if (allRoles.length < 1) return ( + <> + {t('settingsPage.emptyRolesNotify')} + + + ) return ( <>