Selaa lähdekoodia

react select with autocomplete for relation to one. TODO: fix remove relation

Ivan Asmer 4 vuotta sitten
vanhempi
commit
a8f07e580b
4 muutettua tiedostoa jossa 308 lisäystä ja 29 poistoa
  1. 260 15
      package-lock.json
  2. 2 1
      package.json
  3. 5 0
      src/App.css
  4. 41 13
      src/App.js

+ 260 - 15
package-lock.json

@@ -926,6 +926,102 @@
       "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-9.0.1.tgz",
       "integrity": "sha512-6It2EVfGskxZCQhuykrfnALg7oVeiI6KclWSmGDqB0AiInVrTGB9Jp9i4/Ad21u9Jde/voVQz6eFX/eSg/UsPA=="
     },
+    "@emotion/cache": {
+      "version": "10.0.29",
+      "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
+      "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==",
+      "requires": {
+        "@emotion/sheet": "0.9.4",
+        "@emotion/stylis": "0.8.5",
+        "@emotion/utils": "0.11.3",
+        "@emotion/weak-memoize": "0.2.5"
+      }
+    },
+    "@emotion/core": {
+      "version": "10.0.28",
+      "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz",
+      "integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==",
+      "requires": {
+        "@babel/runtime": "^7.5.5",
+        "@emotion/cache": "^10.0.27",
+        "@emotion/css": "^10.0.27",
+        "@emotion/serialize": "^0.11.15",
+        "@emotion/sheet": "0.9.4",
+        "@emotion/utils": "0.11.3"
+      },
+      "dependencies": {
+        "@babel/runtime": {
+          "version": "7.10.2",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
+          "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+          "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+        }
+      }
+    },
+    "@emotion/css": {
+      "version": "10.0.27",
+      "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz",
+      "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==",
+      "requires": {
+        "@emotion/serialize": "^0.11.15",
+        "@emotion/utils": "0.11.3",
+        "babel-plugin-emotion": "^10.0.27"
+      }
+    },
+    "@emotion/hash": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
+      "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
+    },
+    "@emotion/memoize": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+      "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
+    },
+    "@emotion/serialize": {
+      "version": "0.11.16",
+      "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz",
+      "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==",
+      "requires": {
+        "@emotion/hash": "0.8.0",
+        "@emotion/memoize": "0.7.4",
+        "@emotion/unitless": "0.7.5",
+        "@emotion/utils": "0.11.3",
+        "csstype": "^2.5.7"
+      }
+    },
+    "@emotion/sheet": {
+      "version": "0.9.4",
+      "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz",
+      "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA=="
+    },
+    "@emotion/stylis": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+      "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
+    },
+    "@emotion/unitless": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+      "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
+    },
+    "@emotion/utils": {
+      "version": "0.11.3",
+      "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz",
+      "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw=="
+    },
+    "@emotion/weak-memoize": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
+      "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
+    },
     "@hapi/address": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz",
@@ -2059,6 +2155,23 @@
         "object.assign": "^4.1.0"
       }
     },
+    "babel-plugin-emotion": {
+      "version": "10.0.33",
+      "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz",
+      "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==",
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@emotion/hash": "0.8.0",
+        "@emotion/memoize": "0.7.4",
+        "@emotion/serialize": "^0.11.16",
+        "babel-plugin-macros": "^2.0.0",
+        "babel-plugin-syntax-jsx": "^6.18.0",
+        "convert-source-map": "^1.5.0",
+        "escape-string-regexp": "^1.0.5",
+        "find-root": "^1.1.0",
+        "source-map": "^0.5.7"
+      }
+    },
     "babel-plugin-istanbul": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
@@ -2093,6 +2206,11 @@
       "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.2.tgz",
       "integrity": "sha512-CxwvxrZ9OirpXQ201Ec57OmGhmI8/ui/GwTDy0hSp6CmRvgRC0pSair6Z04Ck+JStA0sMPZzSJ3uE4n17EXpPQ=="
     },
