From 48edd7134f14d6ea2a7a0d1c2a970e0fae0fc28d Mon Sep 17 00:00:00 2001 From: garrettmills Date: Sat, 9 Jul 2022 12:58:13 -0500 Subject: [PATCH] Upgrade @extollo/lib and finish dashboard interfaces --- package.json | 2 +- pnpm-lock.yaml | 200 +++++++++--------- src/app/cobalt.ts | 6 + src/app/configs/cobalt.config.ts | 177 +++++++++++++++- .../cobalt/Interface.controller.ts | 9 + .../cobalt/ResourceAPI.controller.ts | 4 +- src/app/http/routes/dash.routes.ts | 25 +-- .../assets/cobalt/component/Form.component.js | 63 ++++-- .../cobalt/component/Listing.component.js | 14 +- .../cobalt/component/Monaco.component.js | 35 +++ src/app/resources/assets/cobalt/components.js | 2 + .../assets/cobalt/service/Action.service.js | 5 +- src/app/resources/views/dash/template.pug | 8 +- 13 files changed, 408 insertions(+), 142 deletions(-) create mode 100644 src/app/resources/assets/cobalt/component/Monaco.component.js diff --git a/package.json b/package.json index 1988295..163b651 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "lib": "lib" }, "dependencies": { - "@extollo/lib": "^0.9.50", + "@extollo/lib": "^0.10.5", "any-date-parser": "^1.5.3", "copyfiles": "^2.4.1", "feed": "^4.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8be3a5..9758476 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2,7 +2,7 @@ lockfileVersion: 5.3 specifiers: '@extollo/cc': ^0.6.0 - '@extollo/lib': ^0.9.50 + '@extollo/lib': ^0.10.5 any-date-parser: ^1.5.3 copyfiles: ^2.4.1 feed: ^4.2.2 @@ -15,7 +15,7 @@ specifiers: zod: ^3.11.6 dependencies: - '@extollo/lib': 0.9.50 + '@extollo/lib': 0.10.5 any-date-parser: 1.5.3 copyfiles: 2.4.1 feed: 4.2.2 @@ -37,10 +37,10 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0, npm: '>=6.14.11'} hasBin: true dependencies: - '@babel/runtime': 7.17.8 - arg: 5.0.1 + '@babel/runtime': 7.18.6 + arg: 5.0.2 chalk: 4.1.2 - core-js: 3.21.1 + core-js: 3.23.3 fs-extra: 10.0.1 graceful-fs: 4.2.9 inquirer: 8.2.0 @@ -50,29 +50,29 @@ packages: tslib: 2.3.1 dev: false - /@babel/helper-validator-identifier/7.16.7: - resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} + /@babel/helper-validator-identifier/7.18.6: + resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} engines: {node: '>=6.9.0'} dev: false - /@babel/parser/7.17.8: - resolution: {integrity: sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==} + /@babel/parser/7.18.8: + resolution: {integrity: sha512-RSKRfYX20dyH+elbJK2uqAkVyucL+xXzhqlMD5/ZXx+dAAwpyB7HsvnHe/ZUGOF+xLr5Wx9/JoXVTj6BQE2/oA==} engines: {node: '>=6.0.0'} hasBin: true dev: false - /@babel/runtime/7.17.8: - resolution: {integrity: sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==} + /@babel/runtime/7.18.6: + resolution: {integrity: sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.9 dev: false - /@babel/types/7.17.0: - resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} + /@babel/types/7.18.8: + resolution: {integrity: sha512-qwpdsmraq0aJ3osLJRApsc2ouSJCdnMeZwB0DhbtHAtRpZNZCdlbRnHIgcRKzdE1g0iOGg644fzjOBcdOz9cPw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.16.7 + '@babel/helper-validator-identifier': 7.18.6 to-fast-properties: 2.0.0 dev: false @@ -116,11 +116,11 @@ packages: - supports-color dev: true - /@extollo/lib/0.9.50: - resolution: {integrity: sha512-6tKIpKJ5FDuuGFnvNU+OiPGzYQKvRi1eTVlEd0bgxG0zksZVzN+/lVxvLguk2lXbqumRxWRNzJtJh4uA2NyRig==} + /@extollo/lib/0.10.5: + resolution: {integrity: sha512-iZKRzjzsfU5gWks79y0FAHJJECed+e1QYozpYFDPExuWYpPdYZB6M7WKTmX1cBnF6Tv7QGtLXGsEHJxAmEl3gw==} dependencies: '@atao60/fse-cli': 0.1.7 - '@extollo/ui': 0.1.0_@types+node@14.18.12 + '@extollo/ui': 0.1.0_@types+node@14.18.21 '@types/bcrypt': 5.0.0 '@types/busboy': 0.2.4 '@types/cli-table': 0.3.0 @@ -129,7 +129,7 @@ packages: '@types/mime-types': 2.1.1 '@types/mkdirp': 1.0.2 '@types/negotiator': 0.6.1 - '@types/node': 14.18.12 + '@types/node': 14.18.21 '@types/pg': 8.6.5 '@types/pluralize': 0.0.29 '@types/pug': 2.0.6 @@ -146,13 +146,13 @@ packages: mime-types: 2.1.35 mkdirp: 1.0.4 negotiator: 0.6.3 - node-fetch: 3.2.3 + node-fetch: 3.2.6 pg: 8.7.3 pluralize: 8.0.0 pug: 3.0.2 reflect-metadata: 0.1.13 rimraf: 3.0.2 - ssh2: 1.8.0 + ssh2: 1.11.0 ts-node: 9.1.1_typescript@4.6.3 typedoc: 0.20.37_typescript@4.6.3 typedoc-plugin-pages-fork: 0.0.1 @@ -168,17 +168,17 @@ packages: - supports-color dev: false - /@extollo/ui/0.1.0_@types+node@14.18.12: + /@extollo/ui/0.1.0_@types+node@14.18.21: resolution: {integrity: sha512-EuFpNfIyL9ZTbrlCxeOwIJaZnZo3EOLEKNUDHgGgTfEUJPDKKl8VTrGsuCEGWtPnwZwz/kwD0q8Qv+jTdgducQ==} dependencies: - '@popperjs/core': 2.11.4 + '@popperjs/core': 2.11.5 '@types/rimraf': 3.0.2 '@types/uuid': 8.3.4 - bootstrap: 5.1.3_@popperjs+core@2.11.4 + bootstrap: 5.1.3_@popperjs+core@2.11.5 dotenv: 10.0.0 mkdirp: 1.0.4 rimraf: 3.0.2 - ts-node: 10.7.0_b34c2d00f7bffffd3f771e5188a8c9e6 + ts-node: 10.7.0_2c83ab3fa4a45acf1e79be32ccb30210 typescript: 4.6.3 uuid: 8.3.2 transitivePeerDependencies: @@ -192,7 +192,7 @@ packages: hasBin: true dependencies: detect-libc: 2.0.1 - https-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 make-dir: 3.1.0 node-fetch: 2.6.7 nopt: 5.0.0 @@ -305,8 +305,8 @@ packages: transitivePeerDependencies: - supports-color - /@popperjs/core/2.11.4: - resolution: {integrity: sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==} + /@popperjs/core/2.11.5: + resolution: {integrity: sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==} dev: false /@sindresorhus/is/2.1.1: @@ -420,8 +420,8 @@ packages: resolution: {integrity: sha512-c4mvXFByghezQ/eVGN5HvH/jI63vm3B7FiE81BUzDAWmuiohRecCO6ddU60dfq29oKUMiQujsoB2h0JQC7JHKA==} dev: false - /@types/node/14.18.12: - resolution: {integrity: sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A==} + /@types/node/14.18.21: + resolution: {integrity: sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==} dev: false /@types/node/17.0.23: @@ -560,8 +560,8 @@ packages: /arg/4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - /arg/5.0.1: - resolution: {integrity: sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==} + /arg/5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} dev: false /argparse/2.0.1: @@ -573,7 +573,7 @@ packages: engines: {node: '>=8'} /asap/2.0.6: - resolution: {integrity: sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=} + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: false /asn1/0.2.6: @@ -597,7 +597,7 @@ packages: resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} engines: {node: '>= 10.0.0'} dependencies: - '@babel/types': 7.17.0 + '@babel/types': 7.18.8 dev: false /balanced-match/1.0.2: @@ -607,7 +607,7 @@ packages: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} /bcrypt-pbkdf/1.0.2: - resolution: {integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=} + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: tweetnacl: 0.14.5 dev: false @@ -635,12 +635,12 @@ packages: inherits: 2.0.4 readable-stream: 3.6.0 - /bootstrap/5.1.3_@popperjs+core@2.11.4: + /bootstrap/5.1.3_@popperjs+core@2.11.5: resolution: {integrity: sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==} peerDependencies: '@popperjs/core': ^2.10.2 dependencies: - '@popperjs/core': 2.11.4 + '@popperjs/core': 2.11.5 dev: false /brace-expansion/1.1.11: @@ -712,7 +712,7 @@ packages: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 - get-intrinsic: 1.1.1 + get-intrinsic: 1.1.2 dev: false /callsites/3.1.0: @@ -731,7 +731,7 @@ packages: supports-color: 7.2.0 /character-parser/2.2.0: - resolution: {integrity: sha1-x84o821LzZdE5f/CxfzeHHMmH8A=} + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} dependencies: is-regex: 1.1.4 dev: false @@ -834,7 +834,7 @@ packages: dev: false /colors/1.0.3: - resolution: {integrity: sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=} + resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} dev: false @@ -859,14 +859,14 @@ packages: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} /console-control-strings/1.1.0: - resolution: {integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=} + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} dev: false /constantinople/4.0.1: resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} dependencies: - '@babel/parser': 7.17.8 - '@babel/types': 7.17.0 + '@babel/parser': 7.18.8 + '@babel/types': 7.18.8 dev: false /copyfiles/2.4.1: @@ -882,8 +882,8 @@ packages: yargs: 16.2.0 dev: false - /core-js/3.21.1: - resolution: {integrity: sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==} + /core-js/3.23.3: + resolution: {integrity: sha512-oAKwkj9xcWNBAvGbT//WiCdOMpb9XQG92/Fe3ABFM/R16BsHgePG00mFOgKf7IsCtfj8tA1kHtf/VwErhriz5Q==} requiresBuild: true dev: false @@ -891,8 +891,8 @@ packages: resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=} dev: false - /cpu-features/0.0.3: - resolution: {integrity: sha512-p6C/uud4F4bDyCz9+BNU22KdV1AGxPK6L9rQG9x3x4SSzdMPyBPErP7Rxn8avT2ex1M2g5Rpjz5Us/ri/766Qg==} + /cpu-features/0.0.4: + resolution: {integrity: sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==} engines: {node: '>=10.0.0'} requiresBuild: true dependencies: @@ -945,7 +945,7 @@ packages: dev: false /delegates/1.0.0: - resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} dev: false /denque/1.5.1: @@ -976,7 +976,7 @@ packages: path-type: 4.0.0 /doctypes/1.1.0: - resolution: {integrity: sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=} + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} dev: false /dotenv/10.0.0: @@ -1102,12 +1102,12 @@ packages: xml-js: 1.6.11 dev: false - /fetch-blob/3.1.5: - resolution: {integrity: sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==} + /fetch-blob/3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} dependencies: node-domexception: 1.0.0 - web-streams-polyfill: 3.2.0 + web-streams-polyfill: 3.2.1 dev: false /figures/3.2.0: @@ -1126,7 +1126,7 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} dependencies: - fetch-blob: 3.1.5 + fetch-blob: 3.2.0 dev: false /fs-extra/10.0.1: @@ -1158,7 +1158,7 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 dev: false /fs.realpath/1.0.0: @@ -1194,8 +1194,8 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: false - /get-intrinsic/1.1.1: - resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} + /get-intrinsic/1.1.2: + resolution: {integrity: sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==} dependencies: function-bind: 1.1.1 has: 1.0.3 @@ -1284,7 +1284,7 @@ packages: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.16.1 + uglify-js: 3.16.2 dev: false /has-flag/4.0.0: @@ -1304,7 +1304,7 @@ packages: dev: false /has-unicode/2.0.1: - resolution: {integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=} + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} dev: false /has/1.0.3: @@ -1317,8 +1317,8 @@ packages: resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} dev: false - /https-proxy-agent/5.0.0: - resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} + /https-proxy-agent/5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 @@ -1480,7 +1480,7 @@ packages: resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} /js-stringify/1.0.2: - resolution: {integrity: sha1-Fzb939lyTyijaCrcYjCufk6Weds=} + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} dev: false /json-buffer/3.0.1: @@ -1553,43 +1553,43 @@ packages: engines: {node: '>=0.10.0'} /lodash.defaults/4.2.0: - resolution: {integrity: sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=} + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} dev: false /lodash.flatten/4.4.0: - resolution: {integrity: sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=} + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: false /lodash.includes/4.3.0: - resolution: {integrity: sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=} + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} dev: false /lodash.isarguments/3.1.0: - resolution: {integrity: sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=} + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} dev: false /lodash.isboolean/3.0.3: - resolution: {integrity: sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=} + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} dev: false /lodash.isinteger/4.0.4: - resolution: {integrity: sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=} + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} dev: false /lodash.isnumber/3.0.3: - resolution: {integrity: sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=} + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} dev: false /lodash.isplainobject/4.0.6: - resolution: {integrity: sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=} + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} dev: false /lodash.isstring/4.0.1: - resolution: {integrity: sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=} + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} dev: false /lodash.once/4.1.1: - resolution: {integrity: sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=} + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} dev: false /lodash/4.17.21: @@ -1701,8 +1701,8 @@ packages: /minimist/1.2.5: resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} - /minipass/3.1.6: - resolution: {integrity: sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==} + /minipass/3.3.4: + resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} engines: {node: '>=8'} dependencies: yallist: 4.0.0 @@ -1712,7 +1712,7 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 yallist: 4.0.0 dev: false @@ -1766,12 +1766,12 @@ packages: whatwg-url: 5.0.0 dev: false - /node-fetch/3.2.3: - resolution: {integrity: sha512-AXP18u4pidSZ1xYXRDPY/8jdv3RAozIt/WLNR/MBGZAz+xjtlr90RvCnsvHQRiXyWliZF/CpytExp32UU67/SA==} + /node-fetch/3.2.6: + resolution: {integrity: sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: data-uri-to-buffer: 4.0.0 - fetch-blob: 3.1.5 + fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 dev: false @@ -1809,7 +1809,7 @@ packages: dev: false /object-assign/4.1.1: - resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} dev: false @@ -1960,7 +1960,7 @@ packages: dev: false /postgres-bytea/1.0.0: - resolution: {integrity: sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=} + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} engines: {node: '>=0.10.0'} dev: false @@ -2143,12 +2143,12 @@ packages: dev: false /redis-errors/1.2.0: - resolution: {integrity: sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=} + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} engines: {node: '>=4'} dev: false /redis-parser/3.0.0: - resolution: {integrity: sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=} + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} dependencies: redis-errors: 1.2.0 @@ -2244,7 +2244,7 @@ packages: lru-cache: 6.0.0 /set-blocking/2.0.0: - resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=} + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: false /shelljs/0.8.5: @@ -2288,15 +2288,15 @@ packages: engines: {node: '>= 10.x'} dev: false - /ssh2/1.8.0: - resolution: {integrity: sha512-NVIRkIwJvWl+mcRozp+EBzHMVCcbDKBea64ToPdZEk43yAVGwmfqYZRPFRnnvGjsKC34wYCmiupTcKgCVNVNNg==} + /ssh2/1.11.0: + resolution: {integrity: sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==} engines: {node: '>=10.16.0'} requiresBuild: true dependencies: asn1: 0.2.6 bcrypt-pbkdf: 1.0.2 optionalDependencies: - cpu-features: 0.0.3 + cpu-features: 0.0.4 nan: 2.16.0 dev: false @@ -2372,7 +2372,7 @@ packages: dependencies: chownr: 2.0.0 fs-minipass: 2.1.0 - minipass: 3.1.6 + minipass: 3.3.4 minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 @@ -2429,7 +2429,7 @@ packages: os-tmpdir: 1.0.2 /to-fast-properties/2.0.0: - resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} dev: false @@ -2449,13 +2449,13 @@ packages: dev: false /tr46/0.0.3: - resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=} + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false /ts-expose-internals/4.5.4: resolution: {integrity: sha512-HobejGI9ZnpRlyA0nlpIBpLG8A/gv+pDXP3L0OTRTqkJiInz3+yoMnRCaxw343pzQtxCYM0J/gpZ4IkLudrOWw==} - /ts-node/10.7.0_b34c2d00f7bffffd3f771e5188a8c9e6: + /ts-node/10.7.0_2c83ab3fa4a45acf1e79be32ccb30210: resolution: {integrity: sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==} hasBin: true peerDependencies: @@ -2474,7 +2474,7 @@ packages: '@tsconfig/node12': 1.0.9 '@tsconfig/node14': 1.0.1 '@tsconfig/node16': 1.0.2 - '@types/node': 14.18.12 + '@types/node': 14.18.21 acorn: 8.7.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -2607,7 +2607,7 @@ packages: typescript: 4.5.4 /tweetnacl/0.14.5: - resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=} + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} dev: false /type-fest/0.10.0: @@ -2696,8 +2696,8 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - /uglify-js/3.16.1: - resolution: {integrity: sha512-X5BGTIDH8U6IQ1TIRP62YC36k+ULAa1d59BxlWvPUJ1NkW5L3FwcGfEzuVvGmhJFBu0YJ5Ge25tmRISqCmLiRQ==} + /uglify-js/3.16.2: + resolution: {integrity: sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg==} engines: {node: '>=0.8.0'} hasBin: true requiresBuild: true @@ -2728,7 +2728,7 @@ packages: resolution: {integrity: sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==} /void-elements/3.1.0: - resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} dev: false @@ -2745,17 +2745,17 @@ packages: dependencies: defaults: 1.0.3 - /web-streams-polyfill/3.2.0: - resolution: {integrity: sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==} + /web-streams-polyfill/3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} dev: false /webidl-conversions/3.0.1: - resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=} + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false /whatwg-url/5.0.0: - resolution: {integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0=} + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 @@ -2783,14 +2783,14 @@ packages: resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} engines: {node: '>= 10.0.0'} dependencies: - '@babel/parser': 7.17.8 - '@babel/types': 7.17.0 + '@babel/parser': 7.18.8 + '@babel/types': 7.18.8 assert-never: 1.2.1 babel-walk: 3.0.0-canary-5 dev: false /wordwrap/1.0.0: - resolution: {integrity: sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=} + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: false /wrap-ansi/6.2.0: diff --git a/src/app/cobalt.ts b/src/app/cobalt.ts index b456a1b..0df6a11 100644 --- a/src/app/cobalt.ts +++ b/src/app/cobalt.ts @@ -2,11 +2,13 @@ export enum FieldType { text = 'text', textarea = 'textarea', + html = 'html', email = 'email', number = 'number', integer = 'integer', date = 'date', select = 'select', + bool = 'bool', } enum ResourceAction { @@ -41,6 +43,10 @@ export type FieldBase = { readonly?: boolean, helpText?: string, placeholder?: string, + hideOn?: { + form?: boolean, + listing?: boolean, + }, } export type SelectOptions = {display: string, value: any}[] diff --git a/src/app/configs/cobalt.config.ts b/src/app/configs/cobalt.config.ts index cd5032f..c581724 100644 --- a/src/app/configs/cobalt.config.ts +++ b/src/app/configs/cobalt.config.ts @@ -1,4 +1,4 @@ -import {allResourceActions, FieldType, Renderer, ResourceConfiguration} from '../cobalt' +import {allResourceActions, FieldType, Renderer, ResourceAction, ResourceConfiguration} from '../cobalt' export default { resources: [ @@ -22,7 +22,7 @@ export default { { key: 'description', display: 'Description', - type: FieldType.textarea, + type: FieldType.html, required: true, renderer: Renderer.html, }, @@ -43,5 +43,178 @@ export default { } ], }, + { + key: 'snippet', + primaryKey: 'snippet_id', + collection: 'snippets', + display: { + field: 'slug', + singular: 'Snippet', + plural: 'Snippets', + }, + supportedActions: allResourceActions, + fields: [ + { + key: 'slug', + display: 'Slug', + type: FieldType.text, + required: true, + sort: 'asc', + }, + { + key: 'syntax', + display: 'Syntax', + type: FieldType.text, + required: true, + }, + { + key: 'users_only', + display: 'Users only?', + type: FieldType.bool, + required: true, + renderer: Renderer.bool, + }, + { + key: 'single_access_only', + display: 'Single-access only?', + type: FieldType.bool, + required: true, + renderer: Renderer.bool, + }, + { + key: 'access_key', + display: 'Access key', + type: FieldType.text, + required: false, + hideOn: { + listing: true, + }, + }, + { + key: 'body', + display: 'Content', + type: FieldType.textarea, + required: true, + hideOn: { + listing: true, + }, + }, + ], + }, + { + key: 'contactSubmission', + primaryKey: 'contact_submission_id', + collection: 'contact_submissions', + display: { + field: 'name', + singular: 'Contact Submission', + plural: 'Contact Submissions', + }, + supportedActions: [ + ResourceAction.read, ResourceAction.readOne, ResourceAction.delete, + ], + fields: [ + { + key: 'name', + display: 'Name', + type: FieldType.text, + required: true, + }, + { + key: 'email', + display: 'E-Mail Address', + type: FieldType.text, + required: true, + }, + { + key: 'message', + display: 'Message', + type: FieldType.textarea, + required: true, + }, + { + key: 'sent_at', + display: 'Sent At', + type: FieldType.date, + renderer: FieldType.date, + required: false, + sort: 'desc', + }, + ], + }, + { + key: 'goLink', + primaryKey: 'go_link_id', + collection: 'go_links', + display: { + field: 'short', + singular: 'Go Link', + plural: 'Go Links', + }, + supportedActions: allResourceActions, + fields: [ + { + key: 'short', + display: 'Slug', + type: FieldType.text, + required: true, + sort: 'asc', + }, + { + key: 'url', + display: 'URL', + type: FieldType.text, + required: true, + }, + { + key: 'active', + display: 'Active?', + type: FieldType.bool, + renderer: Renderer.bool, + required: true, + }, + ], + }, + { + key: 'feedPost', + primaryKey: 'feed_post_id', + collection: 'feed_posts', + display: { + // field: '', + singular: 'Feed Post', + plural: 'Feed Posts', + }, + supportedActions: allResourceActions, + fields: [ + { + key: 'posted_at', + display: 'Posted At', + type: FieldType.date, + sort: 'desc', + required: false, + renderer: Renderer.date, + }, + { + key: 'tag', + display: 'Tag', + type: FieldType.text, + required: true, + }, + { + key: 'body', + display: 'Body', + type: FieldType.html, + renderer: Renderer.html, + required: true, + }, + { + key: 'visible', + display: 'Visible?', + type: FieldType.bool, + renderer: Renderer.bool, + required: false, + }, + ], + } ] as ResourceConfiguration[], } diff --git a/src/app/http/controllers/cobalt/Interface.controller.ts b/src/app/http/controllers/cobalt/Interface.controller.ts index 92bf747..b0fb3ae 100644 --- a/src/app/http/controllers/cobalt/Interface.controller.ts +++ b/src/app/http/controllers/cobalt/Interface.controller.ts @@ -38,6 +38,15 @@ export class Interface extends Controller { }) } + public viewForm(key: string, id: number|string) { + this.getResourceConfigOrFail(key) + return view('dash:form', { + resourcekey: key, + resourceid: id, + resourcemode: 'view', + }) + } + public insertForm(key: string) { this.getResourceConfigOrFail(key) return view('dash:form', { diff --git a/src/app/http/controllers/cobalt/ResourceAPI.controller.ts b/src/app/http/controllers/cobalt/ResourceAPI.controller.ts index 52d9c57..8e92f07 100644 --- a/src/app/http/controllers/cobalt/ResourceAPI.controller.ts +++ b/src/app/http/controllers/cobalt/ResourceAPI.controller.ts @@ -151,7 +151,7 @@ export class ResourceAPI extends Controller { private castValue(fieldDef: FieldDefinition, value: any): any { const { type, key, required } = fieldDef - if ( type === FieldType.text || type === FieldType.textarea ) { + if ( type === FieldType.text || type === FieldType.textarea || type === FieldType.html ) { const cast = String(value || '') if ( required && !cast ) { throw new HTTPError(HTTPStatus.BAD_REQUEST, `Missing required field: ${key}`) @@ -205,6 +205,8 @@ export class ResourceAPI extends Controller { if ( required ) { throw new HTTPError(HTTPStatus.BAD_REQUEST, `Invalid or missing value for select: ${key}`) } + } else if ( type === FieldType.bool ) { + return !!value } } diff --git a/src/app/http/routes/dash.routes.ts b/src/app/http/routes/dash.routes.ts index 33c461f..bcab1c0 100644 --- a/src/app/http/routes/dash.routes.ts +++ b/src/app/http/routes/dash.routes.ts @@ -16,26 +16,6 @@ Route .alias('@dash') .calls(Dash, dash => dash.main) - Route.get('/work-items') - .alias('@dash:work-items') - .handledBy(() => 'nope') - - Route.get('/feed') - .alias('@dash:feed') - .handledBy(() => 'nope') - - Route.get('/links') - .alias('@dash:links') - .handledBy(() => 'nope') - - Route.get('/snippets') - .alias('@dash:snippets') - .handledBy(() => 'nope') - - Route.get('/contact') - .alias('@dash:contact') - .handledBy(() => 'nope') - Route.group('/cobalt/resource', () => { Route.get('/:key/configure') .parameterMiddleware(parseKey) @@ -79,6 +59,11 @@ Route .parameterMiddleware(parseKey) .parameterMiddleware(parseId) .calls(Interface, (i: Interface) => i.updateForm) + + Route.get('/cobalt/form/:key/:id/view') + .parameterMiddleware(parseKey) + .parameterMiddleware(parseId) + .calls(Interface, (i: Interface) => i.viewForm) }) .pre(SessionAuthMiddleware) .pre(AuthRequiredMiddleware) diff --git a/src/app/resources/assets/cobalt/component/Form.component.js b/src/app/resources/assets/cobalt/component/Form.component.js index bd571bc..5109285 100644 --- a/src/app/resources/assets/cobalt/component/Form.component.js +++ b/src/app/resources/assets/cobalt/component/Form.component.js @@ -12,6 +12,17 @@ const template = `
Loading...
+ + +
{ + return !(f.hideOn && f.hideOn.form) + }) this.fields.forEach(field => { if ( field.type === 'date' && this.data[field.key] ) { @@ -165,6 +188,12 @@ export class FormComponent extends Component { this.statusMessage = '' } + onMonacoChange(field, data, args) { + console.log('on monaco change', {field, data, args}) + this.data[field.key] = args[0] + console.log('after save', this.data) + } + async save() { if ( !this.validate() ) return; @@ -173,29 +202,35 @@ export class FormComponent extends Component { const values = {} this.fields.forEach(field => { let value = this.data[field.key] - const isUndef = !value && !(['integer', 'number'].includes(field.type) && value === 0) + const isUndef = !value && !(['integer', 'number'].includes(field.type) && value === 0) && (field.type !== 'bool') if ( isUndef ) return; if ( field.type === 'number' ) value = parseFloat(String(value)) if ( field.type === 'integer' ) value = parseInt(String(value), 10) if ( field.type === 'date' ) value = value.toISOString() + if ( field.type === 'bool' ) value = !!value values[field.key] = value }) - if ( this.internalResourceId ) { - await this.resource.update(this.internalResourceId, values) - } else { - const result = await this.resource.create(values) - this.internalResourceId = result[this.resource.configuration.primaryKey] - history.replaceState({}, document.getElementsByTagName('title')[0].innerText, `${location.protocol}//${location.host}/dash/cobalt/form/${this.resource.key}/${this.internalResourceId}`) - } + try { + if (this.internalResourceId) { + await this.resource.update(this.internalResourceId, values) + } else { + const result = await this.resource.create(values) + this.internalResourceId = result[this.resource.configuration.primaryKey] + history.replaceState({}, document.getElementsByTagName('title')[0].innerText, `${location.protocol}//${location.host}/dash/cobalt/form/${this.resource.key}/${this.internalResourceId}`) + } - await this.load() + await this.load() - this.statusMessage = `${this.resource.singular()} ${this.mode === 'insert' ? 'created' : 'saved'}` - this.mode = 'edit' - setTimeout(() => this.statusMessage = '', 7000) + this.statusMessage = `${this.resource.singular()} ${this.mode === 'insert' ? 'created' : 'saved'}` + this.mode = 'edit' + setTimeout(() => this.statusMessage = '', 7000) + } catch (e) { + console.error(e) + this.statusMessage = 'An unknown error occurred while saving' + } } validate() { @@ -206,7 +241,7 @@ export class FormComponent extends Component { // FIXME select const value = this.data[field.key] - const isUndef = !value && !(['integer', 'number'].includes(field.type) && value === 0) + const isUndef = !value && !(['integer', 'number'].includes(field.type) && value === 0) && (field.type !== 'bool') if ( field.required && isUndef ) { this.errors[field.key] = 'This field is required' pass = false diff --git a/src/app/resources/assets/cobalt/component/Listing.component.js b/src/app/resources/assets/cobalt/component/Listing.component.js index 1f95c97..f99327f 100644 --- a/src/app/resources/assets/cobalt/component/Listing.component.js +++ b/src/app/resources/assets/cobalt/component/Listing.component.js @@ -92,7 +92,9 @@ export class ListingComponent extends Component { } async load(reload = false) { - this.columns = [...this.resource.configuration.fields] + this.columns = [...this.resource.configuration.fields].filter(col => { + return !(col.hideOn && col.hideOn.listing) + }) if ( !reload && this.resource.supports(ResourceActions.create) ) { this.actions.push({ @@ -117,6 +119,16 @@ export class ListingComponent extends Component { action: 'update', defer: true, }) + } else if ( !reload && this.resource.supports(ResourceActions.read) ) { + this.actions.push({ + title: 'View', + color: 'primary', + icon: 'fa-eye', + type: 'resource', + resource: this.resource.key, + action: 'view', + defer: true, + }) } if ( !reload && this.resource.supports(ResourceActions.delete) ) { diff --git a/src/app/resources/assets/cobalt/component/Monaco.component.js b/src/app/resources/assets/cobalt/component/Monaco.component.js new file mode 100644 index 0000000..024131e --- /dev/null +++ b/src/app/resources/assets/cobalt/component/Monaco.component.js @@ -0,0 +1,35 @@ +import {Component} from '../../vues6.js' +import {uuid} from '../util.js' + +const template = ` +
+
+` +export class MonacoComponent extends Component { + static get template() { return template } + static get selector() { return 'cobalt-monaco' } + static get props() { return ['initialvalue', 'syntax'] } + + constructor() { + super() + this.id = 'monaco-' + uuid() + this.value = '' + } + + vue_on_create() { + this.value = this.initialvalue + this.$nextTick(() => { + this.el = document.querySelector(`#${this.id}`) + this.editor = monaco.editor.create(this.el, { + theme: 'vs-dark', + value: this.value, + language: this.syntax, + }) + + this.editor.onDidChangeModelContent(e => { + this.value = this.editor.getValue() + this.$emit('changed', this.value) + }) + }) + } +} diff --git a/src/app/resources/assets/cobalt/components.js b/src/app/resources/assets/cobalt/components.js index b30673d..b4ac8bc 100644 --- a/src/app/resources/assets/cobalt/components.js +++ b/src/app/resources/assets/cobalt/components.js @@ -2,12 +2,14 @@ import {MessageContainerComponent} from './component/MessageContainer.component. import {ListingComponent} from './component/Listing.component.js' import {FormComponent} from './component/Form.component.js' import {ActionButtonComponent} from './component/ActionButton.component.js' +import {MonacoComponent} from './component/Monaco.component.js' const components = { MessageContainerComponent, ListingComponent, ActionButtonComponent, FormComponent, + MonacoComponent, } export { components } diff --git a/src/app/resources/assets/cobalt/service/Action.service.js b/src/app/resources/assets/cobalt/service/Action.service.js index 51a5b5d..88c08ab 100644 --- a/src/app/resources/assets/cobalt/service/Action.service.js +++ b/src/app/resources/assets/cobalt/service/Action.service.js @@ -21,6 +21,7 @@ export class ActionService { if ( action.action === 'insert' ) this.launchResourceForm(action.resource) if ( action.action === 'update' ) this.launchResourceForm(action.resource, data[resource.configuration.primaryKey]) if ( action.action === 'list' ) this.launchResourceListing(action.resource) + if ( action.action === 'view' ) this.launchResourceForm(action.resource, data[resource.configuration.primaryKey], true) if ( action.action === 'delete' ) { await Message.get() .modal({ @@ -55,8 +56,8 @@ export class ActionService { location.assign(Session.get().url(`dash/cobalt/listing/${key}`)) } - launchResourceForm(key, id) { - location.assign(Session.get().url(`dash/cobalt/form/${key}${id ? '/' + id : ''}`)) + launchResourceForm(key, id, view = false) { + location.assign(Session.get().url(`dash/cobalt/form/${key}${id ? '/' + id : ''}${view ? '/view' : ''}`)) } goBack() { diff --git a/src/app/resources/views/dash/template.pug b/src/app/resources/views/dash/template.pug index b5ed42a..3321f60 100644 --- a/src/app/resources/views/dash/template.pug +++ b/src/app/resources/views/dash/template.pug @@ -13,6 +13,7 @@ head link(href=asset('dash/vendor/fontawesome-free/css/all.min.css') rel='stylesheet' type='text/css') link(href=asset('dash/vendor/datatables2/dataTables.bootstrap4.min.css')) link(rel='stylesheet' href='https://unpkg.com/vue2-datepicker@latest/index.css') + link(rel='stylesheet' data-name='vs/editor/editor.main' href=asset('monaco/package/min/vs/editor/editor.main.css')) #wrapper ul#accordionSidebar.navbar-nav.bg-gradient-primary.sidebar.sidebar-dark.accordion a.sidebar-brand.d-flex.align-items-center.justify-content-center(href='index.html') @@ -40,7 +41,7 @@ head hr.sidebar-divider .sidebar-heading Analytics li.nav-item - a.nav-link(href=named('@dash:contact')) + a.nav-link(href=route('dash/cobalt/listing/contactSubmission')) i.fas.fa-fw.fa-comment-alt span Contact Form #content-wrapper.d-flex.flex-column @@ -135,6 +136,11 @@ block scripts script(src=asset('dash/vendor/datatables2/jquery.dataTables.min.js')) script(src=asset('dash/vendor/datatables2/dataTables.bootstrap4.min.js')) script(src='https://unpkg.com/vue2-datepicker@latest') + script. + var require = { paths: { vs: "#{asset('monaco/package/min/vs')}" }} + script(src=asset('monaco/package/min/vs/loader.js')) + script(src=asset('monaco/package/min/vs/editor/editor.main.nls.js')) + script(src=asset('monaco/package/min/vs/editor/editor.main.js')) script(type='module'). import { Session } from "#{asset('cobalt/service/Session.service.js')}" import { EventBus } from "#{asset('cobalt/service/EventBus.service.js')}"