Добавлено хранение данных пользователя в localStorage для использования в контексте

This commit is contained in:
goodmice 2022-10-13 13:10:19 +05:00
parent 8c2c1b7913
commit ddc6f7840d
No known key found for this signature in database
GPG Key ID: 63EA771203189CF1
5 changed files with 53 additions and 28 deletions

View File

@ -0,0 +1,17 @@
import { memo, useMemo } from 'react'
import { Outlet } from 'react-router-dom'
import { UserContext } from '@asb/context'
import { getUser } from '@utils'
export const UserOutlet = memo(() => {
const user = useMemo(() => getUser() ?? {}, [])
return (
<UserContext.Provider value={user}>
<Outlet />
</UserContext.Provider>
)
})
export default UserOutlet

View File

@ -0,0 +1 @@
export * from './UserOutlet'

View File

@ -1,22 +1,31 @@
import { createContext, useContext } from 'react' import { createContext, useContext } from 'react'
import { WellDto } from '@api' import { UserTokenDto, WellDto } from '@api'
/** Контекст текущей скважины */ /** Контекст текущей скважины */
export const WellContext = createContext<[WellDto, (well: WellDto) => void]>([{}, () => {}]) export const WellContext = createContext<[WellDto, (well: WellDto) => void]>([{}, () => {}])
/** Контекст текущего корневого пути */ /** Контекст текущего корневого пути */
export const RootPathContext = createContext<string>('') export const RootPathContext = createContext<string>('/')
/** Контекст текущего пользователя */
export const UserContext = createContext<UserTokenDto>({})
/** /**
* Получение текущей скважины * Получить текущую скважину
* *
* @returns Текущая скважина, либо `null` * @returns Текущая скважина, либо `null`
*/ */
export const useWell = () => useContext(WellContext) export const useWell = () => useContext(WellContext)
/** /**
* Получает текущий корневой путь * Получить текущий корневой путь
* *
* @returns Текущий корневой путь * @returns Текущий корневой путь
*/ */
export const useRootPath = () => useContext(RootPathContext) export const useRootPath = () => useContext(RootPathContext)
/**
* Получить текущего пользователя
*
* @returns Текущий пользователь, либо `null`
*/
export const useUser = () => useContext(UserContext)

View File