+    "babel-plugin-syntax-jsx": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+      "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
+    },
     "babel-plugin-syntax-object-rest-spread": {
       "version": "6.13.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
@@ -2782,7 +2900,8 @@
             },
             "ansi-regex": {
               "version": "2.1.1",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "aproba": {
               "version": "1.2.0",
@@ -3147,7 +3266,8 @@
             },
             "safe-buffer": {
               "version": "5.1.2",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "safer-buffer": {
               "version": "2.1.2",
@@ -3195,6 +3315,7 @@
             "strip-ansi": {
               "version": "3.0.1",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "ansi-regex": "^2.0.0"
               }
@@ -3233,11 +3354,13 @@
             },
             "wrappy": {
               "version": "1.0.2",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "yallist": {
               "version": "3.0.3",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             }
           }
         },
@@ -3928,6 +4051,11 @@
         "cssom": "0.3.x"
       }
     },
+    "csstype": {
+      "version": "2.6.10",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
+      "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
+    },
     "cyclist": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
@@ -4214,6 +4342,30 @@
         "utila": "~0.4"
       }
     },
+    "dom-helpers": {
+      "version": "5.1.4",
+      "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+      "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
+      "requires": {
+        "@babel/runtime": "^7.8.7",
+        "csstype": "^2.6.7"
+      },
+      "dependencies": {
+        "@babel/runtime": {
+          "version": "7.10.2",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
+          "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+          "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+        }
+      }
+    },
     "dom-serializer": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz",
@@ -5285,6 +5437,11 @@
         "pkg-dir": "^3.0.0"
       }
     },
+    "find-root": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+    },
     "find-up": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@@ -6665,7 +6822,8 @@
             },
             "ansi-regex": {
               "version": "2.1.1",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "aproba": {
               "version": "1.2.0",
@@ -6683,11 +6841,13 @@
             },
             "balanced-match": {
               "version": "1.0.0",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "brace-expansion": {
               "version": "1.1.11",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
@@ -6700,15 +6860,18 @@
             },
             "code-point-at": {
               "version": "1.1.0",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "concat-map": {
               "version": "0.0.1",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "console-control-strings": {
               "version": "1.1.0",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "core-util-is": {
               "version": "1.0.2",
@@ -6811,7 +6974,8 @@
             },
             "inherits": {
               "version": "2.0.3",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "ini": {
               "version": "1.3.5",
@@ -6821,6 +6985,7 @@
             "is-fullwidth-code-point": {
               "version": "1.0.0",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "number-is-nan": "^1.0.0"
               }
@@ -6833,17 +6998,20 @@
             "minimatch": {
               "version": "3.0.4",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "brace-expansion": "^1.1.7"
               }
             },
             "minimist": {
               "version": "0.0.8",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "minipass": {
               "version": "2.3.5",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "safe-buffer": "^5.1.2",
                 "yallist": "^3.0.0"
@@ -6860,6 +7028,7 @@
             "mkdirp": {
               "version": "0.5.1",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "minimist": "0.0.8"
               }
@@ -6932,7 +7101,8 @@
             },
             "number-is-nan": {
               "version": "1.0.1",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "object-assign": {
               "version": "4.1.1",
@@ -6942,6 +7112,7 @@
             "once": {
               "version": "1.4.0",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "wrappy": "1"
               }
@@ -7017,7 +7188,8 @@
             },
             "safe-buffer": {
               "version": "5.1.2",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "safer-buffer": {
               "version": "2.1.2",
@@ -7047,6 +7219,7 @@
             "string-width": {
               "version": "1.0.2",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "code-point-at": "^1.0.0",
                 "is-fullwidth-code-point": "^1.0.0",
@@ -7064,6 +7237,7 @@
             "strip-ansi": {
               "version": "3.0.1",
               "bundled": true,
+              "optional": true,
               "requires": {
                 "ansi-regex": "^2.0.0"
               }
@@ -7102,11 +7276,13 @@
             },
             "wrappy": {
               "version": "1.0.2",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             },
             "yallist": {
               "version": "3.0.3",
-              "bundled": true
+              "bundled": true,
+              "optional": true
             }
           }
         }
@@ -7909,6 +8085,11 @@
         }
       }
     },
+    "memoize-one": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
+      "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA=="
+    },
     "memory-fs": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@@ -10082,6 +10263,14 @@
       "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-5.1.6.tgz",
       "integrity": "sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q=="
     },
+    "react-input-autosize": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz",
+      "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==",
+      "requires": {
+        "prop-types": "^15.5.8"
+      }
+    },
     "react-is": {
       "version": "16.8.6",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
@@ -10147,6 +10336,62 @@
         "workbox-webpack-plugin": "4.2.0"
       }
     },
+    "react-select": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.0.tgz",
+      "integrity": "sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g==",
+      "requires": {
+        "@babel/runtime": "^7.4.4",
+        "@emotion/cache": "^10.0.9",
+        "@emotion/core": "^10.0.9",
+        "@emotion/css": "^10.0.9",
+        "memoize-one": "^5.0.0",
+        "prop-types": "^15.6.0",
+        "react-input-autosize": "^2.2.2",
+        "react-transition-group": "^4.3.0"
+      },
+      "dependencies": {
+        "@babel/runtime": {
+          "version": "7.10.2",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
+          "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+          "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+        }
+      }
+    },
+    "react-transition-group": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+      "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+      "requires": {
+        "@babel/runtime": "^7.5.5",
+        "dom-helpers": "^5.0.1",
+        "loose-envify": "^1.4.0",
+        "prop-types": "^15.6.2"
+      },
+      "dependencies": {
+        "@babel/runtime": {
+          "version": "7.10.2",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
+          "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+          "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+        }
+      }
+    },
     "read-pkg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",

