mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Show user info as a part of persons table and details
This commit is contained in:
@@ -1,15 +1,24 @@
|
||||
import { nowDb } from '../utils/db'
|
||||
|
||||
export const getAllPersons = async () => {
|
||||
const result = await nowDb.com_people.findMany({})
|
||||
return result
|
||||
const persons = await nowDb.com_people.findMany({})
|
||||
const users = await nowDb.com_users.findMany({})
|
||||
const userMap = new Map(users.map(user => [user.user_id, user]))
|
||||
return persons.map(person => ({ ...person, user: person.user_id ? userMap.get(person.user_id) : null }))
|
||||
}
|
||||
|
||||
export const getPersonDetails = async (id: string) => {
|
||||
// TODO: Check if user has access
|
||||
|
||||
const result = await nowDb.com_people.findUnique({
|
||||
const person = await nowDb.com_people.findUnique({
|
||||
where: { initials: id },
|
||||
})
|
||||
return result
|
||||
|
||||
if (!person) return null
|
||||
|
||||
if (!person.user_id) return { ...person, user: null }
|
||||
|
||||
const user = await nowDb.com_users.findUnique({ where: { user_id: person.user_id } })
|
||||
|
||||
return { ...person, user }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
speciesPage,
|
||||
timeBoundPage,
|
||||
timeUnitPage,
|
||||
userPage,
|
||||
} from './components/pages'
|
||||
|
||||
const App = () => {
|
||||
@@ -35,7 +34,6 @@ const App = () => {
|
||||
<Route element={regionPage} path="/region/:id?" />
|
||||
<Route element={personPage} path="/person/:id?" />
|
||||
<Route element={projectPage} path="/project/:id?" />
|
||||
<Route element={userPage} path="/user/:id?" />
|
||||
<Route element={<FrontPage />} path="/" />
|
||||
<Route element={<Login />} path="/login" />
|
||||
<Route element={<div>Page not found.</div>} path="*" />
|
||||
|
||||
Vendored
+1
-3
@@ -40,7 +40,7 @@ export type SpeciesLocality = FixBigInt<Prisma.now_ls> & { now_loc: Prisma.now_l
|
||||
export type LocalityUpdate = Prisma.now_lau & { now_lr: LocalityReference[] } & { updates: UpdateLog[] }
|
||||
export type SpeciesUpdate = Prisma.now_sau & { now_sr: Prisma.now_sr }
|
||||
export type Museum = Prisma.com_mlist
|
||||
export type PersonDetailsType = Prisma.com_people
|
||||
export type PersonDetailsType = Prisma.com_people & { user: Prisma.com_users | null }
|
||||
export type ProjectPeople = Prisma.now_proj_people
|
||||
export type ProjectDetailsType = Prisma.now_proj & { now_proj_people: Array<ProjectPeople> }
|
||||
export type Project = Prisma.now_proj
|
||||
@@ -163,5 +163,3 @@ export type TimeUnitDetailsType = Prisma.now_time_unit & { now_tu_sequence: Sequ
|
||||
export type ReferenceType = Prisma.ref_ref_type & { ref_field_name: Prisma.ref_field_name[] }
|
||||
|
||||
export type ReferenceField = Prisma.ref_field_name
|
||||
export type User = Prisma.com_users
|
||||
export type UserDetailsType = Prisma.com_users
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useGetPersonDetailsQuery } from '../../redux/personReducer'
|
||||
import { CircularProgress } from '@mui/material'
|
||||
import { DetailView, TabType } from '../DetailView/DetailView'
|
||||
import { PersonTab } from './Tabs/PersonTab'
|
||||
import { UserTab } from './Tabs/UserTab'
|
||||
|
||||
export const PersonDetails = () => {
|
||||
const { id } = useParams()
|
||||
@@ -18,5 +19,7 @@ export const PersonDetails = () => {
|
||||
},
|
||||
]
|
||||
|
||||
if (data.user) tabs.push({ title: 'User', content: <UserTab /> })
|
||||
|
||||
return <DetailView tabs={tabs} data={data} validator={() => ({ name: '', error: null })} />
|
||||
}
|
||||
|
||||
@@ -33,6 +33,20 @@ export const PersonTable = ({ selectorFn }: { selectorFn?: (id: PersonDetailsTyp
|
||||
accessorKey: 'country',
|
||||
header: 'Country',
|
||||
},
|
||||
{
|
||||
id: 'user_id',
|
||||
accessorKey: 'user.user_id',
|
||||
header: 'User Id',
|
||||
size: 20,
|
||||
},
|
||||
{
|
||||
accessorKey: 'user.user_name',
|
||||
header: 'User name',
|
||||
},
|
||||
{
|
||||
accessorKey: 'user.last_login',
|
||||
header: 'Last login',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
@@ -3,10 +3,9 @@ import { ArrayFrame } from '../../DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const PersonTab = () => {
|
||||
const { textField } = useDetailContext<PersonDetailsType>()
|
||||
const { textField, data } = useDetailContext<PersonDetailsType>()
|
||||
|
||||
const person = [
|
||||
['User ID', textField('user_id', { type: 'number' })],
|
||||
['Initials', textField('initials')],
|
||||
['First Name', textField('first_name')],
|
||||
['Surname', textField('surname')],
|
||||
@@ -15,9 +14,18 @@ export const PersonTab = () => {
|
||||
['Country', textField('country')],
|
||||
]
|
||||
|
||||
const user = data.user
|
||||
? [
|
||||
['User Name', data.user?.user_name ?? ''],
|
||||
['Last log in', data.user?.last_login?.toString()],
|
||||
['User Group', data.user?.now_user_group ?? ''],
|
||||
]
|
||||
: [['Not a user']]
|
||||
|
||||
return (
|
||||
<>
|
||||
<ArrayFrame array={person} title="Person" />
|
||||
<ArrayFrame array={user} title="User" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { PersonDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame } from '../../DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const UserTab = () => {
|
||||
const { data } = useDetailContext<PersonDetailsType>()
|
||||
|
||||
const user = [
|
||||
['User Name', data.user!.user_name ?? ''],
|
||||
['Last log in', data.user!.last_login?.toString()],
|
||||
['User Group', data.user!.now_user_group ?? ''],
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
<ArrayFrame array={user} title="User" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { UserDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame } from '../../DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const UserTab = () => {
|
||||
const { textField } = useDetailContext<UserDetailsType>()
|
||||
|
||||
const user = [
|
||||
['User Name', textField('user_name')],
|
||||
['Password', textField('password')],
|
||||
['Confirm Password', textField('password')],
|
||||
['Last log in', textField('last_login')],
|
||||
['User Group', textField('now_user_group')],
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
<ArrayFrame array={user} title="User" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { useGetUserDetailsQuery } from '../../redux/userReducer'
|
||||
import { CircularProgress } from '@mui/material'
|
||||
import { DetailView, TabType } from '../DetailView/DetailView'
|
||||
import { UserTab } from './Tabs/UserTab'
|
||||
|
||||
export const UserDetails = () => {
|
||||
const { id } = useParams()
|
||||
const { isLoading, isError, data } = useGetUserDetailsQuery(id!)
|
||||
|
||||
if (isError) return <div>Error loading data</div>
|
||||
if (isLoading || !data) return <CircularProgress />
|
||||
|
||||
const tabs: TabType[] = [
|
||||
{
|
||||
title: 'Person',
|
||||
content: <UserTab />,
|
||||
},
|
||||
]
|
||||
|
||||
return <DetailView tabs={tabs} data={data} validator={() => ({ name: '', error: null })} />
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import { useMemo } from 'react'
|
||||
import { type MRT_ColumnDef } from 'material-react-table'
|
||||
import { useGetAllUsersQuery } from '../../redux/userReducer'
|
||||
import { PersonDetailsType } from '@/backendTypes'
|
||||
import { TableView } from '../TableView/TableView'
|
||||
|
||||
export const UserTable = ({ selectorFn }: { selectorFn?: (person: PersonDetailsType) => void }) => {
|
||||
const userQuery = useGetAllUsersQuery()
|
||||
const columns = useMemo<MRT_ColumnDef<PersonDetailsType>[]>(
|
||||
() => [
|
||||
{
|
||||
id: 'id',
|
||||
accessorKey: 'User_id',
|
||||
header: 'Id',
|
||||
size: 20,
|
||||
},
|
||||
{
|
||||
accessorKey: 'user_name',
|
||||
header: 'User name',
|
||||
},
|
||||
{
|
||||
accessorKey: 'last_login',
|
||||
header: 'Last login',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
const checkRowRestriction = () => {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
<TableView<PersonDetailsType>
|
||||
selectorFn={selectorFn}
|
||||
checkRowRestriction={checkRowRestriction}
|
||||
idFieldName="initials"
|
||||
columns={columns}
|
||||
data={userQuery.data}
|
||||
url="user"
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
PersonDetailsType,
|
||||
ProjectDetailsType,
|
||||
RegionDetails as RegionDetailsType,
|
||||
UserDetailsType,
|
||||
} from '@/backendTypes'
|
||||
import { LocalityDetails } from './Locality/LocalityDetails'
|
||||
import { LocalityTable } from './Locality/LocalityTable'
|
||||
@@ -26,8 +25,6 @@ import { ProjectTable } from './Project/ProjectTable'
|
||||
import { ProjectDetails } from './Project/ProjectDetails'
|
||||
import { RegionTable } from './Region/RegionTable'
|
||||
import { RegionDetails } from './Region/RegionDetails'
|
||||
import { UserTable } from './User/UserTable'
|
||||
import { UserDetails } from './User/UserDetails'
|
||||
|
||||
export const timeBoundPage = (
|
||||
<Page
|
||||
@@ -108,13 +105,3 @@ export const regionPage = (
|
||||
createTitle={(region: RegionDetailsType) => `${region.region}`}
|
||||
/>
|
||||
)
|
||||
|
||||
export const userPage = (
|
||||
<Page
|
||||
tableView={<UserTable />}
|
||||
detailView={<UserDetails />}
|
||||
viewName="user"
|
||||
idFieldName="user_id"
|
||||
createTitle={(user: UserDetailsType) => `${user.user_name}`}
|
||||
/>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user