瀏覽代碼

+textarea/input, +ace editor, partial scroll width resize on grid

Ivan Asmer 4 年之前
父節點
當前提交
f2c19ac825
共有 4 個文件被更改,包括 72 次插入7 次删除
  1. 32 0
      package-lock.json
  2. 2 0
      package.json
  3. 4 0
      src/App.css
  4. 34 7
      src/App.js

+ 32 - 0
package-lock.json

@@ -1903,6 +1903,11 @@
         "negotiator": "0.6.2"
       }
     },
+    "ace-builds": {
+      "version": "1.4.12",
+      "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.12.tgz",
+      "integrity": "sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg=="
+    },
     "acorn": {
       "version": "6.4.1",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
@@ -4197,6 +4202,11 @@
         }
       }
     },
+    "diff-match-patch": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+      "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+    },
     "diff-sequences": {
       "version": "24.9.0",
       "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz",
@@ -7476,6 +7486,16 @@
       "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
       "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
     },
+    "lodash.get": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+    },
+    "lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+    },
     "lodash.memoize": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -9730,6 +9750,18 @@
         "prop-types": "^15.6.2"
       }
     },
+    "react-ace": {
+      "version": "9.1.3",
+      "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-9.1.3.tgz",
+      "integrity": "sha512-1TZBs/9hFGgPuzu6DUiBogyhRA5Z1Po2wzPfZslbrTFGQtbNe+JXHuPoJNlUu/uerElzOLLsuJEDTO9FfLnZJA==",
+      "requires": {
+        "ace-builds": "^1.4.6",
+        "diff-match-patch": "^1.0.4",
+        "lodash.get": "^4.4.2",
+        "lodash.isequal": "^4.5.0",
+        "prop-types": "^15.7.2"
+      }
+    },
     "react-app-polyfill": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz",

+ 2 - 0
package.json

@@ -3,9 +3,11 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "ace-builds": "^1.4.12",
     "graphql-request": "^1.8.2",
     "mdast": "git+ssh://git@gitlab.a-level.com.ua:gitgod/mdast.git",
     "react": "^16.8.6",
+    "react-ace": "^9.1.3",
     "react-dom": "^16.8.6",
     "react-dropzone": "^11.0.1",
     "react-scripts": "3.0.1",

+ 4 - 0
src/App.css

@@ -92,6 +92,10 @@ textarea {
     height: 100px;
 }
 
+.Cell input {
+    width: 90%;
+}
+
 aside {
     /*float: left;*/
     width: 25%;

+ 34 - 7
src/App.js

@@ -10,6 +10,11 @@ import { GraphQLClient } from 'graphql-request';
 
 import createModels2 from './front-models.mjs'
 
+import AceEditor from 'react-ace'; 
+import "ace-builds/src-noconflict/mode-markdown";
+import "ace-builds/src-noconflict/theme-github";
+
+
 let gql;
 
 const getGQL = () => new GraphQLClient(localStorage.url + 'graphql', {headers: localStorage.authToken ? {Authorization: 'Bearer '+localStorage.authToken} : {}})
@@ -163,8 +168,15 @@ const searchQueryBuilder = (search, model) => {
     return {$or: model.fields.filter(field => field.type.kind == 'SCALAR').map(field => ({[field.name]: queryRegexp}))}
 }
 
-const GridHeaderItem = ({field, sort:[sort], ...props}) => 
-<div className="GridHeaderItem" {...props}>
+const GridHeaderItem = ({field, sort:[sort], model, ...props}) => 
+<div className="GridHeaderItem" 
+    onWheel={e => {
+        //const columnWidths = JSON.parse(localStorage.columWidths || '{}')
+        //if (!columnWidths[localStorage.url]) columnWidths[localStorage.url] = {}
+        //if (!columnWidths[localStorage.url][model.name]) columnWidths[localStorage.url][model.name] = {}
+        //columnWidths[localStorage.url][model.name][field.name]
+    }} 
+    {...props}>
     {field.name in sort && sort[field.name] === -1 && '^ '}
     {field.name}
     {field.name in sort && sort[field.name] === 1 && ' v'}
@@ -172,9 +184,9 @@ const GridHeaderItem = ({field, sort:[sort], ...props}) =>
 
 
 
-const GridHeader = ({fields, sort, onSort}) => 
+const GridHeader = ({fields, sort, onSort, model}) => 
 <div className="GridHeader">
-    {fields.map(field => <GridHeaderItem key={field.name} field={field} sort={sort} onClick={() => onSort(field.name)}/>)}
+    {fields.map(field => <GridHeaderItem model={model} key={field.name} field={field} sort={sort} onClick={() => onSort(field.name)}/>)}
 </div>
 
 const getModelByField = (field, models={}) => {
@@ -271,7 +283,9 @@ const ModelView = ({model, models={}, options, components:Components={Search, Co
                             sort={cursorCalls.sort} 
                             onSort={sort => setCursorCalls({...cursorCalls,
                                 sort: [{[sort]: cursorCalls.sort[0][sort] === 1 ? -1 : 1}]
-                            })}/>
+                            })}
+                            model={model}
+                            />
 
                 <Add onClick={() => { 
                     if (Add === 'button') (new model).save()
@@ -359,7 +373,17 @@ const arrayMove = (arr, newIndex, oldIndex) => {
 }
 const MDEdit = ({children, field, ...props}) => 
                     <div style={{display: 'flex'}}>
-                        <textarea style={{maxWidth: '50%', height: '400px'}} placeholder={field.name} value={children} {...props}/>
+                        <AceEditor 
+
+                    mode="markdown"
+                    width='100%' 
+                    height='400px'
+                    theme='github'
+                    fontFamily="TerminusTTF"
+                    fontSize={15}
+                    enableBasicAutocompletion={true}
+                    enableLiveAutocompletion={true}
+    style={{maxWidth: '50%', height: '400px'}} placeholder={field.name} value={children} {...props}/>
                         <div style={{maxWidth: '50%', height: '400px', overflow: 'auto'}}>
                             {toReact(buildAST(children), React)}
                         </div>
@@ -414,7 +438,10 @@ const defaultAdminOptions =
         edit: {
             formatters:{
                 ID: ({children}) => <b>{children && children.slice(-6).toUpperCase()}</b>,
-                String: ({children, field, ...props}) => <textarea placeholder={field.name} value={children} {...props}/>,
+                String: ({children, field, ...props}) => (typeof children === 'string' && children.includes('\n') ? 
+                                                <textarea placeholder={field.name} value={children} {...props}/> :
+                                                <><input placeholder={field.name} value={children} {...props} />
+                                                   <button onClick={() => props.onChange && props.onChange((children || '') + '\n')}>V</button> </> ),
                 Int: ({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}) => {