From e926ad1b578d1c5b98d0928426eb814e27e32afd Mon Sep 17 00:00:00 2001 From: River Holstege Date: Wed, 25 Oct 2023 14:43:09 -0700 Subject: [PATCH 01/11] arcgis package --- Harvest.Web/ClientApp/package-lock.json | 212 +++++++++++++++++++++++- Harvest.Web/ClientApp/package.json | 1 + 2 files changed, 210 insertions(+), 3 deletions(-) diff --git a/Harvest.Web/ClientApp/package-lock.json b/Harvest.Web/ClientApp/package-lock.json index df6ab852a..30ee69c84 100644 --- a/Harvest.Web/ClientApp/package-lock.json +++ b/Harvest.Web/ClientApp/package-lock.json @@ -8,6 +8,7 @@ "name": "harvest.web", "version": "0.1.0", "dependencies": { + "@arcgis/core": "^4.28.1", "@azure/storage-blob": "^12.14.0", "@david.kucsai/react-pdf-table": "^0.4.1", "@fortawesome/fontawesome-svg-core": "^1.2.36", @@ -106,6 +107,21 @@ "ajv": ">=8" } }, + "node_modules/@arcgis/core": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@arcgis/core/-/core-4.28.1.tgz", + "integrity": "sha512-Pcaa0cZz/vwtFcGwUkZSfH92KHRb3vNJDz7czPjRnq19RncitxgIw0McPkgrJzDUeqGuAqpJR8qR+ERmM/ON8Q==", + "dependencies": { + "@esri/arcgis-html-sanitizer": "~3.0.1", + "@esri/calcite-colors": "~6.1.0", + "@esri/calcite-components": "^1.9.2", + "@popperjs/core": "~2.11.8", + "@zip.js/zip.js": "~2.7.29", + "focus-trap": "~7.5.3", + "luxon": "~3.4.3", + "sortablejs": "~1.15.0" + } + }, "node_modules/@azure/abort-controller": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.4.tgz", @@ -2683,6 +2699,67 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@esri/arcgis-html-sanitizer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@esri/arcgis-html-sanitizer/-/arcgis-html-sanitizer-3.0.1.tgz", + "integrity": "sha512-cwZJwsYCJZwtBQU2AmaiIVFg5nZcVwInPYja1/OgC9iKYO+ytZRoc5h+0S9/ygbFNoS8Nd0RX9A85stLX/BgiA==", + "dependencies": { + "xss": "1.0.13" + } + }, + "node_modules/@esri/calcite-colors": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@esri/calcite-colors/-/calcite-colors-6.1.0.tgz", + "integrity": "sha512-wHQYWFtDa6c328EraXEVZvgOiaQyYr0yuaaZ0G3cB4C3lSkWefW34L/e5TLAhtuG3zJ/wR6pl5X1YYNfBc0/4Q==" + }, + "node_modules/@esri/calcite-components": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@esri/calcite-components/-/calcite-components-1.9.2.tgz", + "integrity": "sha512-nzur8vPVRsju+9ELFjun/HKLMQxrQiDLOhmDtfkizmK9SxZ29djI5UPuyAQim2PsgHslo2dHP0FVdaPyOK5vLA==", + "dependencies": { + "@floating-ui/dom": "1.5.3", + "@stencil/core": "2.22.3", + "@types/color": "3.0.4", + "color": "4.2.3", + "composed-offset-position": "0.0.4", + "dayjs": "1.11.10", + "focus-trap": "7.5.2", + "form-request-submit-polyfill": "2.0.0", + "lodash-es": "4.17.21", + "sortablejs": "1.15.0", + "timezone-groups": "0.8.0" + } + }, + "node_modules/@esri/calcite-components/node_modules/focus-trap": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz", + "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==", + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "0.2.36", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", @@ -3398,9 +3475,9 @@ } }, "node_modules/@popperjs/core": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz", - "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -3719,6 +3796,18 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@stencil/core": { + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.22.3.tgz", + "integrity": "sha512-kmVA0M/HojwsfkeHsifvHVIYe4l5tin7J5+DLgtl8h6WWfiMClND5K3ifCXXI2ETDNKiEk21p6jql3Fx9o2rng==", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=12.10.0", + "npm": ">=6.0.0" + } + }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -4105,6 +4194,27 @@ "@types/node": "*" } }, + "node_modules/@types/color": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.4.tgz", + "integrity": "sha512-OpisS4bqJJwbkkQRrMvURf3DOxBoAg9mysHYI7WgrWpSYHqHGKYBULHdz4ih77SILcLDo/zyHGFyfIl9yb8NZQ==", + "dependencies": { + "@types/color-convert": "*" + } + }, + "node_modules/@types/color-convert": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.2.tgz", + "integrity": "sha512-KGRIgCxwcgazts4MXRCikPbIMzBpjfdgEZSy8TRHU/gtg+f9sOfHdtK8unPfxIoBtyd2aTTwINVLSNENlC8U8A==", + "dependencies": { + "@types/color-name": "*" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.2.tgz", + "integrity": "sha512-JWO/ZyxTKk0bLuOhAavGjnwLR73rUE7qzACnU7gMeyA/gdrSHm2xJwqNPipw2MtaZUaqQ2UG/q7pP6AQiZ8mqw==" + }, "node_modules/@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -4942,6 +5052,16 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "node_modules/@zip.js/zip.js": { + "version": "2.7.30", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.30.tgz", + "integrity": "sha512-nhMvQCj+TF1ATBqYzFds7v+yxPBhdDYHh8J341KtC1D2UrVBUIYcYK4Jy1/GiTsxOXEiKOXSUxvPG/XR+7jMqw==", + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=16.5.0" + } + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -6206,6 +6326,18 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6278,6 +6410,11 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, + "node_modules/composed-offset-position": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/composed-offset-position/-/composed-offset-position-0.0.4.tgz", + "integrity": "sha512-vMlvu1RuNegVE0YsCDSV/X4X10j56mq7PCIyOKK74FxkXzGLwhOUmdkJLSdOBOMwWycobGUMgft2lp+YgTe8hw==" + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -6769,6 +6906,11 @@ "node": ">=4" } }, + "node_modules/cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" + }, "node_modules/cssfontparser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", @@ -6940,6 +7082,11 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -8635,6 +8782,14 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "dependencies": { + "tabbable": "^6.2.0" + } + }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -8806,6 +8961,11 @@ "node": ">= 6" } }, + "node_modules/form-request-submit-polyfill": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/form-request-submit-polyfill/-/form-request-submit-polyfill-2.0.0.tgz", + "integrity": "sha512-p0+M92y2gFnP0AuuL8VJ0GYVzAT0bYp3GsSkmPFhvUopdnfDLP/9xplQTBBc4w8qOjKRzdK7GaFcdL9IhlXdTQ==" + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -11809,6 +11969,14 @@ "yallist": "^3.0.2" } }, + "node_modules/luxon": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.3.tgz", + "integrity": "sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==", + "engines": { + "node": ">=12" + } + }, "node_modules/lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", @@ -15718,6 +15886,11 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sortablejs": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", + "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" + }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -16263,6 +16436,11 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/tailwindcss": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz", @@ -16488,6 +16666,14 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "node_modules/timezone-groups": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/timezone-groups/-/timezone-groups-0.8.0.tgz", + "integrity": "sha512-t7E/9sPfCU0m0ZbS7Cqw52D6CB/UyeaiIBmyJCokI1SyOyOgA/ESiQ/fbreeFaUG9QSenGlZSSk/7rEbkipbOA==", + "bin": { + "timezone-groups": "dist/cli.cjs" + } + }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", @@ -17864,6 +18050,26 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "node_modules/xss": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.13.tgz", + "integrity": "sha512-clu7dxTm1e8Mo5fz3n/oW3UCXBfV89xZ72jM8yzo1vR/pIS0w3sgB3XV2H8Vm6zfGnHL0FzvLJPJEBhd86/z4Q==", + "dependencies": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "bin": { + "xss": "bin/xss" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/xss/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/Harvest.Web/ClientApp/package.json b/Harvest.Web/ClientApp/package.json index 0444ac77c..6519ff71f 100644 --- a/Harvest.Web/ClientApp/package.json +++ b/Harvest.Web/ClientApp/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@arcgis/core": "^4.28.1", "@azure/storage-blob": "^12.14.0", "@david.kucsai/react-pdf-table": "^0.4.1", "@fortawesome/fontawesome-svg-core": "^1.2.36", From 95f7d73da222ccb5b386ff714bdd00edb9467258 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Tue, 31 Oct 2023 15:39:18 -0700 Subject: [PATCH 02/11] css for arcgis js map --- Harvest.Web/ClientApp/src/App.tsx | 5 +- Harvest.Web/ClientApp/src/Maps/Map.tsx | 100 ++++++++++-------- .../ClientApp/src/Quotes/QuoteContainer.tsx | 14 +-- Harvest.Web/ClientApp/src/sass/harvest.scss | 25 ++++- 4 files changed, 90 insertions(+), 54 deletions(-) diff --git a/Harvest.Web/ClientApp/src/App.tsx b/Harvest.Web/ClientApp/src/App.tsx index 7bf35b57d..d1bd53899 100644 --- a/Harvest.Web/ClientApp/src/App.tsx +++ b/Harvest.Web/ClientApp/src/App.tsx @@ -40,7 +40,10 @@ function App() { -
+
{/* Match any server-side routes and send empty content to let MVC return the view details */} { - return ( -
- - - - - - - - A pretty CSS3 popup.
Easily customizable. -
-
-
-
- ); + console.log("Map.tsx"); + const mapDiv = useRef(null); + + useEffect(() => { + if (mapDiv.current) { + /** + * Initialize application + */ + // https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html + const webmap = new WebMap({ + portalItem: { + // the unique id for your map + // you can access this by going to arcgis -> content -> my content -> map and copy the id on the right (or from url) + id: "aa1d3f80270146208328cf66d022e09c", + }, + }); + + const view = new MapView({ + container: mapDiv.current, + map: webmap, + }); + + const bookmarks = new Bookmarks({ + view, + // allows bookmarks to be added, edited, or deleted + editingEnabled: true, + }); + + const bkExpand = new Expand({ + view, + content: bookmarks, + expanded: true, + }); + + // Add the widget to the top-right corner of the view + view.ui.add(bkExpand, "top-right"); + + // bonus - how many bookmarks in the webmap? + webmap.when(() => { + if (webmap.bookmarks && webmap.bookmarks.length) { + console.log("Bookmarks: ", webmap.bookmarks.length); + } else { + console.log("No bookmarks in this webmap."); + } + }); + } + }, [mapDiv]); + + return
; }; diff --git a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx index 82fca4f2c..e4eb8b593 100644 --- a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx +++ b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx @@ -16,6 +16,7 @@ import { ProjectDetail } from "./ProjectDetail"; import { ProjectHeader } from "../Shared/ProjectHeader"; import { ActivitiesContainer } from "./ActivitiesContainer"; import { QuoteTotals } from "./QuoteTotals"; +import { Map } from "../Maps/Map"; import { authenticatedFetch } from "../Util/Api"; import { usePromiseNotification } from "../Util/Notifications"; @@ -236,14 +237,14 @@ export const QuoteContainer = () => { // TODO: we might want to move this all into a separate component if (editFields) { return ( -
-
+
+
-
+
@@ -274,14 +275,15 @@ export const QuoteContainer = () => {
-
- + {/* setQuote({ ...quote, fields })} - > + > */} +
); diff --git a/Harvest.Web/ClientApp/src/sass/harvest.scss b/Harvest.Web/ClientApp/src/sass/harvest.scss index 2f66f692c..c30316780 100644 --- a/Harvest.Web/ClientApp/src/sass/harvest.scss +++ b/Harvest.Web/ClientApp/src/sass/harvest.scss @@ -2,7 +2,28 @@ @charset "utf-8"; @import "import", "typography", "layout", "regions", "components"; +@import "https://js.arcgis.com/4.28/@arcgis/core/assets/esri/themes/light/main.css"; -.searchPersonsClearButton > button{ - margin: -1.3em .5em 0em 0em; +.searchPersonsClearButton > button { + margin: -1.3em 0.5em 0em 0em; +} + +// map css +.mapDiv { + padding: 0; + margin: 0; + height: 100%; + width: 100%; + // position: absolute; +} + +// add to all parent divs of the map +.fullHeightWidth { + height: 100%; + width: 100%; +} + +// highest level div +#root { + height: 100%; } From 8fd1943b07893e7cd9d9c81fb1d7372b6ef97a5b Mon Sep 17 00:00:00 2001 From: River Holstege Date: Thu, 2 Nov 2023 12:21:07 -0700 Subject: [PATCH 03/11] add feature layer, basemap toggle, editor --- Harvest.Web/ClientApp/src/Maps/Map.tsx | 51 ++++++++++++++++++++------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/Harvest.Web/ClientApp/src/Maps/Map.tsx b/Harvest.Web/ClientApp/src/Maps/Map.tsx index e7fd18985..a561bb577 100644 --- a/Harvest.Web/ClientApp/src/Maps/Map.tsx +++ b/Harvest.Web/ClientApp/src/Maps/Map.tsx @@ -3,6 +3,9 @@ import WebMap from "@arcgis/core/WebMap"; import Bookmarks from "@arcgis/core/widgets/Bookmarks"; import Expand from "@arcgis/core/widgets/Expand"; import MapView from "@arcgis/core/views/MapView"; +import Editor from "@arcgis/core/widgets/Editor"; +import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; +import BasemapToggle from "@arcgis/core/widgets/BasemapToggle"; // from: https://github.com/Esri/jsapi-resources/blob/main/esm-samples/jsapi-react/src/App.jsx export const Map = () => { @@ -19,29 +22,53 @@ export const Map = () => { portalItem: { // the unique id for your map // you can access this by going to arcgis -> content -> my content -> map and copy the id on the right (or from url) - id: "aa1d3f80270146208328cf66d022e09c", + id: "8e276b0a2b6b49b88a1ea459d91f5fd3", }, + basemap: "hybrid", // https://developers.arcgis.com/rest/basemap-styles/#arcgis-styles }); const view = new MapView({ container: mapDiv.current, map: webmap, + center: [-121.748, 38.54], + zoom: 13, }); - const bookmarks = new Bookmarks({ - view, - // allows bookmarks to be added, edited, or deleted - editingEnabled: true, - }); + // const bookmarks = new Bookmarks({ + // view, + // // allows bookmarks to be added, edited, or deleted + // editingEnabled: true, + // }); + + // const bkExpand = new Expand({ + // view, + // content: bookmarks, + // expanded: true, + // }); + // Add the widget to the top-right corner of the view + // view.ui.add(bkExpand, "top-right"); - const bkExpand = new Expand({ - view, - content: bookmarks, - expanded: true, + const featureLayer = new FeatureLayer({ + portalItem: { + id: "66289d4facfb4932a5b1d91db8792c4f", + }, }); + webmap.add(featureLayer); - // Add the widget to the top-right corner of the view - view.ui.add(bkExpand, "top-right"); + // Begin Editor constructor + const editor = new Editor({ + view: view, + }); // End Editor constructor + + // Add the widget to the view + view.ui.add(editor, "top-right"); + + // https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-BasemapToggle.html + let basemapToggle = new BasemapToggle({ + view: view, // The view that provides access to the map's "streets-vector" basemap + nextBasemap: "osm", // Allows for toggling to the "osm" basemap + }); + view.ui.add(basemapToggle, "top-left"); // bonus - how many bookmarks in the webmap? webmap.when(() => { From 7f8e0c094da76811dba0ed9ae46eb4954a32086d Mon Sep 17 00:00:00 2001 From: River Holstege Date: Tue, 7 Nov 2023 15:18:37 -0800 Subject: [PATCH 04/11] flesh out editing more --- .../src/Maps/{Map.tsx => MapEditWidget.tsx} | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) rename Harvest.Web/ClientApp/src/Maps/{Map.tsx => MapEditWidget.tsx} (61%) diff --git a/Harvest.Web/ClientApp/src/Maps/Map.tsx b/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx similarity index 61% rename from Harvest.Web/ClientApp/src/Maps/Map.tsx rename to Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx index a561bb577..8eaf88081 100644 --- a/Harvest.Web/ClientApp/src/Maps/Map.tsx +++ b/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx @@ -4,11 +4,14 @@ import Bookmarks from "@arcgis/core/widgets/Bookmarks"; import Expand from "@arcgis/core/widgets/Expand"; import MapView from "@arcgis/core/views/MapView"; import Editor from "@arcgis/core/widgets/Editor"; +import FieldElement from "@arcgis/core/form/elements/FieldElement.js"; +import FormTemplate from "@arcgis/core/form/FormTemplate.js"; + import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; import BasemapToggle from "@arcgis/core/widgets/BasemapToggle"; // from: https://github.com/Esri/jsapi-resources/blob/main/esm-samples/jsapi-react/src/App.jsx -export const Map = () => { +export const MapEditWidget = () => { console.log("Map.tsx"); const mapDiv = useRef(null); @@ -34,20 +37,6 @@ export const Map = () => { zoom: 13, }); - // const bookmarks = new Bookmarks({ - // view, - // // allows bookmarks to be added, edited, or deleted - // editingEnabled: true, - // }); - - // const bkExpand = new Expand({ - // view, - // content: bookmarks, - // expanded: true, - // }); - // Add the widget to the top-right corner of the view - // view.ui.add(bkExpand, "top-right"); - const featureLayer = new FeatureLayer({ portalItem: { id: "66289d4facfb4932a5b1d91db8792c4f", @@ -55,21 +44,48 @@ export const Map = () => { }); webmap.add(featureLayer); - // Begin Editor constructor - const editor = new Editor({ - view: view, - }); // End Editor constructor - - // Add the widget to the view - view.ui.add(editor, "top-right"); - // https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-BasemapToggle.html let basemapToggle = new BasemapToggle({ - view: view, // The view that provides access to the map's "streets-vector" basemap - nextBasemap: "osm", // Allows for toggling to the "osm" basemap + view: view, + nextBasemap: "osm", // Allows for toggling to the openstreetmaps (non-satellite ) }); view.ui.add(basemapToggle, "top-left"); + view.when(() => { + // when our view is loaded + const editor = new Editor({ + view: view, + label: "LABEL", + layerInfos: [ + { + layer: featureLayer, + formTemplate: new FormTemplate({ + description: "", + // expressionInfos: [], + // preserveFieldValuesWhenHidden: false, + title: "Edit Field Details", + elements: [ + new FieldElement({ + fieldName: "Name", + label: "Name", + }), + new FieldElement({ + fieldName: "Crop", + label: "Crop", + }), + new FieldElement({ + fieldName: "Details", + label: "Details", + }), + ], + }), + }, + ], + }); + + // Add the widget to the view + view.ui.add(editor, "top-right"); + }); // bonus - how many bookmarks in the webmap? webmap.when(() => { if (webmap.bookmarks && webmap.bookmarks.length) { From 96bedbb5ad2d55ffd1f51701ac0c521401a541ff Mon Sep 17 00:00:00 2001 From: River Holstege Date: Tue, 7 Nov 2023 15:18:48 -0800 Subject: [PATCH 05/11] start of sketch widget but its funky --- .../ClientApp/src/Maps/MapSketchWidget.tsx | 84 +++++++++++++++++++ .../ClientApp/src/Quotes/QuoteContainer.tsx | 6 +- 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx diff --git a/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx b/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx new file mode 100644 index 000000000..2ca8aa309 --- /dev/null +++ b/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx @@ -0,0 +1,84 @@ +import React, { useEffect, useRef, useState } from "react"; +import WebMap from "@arcgis/core/WebMap"; +import MapView from "@arcgis/core/views/MapView"; +import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; +import BasemapToggle from "@arcgis/core/widgets/BasemapToggle"; +import Sketch from "@arcgis/core/widgets/Sketch"; +import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer"; +import Graphic from "@arcgis/core/Graphic.js"; +import Collection from "@arcgis/core/core/Collection.js"; +import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js"; +import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js"; + +// from: https://github.com/Esri/jsapi-resources/blob/main/esm-samples/jsapi-react/src/App.jsx +export const MapSketchWidget = () => { + console.log("Map.tsx"); + const mapDiv = useRef(null); + + const [graphics, setGraphics] = useState>( + new Collection() + ); + + useEffect(() => { + if (mapDiv.current) { + /** + * Initialize application + */ + + // https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html + const webmap = new WebMap({ + portalItem: { + // the unique id for your map + // you can access this by going to arcgis -> content -> my content -> map and copy the id on the right (or from url) + id: "8e276b0a2b6b49b88a1ea459d91f5fd3", + }, + basemap: "hybrid", // https://developers.arcgis.com/rest/basemap-styles/#arcgis-styles + }); + + const view = new MapView({ + container: mapDiv.current, + map: webmap, + center: [-121.748, 38.54], + zoom: 13, + }); + + const featureLayer = new FeatureLayer({ + portalItem: { + id: "66289d4facfb4932a5b1d91db8792c4f", + }, + }); + webmap.add(featureLayer); + + // https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-BasemapToggle.html + let basemapToggle = new BasemapToggle({ + view: view, // The view that provides access to the map's "streets-vector" basemap + nextBasemap: "osm", // Allows for toggling to the "osm" basemap + }); + view.ui.add(basemapToggle, "top-left"); + + const graphicsLayer = new GraphicsLayer(); + const sketch = new Sketch({ + layer: graphicsLayer, + view: view, + // graphic will be selected as soon as it is created + creationMode: "update", + }); + view.ui.add(sketch, "top-right"); + + // const handle = reactiveUtils.watch( + // // getValue function + // () => graphicsLayer.graphics, + // // Callback function + // (newValue, oldValue) => { + // console.log("New value: ", newValue, "Old value: ", oldValue); + // }, + // // Optional parameters + // { + // // initial: true, + // } + // ); + } + }, [mapDiv]); + + return
; +}; diff --git a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx index e4eb8b593..2f335ee71 100644 --- a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx +++ b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx @@ -16,7 +16,8 @@ import { ProjectDetail } from "./ProjectDetail"; import { ProjectHeader } from "../Shared/ProjectHeader"; import { ActivitiesContainer } from "./ActivitiesContainer"; import { QuoteTotals } from "./QuoteTotals"; -import { Map } from "../Maps/Map"; +import { MapEditWidget } from "../Maps/MapEditWidget"; +import { MapSketchWidget } from "../Maps/MapSketchWidget"; import { authenticatedFetch } from "../Util/Api"; import { usePromiseNotification } from "../Util/Notifications"; @@ -276,7 +277,8 @@ export const QuoteContainer = () => {
- + + {/* */} {/* Date: Tue, 7 Nov 2023 15:59:00 -0800 Subject: [PATCH 06/11] casing is important :((( --- Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx b/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx index 8eaf88081..852d29ff6 100644 --- a/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx +++ b/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx @@ -39,6 +39,7 @@ export const MapEditWidget = () => { const featureLayer = new FeatureLayer({ portalItem: { + // the feature layer is not added to the map in ArcGIS Online, but is overlayed here id: "66289d4facfb4932a5b1d91db8792c4f", }, }); @@ -65,9 +66,10 @@ export const MapEditWidget = () => { // preserveFieldValuesWhenHidden: false, title: "Edit Field Details", elements: [ + // was having trouble with the autocast so this is my workaround new FieldElement({ - fieldName: "Name", - label: "Name", + fieldName: "name", // fieldName has to match the case of the field name in the feature layer + label: "Name", // you can check that at Content -> select feature layer -> Data (at top) -> fields }), new FieldElement({ fieldName: "Crop", From 104609ae58b754c53b61a57f517977983eca5684 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Wed, 8 Nov 2023 11:13:09 -0800 Subject: [PATCH 07/11] map edit widget dropdown and query --- .../ClientApp/src/Maps/MapEditWidget.tsx | 70 +++++++++++++++++-- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx b/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx index 852d29ff6..edc3e821e 100644 --- a/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx +++ b/Harvest.Web/ClientApp/src/Maps/MapEditWidget.tsx @@ -1,11 +1,10 @@ -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; import WebMap from "@arcgis/core/WebMap"; -import Bookmarks from "@arcgis/core/widgets/Bookmarks"; -import Expand from "@arcgis/core/widgets/Expand"; import MapView from "@arcgis/core/views/MapView"; import Editor from "@arcgis/core/widgets/Editor"; import FieldElement from "@arcgis/core/form/elements/FieldElement.js"; import FormTemplate from "@arcgis/core/form/FormTemplate.js"; +import CodedValueDomain from "@arcgis/core/layers/support/CodedValueDomain.js"; import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; import BasemapToggle from "@arcgis/core/widgets/BasemapToggle"; @@ -74,6 +73,33 @@ export const MapEditWidget = () => { new FieldElement({ fieldName: "Crop", label: "Crop", + domain: new CodedValueDomain({ + // dropdown list of available crop values + // https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-CodedValueDomain.html + // doesnt look like this supports dynamic values, but it's currently a dropdown anyways + codedValues: [ + { + name: "Potato", + code: "potato", + }, + { + name: "Tomato", + code: "Tomato", + }, + { + name: "Corn", + code: "Corn", + }, + { + name: "Celery", + code: "Celery", + }, + { + name: "Carrot", + code: "Carrot", + }, + ], + }), }), new FieldElement({ fieldName: "Details", @@ -88,13 +114,43 @@ export const MapEditWidget = () => { // Add the widget to the view view.ui.add(editor, "top-right"); }); - // bonus - how many bookmarks in the webmap? + + // once the whole webmap is loaded webmap.when(() => { - if (webmap.bookmarks && webmap.bookmarks.length) { - console.log("Bookmarks: ", webmap.bookmarks.length); + if (webmap.allLayers && webmap.allLayers.length) { + console.log("All layers: ", webmap.allLayers.length); + } else { + console.log("No layers in this webmap"); + } + if (webmap.allTables && webmap.allTables.length) { + console.log("All tables: ", webmap.allTables.length); } else { - console.log("No bookmarks in this webmap."); + console.log("No tables in this webmap"); } + + // query the features once webmap is loaded + featureLayer + .queryFeatures() + .then((featureSet) => { + console.log("features", featureSet.features); + // then we can do things like: + console.log( + "featureSet.features[0].attributes: ", + featureSet.features[0].attributes + ); + // and get: + // { + // Crop: "Cabbage", + // Details: null, + // OBJECTID: 2, + // Shape__Area: 176921.81640625, + // Shape__Length: 1728.6668691192322, + // name: "cabbages" + // } + }) + .catch((error) => { + console.error("Error querying features: ", error); + }); }); } }, [mapDiv]); From 3576044d61652b679853622087e98f4b57b3529e Mon Sep 17 00:00:00 2001 From: River Holstege Date: Wed, 8 Nov 2023 11:13:49 -0800 Subject: [PATCH 08/11] sketch widget --- .../ClientApp/src/Maps/MapSketchWidget.tsx | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx b/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx index 2ca8aa309..0230709f2 100644 --- a/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx +++ b/Harvest.Web/ClientApp/src/Maps/MapSketchWidget.tsx @@ -10,6 +10,11 @@ import Collection from "@arcgis/core/core/Collection.js"; import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js"; import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js"; +// here i'm trying to use the sketch widget to draw a polygon on the map +// and then use the reactiveUtils.watch to watch the graphicsLayer.graphics +// doesn't work yet (and i think we'd use the Edit Widget instead) +// but i'm interested in the reactiveUtils.watch function + // from: https://github.com/Esri/jsapi-resources/blob/main/esm-samples/jsapi-react/src/App.jsx export const MapSketchWidget = () => { console.log("Map.tsx"); @@ -65,18 +70,19 @@ export const MapSketchWidget = () => { }); view.ui.add(sketch, "top-right"); - // const handle = reactiveUtils.watch( - // // getValue function - // () => graphicsLayer.graphics, - // // Callback function - // (newValue, oldValue) => { - // console.log("New value: ", newValue, "Old value: ", oldValue); - // }, - // // Optional parameters - // { - // // initial: true, - // } - // ); + // https://developers.arcgis.com/javascript/latest/api-reference/esri-core-reactiveUtils.html#watch + const handle = reactiveUtils.watch( + // getValue function + () => graphicsLayer.graphics, + // Callback function + (newValue, oldValue) => { + console.log("New value: ", newValue, "Old value: ", oldValue); + }, + // Optional parameters + { + // initial: true, + } + ); } }, [mapDiv]); From f164afe3413067c477bcc71d1276d93445a10c19 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Wed, 8 Nov 2023 11:15:03 -0800 Subject: [PATCH 09/11] add map edit widget with react state --- .../src/Maps/MapEditWidgetReactState.tsx | 196 ++++++++++++++++++ .../ClientApp/src/Quotes/QuoteContainer.tsx | 4 +- 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx diff --git a/Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx b/Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx new file mode 100644 index 000000000..8f6bdc747 --- /dev/null +++ b/Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx @@ -0,0 +1,196 @@ +import React, { useEffect, useRef, useState } from "react"; +import { Button, Input } from "reactstrap"; + +import WebMap from "@arcgis/core/WebMap"; +import MapView from "@arcgis/core/views/MapView"; +import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; +import BasemapToggle from "@arcgis/core/widgets/BasemapToggle"; +import Graphic from "@arcgis/core/Graphic"; +import Polygon from "@arcgis/core/geometry/Polygon"; +import Layer from "@arcgis/core/layers/Layer"; + +// the attributes of the feature layer () +interface FieldAttributes { + name: string; // field name, not display name (i messed up the casing but you can't rename the field name) + Crop: string; + Details: string; +} + +// from: https://github.com/Esri/jsapi-resources/blob/main/esm-samples/jsapi-react/src/App.jsx +export const MapEditWidgetReactState = () => { + console.log("Map.tsx"); + const mapDiv = useRef(null); + const [features, setFeatures] = useState([]); + const [viewState, setViewState] = useState(); + + const [newAttributes, setNewAttributes] = useState({ + name: "New Attributes Test", + Crop: "Potato", + Details: "Created from React", + }); + + const addFeature = () => { + if (!viewState) { + console.error("View state not set"); + return; + } + const layer: Layer = viewState.map.findLayerById("fieldsLayer"); + if (!layer) { + console.error("Feature layer not found"); + return; + } + // have to be sure that the layer is a feature layer to do this + const featureLayer = layer as FeatureLayer; + + const newFeature = new Graphic({ + geometry: new Polygon({ + rings: [ + [ + [-121.80148, 38.568554], + [-121.80148, 38.568554 - 0.01], + [-121.80148 + 0.01, 38.568554 - 0.01], + [-121.80148 + 0.01, 38.568554], + [-121.80148, 38.568554], + ], + ], + spatialReference: { wkid: 4326 }, + }), + attributes: newAttributes, + }); + + featureLayer + .applyEdits({ addFeatures: [newFeature] }) + .then((res) => { + if (res.addFeatureResults.length > 0) { + console.log("Feature added successfully"); + newFeature.attributes.objectId = res.addFeatureResults[0].objectId; + setFeatures([...features, newFeature]); + } + }) + .catch((error) => { + console.error("Error adding feature: ", error); + }); + }; + + const deleteFeature = () => { + if (!viewState) { + console.error("View state not set"); + return; + } + const layer: Layer = viewState.map.findLayerById("fieldsLayer"); + if (!layer) { + console.error("Feature layer not found"); + return; + } + // have to be sure that the layer is a feature layer to do this + const featureLayer = layer as FeatureLayer; + + // just delete the most recent feature for now + const feature = features[features.length - 1]; + + featureLayer + .applyEdits({ deleteFeatures: [feature] }) + .then((res) => { + if (res.deleteFeatureResults.length > 0) { + console.log("Feature deleted successfully"); + const featureIndex = features.findIndex( + (f) => f.getObjectId() === feature.getObjectId() + ); + setFeatures(features.splice(featureIndex, 1)); + } + }) + .catch((error) => { + console.error("Error deleting feature: ", error); + }); + }; + + useEffect(() => { + if (mapDiv.current) { + /** + * Initialize application + */ + // https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html + const webmap = new WebMap({ + portalItem: { + // the unique id for your map + // you can access this by going to arcgis -> content -> my content -> map and copy the id on the right (or from url) + id: "8e276b0a2b6b49b88a1ea459d91f5fd3", + }, + basemap: "hybrid", // https://developers.arcgis.com/rest/basemap-styles/#arcgis-styles + }); + + const view = new MapView({ + container: mapDiv.current, + map: webmap, + center: [-121.748, 38.54], + zoom: 13, + }); + setViewState(view); + + const featureLayer = new FeatureLayer({ + id: "fieldsLayer", + portalItem: { + // the feature layer is not added to the map in ArcGIS Online, but is overlayed here + id: "66289d4facfb4932a5b1d91db8792c4f", + }, + }); + webmap.add(featureLayer); + + // https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-BasemapToggle.html + let basemapToggle = new BasemapToggle({ + view: view, + nextBasemap: "osm", // Allows for toggling to the openstreetmaps (non-satellite ) + }); + view.ui.add(basemapToggle, "top-left"); + + // once the whole webmap is loaded + webmap.when(() => { + if (webmap.allLayers && webmap.allLayers.length) { + console.log("All layers: ", webmap.allLayers.length); + } else { + console.log("No layers in this webmap"); + } + if (webmap.allTables && webmap.allTables.length) { + console.log("All tables: ", webmap.allTables.length); + } else { + console.log("No tables in this webmap"); + } + }); + + featureLayer + .queryFeatures() + .then((featureSet) => { + console.log("features", featureSet.features); + // then we can do things like: + // console.log( + // "featureSet.features[0].attributes: ", + // featureSet.features[0].attributes + // ); + // and get: + // { + // Crop: "Cabbage", + // Details: null, + // OBJECTID: 2, + // Shape__Area: 176921.81640625, + // Shape__Length: 1728.6668691192322, + // name: "cabbages" + // } + + // and also: + setFeatures(featureSet.features); + }) + .catch((error) => { + console.error("Error querying features: ", error); + }); + } + }, [mapDiv, newAttributes]); + + return ( + <> + + + +
+ + ); +}; diff --git a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx index 2f335ee71..44b44436b 100644 --- a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx +++ b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx @@ -28,6 +28,7 @@ import { useIsMounted } from "../Shared/UseIsMounted"; import { ShowFor } from "../Shared/ShowFor"; import { validatorOptions } from "../constants"; import { Button } from "reactstrap"; +import { MapEditWidgetReactState } from "../Maps/MapEditWidgetReactState"; export const QuoteContainer = () => { const history = useHistory(); @@ -277,8 +278,9 @@ export const QuoteContainer = () => { - + {/* */} {/* */} + {/* Date: Wed, 8 Nov 2023 11:23:25 -0800 Subject: [PATCH 10/11] better name because we don't use the widget --- .../{MapEditWidgetReactState.tsx => MapEditReactState.tsx} | 2 +- Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename Harvest.Web/ClientApp/src/Maps/{MapEditWidgetReactState.tsx => MapEditReactState.tsx} (99%) diff --git a/Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx b/Harvest.Web/ClientApp/src/Maps/MapEditReactState.tsx similarity index 99% rename from Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx rename to Harvest.Web/ClientApp/src/Maps/MapEditReactState.tsx index 8f6bdc747..d3672c3f6 100644 --- a/Harvest.Web/ClientApp/src/Maps/MapEditWidgetReactState.tsx +++ b/Harvest.Web/ClientApp/src/Maps/MapEditReactState.tsx @@ -17,7 +17,7 @@ interface FieldAttributes { } // from: https://github.com/Esri/jsapi-resources/blob/main/esm-samples/jsapi-react/src/App.jsx -export const MapEditWidgetReactState = () => { +export const MapEditReactState = () => { console.log("Map.tsx"); const mapDiv = useRef(null); const [features, setFeatures] = useState([]); diff --git a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx index 44b44436b..f4b84d1b9 100644 --- a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx +++ b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx @@ -28,7 +28,7 @@ import { useIsMounted } from "../Shared/UseIsMounted"; import { ShowFor } from "../Shared/ShowFor"; import { validatorOptions } from "../constants"; import { Button } from "reactstrap"; -import { MapEditWidgetReactState } from "../Maps/MapEditWidgetReactState"; +import { MapEditReactState } from "../Maps/MapEditReactState"; export const QuoteContainer = () => { const history = useHistory(); @@ -280,7 +280,7 @@ export const QuoteContainer = () => { {/* */} {/* */} - + {/* Date: Wed, 8 Nov 2023 14:15:06 -0800 Subject: [PATCH 11/11] default to edit widget --- Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx index f4b84d1b9..0702eab67 100644 --- a/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx +++ b/Harvest.Web/ClientApp/src/Quotes/QuoteContainer.tsx @@ -278,9 +278,9 @@ export const QuoteContainer = () => { - {/* */} + + {/* */} {/* */} - {/*