@ -1,7 +1,7 @@
import { memo, NamedExoticComponent, ReactElement, ReactNode, useMemo } from 'react' import { memo, NamedExoticComponent, ReactElement, ReactNode, useMemo } from 'react'
import { Navigate, useParams } from 'react-router-dom' import { Navigate, useParams } from 'react-router-dom'
import { getUserLogin, getUserPermissions, getUserRoles } from '@utils' import { getUserLogin, getUserPermissions } from '@utils'
import { isDev } from '@utils' import { isDev } from '@utils'
import AccessDenied from '@pages/AccessDenied' import AccessDenied from '@pages/AccessDenied'
@ -31,22 +31,13 @@ export const getPermissions = (...values: PermissionRequest[]) => {
export const hasPermission = (permission?: Permission | Permission[], userPermissions?: Permission[]): boolean => { export const hasPermission = (permission?: Permission | Permission[], userPermissions?: Permission[]): boolean => {
if (!Array.isArray(permission) && typeof permission !== 'string') if (!Array.isArray(permission) && typeof permission !== 'string')
return true return true
const userPerms = userPermissions ?? getUserPermissions() const userPerms = userPermissions ?? getUserPermissions() ?? []
if (typeof permission === 'string') if (typeof permission === 'string')
permission = [permission] permission = [permission]
return permission.every((perm) => userPerms.includes(perm)) return permission.every((perm) => userPerms.includes(perm))
} }
export const isInRole = (roles?: Role[] | Role): boolean => { const sectionAvailable = (section: PermissionRecord, userPermission: Permission[]) => {
if (typeof roles === 'string' && !Array.isArray(roles))
roles = [roles]
if (!roles?.length) return true
const user_roles = getUserRoles()
return roles.some((role) => user_roles.includes(role))
}
const sectionAvailable = (section: PermissionRecord, userPermission: Permission[] = getUserPermissions()) => {
for (const child of Object.values(section)) { for (const child of Object.values(section)) {
if (!child) continue if (!child) continue
if (Array.isArray(child)) { if (Array.isArray(child)) {
@ -81,7 +72,7 @@ export const isURLAvailable = (path: string, userPermissions?: Permission[]) =>
} }
if (!perms) return false if (!perms) return false
const userPerms: string[] = userPermissions ?? getUserPermissions() const userPerms: string[] = userPermissions ?? getUserPermissions() ?? []
if (Array.isArray(perms)) { if (Array.isArray(perms)) {
return perms.every((perm) => userPerms.includes(perm)) return perms.every((perm) => userPerms.includes(perm))
} }

View File

@ -1,7 +1,8 @@
import { OpenAPI, UserTokenDto } from '@api' import { OpenAPI, UserTokenDto } from '@api'
import { isDev } from '..'
import { wrapValues } from './objects' import { wrapValues } from './objects'
import { Role, Permission } from './permissions' import { Permission } from './permissions'
import { normalizeTableColumn, optimizeTableColumn, TableSettings, TableSettingsStore } from './table_settings' import { normalizeTableColumn, optimizeTableColumn, TableSettings, TableSettingsStore } from './table_settings'
export enum StorageNames { export enum StorageNames {
@ -10,6 +11,7 @@ export enum StorageNames {
login = 'login', login = 'login',
permissions = 'permissions', permissions = 'permissions',
roles = 'roles', roles = 'roles',
user = 'user',
tableSettings = 'tableSettings', tableSettings = 'tableSettings',
dashboardNNB = 'dashboardNNB', dashboardNNB = 'dashboardNNB',
witsInfo = 'witsInfo' witsInfo = 'witsInfo'
@ -22,11 +24,12 @@ export const getArrayFromLocalStorage = <T extends string = string>(name: string
} }
export const getJSON = <T,>(name: StorageNames): T | null => { export const getJSON = <T,>(name: StorageNames): T | null => {
const raw = localStorage.getItem(name)
if (!raw) return null
try { try {
return JSON.parse(raw) const raw = localStorage.getItem(name)
} catch {} if (raw) return JSON.parse(raw)
} catch {
if (isDev()) console.warn(`Storage "${name}" parsing exception!`)
}
return null return null
} }
@ -34,25 +37,28 @@ export const setJSON = <T,>(name: StorageNames, data: T | null): boolean => {
try { try {
localStorage.setItem(name, JSON.stringify(data)) localStorage.setItem(name, JSON.stringify(data))
return true return true
} catch {} } catch {
if (isDev()) console.warn(`Storage "${name}" saving exception!`)
}
return false return false
} }
export const getUserRoles = (): Role[] => getArrayFromLocalStorage<Role>(StorageNames.roles) ?? [] export const getUser = (): UserTokenDto | null => getJSON(StorageNames.user)
export const getUserPermissions = (): Permission[] => getArrayFromLocalStorage<Permission>(StorageNames.permissions) ?? []
export const getUserPermissions = (): Permission[] | null => getUser()?.permissions?.map((perm) => perm.name as string) || null
export const getUserId = () => Number(localStorage.getItem(StorageNames.userId)) || null export const getUserId = () => Number(localStorage.getItem(StorageNames.userId)) || null
export const getUserLogin = () => localStorage.getItem(StorageNames.login) export const getUserLogin = () => localStorage.getItem(StorageNames.login)
export const getUserToken = () => localStorage.getItem(StorageNames.token) export const getUserToken = () => localStorage.getItem(StorageNames.token)
export const setUser = (user: UserTokenDto) => { export const setUser = (user: UserTokenDto) => {
OpenAPI.TOKEN = user.token ?? undefined OpenAPI.TOKEN = user.token ?? undefined
localStorage.setItem(StorageNames.user, JSON.stringify(user))
localStorage.setItem(StorageNames.userId, String(user.id)) localStorage.setItem(StorageNames.userId, String(user.id))
localStorage.setItem(StorageNames.token, String(user.token)) localStorage.setItem(StorageNames.token, String(user.token))
localStorage.setItem(StorageNames.login, String(user.login)) localStorage.setItem(StorageNames.login, String(user.login))
if (user.permissions) if (user.permissions)
localStorage.setItem(StorageNames.permissions, user.permissions.map((permission) => permission.name).join(',')) localStorage.setItem(StorageNames.permissions, user.permissions.map((permission) => permission.name).join(','))
if (user.roleNames)
localStorage.setItem(StorageNames.roles, user.roleNames.join(','))
} }
export const removeUser = () => { export const removeUser = () => {
@ -60,7 +66,8 @@ export const removeUser = () => {
localStorage.removeItem(StorageNames.login) localStorage.removeItem(StorageNames.login)
localStorage.removeItem(StorageNames.token) localStorage.removeItem(StorageNames.token)
localStorage.removeItem(StorageNames.permissions) localStorage.removeItem(StorageNames.permissions)
localStorage.removeItem(StorageNames.roles)
localStorage.removeItem(StorageNames.user)
} }
export const getTableSettings = (tableName: string): TableSettings => { export const getTableSettings = (tableName: string): TableSettings => {