change settings page add roles selectors and validators

This commit is contained in:
NlightN22 2024-06-25 19:30:56 +07:00
parent 131f5efac6
commit f760a9f745
5 changed files with 66 additions and 12 deletions

View File

@ -29,6 +29,8 @@ const en = {
realmUrlPH: 'https://your.oidp.server.com/realms/frigate-realm', realmUrlPH: 'https://your.oidp.server.com/realms/frigate-realm',
adminRole: 'Select admin role', adminRole: 'Select admin role',
birdseyeRole: 'Select birds eye role user', birdseyeRole: 'Select birds eye role user',
emptyRolesNotify: 'List of roles are empty. You can manually start updating on server:',
updateRoles: 'Update Roles',
}, },
systemPage: { systemPage: {
cameraStats: 'Cameras stats', cameraStats: 'Cameras stats',
@ -128,6 +130,7 @@ const en = {
youCanRetryOrGoToMain: "You can retry or return to the main page", youCanRetryOrGoToMain: "You can retry or return to the main page",
successfully: "Sucessfully", successfully: "Sucessfully",
successfullySaved: "Sucessfully saved", successfullySaved: "Sucessfully saved",
successfullyUpdated: "Sucessfully updated",
error: "Error", error: "Error",
errors: { errors: {
emptyResponse: 'Empty response', emptyResponse: 'Empty response',

View File

@ -26,7 +26,10 @@ const ru = {
realmUrl: 'OIDP realm URL путь', realmUrl: 'OIDP realm URL путь',
realmUrlPH: 'https://your.oidp.server.com/realms/frigate-realm', realmUrlPH: 'https://your.oidp.server.com/realms/frigate-realm',
adminRole: 'Выбери роль администратора', adminRole: 'Выбери роль администратора',
birdseyeRole: 'Выбери роль birdseye пользователя',}, birdseyeRole: 'Выбери роль birdseye пользователя',
emptyRolesNotify: 'Список ролей пуст. Вы можете вручную запустить обновление на сервере:',
updateRoles: 'Обновить роли',
},
systemPage: { systemPage: {
cameraStats: 'Статистика Камер', cameraStats: 'Статистика Камер',
storageStats: 'Статистика Хранения', storageStats: 'Статистика Хранения',
@ -106,7 +109,7 @@ const ru = {
second: 'Час', second: 'Час',
events: 'События', events: 'События',
notHaveEvents: 'Событий нет', notHaveEvents: 'Событий нет',
selectHost:'Выбери хост', selectHost: 'Выбери хост',
selectCamera: 'Выбери камеру', selectCamera: 'Выбери камеру',
selectRange: 'Выбери период', selectRange: 'Выбери период',
changeTheme: "Изменить тему", changeTheme: "Изменить тему",
@ -125,6 +128,7 @@ const ru = {
youCanRetryOrGoToMain: "Вы можете повторить или вернуться на главную", youCanRetryOrGoToMain: "Вы можете повторить или вернуться на главную",
successfully: "Успешно", successfully: "Успешно",
successfullySaved: "Успешно сохранено", successfullySaved: "Успешно сохранено",
successfullyUpdated: "Успешно обновлено",
error: "Ошибка", error: "Ошибка",
errors: { errors: {
emptyResponse: 'Пустой ответ', emptyResponse: 'Пустой ответ',

View File

@ -6,7 +6,7 @@ import { useContext, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Context } from '..'; import { Context } from '..';
import { useAdminRole } from '../hooks/useAdminRole'; 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 { GetRole } from '../services/frigate.proxy/frigate.schema';
import CenterLoader from '../shared/components/loaders/CenterLoader'; import CenterLoader from '../shared/components/loaders/CenterLoader';
import { dimensions } from '../shared/dimensions/dimensions'; import { dimensions } from '../shared/dimensions/dimensions';
@ -35,7 +35,8 @@ const SettingsPage = () => {
const isMobile = useMediaQuery(dimensions.mobileSize) const isMobile = useMediaQuery(dimensions.mobileSize)
const mutation = useMutation({ const getRoles = useMutation({
mutationKey: [frigateQueryKeys.getRoles],
mutationFn: frigateApi.getRoles, mutationFn: frigateApi.getRoles,
onSuccess: (data) => { onSuccess: (data) => {
setAllRoles(data) setAllRoles(data)
@ -44,7 +45,7 @@ const SettingsPage = () => {
const handleOIDPConfigValid = (valid: boolean) => { const handleOIDPConfigValid = (valid: boolean) => {
setShowRoles(valid) setShowRoles(valid)
mutation.mutate() getRoles.mutate()
} }
if (!isAdmin) return <Forbidden /> if (!isAdmin) return <Forbidden />
@ -59,8 +60,11 @@ const SettingsPage = () => {
<Flex direction='column' h='100%' w='100%' justify='stretch'> <Flex direction='column' h='100%' w='100%' justify='stretch'>
<OIDPSettingsForm isConfigValid={handleOIDPConfigValid} /> <OIDPSettingsForm isConfigValid={handleOIDPConfigValid} />
{ {
showRoles && allRoles && allRoles.length > 0 ? showRoles && allRoles ?
<RolesSettingsForm allRoles={allRoles} /> <RolesSettingsForm
allRoles={allRoles}
refetchRoles={() => getRoles.mutate()}
/>
: null : null
} }
</Flex> </Flex>

View File

@ -55,6 +55,7 @@ export const frigateApi = {
return res.data return res.data
}), }),
getRoles: () => instanceApi.get<GetRole[]>('apiv1/roles').then(res => res.data), getRoles: () => instanceApi.get<GetRole[]>('apiv1/roles').then(res => res.data),
putRoles: () => instanceApi.put<GetRole[]>('apiv1/roles').then(res => res.data),
putRoleWCameras: (roleId: string, cameraIDs: string[]) => instanceApi.put<GetRoleWCameras>(`apiv1/roles/${roleId}/cameras`, putRoleWCameras: (roleId: string, cameraIDs: string[]) => instanceApi.put<GetRoleWCameras>(`apiv1/roles/${roleId}/cameras`,
{ {
cameraIDs: cameraIDs cameraIDs: cameraIDs
@ -237,6 +238,7 @@ export const frigateQueryKeys = {
getRecordings: 'recordings-frigate', getRecordings: 'recordings-frigate',
getEvents: 'events-frigate', getEvents: 'events-frigate',
getRoles: 'roles', getRoles: 'roles',
putRoles: 'putRoles',
getRoleWCameras: 'roles-cameras', getRoleWCameras: 'roles-cameras',
getUsersByRole: 'users-role', getUsersByRole: 'users-role',
getAdminRole: 'admin-role', getAdminRole: 'admin-role',

View File

@ -7,7 +7,7 @@ import RoleSelectFilter from '../shared/components/filters/RoleSelectFilter';
import CogwheelLoader from '../shared/components/loaders/CogwheelLoader'; import CogwheelLoader from '../shared/components/loaders/CogwheelLoader';
import { GetRole } from '../services/frigate.proxy/frigate.schema'; import { GetRole } from '../services/frigate.proxy/frigate.schema';
import { isProduction } from '../shared/env.const'; 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 { notifications } from '@mantine/notifications';
import { IconCircleCheck, IconAlertCircle } from '@tabler/icons-react'; import { IconCircleCheck, IconAlertCircle } from '@tabler/icons-react';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
@ -24,11 +24,13 @@ interface Roles {
} }
interface RolesSettingsFormProps { interface RolesSettingsFormProps {
allRoles: GetRole[] allRoles: GetRole[],
refetchRoles?: () => void,
} }
const RolesSettingsForm: React.FC<RolesSettingsFormProps> = ({ const RolesSettingsForm: React.FC<RolesSettingsFormProps> = ({
allRoles allRoles,
refetchRoles
}) => { }) => {
const [roles, setRoles] = useState<Roles>() const [roles, setRoles] = useState<Roles>()
const { t } = useTranslation() const { t } = useTranslation()
@ -56,6 +58,39 @@ const RolesSettingsForm: React.FC<RolesSettingsFormProps> = ({
}, },
}) })
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: <IconCircleCheck />
})
if (refetchRoles) refetchRoles()
},
onError: (e) => {
notifications.show({
id: e.message,
withCloseButton: true,
autoClose: false,
title: t('error'),
message: e.message,
color: 'red',
icon: <IconAlertCircle />,
})
}
})
const save = useMutation({ const save = useMutation({
mutationFn: async () => { mutationFn: async () => {
if (roles?.adminRole?.name) { if (roles?.adminRole?.name) {
@ -141,6 +176,12 @@ const RolesSettingsForm: React.FC<RolesSettingsFormProps> = ({
if (isPending) return <CogwheelLoader /> if (isPending) return <CogwheelLoader />
if (isError) return <RetryError onRetry={refetch} /> if (isError) return <RetryError onRetry={refetch} />
if (allRoles.length < 1) return (
<>
<Text align='center' mt='lg'>{t('settingsPage.emptyRolesNotify')}</Text>
<Button mt='md' onClick={() => updateRoles.mutate()}>{t('settingsPage.updateRoles')}</Button>
</>
)
return ( return (
<> <>