+ 2 - 1
package.json

@@ -6,7 +6,8 @@
     "graphql-request": "^1.8.2",
     "react": "^16.8.6",
     "react-dom": "^16.8.6",
-    "react-scripts": "3.0.1"
+    "react-scripts": "3.0.1",
+    "react-select": "^3.1.0"
   },
   "scripts": {
     "start": "react-scripts start",

+ 5 - 0
src/App.css

@@ -148,3 +148,8 @@ td {
     max-width: 90vw;
     text-align: left;
 }
+
+div[class$="-menu"]{
+    z-index: 1000;
+    position: relative;
+}

+ 41 - 13
src/App.js

@@ -1,6 +1,7 @@
 import React, {useState, useEffect, useMemo, useRef}  from 'react';
 import logo from './logo.svg';
 import './App.css';
+import Select from 'react-select/async'
 
 import { GraphQLClient } from 'graphql-request';
 
@@ -8,6 +9,8 @@ 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 EditFormRow = ({field, models={}, value, options=defaultAdminOptions, record, onChange}) => {
@@ -23,24 +26,29 @@ const EditForm = ({record, models={}, options=defaultAdminOptions, Components:{E
     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} 
+                <tbody>
+                {Object.entries(fields).map(([key,field]) => <EFR key={key} field={field} 
                                                                    models={models}
                                                                    record={record} 
                                                                    value={edit[field.name]} 
                                                                    options={options}
-                                                                   onChange={event => setEdit({...edit, [field.name]: event.target.value})}
+                                                                   onChange={event => { 
+                                                                       setEdit({...edit, [field.name]: event && event.target && event.target.value || event})
+                                                                   }}
                                                                     />)}
-                {Object.entries(onlyInputs).map(([key,field]) => <EFR field={field} 
+                {Object.entries(onlyInputs).map(([key,field]) => <EFR key={key} field={field} 
                                                                    models={models}
                                                                    record={record} 
                                                                    value={edit[field.name]} 
                                                                    options={options}
-                                                                   onChange={event => setEdit({...edit, [field.name]: event.target.value})}
+                                                                   onChange={event => setEdit({...edit, [field.name]: event && event.target && event.target.value || event})}
                                                                     />)}
 
+                </tbody>
             </table>
             <button onClick={() => {
                 Object.assign(record, edit);
@@ -63,7 +71,7 @@ const Row = ({top, selected, children}) => {
     )
 }
 
-const Cell = ({children, options, record, field, selected, model, models={}, ...props}) => {
+const Cell = ({children, options, record, field, selected, model, models={}, onClick, ...props}) => {
         
     let Formatter = React.Fragment
 
@@ -75,7 +83,7 @@ const Cell = ({children, options, record, field, selected, model, models={}, ...
         Formatter = options[viewOrEdit].fields[field.name]
     }
     if ((children && typeof children === 'object') || model){ 
-        if (viewOrEdit === 'edit') debugger;
+        //if (viewOrEdit === 'edit') debugger;
         if ((children || model).constructor.name in options[viewOrEdit].formatters)
             Formatter = options[viewOrEdit].formatters[(children || model).constructor.name]
         else
@@ -84,8 +92,10 @@ const Cell = ({children, options, record, field, selected, model, models={}, ...
 
 
     return( 
-        <div className='Cell' {...props}>
-            <Formatter options={options} model={model} models={models} {...props} field={field}>{Formatter === React.Fragment ? (children && children.toString()) : children}</Formatter>
+        <div className='Cell' onClick={onClick}>
+            <Formatter options={options} model={model} models={models} {...props} field={field}>
+                  {Formatter === React.Fragment ? (children && children.toString()) : children}
+            </Formatter>
         </div>
     )
 }
@@ -132,7 +142,7 @@ const GridHeaderItem = ({field, sort:[sort], ...props}) =>
 
 const GridHeader = ({fields, sort, onSort}) => 
 <div className="GridHeader">
-    {fields.map(field => <GridHeaderItem field={field} sort={sort} onClick={() => onSort(field.name)}/>)}
+    {fields.map(field => <GridHeaderItem key={field.name} field={field} sort={sort} onClick={() => onSort(field.name)}/>)}
 </div>
 
 const getModelByField = (field, models={}) => {
@@ -240,6 +250,7 @@ const ModelView = ({model, models={}, options, components:Components={Search, Co
     )
 }
 
+
 const ObjectShortView = ({children}) => {
     const [record, setRecord] = useState(children)
     if (!children) return <></>
@@ -250,7 +261,7 @@ const ObjectShortView = ({children}) => {
     if (typeof children === 'object' && children._id){
         return (
         <div className="ObjectShortView">
-            {record.name || record.key || record.login || record.originalFileName || record._id}
+            {shortName(record)}
         </div>
         )
     }
@@ -263,10 +274,27 @@ const ObjectShortView = ({children}) => {
     }
 }
 
-const ObjectShortEdit = ({children}) =>
+const ForeignAutocomplete = ({models={}, children:value, onChange, model, exclude=[]}) => {
+    return (
+         <Select cacheOptions 
+                defaultOptions 
+                placeholder={model.name}
+                loadOptions={async search => {
+                    const suggesions = await model.find(searchQueryBuilder(search, model)) || []
+                    return [{_id: null, key: 'REMOVE'}, ...suggesions].map((record) => ({value: record._id, label: shortName(record), record}))
+                }}
+                value={value && {value: value._id, label: shortName(value), record: value}}
+                onChange={(obj) => {
+                    onChange(obj.record._id ? obj.record : null)
+                }}
+                />
+
+    )
+}
+
+const ObjectShortEdit = ({...props}) =>
 <>
-    <ObjectShortView children={children} />
-    <input placeholder="autocomplete" />
+    <ForeignAutocomplete {...props}/>
 </>