mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Add initial version of reference selection on saving
This commit is contained in:
@@ -2,11 +2,13 @@ import { ReactNode, createContext, useState, JSX, useEffect } from 'react'
|
||||
import { DropdownOption } from '../common/editingComponents'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
export type ModeType = 'read' | 'new' | 'edit'
|
||||
// -ref modes mean that user is selecting reference for either adding or editing item
|
||||
export type ModeType = 'read' | 'new' | 'edit' | 'new-ref' | 'edit-ref'
|
||||
|
||||
export type DetailContextType<T> = {
|
||||
data: T
|
||||
mode: ModeType
|
||||
setMode: (newMode: ModeType) => void
|
||||
editData: T
|
||||
setEditData: (editData: T) => void
|
||||
textField: (field: keyof T, type?: React.HTMLInputTypeAttribute) => JSX.Element
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import { useNavigate } from 'react-router-dom'
|
||||
import { useContext } from 'react'
|
||||
import { PageContext } from '../Page'
|
||||
|
||||
export const TopBar = <T,>() => {
|
||||
export const DetailBrowser = <T,>() => {
|
||||
const { data } = useDetailContext<T>()
|
||||
const navigate = useNavigate()
|
||||
const { idList, idFieldName, viewName } = useContext(PageContext)
|
||||
@@ -1,53 +1,19 @@
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { Box, Button, Paper, Stack, Tab, Tabs } from '@mui/material'
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
|
||||
import EditIcon from '@mui/icons-material/Edit'
|
||||
import SaveIcon from '@mui/icons-material/Save'
|
||||
import { useEffect, useState, JSX, useContext } from 'react'
|
||||
import { useEffect, useState, JSX } from 'react'
|
||||
import { DetailContextProvider, ModeType } from './Context/DetailContext'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useDetailContext } from './hooks'
|
||||
import { DropdownOption, DropdownSelector, EditableTextField, RadioSelector } from './common/editingComponents'
|
||||
import { TopBar } from './TopBar'
|
||||
import { PageContext } from '../Page'
|
||||
import { DetailBrowser } from './DetailBrowser'
|
||||
import { ReferenceSelection } from './ReferenceSelection'
|
||||
import { ReturnButton, WriteButton } from './components'
|
||||
|
||||
export type TabType = {
|
||||
title: string
|
||||
content: JSX.Element
|
||||
}
|
||||
|
||||
const WriteButton = <T,>({
|
||||
onWrite,
|
||||
setMode,
|
||||
}: {
|
||||
onWrite: (editData: T) => void
|
||||
setMode: (newMode: ModeType) => void
|
||||
}) => {
|
||||
const { editData } = useDetailContext<T>()
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
onWrite(editData)
|
||||
setMode('read')
|
||||
}}
|
||||
variant="contained"
|
||||
>
|
||||
<SaveIcon />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
const ReturnButton = () => {
|
||||
const navigate = useNavigate()
|
||||
const { tableUrl } = useContext(PageContext)
|
||||
return (
|
||||
<Button onClick={() => navigate(tableUrl, { relative: 'path' })}>
|
||||
<ArrowBackIcon color="primary" style={{ marginRight: '0.35em' }} />
|
||||
Return to table
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
export const DetailView = <T extends object>({
|
||||
tabs,
|
||||
data,
|
||||
@@ -91,9 +57,11 @@ export const DetailView = <T extends object>({
|
||||
)
|
||||
|
||||
const bigTextField = (field: keyof T) => <EditableTextField<T> field={field} type="text" big />
|
||||
|
||||
const initialState = {
|
||||
data,
|
||||
mode,
|
||||
setMode,
|
||||
editData: cloneDeep(data),
|
||||
textField,
|
||||
dropdown,
|
||||
@@ -102,42 +70,66 @@ export const DetailView = <T extends object>({
|
||||
validator,
|
||||
}
|
||||
|
||||
const paperProps = {
|
||||
style: {
|
||||
minHeight: '10em',
|
||||
backgroundColor: 'lightgray',
|
||||
padding: '1em',
|
||||
},
|
||||
elevation: 5,
|
||||
}
|
||||
|
||||
const refMode = ['new-ref', 'edit-ref'].includes(mode)
|
||||
|
||||
const refSelectionView = (
|
||||
<Paper {...paperProps}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', rowGap: '1em' }}>
|
||||
<ReferenceSelection />
|
||||
</Box>
|
||||
</Paper>
|
||||
)
|
||||
|
||||
const tabView = (
|
||||
<>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||
<Tabs value={tab} onChange={(_event, newValue) => setTab(newValue as number)}>
|
||||
{tabs.map(tab => (
|
||||
<Tab key={tab.title} label={tab.title} />
|
||||
))}
|
||||
</Tabs>
|
||||
</Box>
|
||||
<Paper {...paperProps}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', rowGap: '1em' }}>{tabs[tab].content}</Box>
|
||||
</Paper>
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<Stack rowGap={2}>
|
||||
<DetailContextProvider contextState={initialState}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignContent: 'center', marginTop: 'auto' }}>
|
||||
<Box sx={{ display: 'flex' }} gap={10}>
|
||||
<ReturnButton />
|
||||
<Button
|
||||
onClick={() => setMode(mode === 'edit' ? 'read' : 'edit')}
|
||||
variant={mode === 'edit' ? 'contained' : 'outlined'}
|
||||
style={{ width: '12em' }}
|
||||
>
|
||||
<EditIcon /> {mode === 'read' ? 'Edit' : 'Stop editing'}
|
||||
</Button>
|
||||
{mode === 'edit' && onWrite && <WriteButton onWrite={onWrite} setMode={setMode} />}
|
||||
</Box>
|
||||
<Box sx={{ marginRight: '3em' }}>
|
||||
<TopBar<T> />
|
||||
{!refMode && (
|
||||
<Button
|
||||
onClick={() => setMode(mode === 'edit' ? 'read' : 'edit')}
|
||||
variant={mode === 'edit' ? 'contained' : 'outlined'}
|
||||
style={{ width: '12em' }}
|
||||
>
|
||||
<EditIcon style={{ marginRight: '0.5em' }} /> {mode === 'read' ? 'Edit' : 'Stop editing'}
|
||||
</Button>
|
||||
)}
|
||||
{mode !== 'read' && onWrite && (
|
||||
<WriteButton onWrite={onWrite} text={refMode ? 'Complete and save' : 'Select reference'} />
|
||||
)}
|
||||
</Box>
|
||||
{!refMode && (
|
||||
<Box sx={{ marginRight: '3em' }}>
|
||||
<DetailBrowser<T> />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||
<Tabs value={tab} onChange={(_event, newValue) => setTab(newValue as number)}>
|
||||
{tabs.map(tab => (
|
||||
<Tab key={tab.title} label={tab.title} />
|
||||
))}
|
||||
</Tabs>
|
||||
</Box>
|
||||
<Paper
|
||||
style={{
|
||||
minHeight: '10em',
|
||||
backgroundColor: 'lightgray',
|
||||
padding: '1em',
|
||||
}}
|
||||
elevation={5}
|
||||
>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', rowGap: '1em' }}>{tabs[tab].content}</Box>
|
||||
</Paper>
|
||||
{refMode ? refSelectionView : tabView}
|
||||
</DetailContextProvider>
|
||||
</Stack>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Grouped } from './common/tabLayoutHelpers'
|
||||
|
||||
export const ReferenceSelection = () => {
|
||||
return <Grouped title="Reference for the new data">Selecting reference</Grouped>
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useDetailContext } from './hooks'
|
||||
import { Button } from '@mui/material'
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
|
||||
import SaveIcon from '@mui/icons-material/Save'
|
||||
import { useContext } from 'react'
|
||||
import { PageContext } from '../Page'
|
||||
|
||||
export const WriteButton = <T,>({ onWrite, text }: { onWrite: (editData: T) => void; text?: string }) => {
|
||||
const { editData, mode, setMode } = useDetailContext<T>()
|
||||
return (
|
||||
<Button
|
||||
sx={{ width: '20em' }}
|
||||
onClick={() => {
|
||||
if (mode === 'edit') {
|
||||
setMode('edit-ref')
|
||||
return
|
||||
}
|
||||
if (mode === 'new') {
|
||||
setMode('new-ref')
|
||||
return
|
||||
}
|
||||
onWrite(editData)
|
||||
setMode('read')
|
||||
}}
|
||||
variant="contained"
|
||||
>
|
||||
<SaveIcon style={{ marginRight: '0.5em' }} />
|
||||
{text}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
export const ReturnButton = () => {
|
||||
const navigate = useNavigate()
|
||||
const { tableUrl } = useContext(PageContext)
|
||||
const { mode, setMode } = useDetailContext()
|
||||
if (['new-ref', 'edit-ref'].includes(mode)) {
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
setMode('edit')
|
||||
}}
|
||||
>
|
||||
<ArrowBackIcon color="primary" style={{ marginRight: '0.2em' }} />
|
||||
Return to editing
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Button onClick={() => navigate(tableUrl, { relative: 'path' })}>
|
||||
<ArrowBackIcon color="primary" style={{ marginRight: '0.2em' }} />
|
||||
Return to table
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user