Browse Source

near object/relation edit

Ivan Asmer 4 years ago
parent
commit
ebca25680d
1 changed files with 40 additions and 18 deletions
  1. 40 18
      src/App.js

+ 40 - 18
src/App.js

@@ -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>
         </>
     )