Browse Source

almost working with list rearrange with relations and nested objects

Ivan Asmer 4 years ago
parent
commit
94e09f1ed1
2 changed files with 42 additions and 29 deletions
  1. 39 27
      src/App.js
  2. 3 2
      src/front-models.js

+ 39 - 27
src/App.js

@@ -10,7 +10,7 @@ import createModels2 from './front-models'
 
 let gql = new GraphQLClient("/graphql", {headers: localStorage.authToken ? {Authorization: 'Bearer '+localStorage.authToken} : {}})
 
-const shortName = record => record && record.name || record.key || record.login || record.originalFileName || record._id
+const shortName = record => <>{(record && record.name) || record.key || record.login || record.originalFileName || record._id}</>
 
 
 
@@ -23,11 +23,13 @@ const EditFormRow = ({field, models={}, value, options=defaultAdminOptions, reco
     )
 }
 
-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 EditForm = ({record, models={}, model, options=defaultAdminOptions, Components:{EditFormRow:EFR}={EditFormRow}}) => {
     const [edit, setEdit] = useState({...record})
-    console.log(edit)
+
+    if (!record) return <></>
+
+    const fields =  model.fields
+    const onlyInputs = model.inputs.filter(input => !fields.find(field => field.name === input.name))
     return (
         <>
             <table>
@@ -129,6 +131,7 @@ const Search = ({...props}) =>
 const Count = ({...props}) => <div className="Count" {...props} /> 
 
 const searchQueryBuilder = (search, model) => {
+    if (!search) return {}
     const queryRegexp = `/${search.trim().split(/\s+/).join('|')}/`
     return {$or: model.fields.filter(field => field.type.kind == 'SCALAR').map(field => ({[field.name]: queryRegexp}))}
 }
@@ -166,23 +169,25 @@ const VirtualScroll = ({options, gridHeight, count, rowHeight, components:Compon
 
 
     return (
-    <div className='GridViewport' 
-         style={{maxHeight: gridHeight, height: gridHeight}} >
-        <div className='GridContent' 
-             style={{height: count*rowHeight, minHeight: count*rowHeight, maxHeight: count*rowHeight}} >
-            {records && records.map((record,i) =><React.Fragment key={i}> 
-                                            {edit.record && edit.record._id === record._id ? <EditForm models={models} record={record} options={options}/>: 
-                                            <Row options={options}>
-                                                {fields.map(field => 
-                                                    <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>)}
-                                            </Row>}
-                </React.Fragment>
-            )}
+    <>
+        <div className='GridViewport' 
+             style={{maxHeight: gridHeight, height: gridHeight}} >
+            <div className='GridContent' 
+                 style={{height: count*rowHeight, minHeight: count*rowHeight, maxHeight: count*rowHeight}} >
+                {records && records.map((record,i) =><React.Fragment key={i}> 
+                                                {edit.record && edit.record._id === record._id ? <EditForm model={record.constructor} models={models} record={record} options={options}/>: 
+                                                <Row options={options}>
+                                                    {fields.map(field => 
+                                                        <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>)}
+                                                </Row>}
+                    </React.Fragment>
+                )}
+            </div>
         </div>
-    </div>
+    </>
     )
 }
 
@@ -235,6 +240,11 @@ const ModelView = ({model, models={}, options, components:Components={Search, Co
                                 sort: [{[sort]: cursorCalls.sort[0][sort] === 1 ? -1 : 1}]
                             })}/>
 
+                <button onClick={() => { 
+                    (new model).save()
+                    setCursorCalls({...cursorCalls, sort: [{_id: -1}]})
+                    setSearch('')
+                }}>+</button>
                 {records && <Components.Grid 
                                 models={models}
                                 options={options}
@@ -337,19 +347,21 @@ const defaultAdminOptions =
                 ID: ({children}) => <b>{children && children.slice(-6).toUpperCase()}</b>,
                 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}/>,
+                Float: ({children, ...props}) => <input type='number' value={children}  {...props} onChange={(e) => props.onChange(+e.target.value)}/>,
                 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} />
+                    return model.fields[0].name === '_id' ? <ObjectShortEdit children={children}  model={model} {...props}/> : <EditForm model={model} models={models} record={children} options={options} />
                 },
-                Array: ({children, onChange, ...props}) => {
+                Array: ({children, onChange, model, ...props}) => {
+                    const newItem = !model || (model && model.fields[0].name === '_id') ? null : new model
+
                     return (<><SortableContainer 
                                     pressDelay={200}
                                     onSortEnd={({newIndex, oldIndex}) => {
                                         onChange(arrayMove(children, newIndex, oldIndex))
                                 }}>{children.map((child, i) => 
                                     <SortableCell onDelete={() => onChange(children.filter((item, j) => j !== i))} 
-                                                  onAdd={() => onChange([...children.slice(0, i),null,...children.slice(i)])} 
-                                                index={i} key={(child && (child._id || child.key)) || i} {...props} children={child} selected 
+                                                  onAdd={() => onChange([...children.slice(0, i),newItem,...children.slice(i)])}  //TODO: fix addition of new nested form 
+                                                index={i} key={(child && (child._id || child.key)) || i} model={model} {...props} children={child} selected 
                                             onCh={data => {
                                                                     const copy = [...children]
                                                                     debugger;
@@ -358,7 +370,7 @@ const defaultAdminOptions =
                                             }}
                                         />)}
                         </SortableContainer>
-                        <button onClick={() => onChange([...children, null])}>+</button></>)
+                        <button onClick={() => onChange([...children, newItem])}>+</button></>)
                 }
             },
             fields:{

+ 3 - 2
src/front-models.js

@@ -141,10 +141,11 @@ export default async function createModels2(gql, config={create: 'Upsert', updat
                             if (data && typeof data === 'object' && name in data) this[name] = data[name]
                         },
                         LIST(){
+                            this[name] = []
                             const otherType = inTypes(ofType.name)
                             if (otherType  && data[name])
                                 this[name] = data[name].map(otherEntity => new classes[otherType.name](otherEntity, otherEntity._id && Object.keys(otherEntity).length === 1))
-                            else if (data && typeof data === 'object' && name in data) this[name] = data[name]
+                            else if (data && typeof data === 'object' && name in data) this[name] = data[name] || []
                         },
                         OBJECT(){
                             const otherType = inTypes(otherName)
@@ -208,7 +209,7 @@ export default async function createModels2(gql, config={create: 'Upsert', updat
                         LIST(){
                             const otherType = inInputs(ofType.name)
                             if (otherType  && this[name] && this[name] instanceof Array)
-                                data[name] = this[name].map(otherEntity => (otherEntity._id ? {_id: otherEntity._id} : (otherEntity.mutationData || otherEntity)))
+                                data[name] = this[name].map(otherEntity => (otherEntity && otherEntity._id ? {_id: otherEntity._id} : (otherEntity.mutationData || otherEntity)))
                         },
                         INPUT_OBJECT(){
                             const otherType = inInputs(otherName)