Browse Source

something works

Ivan Asmer 4 years ago
parent
commit
a3f2391e50
1 changed files with 64 additions and 89 deletions
  1. 64 89
      src/App.js

+ 64 - 89
src/App.js

@@ -23,8 +23,9 @@ const dataReader = async () => {
 const Th = p =>
 <div className='Th' {...p} />
 
+//<div className='Row' style={{position: 'relative',top}}>
 const Row = ({top, children}) =>
-<div className='Row' style={{position: 'relative',top}}>
+<div className='Row' >
     {children}
 </div>
 
@@ -34,73 +35,6 @@ const Cell = ({children, ...props}) =>
 </div>
 
 
-function ModelGrid({model, rowHeight, gridHeight, overload, query, cellDoubleClick}){
-    const onScreenRowCount   = gridHeight/rowHeight
-    const overloadedRowCount = overload * onScreenRowCount
-
-    const [totalCount, setTotalCount] = useState(-1)
-
-
-    const [gridContentRef, setGridContentRef] = useState()
-    const [scroll, setScroll]                 = useState(0)
-
-
-
-    const  onScreenFirstRowIndex = Math.floor(scroll/rowHeight)
-    let skip                  =  onScreenFirstRowIndex  - (overloadedRowCount - onScreenRowCount)/2;
-
-    if (skip < 0) skip = 0
-
-    const [sort, setSort] = useState([])
-
-    const [records, setRecords] = useState()
-    const cursorCalls = {skip: [skip], limit: [overloadedRowCount]}
-
-
-
-    if (sort.length) cursorCalls.sort = [sort]
-
-
-    useEffect(() => {
-        if (totalCount > 0) { 
-            model.find(query, cursorCalls).then(records => setRecords(records))
-        }
-    },[model, query, sort, totalCount])
-
-    useEffect(() => {
-        model && model.count(query).then(count =>  setTotalCount(count))
-    },[model, query, totalCount])
-
-    if (!model) return <>No model</>;
-    return(
-        <>
-            <div className='GridHeader'>
-                {model.fields.map(field => <Th onClick={e => (setSort(field.name === sort[0] ? [sort[0], -sort[1]] : [field.name, 1]), setRecords(null))}>{field.name}</Th>)}
-            </div>
-            <div className='GridViewport' 
-                 onScroll={e => {
-                        if (Math.abs(e.target.scrollTop - scroll) > gridHeight*overload/3){  
-                            setScroll(e.target.scrollTop); 
-                            setRecords(null)
-                        } }} 
-                 style={{maxHeight: gridHeight, height: gridHeight}}>
-
-                <div className='GridContent' 
-                     style={{height: totalCount*rowHeight}}
-                     ref={e => setGridContentRef(e)}>
-                    {console.log(records), records && records.map((record,i) => 
-                                                    <Row top={(skip)*rowHeight}>
-                                                        {model.fields.map(field => 
-                                                            <Cell onDoubleClick={e => cellDoubleClick(field.name, record[field.name], record._id)}>
-                                                                {record[field.name] === 'object' ? record[field.name].toString() :  record[field.name]}
-                                                            </Cell>)}
-                                                    </Row>)}
-                </div>
-            </div>
-        </>
-    );
-}
-
 const ModelListItem = "div"
 
 const ModelList = ({models, selected, onChange, Item=ModelListItem}) => {
@@ -131,7 +65,7 @@ const searchQueryBuilder = (search, model) => {
     return {$or: model.fields.filter(field => field.type.kind == 'SCALAR').map(field => ({[field.name]: queryRegexp}))}
 }
 
-const GridHeaderItem = ({field, sort, ...props}) => 
+const GridHeaderItem = ({field, sort:[sort], ...props}) => 
 <div className="GridHeaderItem" {...props}>
     {field.name in sort && sort[field.name] === -1 && '^ '}
     {field.name}
@@ -145,6 +79,46 @@ const GridHeader = ({fields, sort, onSort}) =>
     {fields.map(field => <GridHeaderItem field={field} sort={sort} onClick={() => onSort(field.name)}/>)}
 </div>
 
+const VirtualScroll = ({gridHeight, count, rowHeight, row=Row, onScroll, records, skip}) => { 
+    //const [records, setRecords] = useState([])
+    const limit = gridHeight/rowHeight
+    const Row = row
+
+
+    const timeout = useRef(0)
+
+    return (
+    <div className='GridViewport' 
+         onScroll={e => {
+             let skip = Math.ceil(e.target.scrollTop/rowHeight)
+             if (skip < 0) skip = 0
+             if (skip > count - limit) skip = count - limit
+
+             clearInterval(timeout.current)
+             timeout.current = setTimeout(() => {
+                 console.log(skip, limit)
+                 onScroll(skip,limit)
+             }, 1000)
+         }} 
+         style={{maxHeight: gridHeight, height: gridHeight}} >
+        <div className='GridContent' 
+             style={{height: count*rowHeight, minHeight: count*rowHeight, maxHeight: count*rowHeight}} >
+            <div style={{height: skip*rowHeight}} />
+            {records && records.map((record,i) => 
+                                            <Row key={i}>
+                                                {record.constructor.fields.map(field => 
+                                                    <Cell>
+                                                        {record[field.name] === 'object' ? record[field.name].toString() :  record[field.name]}
+                                                    </Cell>)}
+                                            </Row>)}
+            <div style={{height: (count - skip - records.length)*rowHeight}} />
+        </div>
+    </div>
+    )
+}
+
+
+
 const Grid = ({sort, scroll, gridHeight, overload, setScroll, count, rowHeight, records, skip, model, cellDoubleClick}) =>  {
     const viewport = useRef()
     return (
@@ -156,7 +130,7 @@ const Grid = ({sort, scroll, gridHeight, overload, setScroll, count, rowHeight,
                     //setRecords(null)
                 } }} 
          style={{maxHeight: gridHeight, height: gridHeight}}
-         ref={viewport}>
+         ref={e => e && e.scrollTo(0,scroll)}>
 
         <div className='GridContent' 
              style={{height: count*rowHeight, minHeight: count*rowHeight, maxHeight: count*rowHeight}} >
@@ -176,34 +150,25 @@ const Grid = ({sort, scroll, gridHeight, overload, setScroll, count, rowHeight,
 
 
 const ModelView = ({model, components:Components={Search, Count, GridHeader, Grid}, rowHeight=50, gridHeight=500, overload=2}) => {
-    const onScreenRowCount   = Math.ceil(gridHeight/rowHeight)
-    const overloadedRowCount = Math.ceil(overload * onScreenRowCount)
-    const [scroll, setScroll]                 = useState(0)
-
-
 
-    const  onScreenFirstRowIndex = Math.floor(scroll/rowHeight)
-    let skipAbove             = Math.floor((overloadedRowCount - onScreenRowCount)/2);
-    let skip                  =  onScreenFirstRowIndex  - skipAbove 
 
 
-    const [records, setRecords] = useState()
+    const [records, setRecords] = useState([])
 
 
     const [search, setSearch] = useState("")
     const [count, setCount]   = useState(0)
 
-    if (count - skip < overloadedRowCount) skip = count - overloadedRowCount 
-    if (skip < 0) skip = 0
-
     const [query,  setQuery]  = useState({})
-    const [cursorCalls,  setCursorCalls]  = useState({sort:[{}], skip: skip ? [skip] : undefined, limit: overloadedRowCount ? [overloadedRowCount] : undefined})
+    const [cursorCalls,  setCursorCalls]  = useState({sort:[{}], skip: [0], limit: [gridHeight/rowHeight]})
+
+    const skip = cursorCalls.skip[0]
 
     console.log(cursorCalls)
 
-    useEffect(() => {
-        setCursorCalls({sort:cursorCalls.sort, skip: skip ? [skip] : undefined, limit: overloadedRowCount ? [overloadedRowCount] : undefined})
-    }, [scroll])
+    //useEffect(() => {
+        //setCursorCalls({sort:cursorCalls.sort, skip: skip ? [skip] : undefined, limit: overloadedRowCount ? [overloadedRowCount] : undefined})
+    //}, [scroll])
 
     const timeout = useRef(0)
     useEffect(() => {
@@ -229,10 +194,10 @@ const ModelView = ({model, components:Components={Search, Count, GridHeader, Gri
                 <GridHeader fields={model.fields} 
                             sort={cursorCalls.sort} 
                             onSort={sort => setCursorCalls({...cursorCalls,
-                                sort: {[sort]: cursorCalls.sort[sort] === 1 ? -1 : 1}
+                                sort: [{[sort]: cursorCalls.sort[0][sort] === 1 ? -1 : 1}]
                             })}/>
 
-                {records && <Grid 
+                {/*records && <Grid 
                                 scroll={scroll}
                                 setScroll={setScroll}
                                 gridHeight={gridHeight}
@@ -242,7 +207,17 @@ const ModelView = ({model, components:Components={Search, Count, GridHeader, Gri
                                 records={records}
                                 skip={skip}
                                 model={model}
-                                /> }
+                                /> */}
+                {records && <VirtualScroll 
+                                skip={skip}
+                                count={count}
+                                records={records}
+                                gridHeight={500} 
+                                rowHeight={50} 
+                                onScroll={(skip, limit) =>  {
+                                    model.find(query, {...cursorCalls, limit: [limit], skip: [skip]}).then(records => Promise.all(records)).then(records => setRecords(records)).then(() =>
+                                    setCursorCalls({...cursorCalls, limit: [limit], skip: [skip]}))
+                                }}/> }
         </>
     )
 }