|
@@ -24,30 +24,31 @@ const Th = p =>
|
|
|
<div className='Th' {...p} />
|
|
|
|
|
|
|
|
|
-const EditFormRow = ({field, value, options=defaultAdminOptions, record, onChange}) => {
|
|
|
+const EditFormRow = ({field, models={}, value, options=defaultAdminOptions, record, onChange}) => {
|
|
|
return (
|
|
|
<tr>
|
|
|
<th>{field.name}</th>
|
|
|
- <td><Cell options={options} record={record} field={field} selected onChange={onChange}>{value}</Cell></td>
|
|
|
+ <td><Cell models={models} model={getModelByField(field, models)} options={options} record={record} field={field} selected onChange={onChange}>{value}</Cell></td>
|
|
|
</tr>
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-const EditForm = ({record, options=defaultAdminOptions, Components:{EditFormRow:EFR}={EditFormRow}}) => {
|
|
|
+const EditForm = ({record, models={}, options=defaultAdminOptions, Components:{EditFormRow:EFR}={EditFormRow}}) => {
|
|
|
const fields = record.constructor.fields
|
|
|
const onlyInputs = record.constructor.inputs.filter(input => !fields.find(field => field.name === input.name))
|
|
|
const [edit, setEdit] = useState({...record})
|
|
|
- console.log(edit)
|
|
|
return (
|
|
|
<>
|
|
|
<table>
|
|
|
{Object.entries(fields).map(([key,field]) => <EFR field={field}
|
|
|
+ models={models}
|
|
|
record={record}
|
|
|
value={edit[field.name]}
|
|
|
options={options}
|
|
|
onChange={event => setEdit({...edit, [field.name]: event.target.value})}
|
|
|
/>)}
|
|
|
{Object.entries(onlyInputs).map(([key,field]) => <EFR field={field}
|
|
|
+ models={models}
|
|
|
record={record}
|
|
|
value={edit[field.name]}
|
|
|
options={options}
|
|
@@ -57,7 +58,8 @@ const EditForm = ({record, options=defaultAdminOptions, Components:{EditFormRow:
|
|
|
</table>
|
|
|
<button onClick={() => {
|
|
|
Object.assign(record, edit);
|
|
|
- record.save()
|
|
|
+ if ('_id' in record && 'save' in record)
|
|
|
+ record.save()
|
|
|
}}>
|
|
|
Save
|
|
|
</button>
|
|
@@ -76,7 +78,7 @@ const Row = ({top, selected, children}) => {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-const Cell = ({children, options, record, field, selected, ...props}) => {
|
|
|
+const Cell = ({children, options, record, field, selected, model, models={}, ...props}) => {
|
|
|
|
|
|
let Formatter = React.Fragment
|
|
|
|
|
@@ -87,15 +89,18 @@ const Cell = ({children, options, record, field, selected, ...props}) => {
|
|
|
if (field.name in options[viewOrEdit].fields){
|
|
|
Formatter = options[viewOrEdit].fields[field.name]
|
|
|
}
|
|
|
- if (children && typeof children === 'object'){
|
|
|
- if (children.constructor.name in options[viewOrEdit].formatters)
|
|
|
- Formatter = options[viewOrEdit].formatters[children.constructor.name]
|
|
|
+ if ((children && typeof children === 'object') || model){
|
|
|
+ if (viewOrEdit === 'edit') debugger;
|
|
|
+ if ((children || model).constructor.name in options[viewOrEdit].formatters)
|
|
|
+ Formatter = options[viewOrEdit].formatters[(children || model).constructor.name]
|
|
|
else
|
|
|
Formatter = options[viewOrEdit].formatters.Object
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
return(
|
|
|
<div className='Cell' {...props}>
|
|
|
- <Formatter {...props} field={field}>{Formatter === React.Fragment ? (children && children.toString()) : children}</Formatter>
|
|
|
+ <Formatter options={options} model={model} models={models} {...props} field={field}>{Formatter === React.Fragment ? (children && children.toString()) : children}</Formatter>
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
@@ -145,7 +150,14 @@ const GridHeader = ({fields, sort, onSort}) =>
|
|
|
{fields.map(field => <GridHeaderItem field={field} sort={sort} onClick={() => onSort(field.name)}/>)}
|
|
|
</div>
|
|
|
|
|
|
-const VirtualScroll = ({options, gridHeight, count, rowHeight, components:Components={Row, Cell}, onScroll, records, skip}) => {
|
|
|
+const getModelByField = (field, models={}) => {
|
|
|
+ if (field.type.kind = 'OBJECT') {
|
|
|
+ return models[field.type.name]
|
|
|
+ }
|
|
|
+ if (field.type.kind = 'LIST') return models[field.type.ofType.name]
|
|
|
+}
|
|
|
+
|
|
|
+const VirtualScroll = ({options, gridHeight, count, rowHeight, components:Components={Row, Cell}, onScroll, records, skip, models={}}) => {
|
|
|
//const [records, setRecords] = useState([])
|
|
|
const limit = gridHeight/rowHeight
|
|
|
const {Row, Cell} = Components
|
|
@@ -180,10 +192,10 @@ const VirtualScroll = ({options, gridHeight, count, rowHeight, components:Compon
|
|
|
style={{height: count*rowHeight, minHeight: count*rowHeight, maxHeight: count*rowHeight}} >
|
|
|
{ /* <div style={{height: skip*rowHeight}} /> */ }
|
|
|
{records && records.map((record,i) =><React.Fragment key={i}>
|
|
|
- {edit.record && edit.record._id === record._id ? <EditForm record={record} options={options}/>:
|
|
|
+ {edit.record && edit.record._id === record._id ? <EditForm models={models} record={record} options={options}/>:
|
|
|
<Row options={options}>
|
|
|
{fields.map(field =>
|
|
|
- <Cell record={record} key={field.name} field={field} options={options}
|
|
|
+ <Cell models={models} model={getModelByField(field, models)} record={record} key={field.name} field={field} options={options}
|
|
|
onClick={() => setEdit({record: {...record}, field})}>
|
|
|
{record[field.name]}
|
|
|
</Cell>)}
|
|
@@ -199,7 +211,7 @@ const VirtualScroll = ({options, gridHeight, count, rowHeight, components:Compon
|
|
|
|
|
|
|
|
|
|
|
|
-const ModelView = ({model, options, components:Components={Search, Count, GridHeader, Grid:VirtualScroll}, rowHeight=150, gridHeight=500, overload=2}) => {
|
|
|
+const ModelView = ({model, models={}, options, components:Components={Search, Count, GridHeader, Grid:VirtualScroll}, rowHeight=150, gridHeight=500, overload=2}) => {
|
|
|
|
|
|
|
|
|
|
|
@@ -251,6 +263,7 @@ const ModelView = ({model, options, components:Components={Search, Count, GridHe
|
|
|
})}/>
|
|
|
|
|
|
{records && <Components.Grid
|
|
|
+ models={models}
|
|
|
options={options}
|
|
|
skip={skip}
|
|
|
count={count}
|
|
@@ -268,11 +281,12 @@ const ModelView = ({model, options, components:Components={Search, Count, GridHe
|
|
|
|
|
|
const ObjectShortView = ({children}) => {
|
|
|
const [record, setRecord] = useState(children)
|
|
|
- if (children && typeof children === 'object' && 'then' in children){
|
|
|
+ if (!children) return <></>
|
|
|
+ if (typeof children === 'object' && 'then' in children){
|
|
|
console.log('load')
|
|
|
children.then(child => setRecord({...child}))
|
|
|
}
|
|
|
- if (children._id){
|
|
|
+ if (typeof children === 'object' && children._id){
|
|
|
return (
|
|
|
<div className="ObjectShortView">
|
|
|
{record.name || record.key || record.login || record.originalFileName || record._id}
|
|
@@ -288,6 +302,12 @@ const ObjectShortView = ({children}) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const ObjectShortEdit = ({children}) =>
|
|
|
+<>
|
|
|
+ <ObjectShortView children={children} />
|
|
|
+ <input placeholder="autocomplete" />
|
|
|
+</>
|
|
|
+
|
|
|
|
|
|
const defaultAdminOptions =
|
|
|
{
|
|
@@ -313,7 +333,9 @@ const defaultAdminOptions =
|
|
|
String: ({children, field, ...props}) => <textarea placeholder={field.name} value={children} {...props}/>,
|
|
|
Int: ({children, ...props}) => <input type='number' value={children} {...props}/>,
|
|
|
Float: ({children, ...props}) => <input type='number' value={children} {...props}/>,
|
|
|
- Object: ObjectShortView,
|
|
|
+ Object: ({children, options, model, models, ...props}) => {
|
|
|
+ return model.fields[0].name === '_id' ? <ObjectShortEdit children={children} model={model} {...props}/> : <EditForm models={models} record={children} options={options} />
|
|
|
+ },
|
|
|
Array: ({children}) => <>{children.map(child => <ObjectShortView children={child} />)}</>
|
|
|
},
|
|
|
fields:{
|
|
@@ -339,7 +361,7 @@ const Admin = ({models, components:{ModelList:ML=ModelList, Search:S=Search, Mod
|
|
|
<>
|
|
|
<ML Item={MLI} models={models} onChange={(name) => setSelected(name)} selected={selected}/>
|
|
|
<content>
|
|
|
- {selected && <MV options={mergedOptions} model={models[selected]} components={{Search: S, Count: C, GridHeader:GH, Grid:G}} /> }
|
|
|
+ {selected && <MV models={models} options={mergedOptions} model={models[selected]} components={{Search: S, Count: C, GridHeader:GH, Grid:G}} /> }
|
|
|
</content>
|
|
|
</>
|
|
|
)
|