diff --git a/.github/workflows/Lint.yml b/.github/workflows/Lint.yml deleted file mode 100644 index ffc12ef21..000000000 --- a/.github/workflows/Lint.yml +++ /dev/null @@ -1,29 +0,0 @@ -# name: Lint - -# on: [pull_request] - -# jobs: -# eslint: -# name: Run eslint -# runs-on: ubuntu-latest - -# steps: -# - name: Check out Git repository -# uses: actions/checkout@v2 - -# - name: Set up Node.js -# uses: actions/setup-node@v1 -# with: -# node-version: 12 - -# # ESLint and Prettier must be in `package.json` -# - name: Install Node.js dependencies -# run: npm install - -# - name: Run linters -# uses: samuelmeuli/lint-action@v1 -# with: -# github_token: ${{ secrets.github_token }} -# # Enable linters -# eslint: true -# eslint_extensions: ts,tsx diff --git a/.github/workflows/build-and-push.yaml b/.github/workflows/build-and-push.yaml new file mode 100644 index 000000000..3d58b3dc3 --- /dev/null +++ b/.github/workflows/build-and-push.yaml @@ -0,0 +1,57 @@ +name: Build and push artifacts + +on: + push: + tags: + - 'v*' + +jobs: + build_and_push: + runs-on: ubuntu-latest + steps: + - name: Artifactory Login + uses: MapColonies/shared-workflows/actions/artifactory-login@artifactory-login-v1.0.0 + with: + registry: ${{ secrets.ACR_URL }} + username: ${{ secrets.ACR_PUSH_USER }} + password: ${{ secrets.ACR_PUSH_TOKEN }} + + - name: Build Docker Image + id: build + uses: MapColonies/shared-workflows/actions/build-docker@build-docker-v1.1.0 + with: + domain: app + registry: ${{ secrets.ACR_URL }} + + - name: Push Docker Image + uses: MapColonies/shared-workflows/actions/push-docker@push-docker-v1.0.1 + with: + image_name: ${{ steps.build.outputs.docker_image_full_name }} + image_tag: ${{ steps.build.outputs.docker_image_tag }} + + - name: Build and Push Helm Chart + uses: MapColonies/shared-workflows/actions/build-and-push-helm@build-and-push-helm-v1.0.1 + with: + context: ./helm + domain: app + registry: ${{ secrets.ACR_URL }} + + - name: Update Artifacts File- Docker + uses: MapColonies/shared-workflows/actions/update-artifacts-file@update-artifacts-file-v1.1.1 + with: + domain: app + artifact_name: ${{ github.event.repository.name }} + artifact_tag: ${{ github.ref_name }} + type: docker + registry: ${{ secrets.ACR_URL }} + github_token: ${{ secrets.GH_PAT }} + + - name: Update Artifacts File- Helm + uses: MapColonies/shared-workflows/actions/update-artifacts-file@update-artifacts-file-v1.1.1 + with: + domain: app + artifact_name: ${{ github.event.repository.name }} + artifact_tag: ${{ github.ref_name }} + type: helm + registry: ${{ secrets.ACR_URL }} + github_token: ${{ secrets.GH_PAT }} diff --git a/.github/workflows/build_and_push.yaml b/.github/workflows/build_and_push.yaml deleted file mode 100644 index 725aaca8b..000000000 --- a/.github/workflows/build_and_push.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: Build and push artifacts - -on: - push: - tags: - - 'v*' - - workflow_dispatch: - inputs: - version: - required: true - type: string -env: - HELM_EXPERIMENTAL_OCI: 1 - -permissions: - contents: write - pull-requests: write - -jobs: - build_and_push_docker: - uses: MapColonies/shared-workflows/.github/workflows/build-and-push-docker.yaml@v4 - secrets: inherit - with: - scope: app - - build_and_push_helm: - uses: MapColonies/shared-workflows/.github/workflows/build-and-push-helm.yaml@v4 - secrets: inherit - with: - scope: app diff --git a/.github/workflows/Main.yaml b/.github/workflows/pull-request.yaml similarity index 53% rename from .github/workflows/Main.yaml rename to .github/workflows/pull-request.yaml index 7eb89ed50..c9a37a696 100644 --- a/.github/workflows/Main.yaml +++ b/.github/workflows/pull-request.yaml @@ -1,23 +1,37 @@ -name: CI +name: pull_request on: [pull_request] jobs: + helm-lint: + name: Run Helm lint Check + runs-on: ubuntu-latest + steps: + - name: Check out TS Project Git repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: helm-lint + uses: MapColonies/shared-workflows/actions/helm-lint@helm-lint-v1 + build_and_test: runs-on: ubuntu-latest + permissions: + checks: write + contents: write strategy: matrix: os: [ubuntu-latest] node-version: [16.13.x] steps: - name: checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - uses: actions/cache@v4 with: path: '**/node_modules' key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: ${{ matrix.node-version }} - name: Install yarn @@ -26,20 +40,26 @@ jobs: echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update sudo apt-get install --no-install-recommends yarn - - name: Install dependecies run: yarn - name: Lint - run: yarn run eslint:check + uses: wearerequired/lint-action@v2 + with: + tsc: true + eslint: true + eslint_extensions: js,jsx,ts,tsx + prettier: true + prettier_dir: src - name: Test run: yarn test - security: + build_docker_image: + name: Build Docker Image runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - name: Run Snyk to check for vulnerabilities - uses: snyk/actions/node@master - continue-on-error: true - env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + - name: Checkout repository + uses: actions/checkout@v5 + - name: Build Docker image + uses: docker/build-push-action@v6 + with: + push: false diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml index c34e43cd4..bc2af7c9e 100644 --- a/.github/workflows/release-please.yaml +++ b/.github/workflows/release-please.yaml @@ -2,17 +2,18 @@ on: push: branches: - master + workflow_dispatch: + permissions: contents: write pull-requests: write + name: release-please + jobs: release-please: runs-on: ubuntu-latest steps: - uses: googleapis/release-please-action@v4 with: - # this assumes that you have created a personal access token - # (PAT) and configured it as a GitHub action secret named - # `MY_RELEASE_PLEASE_TOKEN` (this secret name is not important). token: ${{ secrets.GH_PAT }} diff --git a/.prettierignore b/.prettierignore index b77ff691a..b194e6f12 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,7 @@ .vscode/settings.json -schemas/*.json \ No newline at end of file +*.json +helm +confd +public +CHANGELOG.md +src/discrete-layer/models diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ea2b7f13e..60bf00910 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { ".": "4.3.5" -} \ No newline at end of file +} diff --git a/README.md b/README.md index fc6a03677..28f71e8b5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ React app created with typescript that defines manages and displays discrete lay This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app) - ## Installation Install deps with yarn @@ -20,15 +19,15 @@ yarn confd ``` To generate: -public/env-config.js <- For env variables -public/index.html <- For PUBLIC_URL, to support non-root URL +public/env-config.js <- For env variables +public/index.html <- For PUBLIC_URL, to support non-root URL To use app env variables inside a docker, run the following command ```bash node ./confd/generate-config.js --environment production --indocker ``` - + Start app ```bash @@ -45,7 +44,7 @@ To run tests, run the following command yarn test ``` -It will run in an interactive mode +It will run in an interactive mode See [running tests](https://facebook.github.io/create-react-app/docs/running-tests) @@ -63,21 +62,24 @@ See [deployment](https://facebook.github.io/create-react-app/docs/deployment) ## Deployment -> [!IMPORTANT] +> [!IMPORTANT] > We depend on `Red-Hat Yaml Extension` for validating the values files against the relevant schemas from helm-common. > That means, you should install the extension from vscode in order to be able to edit values files according to our schemas. To update helm dependencies + ```bash yarn helm-update ``` -In order to create/renew values schemas +In order to create/renew values schemas + ```bash yarn helm-assets ``` To deploy: helm values **MUST** be combined from global.yaml and values.yaml (use npm script!) + ```bash yarn helm-install ``` diff --git a/config-overrides.js b/config-overrides.js index fc7bd018e..cd769a1e2 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -2,39 +2,42 @@ const webpack = require('webpack'); const path = require('path'); module.exports = function override(config, env) { - //do stuff with the webpack config... + //do stuff with the webpack config... - config.resolve.fallback = { - url: require.resolve('url'), - assert: require.resolve('assert'), - crypto: require.resolve('crypto-browserify'), - http: require.resolve('stream-http'), - https: require.resolve('https-browserify'), - os: require.resolve('os-browserify/browser'), - buffer: require.resolve('buffer'), - stream: require.resolve('stream-browserify'), - zlib: require.resolve("browserify-zlib") - }; + config.resolve.fallback = { + url: require.resolve('url'), + assert: require.resolve('assert'), + crypto: require.resolve('crypto-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + os: require.resolve('os-browserify/browser'), + buffer: require.resolve('buffer'), + stream: require.resolve('stream-browserify'), + zlib: require.resolve('browserify-zlib'), + }; - config.resolve.alias = { - ...config.resolve.alias, - 'react-dnd': path.resolve(__dirname, './node_modules/react-dnd'), - 'react-dnd-html5-backend': path.resolve(__dirname, './node_modules/react-dnd-html5-backend'), - } - - config.plugins.push( - new webpack.ProvidePlugin({ - process: 'process/browser', - Buffer: ['buffer', 'Buffer'], - }), - ); + config.resolve.alias = { + ...config.resolve.alias, + 'react-dnd': path.resolve(__dirname, './node_modules/react-dnd'), + 'react-dnd-html5-backend': path.resolve( + __dirname, + './node_modules/react-dnd-html5-backend' + ), + }; - config.module.rules.push({ - test: /\.m?js/, - resolve: { - fullySpecified: false - } - }) + config.plugins.push( + new webpack.ProvidePlugin({ + process: 'process/browser', + Buffer: ['buffer', 'Buffer'], + }) + ); - return config; -} \ No newline at end of file + config.module.rules.push({ + test: /\.m?js/, + resolve: { + fullySpecified: false, + }, + }); + + return config; +}; diff --git a/docker-compose.yml b/docker-compose.yml index 34051cbb7..cc2decafe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,7 @@ version: '3' services: - - catalog-app-service: - + catalog-app-service: image: catalog-app build: . diff --git a/public/assets/pages/compatibilityError.html b/public/assets/pages/compatibilityError.html index 83dd59d2c..0d85d17ec 100644 --- a/public/assets/pages/compatibilityError.html +++ b/public/assets/pages/compatibilityError.html @@ -14,7 +14,7 @@

-

+

diff --git a/release-please-config.json b/release-please-config.json index 061468b65..d5dfedaaf 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -33,4 +33,4 @@ { "type": "test", "section": "Tests", "hidden": true }, { "type": "ci", "section": "Continuous Integration", "hidden": true } ] -} \ No newline at end of file +} diff --git a/src/App.css b/src/App.css index b8c883567..5e666fe0a 100644 --- a/src/App.css +++ b/src/App.css @@ -1,24 +1,32 @@ -.mdc-checkbox .mdc-checkbox__native-control:checked ~ .mdc-checkbox__background::before, -.mdc-checkbox .mdc-checkbox__native-control:indeterminate ~ .mdc-checkbox__background::before { +.mdc-checkbox + .mdc-checkbox__native-control:checked + ~ .mdc-checkbox__background::before, +.mdc-checkbox + .mdc-checkbox__native-control:indeterminate + ~ .mdc-checkbox__background::before { background-color: #2979ff; /* @alternate */ background-color: var(--mdc-theme-primary, #2979ff); } -.mdc-checkbox.mdc-checkbox--selected .mdc-checkbox__ripple::before, .mdc-checkbox.mdc-checkbox--selected .mdc-checkbox__ripple::after { +.mdc-checkbox.mdc-checkbox--selected .mdc-checkbox__ripple::before, +.mdc-checkbox.mdc-checkbox--selected .mdc-checkbox__ripple::after { background-color: #2979ff; /* @alternate */ background-color: var(--mdc-theme-primary, #2979ff); } -.mdc-checkbox.mdc-ripple-upgraded--background-focused.mdc-checkbox--selected .mdc-checkbox__ripple::before, -.mdc-checkbox.mdc-ripple-upgraded--background-focused.mdc-checkbox--selected .mdc-checkbox__ripple::after { +.mdc-checkbox.mdc-ripple-upgraded--background-focused.mdc-checkbox--selected + .mdc-checkbox__ripple::before, +.mdc-checkbox.mdc-ripple-upgraded--background-focused.mdc-checkbox--selected + .mdc-checkbox__ripple::after { background-color: #2979ff; /* @alternate */ background-color: var(--mdc-theme-primary, #2979ff); } .mdc-checkbox__native-control:enabled:checked ~ .mdc-checkbox__background, -.mdc-checkbox__native-control:enabled:indeterminate ~ .mdc-checkbox__background { +.mdc-checkbox__native-control:enabled:indeterminate + ~ .mdc-checkbox__background { border-color: #2979ff; /* @alternate */ border-color: var(--mdc-theme-primary, #2979ff); @@ -35,14 +43,16 @@ bottom: 40px; left: 8px; } -.mdc-snackbar__label, [dir=rtl] .mdc-snackbar__label { +.mdc-snackbar__label, +[dir='rtl'] .mdc-snackbar__label { padding: 0; } -.mdc-snackbar__surface, [dir=rtl] .mdc-snackbar__surface { +.mdc-snackbar__surface, +[dir='rtl'] .mdc-snackbar__surface { padding: 0; } .mdc-snackbar__action:not(:disabled) { - color: var(--mdc-theme-primary, #2979ff);; + color: var(--mdc-theme-primary, #2979ff); } .app-container { @@ -81,7 +91,7 @@ button.cesium-infoBox-close:hover { left: unset; } -[dir=rtl] .cesium-infoBox { +[dir='rtl'] .cesium-infoBox { right: unset; left: 88px; } @@ -92,7 +102,7 @@ button.cesium-infoBox-close:hover { justify-content: space-evenly; } -[dir=rtl] .cesium-infoBox-title { +[dir='rtl'] .cesium-infoBox-title { direction: ltr; } @@ -123,7 +133,7 @@ button.cesium-infoBox-close:hover { } .appVersionContainer-slave { - color: var(--mdc-theme-gc-site-slave); + color: var(--mdc-theme-gc-site-slave); } title.rtl { @@ -150,10 +160,12 @@ body[dir='ltr'] .react-datepicker__close-icon { @keyframes glow { from { - text-shadow: 0 0 10px #fff, 0 0 12px #fff, 0 0 14px #e60073, 0 0 18px #e60073, 0 0 20px #e60073; + text-shadow: 0 0 10px #fff, 0 0 12px #fff, 0 0 14px #e60073, + 0 0 18px #e60073, 0 0 20px #e60073; } to { - text-shadow: 0 0 12px #fff, 0 0 14px #ff4da6, 0 0 16px #ff4da6, 0 0 18px #ff4da6, 0 0 20px #ff4da6, 0 0 22px #ff4da6; + text-shadow: 0 0 12px #fff, 0 0 14px #ff4da6, 0 0 16px #ff4da6, + 0 0 18px #ff4da6, 0 0 20px #ff4da6, 0 0 22px #ff4da6; } } @@ -164,8 +176,8 @@ input::-webkit-inner-spin-button { } input:-webkit-autofill, -input:-webkit-autofill:hover, -input:-webkit-autofill:focus, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, input:-webkit-autofill:active { -webkit-box-shadow: 0 0 0 30px var(--mdc-theme-alternative-surface) inset !important; } @@ -202,7 +214,11 @@ input:disabled { } } -.mdc-checkbox .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate):not([data-indeterminate=true]) ~ .mdc-checkbox__background { +.mdc-checkbox + .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate):not( + [data-indeterminate='true'] + ) + ~ .mdc-checkbox__background { border: 1px solid var(--mdc-theme-on-surface); } @@ -220,4 +236,4 @@ input:disabled { 100% { opacity: 1; /* Fully visible again */ } -} \ No newline at end of file +} diff --git a/src/App.dark-theme.css b/src/App.dark-theme.css index 01d878451..d99a5b6c4 100644 --- a/src/App.dark-theme.css +++ b/src/App.dark-theme.css @@ -66,7 +66,7 @@ .dark-theme .mdc-menu .mdc-list { /* color: var(--mdc-theme-text-primary-on-background, rgba(0, 0, 0, 0.87)); */ - color: var(--mdc-theme-text-primary-on-dark) + color: var(--mdc-theme-text-primary-on-dark); } .dark-theme .mdc-menu .mdc-list .mdc-list-item { @@ -97,15 +97,18 @@ } .dark-theme .mdc-select.mdc-select--disabled .mdc-select__selected-text { - color: unset; + color: unset; } -.dark-theme .mdc-select.mdc-select--outlined.mdc-select--no-label.mdc-select--disabled { +.dark-theme + .mdc-select.mdc-select--outlined.mdc-select--no-label.mdc-select--disabled { background-color: var(--mdc-theme-text-disabled-on-light); opacity: 0.3; } -.dark-theme .mdc-list.mdc-menu__items .mdc-list-item.mdc-ripple-upgraded--background-focused { +.dark-theme + .mdc-list.mdc-menu__items + .mdc-list-item.mdc-ripple-upgraded--background-focused { color: var(--mdc-theme-primary); } @@ -140,7 +143,7 @@ } .dark-theme .ag-theme-alpine-dark .ag-row-hover:before { - background-color: unset + background-color: unset; } .dark-theme .ag-theme-alpine-dark .ag-cell-focus { @@ -176,7 +179,7 @@ .dark-theme .mdc-text-field--invalid .mdc-text-field__input { color: var(--mdc-theme-gc-error-high, red) !important; } - + .dark-theme .mdc-text-field__input { color: var(--mdc-theme-text-primary-on-dark, #fff) !important; } @@ -210,7 +213,8 @@ /* DATE-TIME-PICKER CUSTOMIZATION */ -.MuiGrid-align-items-xs-flex-end.MuiGrid-justify-content-xs-center.MuiGrid-grid-xs-6, .MuiPickersCalendarHeader-switchHeader { +.MuiGrid-align-items-xs-flex-end.MuiGrid-justify-content-xs-center.MuiGrid-grid-xs-6, +.MuiPickersCalendarHeader-switchHeader { direction: ltr; } @@ -354,7 +358,6 @@ body[dir='rtl'] .dark-theme .rst__virtualScrollOverride { opacity: 0.3; } - /* Date Range Picker */ .dark-theme .pickerContainer { @@ -362,20 +365,30 @@ body[dir='rtl'] .dark-theme .rst__virtualScrollOverride { --date-picker-day-background: var(--mdc-theme-alternative-surface); --date-picker-day-font-color: var(--mdc-theme-text-primary-on-background); - --date-picker-day-selecting-range-background: var(--mdc-theme-gc-selection-background); + --date-picker-day-selecting-range-background: var( + --mdc-theme-gc-selection-background + ); --date-picker-day-selecting-range-font-color: var(--mdc-theme-on-primary); --date-picker-day-hover-background: var(--mdc-theme-text-primary-on-dark); --date-picker-day-hover-font-color: var(--mdc-theme-text-primary-on-light); - --date-picker-selected-day-background: var(--mdc-theme-gc-selection-background); - --date-picker-selected-day-hover-background: var(--mdc-theme-text-primary-on-dark); - --date-picker-selected-day-hover-font-color: var(--mdc-theme-text-primary-on-light); + --date-picker-selected-day-background: var( + --mdc-theme-gc-selection-background + ); + --date-picker-selected-day-hover-background: var( + --mdc-theme-text-primary-on-dark + ); + --date-picker-selected-day-hover-font-color: var( + --mdc-theme-text-primary-on-light + ); --date-picker-selected-day-font-color: var(--mdc-theme-on-primary); --date-picker-nav-icons-color: var(--mdc-theme-text-primary-on-background); --date-picker-header-background: var(--mdc-theme-gc-selection-background); --date-picker-header-color: var(--mdc-theme-text-primary-on-background); - --date-picker-shortcuts-hover-background: var(--mdc-theme-text-primary-on-dark); + --date-picker-shortcuts-hover-background: var( + --mdc-theme-text-primary-on-dark + ); --date-picker-shortcuts-background: var(--mdc-theme-alternative-surface); --date-picker-shortcuts-font-color: var(--mdc-theme-text-primary-on-light); @@ -383,9 +396,15 @@ body[dir='rtl'] .dark-theme .rst__virtualScrollOverride { --month-year-pickers-font-color: var(--mdc-theme-on-primary); --month-year-pickers-border-color: var(--mdc-theme-gc-selection-background); - --date-picker-scrollbar-track-background: var(--mdc-theme-text-primary-on-light); - --date-picker-scrollbar-thumb-background: var(--mdc-theme-alternative-surface); - --date-picker-scrollbar-thumb-hover-background: var(--mdc-theme-text-primary-on-dark); + --date-picker-scrollbar-track-background: var( + --mdc-theme-text-primary-on-light + ); + --date-picker-scrollbar-thumb-background: var( + --mdc-theme-alternative-surface + ); + --date-picker-scrollbar-thumb-hover-background: var( + --mdc-theme-text-primary-on-dark + ); } /* LINEAR PROGRESS CUSTOMIZATION */ @@ -394,13 +413,13 @@ body[dir='rtl'] .dark-theme .rst__virtualScrollOverride { } /* COLLAPSABLE PANEL*/ -.dark-theme .rmwc-collapsible-list__children-inner{ - border: 1px solid var(--mdc-theme-gc-selection-background); +.dark-theme .rmwc-collapsible-list__children-inner { + border: 1px solid var(--mdc-theme-gc-selection-background); margin-bottom: 2px; } /* SELLECT BUTTON FLAVOR*/ -.dark-theme .selectButtonFlavor .mdc-select__anchor{ +.dark-theme .selectButtonFlavor .mdc-select__anchor { height: 40px; width: 144px; background-color: transparent; @@ -408,19 +427,21 @@ body[dir='rtl'] .dark-theme .rst__virtualScrollOverride { border: 1px solid var(--mdc-theme-primary); } -.dark-theme .selectButtonFlavor .mdc-select__selected-text{ +.dark-theme .selectButtonFlavor .mdc-select__selected-text { color: var(--mdc-theme-primary) !important; } -.dark-theme .selectButtonFlavor.mdc-select--disabled .mdc-select__selected-text{ +.dark-theme + .selectButtonFlavor.mdc-select--disabled + .mdc-select__selected-text { color: var(--mdc-theme-text-disabled-on-dark) !important; } -.dark-theme .selectButtonFlavor.mdc-select--disabled .mdc-select__anchor{ +.dark-theme .selectButtonFlavor.mdc-select--disabled .mdc-select__anchor { border: solid 1px var(--mdc-theme-on-secondary); opacity: 0.4; } -.dark-theme .selectButtonFlavor .mdc-list-item__ripple{ +.dark-theme .selectButtonFlavor .mdc-list-item__ripple { opacity: 0 !important; -} \ No newline at end of file +} diff --git a/src/App.tsx b/src/App.tsx index 6d5060797..dc4e55887 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import React, { useState, useLayoutEffect,useEffect } from 'react'; +import React, { useState, useLayoutEffect, useEffect } from 'react'; import { IntlProvider } from 'react-intl'; import Moment from 'moment'; import 'moment/locale/he'; // TODO: improve dynamic moment locales loading @@ -38,7 +38,6 @@ import './App.css'; import './App.dark-theme.css'; import './App.light-theme.css'; - import { queue } from './discrete-layer/components/snackbar/notification-queue'; import { SnackContainer } from './discrete-layer/components/snackbar/snack-container'; import DiscreteLayerView from './discrete-layer/views/discrete-layer-view'; @@ -47,21 +46,27 @@ import MESSAGES from './common/i18n'; import CONFIG from './common/config'; import { camelize } from './common/helpers/string'; import { CustomTheme } from './theming/custom.theme'; -import EnumsMapContext, { IEnumsMapType } from './common/contexts/enumsMap.context'; -import LookupTablesContext, { ILookupTableData } from './common/contexts/lookupTables.context'; +import EnumsMapContext, { + IEnumsMapType, +} from './common/contexts/enumsMap.context'; +import LookupTablesContext, { + ILookupTableData, +} from './common/contexts/lookupTables.context'; import WebSocketNotifications from './discrete-layer/views/components/notifications/web-socket-notifications'; import { PasswordAutofillDisabler } from './discrete-layer/views/components/password-autofill-disabler.component'; const App: React.FC = () => { - /*const prefersDarkMode = */useMediaQuery('(prefers-color-scheme: dark)'); + /*const prefersDarkMode = */ useMediaQuery('(prefers-color-scheme: dark)'); // eslint-disable-next-line const [lang, setLang] = useState(CONFIG.I18N.DEFAULT_LANGUAGE); const [enumsMap, setEnumsMap] = useState(null); // const theme = Themes.lightTheme; //TODO: when dark theme will be tuned use this --> prefersDarkMode ? Themes.darkTheme : Themes.lightTheme; - const customThemeProps: Record = {}; + const customThemeProps: Record = {}; for (const prop in CustomTheme.darkTheme) { - customThemeProps[camelize(prop)] = (CustomTheme.darkTheme as Record)[prop]; + customThemeProps[camelize(prop)] = ( + CustomTheme.darkTheme as Record + )[prop]; } const theme = { ...Themes.darkTheme, @@ -70,11 +75,13 @@ const App: React.FC = () => { alternativeSurface: '#2D3748', ...customThemeProps, custom: { - ...CustomTheme.darkTheme - } + ...CustomTheme.darkTheme, + }, }; - const [lookupTablesData, setLookupTablesData] = useState({}); + const [lookupTablesData, setLookupTablesData] = useState( + {} + ); useLayoutEffect(() => { setLang(document.documentElement.lang); @@ -87,7 +94,11 @@ const App: React.FC = () => { return ( <> - null} locale={lang} messages={MESSAGES[lang] as Record}> + null} + locale={lang} + messages={MESSAGES[lang] as Record} + > { ), }} > - + - + diff --git a/src/__mocks-data__/search-results.mock.ts b/src/__mocks-data__/search-results.mock.ts index 985730363..c3d436a5d 100644 --- a/src/__mocks-data__/search-results.mock.ts +++ b/src/__mocks-data__/search-results.mock.ts @@ -2,7 +2,10 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { ILayerImage } from '../discrete-layer/models/layerImage'; -export const createMockData = (count: number, prefix: string): ILayerImage[] => { +export const createMockData = ( + count: number, + prefix: string +): ILayerImage[] => { const rowData: ILayerImage[] = []; for (let i = 0; i < count; i++) { // @ts-ignore @@ -32,13 +35,15 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ description: '', geojson: { type: 'Polygon', - coordinates: [[ - [34.8076891807199, 31.9042863434239], - [34.816135996859, 31.9042863434239], - [34.816135996859,31.9118071956932], - [34.8076891807199,31.9118071956932], - [34.8076891807199,31.9042863434239], - ]], + coordinates: [ + [ + [34.8076891807199, 31.9042863434239], + [34.816135996859, 31.9042863434239], + [34.816135996859, 31.9118071956932], + [34.8076891807199, 31.9118071956932], + [34.8076891807199, 31.9042863434239], + ], + ], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -50,7 +55,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: 'XYZ_LAYER', url: 'https://tiles.openaerialmap.org/5a852c072553e6000ce5ac8d/0/7950e2de-5d9e-49aa-adec-6e92384be0b9/{z}/{x}/{y}.png', - meta: 'http://oin-hotosm.s3.amazonaws.com/5a852c072553e6000ce5ac8d/0/7950e2de-5d9e-49aa-adec-6e92384be0b9_meta.json' + meta: 'http://oin-hotosm.s3.amazonaws.com/5a852c072553e6000ce5ac8d/0/7950e2de-5d9e-49aa-adec-6e92384be0b9_meta.json', }, }, { @@ -60,13 +65,15 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ description: '', geojson: { type: 'Polygon', - coordinates: [[ - [34.8099445223518, 31.9061345394902], - [34.8200994167574, 31.9061345394902], - [34.8200994167574, 31.9106311613979], - [34.8099445223518, 31.9106311613979], - [34.8099445223518, 31.9061345394902], - ]], + coordinates: [ + [ + [34.8099445223518, 31.9061345394902], + [34.8200994167574, 31.9061345394902], + [34.8200994167574, 31.9106311613979], + [34.8099445223518, 31.9106311613979], + [34.8099445223518, 31.9061345394902], + ], + ], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -78,7 +85,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: 'XYZ_LAYER', url: 'https://tiles.openaerialmap.org/5a9f90c42553e6000ce5ad6c/0/eee1a570-128e-4947-9ffa-1e69c1efab7c/{z}/{x}/{y}.png', - meta: 'http://oin-hotosm.s3.amazonaws.com/5a9f90c42553e6000ce5ad6c/0/eee1a570-128e-4947-9ffa-1e69c1efab7c_meta.json' + meta: 'http://oin-hotosm.s3.amazonaws.com/5a9f90c42553e6000ce5ad6c/0/eee1a570-128e-4947-9ffa-1e69c1efab7c_meta.json', }, }, { @@ -88,13 +95,15 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ description: '', geojson: { type: 'Polygon', - coordinates: [[ - [34.8106008249547, 31.9076273723004], - [34.8137969069015, 31.9076273723004], - [34.8137969069015, 31.9103791381117], - [34.8106008249547, 31.9103791381117], - [34.8106008249547, 31.9076273723004], - ]], + coordinates: [ + [ + [34.8106008249547, 31.9076273723004], + [34.8137969069015, 31.9076273723004], + [34.8137969069015, 31.9103791381117], + [34.8106008249547, 31.9103791381117], + [34.8106008249547, 31.9076273723004], + ], + ], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -106,7 +115,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: 'XYZ_LAYER', url: 'https://tiles.openaerialmap.org/5a8316e22553e6000ce5ac7f/0/c3fcbe99-d339-41b6-8ec0-33d90ccca020/{z}/{x}/{y}.png', - meta: 'http://oin-hotosm.s3.amazonaws.com/5a8316e22553e6000ce5ac7f/0/c3fcbe99-d339-41b6-8ec0-33d90ccca020_meta.json' + meta: 'http://oin-hotosm.s3.amazonaws.com/5a8316e22553e6000ce5ac7f/0/c3fcbe99-d339-41b6-8ec0-33d90ccca020_meta.json', }, }, { @@ -116,13 +125,15 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ description: '', geojson: { type: 'Polygon', - coordinates: [[ - [34.8043847068541, 31.9023297972932], - [34.8142791322292, 31.9023297972932], - [34.8142791322292, 31.9108796531516], - [34.8043847068541, 31.9108796531516], - [34.8043847068541, 31.9023297972932], - ]], + coordinates: [ + [ + [34.8043847068541, 31.9023297972932], + [34.8142791322292, 31.9023297972932], + [34.8142791322292, 31.9108796531516], + [34.8043847068541, 31.9108796531516], + [34.8043847068541, 31.9023297972932], + ], + ], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -134,7 +145,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: 'XYZ_LAYER', url: 'https://tiles.openaerialmap.org/5a831b4a2553e6000ce5ac80/0/d02ddc76-9c2e-4994-97d4-a623eb371456/{z}/{x}/{y}.png', - meta: 'http://oin-hotosm.s3.amazonaws.com/5a831b4a2553e6000ce5ac80/0/d02ddc76-9c2e-4994-97d4-a623eb371456_meta.json' + meta: 'http://oin-hotosm.s3.amazonaws.com/5a831b4a2553e6000ce5ac80/0/d02ddc76-9c2e-4994-97d4-a623eb371456_meta.json', }, }, { @@ -143,31 +154,101 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ creationDate: new Date('2018-06-01T16:39:55.400Z'), description: '', geojson: { - type:'MultiPolygon', - coordinates:[ - [[ - [34.820514,31.90975],[34.820513,31.909689],[34.820549,31.909688],[34.82055,31.909749],[34.820514,31.90975] - ]], - [[ - [34.81642,31.913197],[34.816419,31.913136],[34.816383,31.913136],[34.816312,31.913138],[34.81631,31.913076], - [34.816275,31.913077],[34.816239,31.913077],[34.816238,31.913047],[34.816166,31.913048],[34.816167,31.913079], - [34.816095,31.91308],[34.816095,31.913049],[34.816059,31.91305],[34.816023,31.91305],[34.816021,31.912959], - [34.816057,31.912958],[34.816056,31.912897],[34.81602,31.912897],[34.816017,31.912745],[34.815981,31.912745], - [34.815873,31.912747],[34.815828,31.910458],[34.815864,31.910458],[34.815863,31.910397],[34.815899,31.910396], - [34.815897,31.910274],[34.815861,31.910274],[34.815858,31.910122],[34.815822,31.910122],[34.815818,31.909939], - [34.815854,31.909939],[34.815854,31.909908],[34.815889,31.909908],[34.815888,31.909847],[34.815924,31.909846], - [34.815923,31.909816],[34.815888,31.909816],[34.815887,31.909786],[34.815851,31.909786],[34.815852,31.909817], - [34.815816,31.909817],[34.815812,31.909634],[34.815848,31.909634],[34.815848,31.909603],[34.815883,31.909603], - [34.815882,31.909542],[34.815954,31.909541],[34.815952,31.909449],[34.816167,31.909446],[34.816166,31.909354], - [34.81882,31.909316],[34.818821,31.909377],[34.818893,31.909376],[34.818929,31.909376],[34.818929,31.909406], - [34.819252,31.909402],[34.81925,31.90931],[34.819896,31.909301],[34.819896,31.909331],[34.819932,31.909331], - [34.819933,31.909392],[34.820364,31.909386],[34.8204,31.909385],[34.820406,31.90969],[34.820442,31.90969], - [34.820477,31.909689],[34.820479,31.909751],[34.820514,31.90975],[34.820515,31.909781],[34.820551,31.90978], - [34.820608,31.912679],[34.820536,31.91268],[34.820539,31.912833],[34.820468,31.912834],[34.820471,31.912986], - [34.820363,31.912988],[34.820366,31.913141],[34.81642,31.913197] - ]] + type: 'MultiPolygon', + coordinates: [ + [ + [ + [34.820514, 31.90975], + [34.820513, 31.909689], + [34.820549, 31.909688], + [34.82055, 31.909749], + [34.820514, 31.90975], + ], + ], + [ + [ + [34.81642, 31.913197], + [34.816419, 31.913136], + [34.816383, 31.913136], + [34.816312, 31.913138], + [34.81631, 31.913076], + [34.816275, 31.913077], + [34.816239, 31.913077], + [34.816238, 31.913047], + [34.816166, 31.913048], + [34.816167, 31.913079], + [34.816095, 31.91308], + [34.816095, 31.913049], + [34.816059, 31.91305], + [34.816023, 31.91305], + [34.816021, 31.912959], + [34.816057, 31.912958], + [34.816056, 31.912897], + [34.81602, 31.912897], + [34.816017, 31.912745], + [34.815981, 31.912745], + [34.815873, 31.912747], + [34.815828, 31.910458], + [34.815864, 31.910458], + [34.815863, 31.910397], + [34.815899, 31.910396], + [34.815897, 31.910274], + [34.815861, 31.910274], + [34.815858, 31.910122], + [34.815822, 31.910122], + [34.815818, 31.909939], + [34.815854, 31.909939], + [34.815854, 31.909908], + [34.815889, 31.909908], + [34.815888, 31.909847], + [34.815924, 31.909846], + [34.815923, 31.909816], + [34.815888, 31.909816], + [34.815887, 31.909786], + [34.815851, 31.909786], + [34.815852, 31.909817], + [34.815816, 31.909817], + [34.815812, 31.909634], + [34.815848, 31.909634], + [34.815848, 31.909603], + [34.815883, 31.909603], + [34.815882, 31.909542], + [34.815954, 31.909541], + [34.815952, 31.909449], + [34.816167, 31.909446], + [34.816166, 31.909354], + [34.81882, 31.909316], + [34.818821, 31.909377], + [34.818893, 31.909376], + [34.818929, 31.909376], + [34.818929, 31.909406], + [34.819252, 31.909402], + [34.81925, 31.90931], + [34.819896, 31.909301], + [34.819896, 31.909331], + [34.819932, 31.909331], + [34.819933, 31.909392], + [34.820364, 31.909386], + [34.8204, 31.909385], + [34.820406, 31.90969], + [34.820442, 31.90969], + [34.820477, 31.909689], + [34.820479, 31.909751], + [34.820514, 31.90975], + [34.820515, 31.909781], + [34.820551, 31.90978], + [34.820608, 31.912679], + [34.820536, 31.91268], + [34.820539, 31.912833], + [34.820468, 31.912834], + [34.820471, 31.912986], + [34.820363, 31.912988], + [34.820366, 31.913141], + [34.81642, 31.913197], + ], + ], ], - bbox:[34.815812,31.909301,34.820608,31.913197] + bbox: [34.815812, 31.909301, 34.820608, 31.913197], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -179,7 +260,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: 'XYZ_LAYER', url: 'https://tiles.openaerialmap.org/5b1388c02b6a08001185f4f3/0/5b1388c02b6a08001185f4f4/{z}/{x}/{y}.png', - meta: 'http://oin-hotosm.s3.amazonaws.com/5b1388c02b6a08001185f4f3/0/5b1388c02b6a08001185f4f4_meta.json' + meta: 'http://oin-hotosm.s3.amazonaws.com/5b1388c02b6a08001185f4f3/0/5b1388c02b6a08001185f4f4_meta.json', }, }, { @@ -188,32 +269,108 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ creationDate: new Date('2018-06-08T16:39:55.400Z'), description: '', geojson: { - type:'MultiPolygon', - coordinates:[[ - [ - [34.813942,32.041277],[34.813942,32.041233],[34.813916,32.041233],[34.813813,32.041235],[34.813812,32.041169],[34.813786,32.04117], - [34.813785,32.041126],[34.81376,32.041126],[34.813734,32.041127],[34.813733,32.041061],[34.813707,32.041061],[34.813656,32.041062], - [34.813653,32.040909],[34.813627,32.040909],[34.813602,32.04091],[34.8136,32.040844],[34.813575,32.040845],[34.813575,32.040866], - [34.813549,32.040867],[34.813521,32.039446],[34.813624,32.039444],[34.813624,32.039423],[34.813649,32.039422],[34.813648,32.039378], - [34.813751,32.039377],[34.81375,32.039311],[34.813775,32.039311],[34.813775,32.039289],[34.813852,32.039288],[34.813851,32.039266], - [34.813928,32.039265],[34.81393,32.039331],[34.814161,32.039327],[34.81416,32.039284],[34.814211,32.039283],[34.814211,32.039261], - [34.81457,32.039256],[34.81457,32.0393],[34.814801,32.039296],[34.8148,32.039253],[34.815236,32.039246],[34.815237,32.03929], - [34.81534,32.039289],[34.81534,32.039267],[34.815468,32.039265],[34.815467,32.039243],[34.815749,32.039239],[34.81575,32.039283], - [34.815853,32.039281],[34.815852,32.039238],[34.81598,32.039236],[34.816006,32.039235],[34.816007,32.039301],[34.816366,32.039296], - [34.816392,32.039295],[34.816401,32.039733],[34.816426,32.039732],[34.816452,32.039732],[34.816475,32.040912],[34.816424,32.040913], - [34.816428,32.041132],[34.816403,32.041132],[34.816403,32.041154],[34.816377,32.041154],[34.816378,32.041176],[34.816352,32.041177], - [34.816353,32.041198],[34.816301,32.041199],[34.816302,32.041221],[34.816327,32.041221],[34.816328,32.041243],[34.814789,32.041265], - [34.814788,32.041243],[34.814763,32.041243],[34.814763,32.041265],[34.814712,32.041266],[34.814711,32.041244],[34.814609,32.041245], - [34.814609,32.041267],[34.813942,32.041277] - ], + type: 'MultiPolygon', + coordinates: [ [ - [34.814956,32.039316],[34.815058,32.039314],[34.815058,32.039293],[34.814955,32.039294],[34.814956,32.039316] + [ + [34.813942, 32.041277], + [34.813942, 32.041233], + [34.813916, 32.041233], + [34.813813, 32.041235], + [34.813812, 32.041169], + [34.813786, 32.04117], + [34.813785, 32.041126], + [34.81376, 32.041126], + [34.813734, 32.041127], + [34.813733, 32.041061], + [34.813707, 32.041061], + [34.813656, 32.041062], + [34.813653, 32.040909], + [34.813627, 32.040909], + [34.813602, 32.04091], + [34.8136, 32.040844], + [34.813575, 32.040845], + [34.813575, 32.040866], + [34.813549, 32.040867], + [34.813521, 32.039446], + [34.813624, 32.039444], + [34.813624, 32.039423], + [34.813649, 32.039422], + [34.813648, 32.039378], + [34.813751, 32.039377], + [34.81375, 32.039311], + [34.813775, 32.039311], + [34.813775, 32.039289], + [34.813852, 32.039288], + [34.813851, 32.039266], + [34.813928, 32.039265], + [34.81393, 32.039331], + [34.814161, 32.039327], + [34.81416, 32.039284], + [34.814211, 32.039283], + [34.814211, 32.039261], + [34.81457, 32.039256], + [34.81457, 32.0393], + [34.814801, 32.039296], + [34.8148, 32.039253], + [34.815236, 32.039246], + [34.815237, 32.03929], + [34.81534, 32.039289], + [34.81534, 32.039267], + [34.815468, 32.039265], + [34.815467, 32.039243], + [34.815749, 32.039239], + [34.81575, 32.039283], + [34.815853, 32.039281], + [34.815852, 32.039238], + [34.81598, 32.039236], + [34.816006, 32.039235], + [34.816007, 32.039301], + [34.816366, 32.039296], + [34.816392, 32.039295], + [34.816401, 32.039733], + [34.816426, 32.039732], + [34.816452, 32.039732], + [34.816475, 32.040912], + [34.816424, 32.040913], + [34.816428, 32.041132], + [34.816403, 32.041132], + [34.816403, 32.041154], + [34.816377, 32.041154], + [34.816378, 32.041176], + [34.816352, 32.041177], + [34.816353, 32.041198], + [34.816301, 32.041199], + [34.816302, 32.041221], + [34.816327, 32.041221], + [34.816328, 32.041243], + [34.814789, 32.041265], + [34.814788, 32.041243], + [34.814763, 32.041243], + [34.814763, 32.041265], + [34.814712, 32.041266], + [34.814711, 32.041244], + [34.814609, 32.041245], + [34.814609, 32.041267], + [34.813942, 32.041277], + ], + [ + [34.814956, 32.039316], + [34.815058, 32.039314], + [34.815058, 32.039293], + [34.814955, 32.039294], + [34.814956, 32.039316], + ], + [ + [34.814481, 32.041247], + [34.81448, 32.041225], + [34.814583, 32.041224], + [34.814583, 32.041246], + [34.814481, 32.041247], + ], ], - [ - [34.814481,32.041247],[34.81448,32.041225],[34.814583,32.041224],[34.814583,32.041246],[34.814481,32.041247] - ] - ]], - bbox :[34.813521,32.039235,34.816475,32.041277] + ], + bbox: [34.813521, 32.039235, 34.816475, 32.041277], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -225,7 +382,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: 'XYZ_LAYER', url: 'https://tiles.openaerialmap.org/5b25fa612b6a08001185f80f/0/5b25fa612b6a08001185f810/{z}/{x}/{y}.png', - meta: 'http://oin-hotosm.s3.amazonaws.com/5b25fa612b6a08001185f80f/0/5b25fa612b6a08001185f810_meta.json' + meta: 'http://oin-hotosm.s3.amazonaws.com/5b25fa612b6a08001185f80f/0/5b25fa612b6a08001185f810_meta.json', }, }, { @@ -234,14 +391,16 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ creationDate: new Date('2021-01-07T10:39:55.400Z'), description: '', geojson: { - type:'Polygon', - coordinates:[[ - [34.81576, 31.91132], - [34.81901, 31.91126], - [34.81904, 31.90932], - [34.81569, 31.90938], - [34.81576, 31.91132], - ]], + type: 'Polygon', + coordinates: [ + [ + [34.81576, 31.91132], + [34.81901, 31.91126], + [34.81904, 31.90932], + [34.81569, 31.90938], + [34.81576, 31.91132], + ], + ], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -253,7 +412,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: '3D_LAYER', url: '/mock/Rehovot_solar_tileset/L16_31023/L16_31023.json', - meta: 'NOT_DEFINED' + meta: 'NOT_DEFINED', }, }, { @@ -262,14 +421,16 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ creationDate: new Date('2021-01-07T10:39:55.400Z'), description: '', geojson: { - type:'Polygon', - coordinates:[[ - [34.82720, 31.91292], - [34.83051, 31.91287], - [34.83042, 31.91093], - [34.82717, 31.91097], - [34.82720, 31.91292], - ]], + type: 'Polygon', + coordinates: [ + [ + [34.8272, 31.91292], + [34.83051, 31.91287], + [34.83042, 31.91093], + [34.82717, 31.91097], + [34.8272, 31.91292], + ], + ], }, referenceSystem: '', imagingTimeStart: new Date(), @@ -281,7 +442,7 @@ export const MOCK_DATA_IMAGERY_LAYERS_ISRAEL = [ properties: { protocol: '3D_LAYER', url: '/mock/Rehovot_solar_tileset/L16_31023/L16_31023.json', - meta: 'NOT_DEFINED' + meta: 'NOT_DEFINED', }, }, ]; diff --git a/src/__mocks__/confEnvShim.js b/src/__mocks__/confEnvShim.js index 2dac4efb8..a2fa1a3da 100644 --- a/src/__mocks__/confEnvShim.js +++ b/src/__mocks__/confEnvShim.js @@ -17,7 +17,8 @@ if (!window._env_) { }, ACTIVE_LAYER: 'ACTIVE_LAYER', ACTIVE_LAYER_PROPERTIES: { - urlPattern: 'arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS', + urlPattern: + 'arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS', urlPatternParams: { service: 'WMTS', layers: 'USGSShadedReliefOnly', @@ -53,7 +54,8 @@ if (!window._env_) { DEFAULT_USER: { role: 'USER', }, - BASE_MAPS: '{ "maps": [ { "id": "1st", "title": "1st Map", "isForPreview": true, "thumbnail": "https://mt1.google.com/vt/lyrs=s&x=6&y=4&z=3", "baseRasterLayers": [ { "id": "GOOGLE_TERRAIN", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 0, "options": { "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", "layers": "", "credit": "GOOGLE" } }, { "id": "INFRARED_RASTER", "type": "WMS_LAYER", "opacity": 0.6, "zIndex": 1, "options": { "url": "https://mesonet.agron.iastate.edu/cgi-bin/wms/goes/conus_ir.cgi?", "layers": "goes_conus_ir", "credit": "Infrared data courtesy Iowa Environmental Mesonet", "parameters": { "transparent": "true", "format": "image/png" } } } ] }, { "id": "2nd", "title": "2nd Map", "thumbnail": "https://mt1.google.com/vt/lyrs=s&x=6&y=4&z=3", "baseRasterLayers": [ { "id": "RADAR_RASTER", "type": "WMS_LAYER", "opacity": 0.6, "zIndex": 1, "options": { "url": "https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi?", "layers": "nexrad-n0r", "credit": "Radar data courtesy Iowa Environmental Mesonet", "parameters": { "transparent": "true", "format": "image/png" } } }, { "id": "GOOGLE_TERRAIN", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 0, "options": { "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", "layers": "", "credit": "GOOGLE" } }, { "id": "VECTOR_TILES_GPS", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 2, "options": { "url": "https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png", "layers": "", "credit": "openstreetmap" } } ] }, { "id": "3rd", "title": "3rd Map", "isCurrent": true, "thumbnail": "https://a.tile.thunderforest.com/cycle/17/78208/53265.png", "baseRasterLayers": [ { "id": "VECTOR_TILES", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 0, "options": { "url": "https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=6170aad10dfd42a38d4d8c709a536f38", "layers": "", "credit": "thunderforest" } }, { "id": "VECTOR_TILES_GPS", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 1, "options": { "url": "https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png", "layers": "", "credit": "openstreetmap" } } ] } ] }', + BASE_MAPS: + '{ "maps": [ { "id": "1st", "title": "1st Map", "isForPreview": true, "thumbnail": "https://mt1.google.com/vt/lyrs=s&x=6&y=4&z=3", "baseRasterLayers": [ { "id": "GOOGLE_TERRAIN", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 0, "options": { "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", "layers": "", "credit": "GOOGLE" } }, { "id": "INFRARED_RASTER", "type": "WMS_LAYER", "opacity": 0.6, "zIndex": 1, "options": { "url": "https://mesonet.agron.iastate.edu/cgi-bin/wms/goes/conus_ir.cgi?", "layers": "goes_conus_ir", "credit": "Infrared data courtesy Iowa Environmental Mesonet", "parameters": { "transparent": "true", "format": "image/png" } } } ] }, { "id": "2nd", "title": "2nd Map", "thumbnail": "https://mt1.google.com/vt/lyrs=s&x=6&y=4&z=3", "baseRasterLayers": [ { "id": "RADAR_RASTER", "type": "WMS_LAYER", "opacity": 0.6, "zIndex": 1, "options": { "url": "https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi?", "layers": "nexrad-n0r", "credit": "Radar data courtesy Iowa Environmental Mesonet", "parameters": { "transparent": "true", "format": "image/png" } } }, { "id": "GOOGLE_TERRAIN", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 0, "options": { "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", "layers": "", "credit": "GOOGLE" } }, { "id": "VECTOR_TILES_GPS", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 2, "options": { "url": "https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png", "layers": "", "credit": "openstreetmap" } } ] }, { "id": "3rd", "title": "3rd Map", "isCurrent": true, "thumbnail": "https://a.tile.thunderforest.com/cycle/17/78208/53265.png", "baseRasterLayers": [ { "id": "VECTOR_TILES", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 0, "options": { "url": "https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=6170aad10dfd42a38d4d8c709a536f38", "layers": "", "credit": "thunderforest" } }, { "id": "VECTOR_TILES_GPS", "type": "XYZ_LAYER", "opacity": 1, "zIndex": 1, "options": { "url": "https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png", "layers": "", "credit": "openstreetmap" } } ] } ] }', DEFAULT_TERRAIN_PROVIDER_URL: 'http://nginx-s3-gateway-URL', WEB_TOOLS_URL: 'http://mc-web-tools-URL', MODEL_VIEWER_ROUTE: 'simple-catalog-viewer', @@ -63,15 +65,18 @@ if (!window._env_) { autocomplete: false, }, NUMBER_OF_CHARACTERS_LIMIT: 18, - SERVED_ENTITY_TYPES: 'RECORD_ALL,RECORD_RASTER,RECORD_3D,RECORD_DEM,RECORD_VECTOR', + SERVED_ENTITY_TYPES: + 'RECORD_ALL,RECORD_RASTER,RECORD_3D,RECORD_DEM,RECORD_VECTOR', ACCESS_TOKEN: { attributeName: 'token', injectionType: 'queryParam', tokenValue: 'TOKEN', }, - RASTER_INGESTION_FILES_STRUCTURE: '{"data": {"allowedExt": [".gpkg"], "selectableExt": [".gpkg"], "relativeToAOIDirPath": "./data", "producerFileName": "*", "selectablePattern": "*"}, "product": {"allowedExt": [".shp", ".shx", ".dbf", ".prj", ".sbn", ".sbx", ".xml", ".cpg", ".qix"], "selectableExt": [".shp"], "relativeToAOIDirPath": "./shape", "producerFileName": "Product", "selectablePattern": "Product"}, "shapeMetadata": {"allowedExt": [".shp", ".shx", ".dbf", ".prj", ".sbn", ".sbx", ".xml", ".cpg", ".qix"], "selectableExt": [".shp"], "relativeToAOIDirPath": "./shape", "producerFileName": "ShapeMetadata", "selectablePattern": "ShapeMetadata"}}', + RASTER_INGESTION_FILES_STRUCTURE: + '{"data": {"allowedExt": [".gpkg"], "selectableExt": [".gpkg"], "relativeToAOIDirPath": "./data", "producerFileName": "*", "selectablePattern": "*"}, "product": {"allowedExt": [".shp", ".shx", ".dbf", ".prj", ".sbn", ".sbx", ".xml", ".cpg", ".qix"], "selectableExt": [".shp"], "relativeToAOIDirPath": "./shape", "producerFileName": "Product", "selectablePattern": "Product"}, "shapeMetadata": {"allowedExt": [".shp", ".shx", ".dbf", ".prj", ".sbn", ".sbx", ".xml", ".cpg", ".qix"], "selectableExt": [".shp"], "relativeToAOIDirPath": "./shape", "producerFileName": "ShapeMetadata", "selectablePattern": "ShapeMetadata"}}', WHATSNEW_URL: 'http://whatsnew-URL', - SITES_CONFIG: '{"masters": [{ "dns": "http://localhost:3000", "isAlias": false }], "slaves": [{ "dns": "http://localhost:8090", "isAlias": false }], "generics": [{ "dns": "https://catalog.mapcolonies.net", "isAlias": false }]}', + SITES_CONFIG: + '{"masters": [{ "dns": "http://localhost:3000", "isAlias": false }], "slaves": [{ "dns": "http://localhost:8090", "isAlias": false }], "generics": [{ "dns": "https://catalog.mapcolonies.net", "isAlias": false }]}', BFF_PATH: '/graphql', SELECTION_MODE_DEFAULT: '', SHOW_SELECTION_MODE_SWITCH: true, @@ -88,7 +93,8 @@ if (!window._env_) { }, }, WFS: { - style: '{"color": "#01FF1F", "hover": "#24AEE9", "pointStroke": "#01FF1F"}', + style: + '{"color": "#01FF1F", "hover": "#24AEE9", "pointStroke": "#01FF1F"}', keyField: 'id', max: { pageSize: 300, @@ -99,7 +105,7 @@ if (!window._env_) { GEOCODER: { url: 'http://geocoder-URL', callbackUrl: 'http://geocoder-callback-URL', - }, + }, CHANGES_IN_SHAPE_FILES: { timeDifferenceGraceMinutes: 10, timeModifiedThresholdHours: 12, diff --git a/src/common/actions/context.actions.ts b/src/common/actions/context.actions.ts index 0a7ba4418..777887de5 100644 --- a/src/common/actions/context.actions.ts +++ b/src/common/actions/context.actions.ts @@ -1,4 +1,3 @@ - import { TabViews } from '../../discrete-layer/views/tab-views'; import { IAction, IActionGroup } from './entity.actions'; @@ -33,15 +32,15 @@ export enum ContextActionsGroupTemplates { export enum ActionSpreadPreference { FLAT = 'flat', - MENU = 'menu' + MENU = 'menu', } -export type SeparatorPosition = "BEFORE" | "AFTER"; +export type SeparatorPosition = 'BEFORE' | 'AFTER'; export interface IContextAction extends IAction { templateId?: ContextActionsTemplates; separator?: SeparatorPosition; -}; +} export interface IContextActionGroup extends Omit { order: number; @@ -62,11 +61,12 @@ export interface IContextActions { groups: IContextActionGroup[]; } - // A "type guard" helper function used to infer if action is a group or a single action. -export const isActionGroup = (action: IContextAction | IContextActionGroup): action is IContextActionGroup => { +export const isActionGroup = ( + action: IContextAction | IContextActionGroup +): action is IContextActionGroup => { return (action as IContextActionGroup).actions !== undefined; -} +}; const DEFAULT_MINIMUM_ITEMS_IN_MENU = 2; @@ -79,14 +79,14 @@ const defaultContextActionProps: IAction = { views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }; -const defaultContextActionGroupProps: Omit = { +const defaultContextActionGroupProps: Omit = { id: 0, actionsSpreadPreference: ActionSpreadPreference.MENU, minimumItemsInMenu: DEFAULT_MINIMUM_ITEMS_IN_MENU, actions: [], titleTranslationId: '', - type: '' -} + type: '', +}; const CONTEXT_ACTIONS_CONFIG: IContextActions[] = [ { @@ -107,7 +107,7 @@ const CONTEXT_ACTIONS_CONFIG: IContextActions[] = [ ...defaultContextActionProps, templateId: ContextActionsTemplates.WFS_QUERY_FEATURES, action: ContextActions.QUERY_WFS_FEATURE, - } + }, ], }, { @@ -149,7 +149,7 @@ const CONTEXT_ACTIONS_CONFIG: IContextActions[] = [ ...defaultContextActionProps, titleTranslationId: 'map-context-menu.polygon-parts.title', action: ContextActions.QUERY_POLYGON_PARTS, - separator: 'AFTER' + separator: 'AFTER', }, { ...defaultContextActionProps, diff --git a/src/common/actions/entity.actions.ts b/src/common/actions/entity.actions.ts index eb4161156..835b36f58 100644 --- a/src/common/actions/entity.actions.ts +++ b/src/common/actions/entity.actions.ts @@ -16,7 +16,7 @@ export interface IAction { titleTranslationId: string; views: TabViews[]; dependentField?: DependentField; -}; +} export interface IActionGroup { id: number; @@ -39,8 +39,14 @@ export enum EntityActionsTypes { EXPORT_ACTIONS = 'exportActions', } -export const isDependentFieldWithValue = (dependentField?: DependentField): dependentField is DependentFieldWithValue => { - return typeof dependentField !== 'undefined' && typeof dependentField !== 'string' && 'expectedValue' in dependentField; +export const isDependentFieldWithValue = ( + dependentField?: DependentField +): dependentField is DependentFieldWithValue => { + return ( + typeof dependentField !== 'undefined' && + typeof dependentField !== 'string' && + 'expectedValue' in dependentField + ); }; const GENERAL_ACTIONS_GROUP: IActionGroup = { @@ -54,7 +60,7 @@ const GENERAL_ACTIONS_GROUP: IActionGroup = { icon: '', class: 'mc-icon-Fly-to', titleTranslationId: 'action.flyTo.tooltip', - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, { action: 'viewer', @@ -62,8 +68,12 @@ const GENERAL_ACTIONS_GROUP: IActionGroup = { icon: '', class: 'mc-icon-Earth', titleTranslationId: 'action.viewer.tooltip', - dependentField: {field: 'productStatus', expectedValue: RecordStatus.BEING_DELETED, operator: 'notEquals'}, - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + dependentField: { + field: 'productStatus', + expectedValue: RecordStatus.BEING_DELETED, + operator: 'notEquals', + }, + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, { action: 'export', @@ -71,8 +81,8 @@ const GENERAL_ACTIONS_GROUP: IActionGroup = { icon: '', class: 'mc-icon-Export', titleTranslationId: 'action.export.tooltip', - dependentField: {field: 'layerURLMissing', expectedValue: false}, - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + dependentField: { field: 'layerURLMissing', expectedValue: false }, + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, ], }; @@ -93,8 +103,8 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Edit1', titleTranslationId: 'action.edit.tooltip', - dependentField: {field: 'layerURLMissing', expectedValue: false}, - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + dependentField: { field: 'layerURLMissing', expectedValue: false }, + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, { action: 'update', @@ -102,12 +112,12 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Update', titleTranslationId: 'action.update.tooltip', - dependentField: {field: 'layerURLMissing', expectedValue: false}, - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + dependentField: { field: 'layerURLMissing', expectedValue: false }, + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, ], - } - ] + }, + ], }, { entity: 'Layer3DRecord', @@ -124,8 +134,12 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Edit1', titleTranslationId: 'action.edit.tooltip', - dependentField: {field: 'productStatus', expectedValue: RecordStatus.BEING_DELETED, operator: 'notEquals'}, - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + dependentField: { + field: 'productStatus', + expectedValue: RecordStatus.BEING_DELETED, + operator: 'notEquals', + }, + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, { action: 'delete', @@ -133,12 +147,16 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Delete', titleTranslationId: 'action.delete.tooltip', - dependentField: {field: 'productStatus', expectedValue: RecordStatus.BEING_DELETED, operator: 'notEquals'}, - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + dependentField: { + field: 'productStatus', + expectedValue: RecordStatus.BEING_DELETED, + operator: 'notEquals', + }, + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, ], }, - ] + ], }, { entity: 'VectorBestRecord', @@ -155,11 +173,11 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Edit1', titleTranslationId: 'action.edit.tooltip', - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, ], - } - ] + }, + ], }, { entity: 'QuantizedMeshBestRecord', @@ -176,11 +194,11 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Edit1', titleTranslationId: 'action.edit.tooltip', - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, ], - } - ] + }, + ], }, { entity: 'LayerDemRecord', @@ -197,7 +215,7 @@ const ACTIONS_CONFIG: IEntityActions[] = [ icon: '', class: 'mc-icon-Edit1', titleTranslationId: 'action.edit.tooltip', - views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] + views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS], }, // { // action: 'delete', @@ -208,8 +226,8 @@ const ACTIONS_CONFIG: IEntityActions[] = [ // views: [TabViews.CATALOG, TabViews.SEARCH_RESULTS] // }, ], - } - ] + }, + ], }, { entity: 'Job', @@ -262,10 +280,9 @@ const ACTIONS_CONFIG: IEntityActions[] = [ views: [], }, ], - } - ] - - } + }, + ], + }, ]; export default ACTIONS_CONFIG; diff --git a/src/common/components/auto-direction-box/auto-direction-box.component.tsx b/src/common/components/auto-direction-box/auto-direction-box.component.tsx index df04ea371..ac89eab86 100644 --- a/src/common/components/auto-direction-box/auto-direction-box.component.tsx +++ b/src/common/components/auto-direction-box/auto-direction-box.component.tsx @@ -1,8 +1,13 @@ -import { DetailedHTMLProps, HTMLAttributes, PropsWithChildren, forwardRef } from 'react'; +import { + DetailedHTMLProps, + HTMLAttributes, + PropsWithChildren, + forwardRef, +} from 'react'; export const AutoDirectionBox = forwardRef< HTMLElement, PropsWithChildren, HTMLElement>> >((props, ref) => { return ; -}); \ No newline at end of file +}); diff --git a/src/common/components/browser-compatibility-checker/browser-compatibility-checker.css b/src/common/components/browser-compatibility-checker/browser-compatibility-checker.css index 76e4a2422..4dd7b2198 100644 --- a/src/common/components/browser-compatibility-checker/browser-compatibility-checker.css +++ b/src/common/components/browser-compatibility-checker/browser-compatibility-checker.css @@ -13,4 +13,4 @@ white-space: pre-line; text-align: center; user-select: none; -} \ No newline at end of file +} diff --git a/src/common/components/browser-compatibility-checker/browser-compatibility-checker.tsx b/src/common/components/browser-compatibility-checker/browser-compatibility-checker.tsx index c26a9a0ab..007294140 100644 --- a/src/common/components/browser-compatibility-checker/browser-compatibility-checker.tsx +++ b/src/common/components/browser-compatibility-checker/browser-compatibility-checker.tsx @@ -5,7 +5,7 @@ import { Typography } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import CONFIG from '../../config'; -import './browser-compatibility-checker.css' +import './browser-compatibility-checker.css'; const uaParserObj = new UAParser(); const FIRST_ELEM = 0; @@ -34,14 +34,13 @@ export const BrowserCompatibilityChecker: React.FC = () => { return ( <> - { - (!isEngineChromium || !isBrowserVersionSupported) && + {(!isEngineChromium || !isBrowserVersionSupported) && ( {isEngineChromium ? browserTooOldErr : browserNotSupportedErr} - } + )} ); }; diff --git a/src/common/components/collapse-button/collapse.button.tsx b/src/common/components/collapse-button/collapse.button.tsx index eb73037f1..487e1fe15 100644 --- a/src/common/components/collapse-button/collapse.button.tsx +++ b/src/common/components/collapse-button/collapse.button.tsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import { Icon } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; - const BASE_ICON_ANGLE = 0; const UPSIDE_DOWN_ANGLE = 180; diff --git a/src/common/components/copy/copy.tsx b/src/common/components/copy/copy.tsx index dfd1e0683..774d3f1d6 100644 --- a/src/common/components/copy/copy.tsx +++ b/src/common/components/copy/copy.tsx @@ -20,29 +20,31 @@ export const Copy = (props: IProps) => { return ( <> - setIsCopied(true)}> + setIsCopied(true)} + > - { + {props.copyToClipboardChildren ? ( props.copyToClipboardChildren - ? props.copyToClipboardChildren - : { - setIsCopied(true); - }} - label={isCopied ? 'Success' : 'Copy'} - /> - } - { - isCopied && + ) : ( + { + setIsCopied(true); + }} + label={isCopied ? 'Success' : 'Copy'} + /> + )} + {isCopied && ( - } + )} - ) + ); }; diff --git a/src/common/components/error/graphql.error-presentor.tsx b/src/common/components/error/graphql.error-presentor.tsx index 16eb9cde1..3bc60001f 100644 --- a/src/common/components/error/graphql.error-presentor.tsx +++ b/src/common/components/error/graphql.error-presentor.tsx @@ -30,28 +30,34 @@ interface IServerErrorResponse { } export const GraphQLError: React.FC = ({ error }) => { - const intl = useIntl(); const formatMessage = (serverError: IServerError): string => { const status = serverError.serverResponse?.status ?? NONE; - const message = serverError.serverResponse?.data.message ? - serverError.serverResponse.data.message : - serverError.serverResponse?.statusText ?? ''; - if (status && status >= USER_ERROR_RESPONSE_CODE && status < SERVER_ERROR_RESPONSE_CODE) { - const translatedError = intl.formatMessage({ id: `general.http-${status}.error` }); + const message = serverError.serverResponse?.data.message + ? serverError.serverResponse.data.message + : serverError.serverResponse?.statusText ?? ''; + if ( + status && + status >= USER_ERROR_RESPONSE_CODE && + status < SERVER_ERROR_RESPONSE_CODE + ) { + const translatedError = intl.formatMessage({ + id: `general.http-${status}.error`, + }); return `${translatedError}
${message}`; - } else if (message) { + } else if (message) { return message; } else { - return serverError.message.substring(+serverError.message.indexOf('; ') + 1); + return serverError.message.substring( + +serverError.message.indexOf('; ') + 1 + ); } }; return ( <> - { - !isEmpty(error?.response) && + {!isEmpty(error?.response) && ( = ({ error }) => { }} />
    - { - error.response.errors?.map((error: IServerError, index: number) => { + {error.response.errors?.map( + (error: IServerError, index: number) => { return ( -
  • +
  • ); - }) - } - { - error.response.status >= USER_ERROR_RESPONSE_CODE && - error.response.status < SERVER_ERROR_RESPONSE_CODE && -
  • - } - { - error.response.status >= SERVER_ERROR_RESPONSE_CODE && -
  • - } + } + )} + {error.response.status >= USER_ERROR_RESPONSE_CODE && + error.response.status < SERVER_ERROR_RESPONSE_CODE && ( +
  • + +
  • + )} + {error.response.status >= SERVER_ERROR_RESPONSE_CODE && ( +
  • + +
  • + )}
- } + )} ); - }; diff --git a/src/common/components/error/logic.error-presentor.tsx b/src/common/components/error/logic.error-presentor.tsx index 41e7d4c05..ce6c140a8 100644 --- a/src/common/components/error/logic.error-presentor.tsx +++ b/src/common/components/error/logic.error-presentor.tsx @@ -12,17 +12,17 @@ interface ILogicErrorProps { } export const LogicError: React.FC = ({ errors }) => { - const intl = useIntl(); const iconButtonErrorLevel = React.useMemo(() => { - return errors.some((error) => error.level === 'error') ? 'error' : 'warning'; + return errors.some((error) => error.level === 'error') + ? 'error' + : 'warning'; }, [errors]); return ( <> - { - !isEmpty(errors) && + {!isEmpty(errors) && ( = ({ errors }) => { }} />
    - { - errors.map((error, index) => ( -
  • - )) - } + {errors.map((error, index) => ( +
  • + ))}
- } + )} ); - }; diff --git a/src/common/components/error/validations.error-presentor.tsx b/src/common/components/error/validations.error-presentor.tsx index 4a2c14cf8..0efa18c9b 100644 --- a/src/common/components/error/validations.error-presentor.tsx +++ b/src/common/components/error/validations.error-presentor.tsx @@ -13,31 +13,33 @@ interface IValidationsError { errors: Record; } -export const ValidationsError: React.FC = ({ errors })=> { +export const ValidationsError: React.FC = ({ errors }) => { return ( <> - { - Object.keys(errors).length > NONE && + {Object.keys(errors).length > NONE && ( - { e.preventDefault(); e.stopPropagation(); }} />
    - { - Object.keys(errors).map((key: string) => { - return errors[key].map((errorMessage: string, index: number) => { - return ( -
  • - ); - }) - }) - } + {Object.keys(errors).map((key: string) => { + return errors[key].map((errorMessage: string, index: number) => { + return ( +
  • + ); + }); + })}
- } + )} ); }; diff --git a/src/common/components/file-picker/file-picker.tsx b/src/common/components/file-picker/file-picker.tsx index 154418bd3..0821638a7 100644 --- a/src/common/components/file-picker/file-picker.tsx +++ b/src/common/components/file-picker/file-picker.tsx @@ -104,8 +104,9 @@ export const FilePickerComponent = React.forwardRef< } } else if (data.id === FilePickerActions.ChangeSelection.id) { setSelection((currentSelection) => { - const selectedIds = fpRef.current?.getFileSelection() as Set; - + const selectedIds = + fpRef.current?.getFileSelection() as Set; + if (!isMultiSelection && selectedIds.size > 1) { fpRef.current?.setFileSelection( new Set(currentSelection.files.map((file) => file.id)) diff --git a/src/common/components/form/field-label.tsx b/src/common/components/form/field-label.tsx index a1c76b579..3f259f7e6 100644 --- a/src/common/components/form/field-label.tsx +++ b/src/common/components/form/field-label.tsx @@ -19,7 +19,11 @@ export const FieldLabelComponent: React.FC = ({ showTooltip, }) => { return ( - + diff --git a/src/common/components/form/tooltipped.value.tsx b/src/common/components/form/tooltipped.value.tsx index 05cd1bada..bf6006a69 100644 --- a/src/common/components/form/tooltipped.value.tsx +++ b/src/common/components/form/tooltipped.value.tsx @@ -21,14 +21,25 @@ const TooltippedValue: React.FC> = ({ }) => { const elementRef = useRef(null); const isEllipsisActive = useIsEllipsisActive(elementRef); - const typographyElement = useMemo(() => ( - }> - {children} - - ), [children]); + const typographyElement = useMemo( + () => ( + } + > + {children} + + ), + [children] + ); return alwaysTooltip || (isEllipsisActive && !disableTooltip) ? ( - {typographyElement} + + {typographyElement} + ) : ( typographyElement ); diff --git a/src/common/components/gpu-insufficiency-detector/gpu-insufficiency-detector.css b/src/common/components/gpu-insufficiency-detector/gpu-insufficiency-detector.css index 4d24a0b43..855e938e6 100644 --- a/src/common/components/gpu-insufficiency-detector/gpu-insufficiency-detector.css +++ b/src/common/components/gpu-insufficiency-detector/gpu-insufficiency-detector.css @@ -1,40 +1,39 @@ - .gpuInsufficientError * { - padding: 0; - margin: 0; - box-sizing: border-box; + padding: 0; + margin: 0; + box-sizing: border-box; } .gpuInsufficientError { - display: flex; - flex-direction: column; - position: absolute; - top: 20px; - left: 50%; - align-items: center; - justify-content: center; - width: 70%; - min-height: 3rem; - background: var(--mdc-theme-gc-error-high); - z-index: 0; - transform: translateX(-50%); - white-space: pre-line; - gap: 12px; - padding: 12px 0; - text-align: center; + display: flex; + flex-direction: column; + position: absolute; + top: 20px; + left: 50%; + align-items: center; + justify-content: center; + width: 70%; + min-height: 3rem; + background: var(--mdc-theme-gc-error-high); + z-index: 0; + transform: translateX(-50%); + white-space: pre-line; + gap: 12px; + padding: 12px 0; + text-align: center; } .closeIconContainer { - position: absolute; - top: 12px; - right: 12px; + position: absolute; + top: 12px; + right: 12px; } .closeIcon { - color: var(--mdc-theme-text-secondary-on-background) !important; - scale: 1.5; + color: var(--mdc-theme-text-secondary-on-background) !important; + scale: 1.5; } .closeIcon:hover { - color: white !important; -} \ No newline at end of file + color: white !important; +} diff --git a/src/common/components/grid/cell-renderer/actions.cell-renderer.css b/src/common/components/grid/cell-renderer/actions.cell-renderer.css index 85e2f0078..dbfd442e9 100644 --- a/src/common/components/grid/cell-renderer/actions.cell-renderer.css +++ b/src/common/components/grid/cell-renderer/actions.cell-renderer.css @@ -45,7 +45,9 @@ body[dir='rtl'] #gridActionsCellRenderer.actionsContainer .actionIcon { right: 0; } -body[dir='rtl'] #gridActionsCellRenderer.actionsContainer > button:not(#allActionsIcon) { +body[dir='rtl'] + #gridActionsCellRenderer.actionsContainer + > button:not(#allActionsIcon) { right: unset; left: -20px; } @@ -61,7 +63,9 @@ body[dir='rtl'] #gridActionsCellRenderer.actionsContainer > button:not(#allActio /* position: fixed; */ } -body[dir='rtl'] #gridActionsMenuContainer .mdc-menu-surface.mdc-menu-surface--open { +body[dir='rtl'] + #gridActionsMenuContainer + .mdc-menu-surface.mdc-menu-surface--open { right: -160px !important; left: unset; } diff --git a/src/common/components/grid/cell-renderer/actions.cell-renderer.tsx b/src/common/components/grid/cell-renderer/actions.cell-renderer.tsx index ae57d0f2f..fcea43998 100644 --- a/src/common/components/grid/cell-renderer/actions.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/actions.cell-renderer.tsx @@ -1,9 +1,19 @@ import React, { useMemo, useState } from 'react'; import { ICellRendererParams } from 'ag-grid-community'; import { get, isEmpty } from 'lodash'; -import { IconButton, MenuSurfaceAnchor, Typography, Menu, MenuItem } from '@map-colonies/react-core'; +import { + IconButton, + MenuSurfaceAnchor, + Typography, + Menu, + MenuItem, +} from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; -import { IActionGroup, IAction, isDependentFieldWithValue } from '../../../actions/entity.actions'; +import { + IActionGroup, + IAction, + isDependentFieldWithValue, +} from '../../../actions/entity.actions'; import './actions.cell-renderer.css'; @@ -11,59 +21,69 @@ const FIRST = 0; const EMPTY_ACTION_GROUP = 0; interface IActionsRendererParams extends ICellRendererParams { - actions: Record; - actionHandler: (action: Record) => void; + actions: Record; + actionHandler: (action: Record) => void; } export const ActionsRenderer: React.FC = (props) => { - const entity = (props.data as Record).__typename as string; + const entity = (props.data as Record).__typename as string; - const filterActionsByDependentFields = (actions: IActionGroup[]): IActionGroup[] => { - const data = (props.data as Record); - const filteredActionGroups = actions.map(actionGroup => { - return ({ + const filterActionsByDependentFields = ( + actions: IActionGroup[] + ): IActionGroup[] => { + const data = props.data as Record; + const filteredActionGroups = actions.map((actionGroup) => { + return { ...actionGroup, - group: actionGroup.group.filter(action => { + group: actionGroup.group.filter((action) => { const { dependentField } = action; if (typeof dependentField === 'undefined') return true; - + if (isDependentFieldWithValue(dependentField)) { if (!(dependentField.field in data)) return true; - if (dependentField.operator === 'notEquals') { - return get(data, dependentField.field) !== dependentField.expectedValue; + if (dependentField.operator === 'notEquals') { + return ( + get(data, dependentField.field) !== dependentField.expectedValue + ); } - return get(data, dependentField.field) === dependentField.expectedValue; + return ( + get(data, dependentField.field) === dependentField.expectedValue + ); } - + return get(data, dependentField) as boolean; - }) - }) + }), + }; }); return filteredActionGroups; }; - const actions = useMemo(() => filterActionsByDependentFields(props.actions[entity]), [props.actions[entity]]); + const actions = useMemo( + () => filterActionsByDependentFields(props.actions[entity]), + [props.actions[entity]] + ); let frequentActions: IAction[] = []; let allFlatActions: IAction[] = []; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (actions !== undefined) { - actions.forEach(actionGroup => { + actions.forEach((actionGroup) => { frequentActions = [ ...frequentActions, - ...actionGroup.group.filter(action => action.frequent) - ]; - allFlatActions = [ - ...allFlatActions, - ...actionGroup.group + ...actionGroup.group.filter((action) => action.frequent), ]; + allFlatActions = [...allFlatActions, ...actionGroup.group]; }); } const [openActionsMenu, setOpenActionsMenu] = useState(false); - const sendAction = (entity: string, action: IAction, data: Record): void => { + const sendAction = ( + entity: string, + action: IAction, + data: Record + ): void => { console.log(`SEND for ${entity} ${action.action} EVENT`); props.actionHandler({ action: `${entity}.${action.action}`, @@ -73,74 +93,77 @@ export const ActionsRenderer: React.FC = (props) => { return ( - { - frequentActions.map((action, idx) => { - return ( - { - sendAction(entity, action, props.data); - }} - /> - ); - }) - } + {frequentActions.map((action, idx) => { + return ( + { + sendAction(entity, action, props.data); + }} + /> + ); + })} setOpenActionsMenu(false)} onMouseOver={(evt: React.MouseEvent): void => evt.stopPropagation()} > - { - actions.map((actionGroup: IActionGroup, groupIdx: number) => { - return ( - - {actionGroup.group.length > EMPTY_ACTION_GROUP && groupIdx > FIRST && + {actions.map((actionGroup: IActionGroup, groupIdx: number) => { + return ( + + {actionGroup.group.length > EMPTY_ACTION_GROUP && + groupIdx > FIRST && ( - } - {actionGroup.group.map((action: IAction, idx: number) => { - return ( - { - sendAction(entity, action, props.data); - setOpenActionsMenu(false); - }} - key={`menuItemAct_${action.action}_${idx}`}> - { + return ( + { + sendAction(entity, action, props.data); + setOpenActionsMenu(false); + }} + key={`menuItemAct_${action.action}_${idx}`} + > + + + - - - {action.titleTranslationId} - - - - ); - })} - - ) - }) - } + {action.titleTranslationId} + + + + ); + })} + + ); + })} - { - !isEmpty(allFlatActions) && - setOpenActionsMenu(!openActionsMenu)} /> - } + )} ); diff --git a/src/common/components/grid/cell-renderer/details-expander.cell-renderer.css b/src/common/components/grid/cell-renderer/details-expander.cell-renderer.css index 0369c1e21..7324ef312 100644 --- a/src/common/components/grid/cell-renderer/details-expander.cell-renderer.css +++ b/src/common/components/grid/cell-renderer/details-expander.cell-renderer.css @@ -12,4 +12,4 @@ #jobsDialog .ag-react-container > span:first-of-type { display: none; pointer-events: none; -} \ No newline at end of file +} diff --git a/src/common/components/grid/cell-renderer/details-expander.cell-renderer.spec.tsx b/src/common/components/grid/cell-renderer/details-expander.cell-renderer.spec.tsx index 4f9cd87b4..eba07dafb 100644 --- a/src/common/components/grid/cell-renderer/details-expander.cell-renderer.spec.tsx +++ b/src/common/components/grid/cell-renderer/details-expander.cell-renderer.spec.tsx @@ -1,6 +1,13 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { ICellRendererParams, Column, RowNode, GridApi, ColumnApi, IRowNode } from 'ag-grid-community'; +import { + ICellRendererParams, + Column, + RowNode, + GridApi, + ColumnApi, + IRowNode, +} from 'ag-grid-community'; // eslint-disable-next-line import '../../../../__mocks__/confEnvShim'; import { DETAILS_ROW_ID_SUFFIX } from '../grid'; @@ -8,15 +15,15 @@ import { DetailsExpanderRenderer } from './details-expander.cell-renderer'; const ID = '1'; /* eslint-disable */ -const mockDataBase:ICellRendererParams = { +const mockDataBase: ICellRendererParams = { value: '', valueFormatted: null, getValue: () => {}, setValue: () => {}, formatValue: () => {}, data: { - isVisible:true, - id: ID, + isVisible: true, + id: ID, }, node: new RowNode(), colDef: {}, @@ -24,7 +31,9 @@ const mockDataBase:ICellRendererParams = { rowIndex: 1, api: { onFilterChanged: () => {}, - getRowNode: (id: string):IRowNode | undefined => {return undefined}, + getRowNode: (id: string): IRowNode | undefined => { + return undefined; + }, }, context: null, refreshCell: () => {}, @@ -37,12 +46,10 @@ const mockDataBase:ICellRendererParams = { describe('AgGrid DetailsExpanderRenderer component', () => { it('renders correctly', () => { const mockData = { - ...mockDataBase + ...mockDataBase, }; - const wrapper = shallow( - - ); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); @@ -54,23 +61,22 @@ describe('AgGrid DetailsExpanderRenderer component', () => { // eslint-disable-next-line jest.spyOn(mockData.api, 'onFilterChanged').mockImplementation(() => {}); - const spyGetRonNode = jest.spyOn(mockData.api, 'getRowNode').mockImplementation(() => { - const val = new RowNode(); - // eslint-disable-next-line - val.setDataValue = (propName, val) => {}; - val.data = { - isVisible: false - }; - return val; - }); + const spyGetRonNode = jest + .spyOn(mockData.api, 'getRowNode') + .mockImplementation(() => { + const val = new RowNode(); + // eslint-disable-next-line + val.setDataValue = (propName, val) => {}; + val.data = { + isVisible: false, + }; + return val; + }); + + const wrapper = shallow(); - const wrapper = shallow( - - ); - const iconContainer = wrapper.find('CollapseButton'); iconContainer.simulate('click'); expect(spyGetRonNode).toHaveBeenCalledWith(`${ID}${DETAILS_ROW_ID_SUFFIX}`); }); - }); diff --git a/src/common/components/grid/cell-renderer/details-expander.cell-renderer.tsx b/src/common/components/grid/cell-renderer/details-expander.cell-renderer.tsx index aee31c384..287230ff6 100644 --- a/src/common/components/grid/cell-renderer/details-expander.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/details-expander.cell-renderer.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { ICellRendererParams } from 'ag-grid-community'; -import {CollapseButton} from '../../collapse-button/collapse.button'; +import { CollapseButton } from '../../collapse-button/collapse.button'; import { DETAILS_ROW_ID_SUFFIX, IGridRowDataDetailsExt } from '../grid'; import './details-expander.cell-renderer.css'; @@ -9,17 +9,22 @@ interface DetailsExpanderRendererProps extends ICellRendererParams { detailsRowCellRendererPresencePredicate?: (data: any) => boolean; } -export const DetailsExpanderRenderer: React.FC = (props): JSX.Element | null => { - const shouldRenderBtn = props.detailsRowCellRendererPresencePredicate?.(props.data) ?? true; +export const DetailsExpanderRenderer: React.FC = ( + props +): JSX.Element | null => { + const shouldRenderBtn = + props.detailsRowCellRendererPresencePredicate?.(props.data) ?? true; const handleCollapseExpand = (): void => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - const rowNode = props.api.getRowNode(`${props.data?.id as string}${DETAILS_ROW_ID_SUFFIX}`); + const rowNode = props.api.getRowNode( + `${props.data?.id as string}${DETAILS_ROW_ID_SUFFIX}` + ); const isVisible = (rowNode?.data as IGridRowDataDetailsExt).isVisible; rowNode?.setDataValue('isVisible', !isVisible); props.api.onFilterChanged(); }; - if (shouldRenderBtn) return + if (shouldRenderBtn) return ; return null; }; diff --git a/src/common/components/grid/cell-renderer/footprint.cell-renderer.tsx b/src/common/components/grid/cell-renderer/footprint.cell-renderer.tsx index 94928e72c..f3a30e1b4 100644 --- a/src/common/components/grid/cell-renderer/footprint.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/footprint.cell-renderer.tsx @@ -6,21 +6,24 @@ import { GridRowNode } from '..'; import './footprint.cell-renderer.css'; interface IFootprintCellRendererParams extends ICellRendererParams { - onClick: (id: string, value: boolean, node: GridRowNode) => void; + onClick: (id: string, value: boolean, node: GridRowNode) => void; } -export const FootprintRenderer: React.FC = (props) => { +export const FootprintRenderer: React.FC = ( + props +) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - const [checked, setChecked] = useState(props.data.footprintShown as boolean); + const [checked, setChecked] = useState( + props.data.footprintShown as boolean + ); return ( - ): void => { - setChecked(evt.currentTarget.checked); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - props.onClick(props.data.id, evt.currentTarget.checked, props.node); - }} + onChange={(evt: React.MouseEvent): void => { + setChecked(evt.currentTarget.checked); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + props.onClick(props.data.id, evt.currentTarget.checked, props.node); + }} /> - ); + ); }; diff --git a/src/common/components/grid/cell-renderer/icon.cell-renderer.tsx b/src/common/components/grid/cell-renderer/icon.cell-renderer.tsx index 71239d1ab..be171a55e 100644 --- a/src/common/components/grid/cell-renderer/icon.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/icon.cell-renderer.tsx @@ -5,17 +5,17 @@ import { Icon } from '@map-colonies/react-core'; import './icon.cell-renderer.css'; export const IconRenderer: React.FC = (props) => { - return ( <> - { - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - props.value && - } + { + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + props.value && ( + + ) + } ); - }; diff --git a/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.css b/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.css index 4a0860322..e915e0ce7 100644 --- a/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.css +++ b/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.css @@ -1,4 +1,4 @@ .productTypeIconContainer { - display: flex; - justify-content: flex-end; -} \ No newline at end of file + display: flex; + justify-content: flex-end; +} diff --git a/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.tsx b/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.tsx index fd8f57aff..9e68fe97b 100644 --- a/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/job-product-type.cell-renderer.tsx @@ -9,14 +9,17 @@ interface IProductTypeCellRendererParams extends ICellRendererParams { style?: Record; } -export const JobProductTypeRenderer: React.FC = (props) => { - +export const JobProductTypeRenderer: React.FC< + IProductTypeCellRendererParams +> = (props) => { const data = props.data as JobModelType; return ( - - + + ); - }; diff --git a/src/common/components/grid/cell-renderer/layer-details.cell-renderer.spec.tsx b/src/common/components/grid/cell-renderer/layer-details.cell-renderer.spec.tsx index f16660386..2587319d6 100644 --- a/src/common/components/grid/cell-renderer/layer-details.cell-renderer.spec.tsx +++ b/src/common/components/grid/cell-renderer/layer-details.cell-renderer.spec.tsx @@ -1,13 +1,19 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { ICellRendererParams, Column, RowNode, GridApi, ColumnApi } from 'ag-grid-community'; +import { + ICellRendererParams, + Column, + RowNode, + GridApi, + ColumnApi, +} from 'ag-grid-community'; import timezoneMock from 'timezone-mock'; // eslint-disable-next-line import '../../../../__mocks__/confEnvShim'; import { LayerDetailsRenderer } from './layer-details.cell-renderer'; /* eslint-disable */ -const mockDataBase:ICellRendererParams = { +const mockDataBase: ICellRendererParams = { value: '', valueFormatted: null, getValue: () => {}, @@ -39,24 +45,20 @@ describe('AgGrid LayerDetailsRenderer component', () => { it('renders correctly', () => { const mockData = { - ...mockDataBase + ...mockDataBase, }; - const wrapper = shallow( - - ); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); it('data fields presented as TOTAL_PARTS = NUM_SPAN_PER_FIELD * NUM_FIEDLS', () => { const mockData = { - ...mockDataBase + ...mockDataBase, }; - const wrapper = shallow( - - ); + const wrapper = shallow(); const spans = wrapper.find('span'); expect(spans).toHaveLength(NUM_SPAN_PER_FIELD * NUM_FIEDLS); diff --git a/src/common/components/grid/cell-renderer/layer-details.cell-renderer.tsx b/src/common/components/grid/cell-renderer/layer-details.cell-renderer.tsx index 7af27bc2a..2bad11952 100644 --- a/src/common/components/grid/cell-renderer/layer-details.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/layer-details.cell-renderer.tsx @@ -2,14 +2,18 @@ import React from 'react'; import { ICellRendererParams } from 'ag-grid-community'; import { FormattedMessage } from 'react-intl'; import { Box } from '@map-colonies/react-components'; -import { dateFormatter, FormatterFunc, stringFormatter } from '../../../helpers/formatters'; +import { + dateFormatter, + FormatterFunc, + stringFormatter, +} from '../../../helpers/formatters'; import './layer-details.cell-renderer.css'; interface DetailsProp { - propName: string, - propLabelId: string, - formatter: FormatterFunc + propName: string; + propLabelId: string; + formatter: FormatterFunc; } const detailsPropsLayout = new Array( @@ -69,37 +73,31 @@ const detailsPropsLayout = new Array( ] ); -export const LayerDetailsRenderer: React.FC = ( - props -) => { +export const LayerDetailsRenderer: React.FC = (props) => { return ( - { - detailsPropsLayout.map((layoutColumn,i) => { + {detailsPropsLayout.map((layoutColumn, i) => { return ( - - { - layoutColumn.map((item:DetailsProp, ii) => { - return( - - - :  - - - { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - item.formatter(props.data[item.propName]) - } - - - ) - }) - } + + {layoutColumn.map((item: DetailsProp, ii) => { + return ( + + + + :  + + + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + item.formatter(props.data[item.propName]) + } + + + ); + })} - ) - }) - } - + ); + })} + ); - }; diff --git a/src/common/components/grid/cell-renderer/layer-image.cell-renderer.tsx b/src/common/components/grid/cell-renderer/layer-image.cell-renderer.tsx index 28b3fdd02..3779edca4 100644 --- a/src/common/components/grid/cell-renderer/layer-image.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/layer-image.cell-renderer.tsx @@ -2,7 +2,10 @@ import React, { useEffect, useState } from 'react'; import { ICellRendererParams } from 'ag-grid-community'; import { IconButton } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; -import { isBeingDeleted, isValidLayerMetadata } from '../../../helpers/layer-url'; +import { + isBeingDeleted, + isValidLayerMetadata, +} from '../../../helpers/layer-url'; import { GridRowNode } from '..'; import './layer-image.cell-renderer.css'; @@ -11,9 +14,13 @@ interface ILayerImageCellRendererParams extends ICellRendererParams { onClick: (id: string, value: boolean, node: GridRowNode) => void; } -export const LayerImageRenderer: React.FC = (props) => { +export const LayerImageRenderer: React.FC = ( + props +) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - const [layerImageShown, setLayerImageShown] = useState(props.data.layerImageShown as boolean); + const [layerImageShown, setLayerImageShown] = useState( + props.data.layerImageShown as boolean + ); useEffect(() => { if (layerImageShown && isBeingDeleted(props.data)) { @@ -22,19 +29,25 @@ export const LayerImageRenderer: React.FC = (prop }, [props.data?.productStatus]); return ( - + { - if (isValidLayerMetadata(props.data)) { - setLayerImageShown(!layerImageShown); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - props.onClick(props.data.id, !layerImageShown, props.node); - } + onClick={(): void => { + if (isValidLayerMetadata(props.data)) { + setLayerImageShown(!layerImageShown); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + props.onClick(props.data.id, !layerImageShown, props.node); } - } + }} /> ); diff --git a/src/common/components/grid/cell-renderer/product-type.cell-renderer.tsx b/src/common/components/grid/cell-renderer/product-type.cell-renderer.tsx index ec6d4203c..1ebc28001 100644 --- a/src/common/components/grid/cell-renderer/product-type.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/product-type.cell-renderer.tsx @@ -2,7 +2,10 @@ import React, { useMemo } from 'react'; import { ICellRendererParams } from 'ag-grid-community'; import { getLinkUrlWithToken } from '../../../../discrete-layer/components/helpers/layersUtils'; import { ILayerImage } from '../../../../discrete-layer/models/layerImage'; -import { LayerRasterRecordModelType, LinkModelType } from '../../../../discrete-layer/models'; +import { + LayerRasterRecordModelType, + LinkModelType, +} from '../../../../discrete-layer/models'; import { getIconStyle } from '../../../helpers/style'; import { LinkType } from '../../../models/link-type.enum'; import { TypeIcon } from '../../shared/type-icon'; @@ -13,28 +16,43 @@ interface IProductTypeCellRendererParams extends ICellRendererParams { onClick?: (data: ILayerImage, value: boolean, gridApi: GridApi) => void; } -export const ProductTypeRenderer: React.FC = (props) => { +export const ProductTypeRenderer: React.FC = ( + props +) => { const data = props.data as ILayerImage; const handleClick = (event: React.MouseEvent) => { if (props.onClick) { - props.onClick(data, !(data as LayerRasterRecordModelType).polygonPartsShown, props.api); + props.onClick( + data, + !(data as LayerRasterRecordModelType).polygonPartsShown, + props.api + ); } }; const computedStyle = useMemo(() => { return { ...(props.style ?? {}), - ...(getIconStyle(data as any, 'color') ?? {}) + ...(getIconStyle(data as any, 'color') ?? {}), }; }, [props.style, data]); return ( ); }; diff --git a/src/common/components/grid/cell-renderer/styled-by-data.cell-renderer.tsx b/src/common/components/grid/cell-renderer/styled-by-data.cell-renderer.tsx index 88717efc8..01f1fcfb5 100644 --- a/src/common/components/grid/cell-renderer/styled-by-data.cell-renderer.tsx +++ b/src/common/components/grid/cell-renderer/styled-by-data.cell-renderer.tsx @@ -4,11 +4,9 @@ import { Typography } from '@map-colonies/react-core'; import { getIconStyle } from '../../../helpers/style'; export const StyledByDataRenderer: React.FC = (props) => { - return ( {props.value} ); - }; diff --git a/src/common/components/grid/grid.tsx b/src/common/components/grid/grid.tsx index cb3a9a325..2c7583ef7 100644 --- a/src/common/components/grid/grid.tsx +++ b/src/common/components/grid/grid.tsx @@ -14,9 +14,9 @@ import { IRowNode, RowHeightParams, RowClickedEvent, - AllCommunityModule, - ModuleRegistry, - IsFullWidthRowParams + AllCommunityModule, + ModuleRegistry, + IsFullWidthRowParams, } from 'ag-grid-community'; import { useTheme } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; @@ -43,47 +43,48 @@ interface GridComponentProps { focusByRowId?: string; setIsRowFound?: (val: boolean) => void; handleFocusError?: (error: IError | undefined) => void; -}; +} -export interface GridApi extends AgGridApi{}; -export interface GridReadyEvent extends AgGridReadyEvent{}; -export interface GridCellMouseOutEvent extends CellMouseOutEvent{}; -export interface GridCellMouseOverEvent extends CellMouseOverEvent{}; -export interface GridRowDragEnterEvent extends RowDragEnterEvent{}; -export interface GridRowDragEndEvent extends RowDragEndEvent{}; -export interface GridRowSelectedEvent extends RowSelectedEvent{}; -export interface GridRowClickedEvent extends RowClickedEvent{}; -export interface GridValueFormatterParams extends ValueFormatterParams{}; +export interface GridApi extends AgGridApi {} +export interface GridReadyEvent extends AgGridReadyEvent {} +export interface GridCellMouseOutEvent extends CellMouseOutEvent {} +export interface GridCellMouseOverEvent extends CellMouseOverEvent {} +export interface GridRowDragEnterEvent extends RowDragEnterEvent {} +export interface GridRowDragEndEvent extends RowDragEndEvent {} +export interface GridRowSelectedEvent extends RowSelectedEvent {} +export interface GridRowClickedEvent extends RowClickedEvent {} +export interface GridValueFormatterParams extends ValueFormatterParams {} export interface GridComponentOptions extends GridOptions { detailsRowCellRenderer?: string; detailsRowHeight?: number; detailsRowExpanderPosition?: 'start' | 'end'; context?: { detailsRowCellRendererPresencePredicate?: (data: any) => boolean; - } -}; + }; +} export interface IGridRowDataDetailsExt { rowHeight: number; fullWidth: boolean; isVisible: boolean; -}; +} export interface IRowPosition { pageNumber: number; rowIndex: number; } -export interface GridRowNode extends IRowNode {}; +export interface GridRowNode extends IRowNode {} export const GridComponent: React.FC = (props) => { - const [rowData, setRowData] = useState() + const [rowData, setRowData] = useState(); const theme = useTheme(); const [gridApi, setGridApi] = useState(); - const {focusByRowId, setIsRowFound, handleFocusError} = props - - const {detailsRowExpanderPosition, ...restGridOptions} = props.gridOptions as GridComponentOptions; + const { focusByRowId, setIsRowFound, handleFocusError } = props; + + const { detailsRowExpanderPosition, ...restGridOptions } = + props.gridOptions as GridComponentOptions; const gridOptionsFromProps: GridComponentOptions = { ...restGridOptions, @@ -92,71 +93,91 @@ export const GridComponent: React.FC = (props) => { field: 'isVisible', hide: true, }, - (props.gridOptions?.detailsRowExpanderPosition === 'start' && props.gridOptions.detailsRowCellRenderer !== undefined) ? - { - headerName: '', - width: EXPANDER_COLUMN_WIDTH, - cellRenderer: 'detailsExpanderRenderer', - suppressMovable: true, - sortable: false, - cellRendererParams: { - detailsRowCellRendererPresencePredicate: props.gridOptions.context?.detailsRowCellRendererPresencePredicate + props.gridOptions?.detailsRowExpanderPosition === 'start' && + props.gridOptions.detailsRowCellRenderer !== undefined + ? { + headerName: '', + width: EXPANDER_COLUMN_WIDTH, + cellRenderer: 'detailsExpanderRenderer', + suppressMovable: true, + sortable: false, + cellRendererParams: { + detailsRowCellRendererPresencePredicate: + props.gridOptions.context + ?.detailsRowCellRendererPresencePredicate, + }, + } + : { + hide: true, + }, + ...(props.gridOptions?.columnDefs as []), + props.gridOptions?.detailsRowExpanderPosition !== 'start' && + props.gridOptions?.detailsRowCellRenderer !== undefined + ? { + headerName: '', + width: EXPANDER_COLUMN_WIDTH, + cellRenderer: 'detailsExpanderRenderer', + suppressMovable: true, + sortable: false, + cellRendererParams: { + detailsRowCellRendererPresencePredicate: + props.gridOptions.context + ?.detailsRowCellRendererPresencePredicate, + }, + } + : { + hide: true, + }, + ], + getRowHeight: + props.gridOptions?.detailsRowCellRenderer !== undefined + ? (params: RowHeightParams): number => { + return (params.data as IGridRowDataDetailsExt).rowHeight; } - } : - { - hide: true, - }, - ...props.gridOptions?.columnDefs as [], - (props.gridOptions?.detailsRowExpanderPosition !== 'start' && props.gridOptions?.detailsRowCellRenderer !== undefined) ? - { - headerName: '', - width: EXPANDER_COLUMN_WIDTH, - cellRenderer: 'detailsExpanderRenderer', - suppressMovable: true, - sortable: false, - cellRendererParams: { - detailsRowCellRendererPresencePredicate: props.gridOptions.context?.detailsRowCellRendererPresencePredicate + : undefined, + isExternalFilterPresent: + props.gridOptions?.detailsRowCellRenderer !== undefined + ? (): boolean => true + : undefined, + doesExternalFilterPass: + props.gridOptions?.detailsRowCellRenderer !== undefined + ? (node): boolean => { + return (node.data as IGridRowDataDetailsExt).isVisible; + //return gridOptions.api.getValue("isVisible", node.rowNode); } - } : - { - hide: true, - }, - ], - getRowHeight: props.gridOptions?.detailsRowCellRenderer !== undefined ? (params: RowHeightParams): number => { - return (params.data as IGridRowDataDetailsExt).rowHeight; - } : undefined, - isExternalFilterPresent: props.gridOptions?.detailsRowCellRenderer !== undefined ? (): boolean => true : undefined, - doesExternalFilterPass: props.gridOptions?.detailsRowCellRenderer !== undefined ? (node): boolean => { - return (node.data as IGridRowDataDetailsExt).isVisible; - //return gridOptions.api.getValue("isVisible", node.rowNode); - } : undefined, - isFullWidthRow: props.gridOptions?.detailsRowCellRenderer !== undefined ? (params: IsFullWidthRowParams): boolean => { - // checked the fullWidth attribute that was set while creating the data - return (params.rowNode.data as IGridRowDataDetailsExt).fullWidth; - } : undefined, - fullWidthCellRenderer: props.gridOptions?.detailsRowCellRenderer ?? undefined, - - components: { - ...props.gridOptions?.components as {[key: string]: any}, - detailsExpanderRenderer: useCallback(DetailsExpanderRenderer, []), - }, - localeText: GRID_MESSAGES[CONFIG.I18N.DEFAULT_LANGUAGE], - onGridReady(params: GridReadyEvent) { - if (typeof(restGridOptions.onGridReady) === 'function') { - restGridOptions.onGridReady(params); - } - - setGridApi(params.api); - }, + : undefined, + isFullWidthRow: + props.gridOptions?.detailsRowCellRenderer !== undefined + ? (params: IsFullWidthRowParams): boolean => { + // checked the fullWidth attribute that was set while creating the data + return (params.rowNode.data as IGridRowDataDetailsExt).fullWidth; + } + : undefined, + fullWidthCellRenderer: + props.gridOptions?.detailsRowCellRenderer ?? undefined, + + components: { + ...(props.gridOptions?.components as { [key: string]: any }), + detailsExpanderRenderer: useCallback(DetailsExpanderRenderer, []), + }, + localeText: GRID_MESSAGES[CONFIG.I18N.DEFAULT_LANGUAGE], + onGridReady(params: GridReadyEvent) { + if (typeof restGridOptions.onGridReady === 'function') { + restGridOptions.onGridReady(params); + } + + setGridApi(params.api); + }, }; - const {detailsRowCellRenderer, detailsRowHeight, ...gridOptions} = gridOptionsFromProps; + const { detailsRowCellRenderer, detailsRowHeight, ...gridOptions } = + gridOptionsFromProps; - const getIsVisible = (id:string): boolean => { + const getIsVisible = (id: string): boolean => { let res = false; gridApi?.forEachNode((node) => { - const nodeData = node.data as Record; + const nodeData = node.data as Record; if (nodeData.id === id) { res = nodeData.isVisible as boolean; } @@ -167,20 +188,26 @@ export const GridComponent: React.FC = (props) => { useEffect(() => { const result: any[] = []; if (props.gridOptions?.detailsRowCellRenderer !== undefined) { - props.rowData?.forEach((element,idx) => { - const rowElement: Record = element as Record; + props.rowData?.forEach((element, idx) => { + const rowElement: Record = element as Record< + string, + unknown + >; result.push({ ...rowElement, - isVisible: true + isVisible: true, }); result.push({ - ...rowElement, + ...rowElement, fullWidth: true, // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access id: `${rowElement.id as string}${DETAILS_ROW_ID_SUFFIX}`, - isVisible: getIsVisible(`${rowElement.id as string}${DETAILS_ROW_ID_SUFFIX}`), - rowHeight: props.gridOptions?.detailsRowHeight ?? DEFAULT_DETAILS_ROW_HEIGHT, + isVisible: getIsVisible( + `${rowElement.id as string}${DETAILS_ROW_ID_SUFFIX}` + ), + rowHeight: + props.gridOptions?.detailsRowHeight ?? DEFAULT_DETAILS_ROW_HEIGHT, }); }); } else { @@ -188,13 +215,12 @@ export const GridComponent: React.FC = (props) => { } if (typeof props.isLoading === 'undefined' || props.isLoading === false) { setRowData(result); - if(result){ - gridApi?.setGridOption("loading", false); + if (result) { + gridApi?.setGridOption('loading', false); } } else { - gridApi?.setGridOption("loading", true); + gridApi?.setGridOption('loading', true); } - }, [props.rowData, props.gridOptions, props.isLoading]); useEffect(() => { @@ -205,7 +231,10 @@ export const GridComponent: React.FC = (props) => { focusAndExpandRow(gridApi, focusByRowId); }, [rowData]); - const getRowPosition = (gridApi: GridApi, id: string): IRowPosition | undefined => { + const getRowPosition = ( + gridApi: GridApi, + id: string + ): IRowPosition | undefined => { const node = gridApi.getRowNode(id); if (!node || node.rowIndex == null) { @@ -219,8 +248,8 @@ export const GridComponent: React.FC = (props) => { return { pageNumber, rowIndex, - } - } + }; + }; const goToRowAndFocus = (gridApi: GridApi, row: IRowPosition) => { gridApi.paginationGoToPage(row.pageNumber); @@ -235,7 +264,7 @@ export const GridComponent: React.FC = (props) => { handleFocusError?.({ code: 'warning.row-not-found', message: '', - level: 'warning' + level: 'warning', }); setIsRowFound?.(false); return; @@ -244,26 +273,27 @@ export const GridComponent: React.FC = (props) => { handleFocusError?.(undefined); setIsRowFound?.(true); goToRowAndFocus(gridApi, row); - - const rowNode = gridApi.getRowNode(`${id as unknown as string}${DETAILS_ROW_ID_SUFFIX}`); + + const rowNode = gridApi.getRowNode( + `${id as unknown as string}${DETAILS_ROW_ID_SUFFIX}` + ); rowNode?.setDataValue('isVisible', true); gridApi.onFilterChanged(); }; const agGridThemeOverrides = GridThemes.getTheme(theme); - + return ( - + ); }; diff --git a/src/common/components/grid/header-renderer/footprint.header-renderer.css b/src/common/components/grid/header-renderer/footprint.header-renderer.css index 3abf50cf6..1a1edf8e6 100644 --- a/src/common/components/grid/header-renderer/footprint.header-renderer.css +++ b/src/common/components/grid/header-renderer/footprint.header-renderer.css @@ -1,3 +1,7 @@ -body[dir='rtl'] .ag-theme-alpine-dark .ag-header .ag-react-container .mdc-checkbox { - position: unset; +body[dir='rtl'] + .ag-theme-alpine-dark + .ag-header + .ag-react-container + .mdc-checkbox { + position: unset; } diff --git a/src/common/components/grid/header-renderer/footprint.header-renderer.tsx b/src/common/components/grid/header-renderer/footprint.header-renderer.tsx index 8d1e514d0..d24c7e619 100644 --- a/src/common/components/grid/header-renderer/footprint.header-renderer.tsx +++ b/src/common/components/grid/header-renderer/footprint.header-renderer.tsx @@ -7,21 +7,22 @@ import './footprint.header-renderer.css'; interface IFootprintCellRendererParams extends ICellRendererParams { isChecked: boolean; - onClick: (value: boolean, gridApi: GridApi) => void; + onClick: (value: boolean, gridApi: GridApi) => void; } -export const HeaderFootprintRenderer: React.FC = (props) => { +export const HeaderFootprintRenderer: React.FC = ( + props +) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const [checked, setChecked] = useState(props.isChecked); return ( - ): void => { - setChecked(evt.currentTarget.checked); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - props.onClick(evt.currentTarget.checked, props.api); - }} + onClick={(evt: React.MouseEvent): void => { + setChecked(evt.currentTarget.checked); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + props.onClick(evt.currentTarget.checked, props.api); + }} /> - ); + ); }; diff --git a/src/common/components/grid/themes/themes.ts b/src/common/components/grid/themes/themes.ts index fed4f6345..361724c4c 100644 --- a/src/common/components/grid/themes/themes.ts +++ b/src/common/components/grid/themes/themes.ts @@ -9,21 +9,30 @@ export class GridThemes { // "--ag-header-background-color": 'green', // }, public static getTheme(mainTheme: IOptions): IOptions { - const alternativeSurfaceColor = get(mainTheme, 'custom.GC_ALTERNATIVE_SURFACE', mainTheme.surface) as string; + const alternativeSurfaceColor = get( + mainTheme, + 'custom.GC_ALTERNATIVE_SURFACE', + mainTheme.surface + ) as string; // const selectionBackground = get(mainTheme, 'custom.GC_SELECTION_BACKGROUND', mainTheme.surface) as string; - const foregroundColor = get(mainTheme, 'textIconOnDark', mainTheme.textPrimaryOnDark) as string; - + const foregroundColor = get( + mainTheme, + 'textIconOnDark', + mainTheme.textPrimaryOnDark + ) as string; + return { - "--ag-header-background-color": alternativeSurfaceColor, - "--ag-border-color": alternativeSurfaceColor, - "--ag-background-color": alternativeSurfaceColor, - "--ag-row-border-color": alternativeSurfaceColor, - "--ag-secondary-border-color": alternativeSurfaceColor, - "--ag-odd-row-background-color": alternativeSurfaceColor, - "--ag-selected-row-background-color": "transparent", - "--ag-foreground-color": foregroundColor, - "--ag-font-size": '13px', - "--ag-selected-details-row-background": '#38455c', /*GC_SELECTION_BACKGROUND with opacity 0.5*/ + '--ag-header-background-color': alternativeSurfaceColor, + '--ag-border-color': alternativeSurfaceColor, + '--ag-background-color': alternativeSurfaceColor, + '--ag-row-border-color': alternativeSurfaceColor, + '--ag-secondary-border-color': alternativeSurfaceColor, + '--ag-odd-row-background-color': alternativeSurfaceColor, + '--ag-selected-row-background-color': 'transparent', + '--ag-foreground-color': foregroundColor, + '--ag-font-size': '13px', + '--ag-selected-details-row-background': + '#38455c' /*GC_SELECTION_BACKGROUND with opacity 0.5*/, }; } -}; \ No newline at end of file +} diff --git a/src/common/components/grid/tooltip-renderer/name.tooltip-renderer.tsx b/src/common/components/grid/tooltip-renderer/name.tooltip-renderer.tsx index d2db28268..1cc39facd 100644 --- a/src/common/components/grid/tooltip-renderer/name.tooltip-renderer.tsx +++ b/src/common/components/grid/tooltip-renderer/name.tooltip-renderer.tsx @@ -4,19 +4,28 @@ import { get } from 'lodash'; import { ITooltipParams } from 'ag-grid-community'; import { Typography } from '@map-colonies/react-core'; import { LayerRecordTypes } from '../../../../discrete-layer/components/layer-details/entity-types-keys'; -import { DateGranularityType, FieldConfigModelType } from '../../../../discrete-layer/models'; +import { + DateGranularityType, + FieldConfigModelType, +} from '../../../../discrete-layer/models'; import { ILayerImage } from '../../../../discrete-layer/models/layerImage'; import { dateFormatter } from '../../../helpers/formatters'; import './name.tooltip-renderer.css'; export default forwardRef((props: ITooltipParams, ref) => { - const [data] = useState(props.api.getDisplayedRowAtIndex(props?.rowIndex as number)?.data); + const [data] = useState( + props.api.getDisplayedRowAtIndex(props?.rowIndex as number)?.data + ); const [layerRecordTypename] = useState(data.__typename); const [color] = useState(get(props, 'color', 'white')); - const [infoTooltipMap] = useState>(get(props, 'infoTooltipMap')); - const [fields] = useState(infoTooltipMap.get(layerRecordTypename) as FieldConfigModelType[]); - + const [infoTooltipMap] = useState< + Map + >(get(props, 'infoTooltipMap')); + const [fields] = useState( + infoTooltipMap.get(layerRecordTypename) as FieldConfigModelType[] + ); + useImperativeHandle(ref, () => { return { // eslint-disable-next-line @@ -27,20 +36,31 @@ export default forwardRef((props: ITooltipParams, ref) => { }); return ( -
+
<> - { - fields.map((field: FieldConfigModelType, index: number) => { + {fields.map((field: FieldConfigModelType, index: number) => { const value = `${get(data, field.fieldName as string)}`; return ( - : - {field.dateGranularity ? dateFormatter(value, field.dateGranularity === DateGranularityType.DATE_AND_TIME) : value} + + :{' '} + + + {field.dateGranularity + ? dateFormatter( + value, + field.dateGranularity === + DateGranularityType.DATE_AND_TIME + ) + : value} + ); - }) - } + })}
); -}); \ No newline at end of file +}); diff --git a/src/common/components/hyperlink/hyperlink.tsx b/src/common/components/hyperlink/hyperlink.tsx index 650396b52..3b00580de 100644 --- a/src/common/components/hyperlink/hyperlink.tsx +++ b/src/common/components/hyperlink/hyperlink.tsx @@ -2,7 +2,13 @@ import React, { PropsWithChildren } from 'react'; import './hyperlink.css'; -export const Hyperlink: React.FC> & { url: string, token?: string, label?: string }> = ({ url, token, label, className, children, ...props }): JSX.Element => { +export const Hyperlink: React.FC< + PropsWithChildren> & { + url: string; + token?: string; + label?: string; + } +> = ({ url, token, label, className, children, ...props }): JSX.Element => { return ( = () => { const mapOl = useMap(); - + useEffect(() => { const handleLoadStartEvent = (e: MapEvent): void => { mapOl.getTargetElement().classList.add('olSpinner'); @@ -30,7 +28,7 @@ export const MapLoadingIndicator: React.FC = () => { console.log('OL loading events remove listener failed', e); } }; - },[]); - + }, []); + return <>; -} \ No newline at end of file +}; diff --git a/src/common/components/multi-selection/multi-selection.tsx b/src/common/components/multi-selection/multi-selection.tsx index bfed259c3..f1a9155d8 100644 --- a/src/common/components/multi-selection/multi-selection.tsx +++ b/src/common/components/multi-selection/multi-selection.tsx @@ -1,20 +1,29 @@ import { isEmpty } from 'lodash'; import React, { useContext, useEffect, useMemo, useState } from 'react'; -import { MultiSelection as McMultiSelection, MultiSelectionOption, StylesConfig } from '@map-colonies/react-components'; +import { + MultiSelection as McMultiSelection, + MultiSelectionOption, + StylesConfig, +} from '@map-colonies/react-components'; import { EntityFormikHandlers } from '../../../discrete-layer/components/layer-details/layer-datails-form'; import { IRecordFieldInfo } from '../../../discrete-layer/components/layer-details/layer-details.field-info'; import CONFIG from '../../config'; -import lookupTablesContext, { ILookupOption } from '../../contexts/lookupTables.context'; +import lookupTablesContext, { + ILookupOption, +} from '../../contexts/lookupTables.context'; -import '../../../App.css' -import '../../../discrete-layer/components/map-container/catalogFilter/catalog-filter-panel.css' +import '../../../App.css'; +import '../../../discrete-layer/components/map-container/catalogFilter/catalog-filter-panel.css'; interface MultiSelectionWrapperProps { fieldInfo: IRecordFieldInfo; - lookupOptions: (ILookupOption | { - value: string; - translationCode: string; - })[]; + lookupOptions: ( + | ILookupOption + | { + value: string; + translationCode: string; + } + )[]; fieldName: string; customStyles?: StylesConfig; placeholder?: string; @@ -23,52 +32,88 @@ interface MultiSelectionWrapperProps { } export const MultiSelection: React.FC = (props) => { - const { fieldInfo, lookupOptions, fieldName, customStyles, placeholder, value, formik } = props; + const { + fieldInfo, + lookupOptions, + fieldName, + customStyles, + placeholder, + value, + formik, + } = props; const lang = CONFIG.I18N.DEFAULT_LANGUAGE; const backLocale = CONFIG.DEFAULT_BACKEND_LOCALE; - const [multiSelectionValues, setMultiSelectionValues] = useState(fieldInfo.isMultiSelection && !isEmpty(value) ? (value as string).split(", ") : []); + const [multiSelectionValues, setMultiSelectionValues] = useState( + fieldInfo.isMultiSelection && !isEmpty(value) + ? (value as string).split(', ') + : [] + ); const { lookupTablesData } = useContext(lookupTablesContext); useEffect(() => { if (fieldInfo.isMultiSelection) { - setMultiSelectionValues(!isEmpty(value) ? (value as string).split(", ") : []); + setMultiSelectionValues( + !isEmpty(value) ? (value as string).split(', ') : [] + ); } }, [value, fieldInfo.isMultiSelection]); - + const multiSelectionOptions = useMemo(() => { return (lookupOptions as ILookupOption[]).map((option) => { - const text = option.translation?.find((trns) => trns.locale === lang)?.text ?? ''; + const text = + option.translation?.find((trns) => trns.locale === lang)?.text ?? ''; return { value: text, label: text }; }); }, [lookupOptions, lang]); const getMultiSelectionValues = () => { - const chosenValueStrings = (multiSelectionValues)?.map((value) => multiSelectionOptions.filter((option) => option.value === value)) + const chosenValueStrings = multiSelectionValues + ?.map((value) => + multiSelectionOptions.filter((option) => option.value === value) + ) .flat() .map((filteredOption) => filteredOption.value); - const chosenValueOptions = chosenValueStrings?.map((value) => { - return [ { value: value, label: value } ]; - }).flat(); + const chosenValueOptions = chosenValueStrings + ?.map((value) => { + return [{ value: value, label: value }]; + }) + .flat(); return chosenValueOptions; }; - const getFormikFieldValue = (values: { value: string, label: string }[]) => { - return values.map((val) => { - const lookupOptionsTranslations = (lookupOptions as ILookupOption[]).map((option) => option.translation); - const valueTranslation = lookupOptionsTranslations.find((trns) => (trns as unknown as { locale: string, text: string }[]).findIndex((trn) => trn.text === val.value) > -1); - return valueTranslation?.find((valueTranslations) => valueTranslations.locale === backLocale)?.text; - }).join(', '); + const getFormikFieldValue = (values: { value: string; label: string }[]) => { + return values + .map((val) => { + const lookupOptionsTranslations = ( + lookupOptions as ILookupOption[] + ).map((option) => option.translation); + const valueTranslation = lookupOptionsTranslations.find( + (trns) => + (trns as unknown as { locale: string; text: string }[]).findIndex( + (trn) => trn.text === val.value + ) > -1 + ); + return valueTranslation?.find( + (valueTranslations) => valueTranslations.locale === backLocale + )?.text; + }) + .join(', '); }; const onChangeMultiSelection = (data: MultiSelectionOption[]) => { formik?.setFieldValue(fieldName, getFormikFieldValue(data)); - setMultiSelectionValues(data.map(item => item.value)); + setMultiSelectionValues(data.map((item) => item.value)); }; - if (!lookupTablesData || !lookupTablesData.dictionary || fieldInfo.lookupTable == null) return null; + if ( + !lookupTablesData || + !lookupTablesData.dictionary || + fieldInfo.lookupTable == null + ) + return null; return ( = (props) => { styles={customStyles} /> ); -} +}; diff --git a/src/common/components/shared/type-icon.tsx b/src/common/components/shared/type-icon.tsx index 6cdda8263..a40dc0ff8 100644 --- a/src/common/components/shared/type-icon.tsx +++ b/src/common/components/shared/type-icon.tsx @@ -3,7 +3,9 @@ import React, { useContext } from 'react'; import { useIntl } from 'react-intl'; import { IconButton, Tooltip } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; -import EnumsMapContext, { DEFAULT_ENUM_DESCRIPTOR } from '../../contexts/enumsMap.context'; +import EnumsMapContext, { + DEFAULT_ENUM_DESCRIPTOR, +} from '../../contexts/enumsMap.context'; const SIZE = 128; @@ -15,10 +17,17 @@ interface ITypeIconProps { onClick?: (event: React.MouseEvent) => void; } -export const TypeIcon: React.FC = ({ typeName, thumbnailUrl, style, className, onClick }) => { +export const TypeIcon: React.FC = ({ + typeName, + thumbnailUrl, + style, + className, + onClick, +}) => { const intl = useIntl(); const { enumsMap } = useContext(EnumsMapContext); - const { icon, translationKey } = enumsMap?.[typeName] ?? DEFAULT_ENUM_DESCRIPTOR; + const { icon, translationKey } = + enumsMap?.[typeName] ?? DEFAULT_ENUM_DESCRIPTOR; const tooltip = intl.formatMessage({ id: translationKey }); const img = (url: string): JSX.Element => { @@ -27,10 +36,16 @@ export const TypeIcon: React.FC = ({ typeName, thumbnailUrl, sty return ( - + diff --git a/src/common/components/skeleton/skeleton.tsx b/src/common/components/skeleton/skeleton.tsx index 8544cff03..0ab623b8f 100644 --- a/src/common/components/skeleton/skeleton.tsx +++ b/src/common/components/skeleton/skeleton.tsx @@ -1,20 +1,31 @@ import { get } from 'lodash'; import React from 'react'; -import { default as RLSkeleton, SkeletonProps as RLSkeletonProps } from 'react-loading-skeleton'; +import { + default as RLSkeleton, + SkeletonProps as RLSkeletonProps, +} from 'react-loading-skeleton'; import { useTheme } from '@map-colonies/react-core'; import CONFIG from '../../../common/config'; import 'react-loading-skeleton/dist/skeleton.css'; -const direction = CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() === 'HE' ? 'rtl' : 'ltr'; +const direction = + CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() === 'HE' ? 'rtl' : 'ltr'; -interface SkeletonProps extends RLSkeletonProps { } +interface SkeletonProps extends RLSkeletonProps {} export const Skeleton: React.FC = ({ ...rest }) => { - const theme = useTheme(); - const GC_SKELETON_BASE = get(theme, 'custom.GC_SKELETON_BASE', 'rgba(235, 235, 235, 0.1)') as string; - const GC_SKELETON_HIGHLIGHT = get(theme, 'custom.GC_SKELETON_HIGHLIGHT', 'rgba(175, 191, 218, 0.4)') as string; + const GC_SKELETON_BASE = get( + theme, + 'custom.GC_SKELETON_BASE', + 'rgba(235, 235, 235, 0.1)' + ) as string; + const GC_SKELETON_HIGHLIGHT = get( + theme, + 'custom.GC_SKELETON_HIGHLIGHT', + 'rgba(175, 191, 218, 0.4)' + ) as string; return ( = ({ ...rest }) => { {...rest} /> ); - }; diff --git a/src/common/components/tree/icon-renderers/actions.button-renderer.css b/src/common/components/tree/icon-renderers/actions.button-renderer.css index 60d140dcc..d019c1808 100644 --- a/src/common/components/tree/icon-renderers/actions.button-renderer.css +++ b/src/common/components/tree/icon-renderers/actions.button-renderer.css @@ -5,7 +5,7 @@ width: 124px; /*36+36+36+16*/ justify-content: flex-end; padding-left: 16px; - background-color: rgb(44,65,89); + background-color: rgb(44, 65, 89); /* ColorRes = Color * alpha + Background * (1 - alpha); Color = rgba(33, 150, 243, 0.1) @@ -27,7 +27,7 @@ body[dir='rtl'] .actionsContainer { left: unset; } -body[dir='rtl'] .actionsContainer .actionIcon{ +body[dir='rtl'] .actionsContainer .actionIcon { left: unset; right: unset; } @@ -62,6 +62,6 @@ body[dir='rtl'] #actionsMenuContainer .mdc-menu-surface.mdc-menu-surface--open { } body[dir='rtl'] .actionMenuItemTitle { - padding-left: unset; - padding-right: 8px; -} \ No newline at end of file + padding-left: unset; + padding-right: 8px; +} diff --git a/src/common/components/tree/icon-renderers/actions.button-renderer.tsx b/src/common/components/tree/icon-renderers/actions.button-renderer.tsx index acfee6571..d766e846e 100644 --- a/src/common/components/tree/icon-renderers/actions.button-renderer.tsx +++ b/src/common/components/tree/icon-renderers/actions.button-renderer.tsx @@ -1,6 +1,11 @@ import React, { useState } from 'react'; import { isEmpty } from 'lodash'; -import { IconButton, MenuSurfaceAnchor, MenuSurface, Typography } from '@map-colonies/react-core'; +import { + IconButton, + MenuSurfaceAnchor, + MenuSurface, + Typography, +} from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { IActionGroup, IAction } from '../../../actions/entity.actions'; @@ -8,93 +13,105 @@ import './actions.button-renderer.css'; interface IActionsRendererParams { actions: IActionGroup[]; - node: Record; + node: Record; entity: string; - actionHandler: (action: Record) => void; + actionHandler: (action: Record) => void; } -export const ActionsRenderer: React.FC = ({node, actions, entity, actionHandler}) => { +export const ActionsRenderer: React.FC = ({ + node, + actions, + entity, + actionHandler, +}) => { let frequentActions: IAction[] = []; let allFlatActions: IAction[] = []; - + if (typeof actions !== 'undefined') { - actions.forEach(actionGroup => { + actions.forEach((actionGroup) => { frequentActions = [ ...frequentActions, - ...actionGroup.group.filter(action => action.frequent) - ]; - allFlatActions = [ - ...allFlatActions, - ...actionGroup.group + ...actionGroup.group.filter((action) => action.frequent), ]; + allFlatActions = [...allFlatActions, ...actionGroup.group]; }); } const [openActionsMenu, setOpenActionsMenu] = useState(false); - const sendAction = (entity: string, action: IAction, data: Record): void => { + const sendAction = ( + entity: string, + action: IAction, + data: Record + ): void => { console.log(`SEND ${action.action} EVENT`); actionHandler({ action: `${entity}.${action.action}`, data: data, }); - } + }; return ( - { - frequentActions.map((action,idx) => { - return ( - { - sendAction(entity, action, node); - }} - /> - ); - }) - } + {frequentActions.map((action, idx) => { + return ( + { + sendAction(entity, action, node); + }} + /> + ); + })} setOpenActionsMenu(false)} - onMouseOver={(evt: React.SyntheticEvent): void => { evt.stopPropagation(); }} + onMouseOver={(evt: React.SyntheticEvent): void => { + evt.stopPropagation(); + }} > - { - allFlatActions.map((action,idx) => { - return ( - { - sendAction(entity, action, node); - setOpenActionsMenu(false); - } } - className="actionMenuItem" + {allFlatActions.map((action, idx) => { + return ( + { + sendAction(entity, action, node); + setOpenActionsMenu(false); + }} + className="actionMenuItem" + > + + - - - {action.titleTranslationId} - - - ); - }) - } + {action.titleTranslationId} + + + ); + })} - { - !isEmpty(allFlatActions) && setOpenActionsMenu(!openActionsMenu)} /> - } + )} - + ); }; diff --git a/src/common/components/tree/icon-renderers/footprint.icon-renderer.css b/src/common/components/tree/icon-renderers/footprint.icon-renderer.css index 2f12b7f32..ebbbc0e37 100644 --- a/src/common/components/tree/icon-renderers/footprint.icon-renderer.css +++ b/src/common/components/tree/icon-renderers/footprint.icon-renderer.css @@ -18,5 +18,5 @@ body[dir='rtl'] .footprintIcon { } body[dir='rtl'] .toolbarButton .mdc-checkbox .mdc-checkbox__background { - left: unset; + left: unset; } diff --git a/src/common/components/tree/icon-renderers/footprint.icon-renderer.tsx b/src/common/components/tree/icon-renderers/footprint.icon-renderer.tsx index b36f84b41..91e919f9b 100644 --- a/src/common/components/tree/icon-renderers/footprint.icon-renderer.tsx +++ b/src/common/components/tree/icon-renderers/footprint.icon-renderer.tsx @@ -9,8 +9,12 @@ interface IFootprintCellRendererParams { data: ILayerImage; } -export const FootprintRenderer: React.FC = (props) => { - const [checked, setChecked] = useState(props.data.footprintShown as boolean); +export const FootprintRenderer: React.FC = ( + props +) => { + const [checked, setChecked] = useState( + props.data.footprintShown as boolean + ); useEffect(() => { setChecked(props.data.footprintShown as boolean); @@ -20,13 +24,11 @@ export const FootprintRenderer: React.FC = (props) ): void => { - evt.stopPropagation(); - setChecked(evt.currentTarget.checked); - props.onClick(props.data, evt.currentTarget.checked); - } - } + onClick={(evt: React.MouseEvent): void => { + evt.stopPropagation(); + setChecked(evt.currentTarget.checked); + props.onClick(props.data, evt.currentTarget.checked); + }} /> ); }; diff --git a/src/common/components/tree/icon-renderers/import.icon-renderer.tsx b/src/common/components/tree/icon-renderers/import.icon-renderer.tsx index 98c9b70f1..70e1935e8 100644 --- a/src/common/components/tree/icon-renderers/import.icon-renderer.tsx +++ b/src/common/components/tree/icon-renderers/import.icon-renderer.tsx @@ -11,22 +11,25 @@ interface IImportCellRendererParams { } export const ImportRenderer: React.FC = (props) => { - const [selected, setSelected] = useState(props.data.isNewlyAddedToBest as boolean); - + const [selected, setSelected] = useState( + props.data.isNewlyAddedToBest as boolean + ); + return ( ): void => { - const value = !selected; - evt.stopPropagation(); - setSelected(value); - props.onClick(props.data, value); - } - } + onClick={(evt: React.MouseEvent): void => { + const value = !selected; + evt.stopPropagation(); + setSelected(value); + props.onClick(props.data, value); + }} /> ); diff --git a/src/common/components/tree/icon-renderers/layer-image.icon-renderer.tsx b/src/common/components/tree/icon-renderers/layer-image.icon-renderer.tsx index fd04c348d..5f99317e1 100644 --- a/src/common/components/tree/icon-renderers/layer-image.icon-renderer.tsx +++ b/src/common/components/tree/icon-renderers/layer-image.icon-renderer.tsx @@ -2,7 +2,10 @@ import React, { useEffect, useState } from 'react'; import { IconButton } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { ILayerImage } from '../../../../discrete-layer/models/layerImage'; -import { isBeingDeleted, isValidLayerMetadata } from '../../../helpers/layer-url'; +import { + isBeingDeleted, + isValidLayerMetadata, +} from '../../../helpers/layer-url'; import './layer-image.icon-renderer.css'; @@ -11,34 +14,46 @@ interface ILayerImageCellRendererParams { data: ILayerImage; } -export const LayerImageRenderer: React.FC = (props) => { - const [layerImageShown, setLayerImageShown] = useState(props.data.layerImageShown as boolean); +export const LayerImageRenderer: React.FC = ( + props +) => { + const [layerImageShown, setLayerImageShown] = useState( + props.data.layerImageShown as boolean + ); useEffect(() => { setLayerImageShown(props.data.layerImageShown as boolean); }, [props.data.layerImageShown]); useEffect(() => { - if ('productStatus' in props.data && layerImageShown && isBeingDeleted(props.data)) { + if ( + 'productStatus' in props.data && + layerImageShown && + isBeingDeleted(props.data) + ) { props.onClick(props.data, false); } }, [(props.data as unknown as Record)?.productStatus]); return ( - ): void => { - if (isValidLayerMetadata(props.data)) { - const val = !layerImageShown; - evt.stopPropagation(); - setLayerImageShown(val); - props.onClick(props.data, val); - } + onClick={(evt: React.MouseEvent): void => { + if (isValidLayerMetadata(props.data)) { + const val = !layerImageShown; + evt.stopPropagation(); + setLayerImageShown(val); + props.onClick(props.data, val); } - } + }} /> ); diff --git a/src/common/components/tree/icon-renderers/product-type.icon-renderer.tsx b/src/common/components/tree/icon-renderers/product-type.icon-renderer.tsx index 2d27472e3..0039b72c4 100644 --- a/src/common/components/tree/icon-renderers/product-type.icon-renderer.tsx +++ b/src/common/components/tree/icon-renderers/product-type.icon-renderer.tsx @@ -10,19 +10,22 @@ interface IProductTypeCellRendererParams { onClick?: (data: ILayerImage, value: boolean) => void; } -export const ProductTypeRenderer: React.FC = ({ data, thumbnailUrl, onClick }) => { - +export const ProductTypeRenderer: React.FC = ({ + data, + thumbnailUrl, + onClick, +}) => { const handleClick = (event: React.MouseEvent) => { const rasterData = data as LayerRasterRecordModelType; - if (onClick && rasterData.links?.some(link => link.protocol === 'WFS')) { + if (onClick && rasterData.links?.some((link) => link.protocol === 'WFS')) { onClick(data, !rasterData.polygonPartsShown); } }; const computedStyle = useMemo(() => { return { - ...(getIconStyle(data as any, 'color') ?? {}) + ...(getIconStyle(data as any, 'color') ?? {}), }; }, [data]); @@ -31,7 +34,9 @@ export const ProductTypeRenderer: React.FC = ({ typeName={data.productType as string} thumbnailUrl={thumbnailUrl} style={computedStyle} - onClick={data.__typename === "LayerRasterRecord" ? handleClick : undefined} + onClick={ + data.__typename === 'LayerRasterRecord' ? handleClick : undefined + } /> ); -}; \ No newline at end of file +}; diff --git a/src/common/components/tree/renderers/node-content-renderer.css b/src/common/components/tree/renderers/node-content-renderer.css index d6990626d..f027ae3ea 100644 --- a/src/common/components/tree/renderers/node-content-renderer.css +++ b/src/common/components/tree/renderers/node-content-renderer.css @@ -14,7 +14,10 @@ } .rowSelected { border-radius: 100px; - background-color: var(--rst-selected-background-color, rgba(33, 150, 243, 0.3)); + background-color: var( + --rst-selected-background-color, + rgba(33, 150, 243, 0.3) + ); } .rowWrapperDragDisabled { cursor: default; @@ -29,15 +32,18 @@ box-sizing: border-box; } /** * The outline of where the element will go if dropped, displayed while dragging */ -.rowLandingPad, .rowCancelPad { +.rowLandingPad, +.rowCancelPad { border: none; box-shadow: none; outline: none; } -.rowLandingPad *, .rowCancelPad * { +.rowLandingPad *, +.rowCancelPad * { opacity: 0 !important; } -.rowLandingPad::before, .rowCancelPad::before { +.rowLandingPad::before, +.rowCancelPad::before { background-color: lightblue; border: 2px dotted black; content: ''; @@ -60,7 +66,10 @@ .rowSearchFocus { box-shadow: inset 0 -7px 7px -3px #fc6421; } -.rowContents, .rowLabel, .rowToolbar, .toolbarButton { +.rowContents, +.rowLabel, +.rowToolbar, +.toolbarButton { display: inline-block; vertical-align: middle; } @@ -92,7 +101,8 @@ body[dir='rtl'] .rowLabel { text-align: end; flex-grow: 1; } -.collapseButton, .expandButton { +.collapseButton, +.expandButton { appearance: none; border: none; background: transparent; @@ -105,7 +115,8 @@ body[dir='rtl'] .rowLabel { transform: translate3d(-50%, -50%, 0); cursor: pointer; } -.collapseButton::after, .expandButton::after { +.collapseButton::after, +.expandButton::after { content: ''; position: absolute; transform-origin: 7px 4px; @@ -115,19 +126,26 @@ body[dir='rtl'] .rowLabel { border-right-width: 7px; border-top-color: gray; } -.collapseButton:hover::after, .expandButton:hover::after { +.collapseButton:hover::after, +.expandButton:hover::after { /* border-top-color: black; */ } -.collapseButton:focus, .expandButton:focus { +.collapseButton:focus, +.expandButton:focus { outline: none; } -.collapseButton:focus::after, .expandButton:focus::after { - filter: drop-shadow(0 0 1px #83bef9) drop-shadow(0 0 1px #83bef9) drop-shadow(0 0 1px #83bef9); +.collapseButton:focus::after, +.expandButton:focus::after { + filter: drop-shadow(0 0 1px #83bef9) drop-shadow(0 0 1px #83bef9) + drop-shadow(0 0 1px #83bef9); } .expandButton::after { transform: translate3d(-50%, -20%, 0) rotateZ(-90deg); } -.rst__rtl .ReactVirtualized__Grid .ReactVirtualized__Grid__innerScrollContainer .expandButton::after { +.rst__rtl + .ReactVirtualized__Grid + .ReactVirtualized__Grid__innerScrollContainer + .expandButton::after { transform: translate3d(-50%, -20%, 0) rotateZ(90deg); } /** * Line for under a node with children */ @@ -136,7 +154,8 @@ body[dir='rtl'] .rowLabel { display: inline-block; } /* ========================================================================== Scaffold Line-overlaid blocks used for showing the tree structure ========================================================================== */ -.lineBlock, .absoluteLineBlock { +.lineBlock, +.absoluteLineBlock { height: 100%; position: relative; display: inline-block; @@ -165,19 +184,19 @@ body[dir='rtl'] .rowLabel { 0% { transform: translate(0, 0); opacity: 0; - } + } 30% { transform: translate(0, 300%); opacity: 1; - } + } 70% { transform: translate(0, 700%); opacity: 1; - } + } 100% { transform: translate(0, 1000%); opacity: 0; - } + } } .highlightLineVertical::after { content: ''; @@ -196,8 +215,10 @@ body[dir='rtl'] .rowLabel { z-index: 3; content: ''; position: absolute; - border-top: solid var(--rst-highlight-line-size) var(--rst-hover-background-color); - border-left: solid var(--rst-highlight-line-size) var(--rst-hover-background-color); + border-top: solid var(--rst-highlight-line-size) + var(--rst-hover-background-color); + border-left: solid var(--rst-highlight-line-size) + var(--rst-hover-background-color); box-sizing: border-box; height: calc(50% + var(--rst-highlight-line-size) / 2); top: 50%; @@ -212,8 +233,10 @@ body[dir='rtl'] .rowLabel { .highlightBottomLeftCorner::before { content: ''; position: absolute; - border-bottom: solid var(--rst-highlight-line-size) var(--rst-hover-background-color); - border-left: solid var(--rst-highlight-line-size) var(--rst-hover-background-color); + border-bottom: solid var(--rst-highlight-line-size) + var(--rst-hover-background-color); + border-left: solid var(--rst-highlight-line-size) + var(--rst-hover-background-color); box-sizing: border-box; height: calc(100% + var(--rst-highlight-line-size) / 2); top: 0; diff --git a/src/common/components/tree/renderers/node-content-renderer.tsx b/src/common/components/tree/renderers/node-content-renderer.tsx index 552a8ce2f..c6690fb1d 100644 --- a/src/common/components/tree/renderers/node-content-renderer.tsx +++ b/src/common/components/tree/renderers/node-content-renderer.tsx @@ -14,7 +14,7 @@ function isDescendant(older, younger) { !!older.children && typeof older.children !== 'function' && older.children.some( - child => child === younger || isDescendant(child, younger) + (child) => child === younger || isDescendant(child, younger) ) ); } @@ -54,13 +54,14 @@ class FileThemeNodeContentRenderer extends Component { ...otherProps } = this.props; const nodeTitle = title || node.title; - const tooltipText = typeof nodeTitle === 'function' - ? nodeTitle({ - node, - path, - treeIndex, - }) - : nodeTitle; + const tooltipText = + typeof nodeTitle === 'function' + ? nodeTitle({ + node, + path, + treeIndex, + }) + : nodeTitle; const styles = { lineBlock: 'lineBlock', @@ -87,7 +88,7 @@ class FileThemeNodeContentRenderer extends Component { const isDraggedDescendant = draggedNode && isDescendant(draggedNode, node); const isLandingPadActive = !didDrop && isDragging; - const isSecondLevelLeaf = node.isGroup === undefined && path.length ===2; + const isSecondLevelLeaf = node.isGroup === undefined && path.length === 2; // Construct the scaffold representing the structure of the tree const scaffold = []; @@ -144,8 +145,16 @@ class FileThemeNodeContentRenderer extends Component { node.expanded ? styles.collapseButton : styles.expandButton } style={{ - left: rowDirection === 'ltr' ? (lowerSiblingCounts.length - 0.4) * scaffoldBlockPxWidth : 'unset', - right: rowDirection === 'rtl' ? (parentNode === null ? -1 * (lowerSiblingCounts.length) * scaffoldBlockPxWidth : 'unset') : 'unset', + left: + rowDirection === 'ltr' + ? (lowerSiblingCounts.length - 0.4) * scaffoldBlockPxWidth + : 'unset', + right: + rowDirection === 'rtl' + ? parentNode === null + ? -1 * lowerSiblingCounts.length * scaffoldBlockPxWidth + : 'unset' + : 'unset', }} onClick={() => toggleChildrenVisibility({ @@ -165,9 +174,12 @@ class FileThemeNodeContentRenderer extends Component { } style={{ position: 'absolute', - left: rowDirection === 'ltr' && !isSecondLevelLeaf ? scaffoldBlockPxWidth : 'unset', + left: + rowDirection === 'ltr' && !isSecondLevelLeaf + ? scaffoldBlockPxWidth + : 'unset', right: rowDirection === 'rtl' ? scaffoldBlockPxWidth * 2 : 'unset', - width: 'calc(100% - var(--rst-expander-size))' + width: 'calc(100% - var(--rst-expander-size))', }} > {/* Set the row preview to be used during drag and drop */} @@ -208,19 +220,16 @@ class FileThemeNodeContentRenderer extends Component { ))}
- - - {tooltipText} - - - - { - !node.children && + + {tooltipText} + + + {!node.children && (
{buttons.map((btn, index) => (
))}
- } + )} - { - node.children && + {node.children && (
- ( {getDescendantCount({node, ignoreCollapsed: false }) - (parentNode !== null ? 0 : (getDepth(node) > 1) ? node.children.length : 0)} ) + ({' '} + {getDescendantCount({ node, ignoreCollapsed: false }) - + (parentNode !== null + ? 0 + : getDepth(node) > 1 + ? node.children.length + : 0)}{' '} + )
- } - + )}
diff --git a/src/common/components/tree/renderers/tree-node-renderer.tsx b/src/common/components/tree/renderers/tree-node-renderer.tsx index 69bfd6cef..f37a0bd4f 100644 --- a/src/common/components/tree/renderers/tree-node-renderer.tsx +++ b/src/common/components/tree/renderers/tree-node-renderer.tsx @@ -37,7 +37,7 @@ class FileThemeTreeNodeRenderer extends Component { return connectDropTarget(
- {Children.map(children, child => + {Children.map(children, (child) => cloneElement(child, { isOver, canDrop, diff --git a/src/common/components/tree/statuses/error.tsx b/src/common/components/tree/statuses/error.tsx index 2a65c27e9..b10f15311 100644 --- a/src/common/components/tree/statuses/error.tsx +++ b/src/common/components/tree/statuses/error.tsx @@ -17,25 +17,35 @@ export const Error: React.FC = (props) => { return ( - - + + + + + + + + + + - - { - message && {message} - } - { - !message && - } + + + + {message && {message}} + {!message && ( + + {' '} + + + )} - { - details !== undefined && + {details !== undefined && ( {details} - } + )} ); }; diff --git a/src/common/components/tree/statuses/loading.tsx b/src/common/components/tree/statuses/loading.tsx index 1b205067e..b8c9be7cd 100644 --- a/src/common/components/tree/statuses/loading.tsx +++ b/src/common/components/tree/statuses/loading.tsx @@ -4,5 +4,10 @@ import { CircularProgress } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; export const Loading: React.FC = (): JSX.Element => { - return ; + return ( + + + + + ); }; diff --git a/src/common/components/tree/themes/themes.ts b/src/common/components/tree/themes/themes.ts index 3ab0d6a3a..546b87407 100644 --- a/src/common/components/tree/themes/themes.ts +++ b/src/common/components/tree/themes/themes.ts @@ -4,19 +4,27 @@ import { IOptions } from '@map-colonies/react-core'; // eslint-disable-next-line export class TreeThemes { public static getTheme(mainTheme: IOptions): IOptions { - const selectionBackground = get(mainTheme, 'custom.GC_SELECTION_BACKGROUND', mainTheme.surface) as string; - const hoverBackground = get(mainTheme, 'custom.GC_HOVER_BACKGROUND', 'rgba(33, 150, 243, 0.1)') as string; - + const selectionBackground = get( + mainTheme, + 'custom.GC_SELECTION_BACKGROUND', + mainTheme.surface + ) as string; + const hoverBackground = get( + mainTheme, + 'custom.GC_HOVER_BACKGROUND', + 'rgba(33, 150, 243, 0.1)' + ) as string; + const rstTheme = { - "--rst-selected-background-color": selectionBackground, - "--rst-hover-background-color": hoverBackground, - "--rst-highlight-line-size": '6px', - "--rst-node-label-width": '280px', - "--rst-expander-size": '30px', + '--rst-selected-background-color': selectionBackground, + '--rst-hover-background-color': hoverBackground, + '--rst-highlight-line-size': '6px', + '--rst-node-label-width': '280px', + '--rst-expander-size': '30px', }; // return Object.entries(rstTheme).map( // ([key, value]) => `${key}:${value}` // ).join(';'); return rstTheme; } -}; \ No newline at end of file +} diff --git a/src/common/components/tree/tree.tsx b/src/common/components/tree/tree.tsx index d6227ff59..8515c57df 100644 --- a/src/common/components/tree/tree.tsx +++ b/src/common/components/tree/tree.tsx @@ -1,22 +1,29 @@ import React, { CSSProperties } from 'react'; import { useTheme } from '@map-colonies/react-core'; -import SortableTree, { ThemeProps, ReactSortableTreeProps, TreeItem as RSTTreeItem } from 'react-sortable-tree'; +import SortableTree, { + ThemeProps, + ReactSortableTreeProps, + TreeItem as RSTTreeItem, +} from 'react-sortable-tree'; import CONFIG from '../../config'; import { TreeThemes } from './themes/themes'; import FileExplorerTheme from './renderers'; -export interface TreeItem extends RSTTreeItem{}; +export interface TreeItem extends RSTTreeItem {} export const TreeComponent: React.FC = (props) => { const theme = useTheme(); const treeTheme = TreeThemes.getTheme(theme) as CSSProperties; - const rowDirection = CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() === 'HE' ? 'rtl' : 'ltr'; - + const rowDirection = + CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() === 'HE' ? 'rtl' : 'ltr'; + return ( -
+
= (props) => { />
); -} \ No newline at end of file +}; diff --git a/src/common/components/utm-grid-data-source/utm-grid-data-source.component.tsx b/src/common/components/utm-grid-data-source/utm-grid-data-source.component.tsx index 909700e07..117e9271d 100644 --- a/src/common/components/utm-grid-data-source/utm-grid-data-source.component.tsx +++ b/src/common/components/utm-grid-data-source/utm-grid-data-source.component.tsx @@ -11,7 +11,6 @@ import center from '@turf/center'; import { points } from '@turf/helpers'; import React from 'react'; - const SELECTION_POLYGON_OUTLINE_COLOR = '#8a3e00'; const SELECTION_POLYGON_LINE_WIDTH = 2; @@ -25,12 +24,16 @@ const UTMGridDataSource: React.FC = () => { // TODO: Change the data source path. data={'./assets/data/utmzone.geojson'} onLoad={(geoJsonDataSource): void => { - geoJsonDataSource.entities.values.forEach(item => { + geoJsonDataSource.entities.values.forEach((item) => { let centerInDegrees; if (item.polyline) { - (item.polyline.clampToGround as CesiumConstantProperty).setValue(true); - (item.polyline.width as CesiumConstantProperty).setValue(HIGHLIGHT_OUTLINE_WIDTH); + (item.polyline.clampToGround as CesiumConstantProperty).setValue( + true + ); + (item.polyline.width as CesiumConstantProperty).setValue( + HIGHLIGHT_OUTLINE_WIDTH + ); // @ts-ignore item.polyline.material = SELECTION_OUTLINE_COLOR; @@ -38,20 +41,28 @@ const UTMGridDataSource: React.FC = () => { centerInDegrees = center( points( // @ts-ignore - ((item.polyline.positions.getValue() as Record).map((pos) => { - const cartographicPos = CesiumCartographic.fromCartesian(pos); + ( + item.polyline.positions.getValue() as Record< + string, + unknown + > + ).map((pos) => { + const cartographicPos = + CesiumCartographic.fromCartesian(pos); return [ CesiumMath.toDegrees(cartographicPos.latitude), CesiumMath.toDegrees(cartographicPos.longitude), ]; - })) + }) ) ).geometry.coordinates; } if (item.polygon) { // @ts-ignore - (item.polygon.outlineColor as CesiumConstantProperty).setValue(CesiumColor.fromCssColorString(SELECTION_POLYGON_OUTLINE_COLOR)); + (item.polygon.outlineColor as CesiumConstantProperty).setValue( + CesiumColor.fromCssColorString(SELECTION_POLYGON_OUTLINE_COLOR) + ); (item.polygon.outlineWidth as CesiumConstantProperty).setValue( SELECTION_POLYGON_LINE_WIDTH ); @@ -62,21 +73,30 @@ const UTMGridDataSource: React.FC = () => { centerInDegrees = center( points( // @ts-ignore - ((item.polygon.hierarchy.getValue() as Record) - .positions as CesiumCartesian3[]).map((pos) => { - const cartographicPos = CesiumCartographic.fromCartesian(pos); - return [ - CesiumMath.toDegrees(cartographicPos.latitude), - CesiumMath.toDegrees(cartographicPos.longitude), - ]; - } - ) + ( + ( + item.polygon.hierarchy.getValue() as Record< + string, + unknown + > + ).positions as CesiumCartesian3[] + ).map((pos) => { + const cartographicPos = + CesiumCartographic.fromCartesian(pos); + return [ + CesiumMath.toDegrees(cartographicPos.latitude), + CesiumMath.toDegrees(cartographicPos.longitude), + ]; + }) ) ).geometry.coordinates; } // @ts-ignore - item.position = CesiumCartesian3.fromDegrees(centerInDegrees[1], centerInDegrees[0]); // [lon, lat] + item.position = CesiumCartesian3.fromDegrees( + centerInDegrees[1], + centerInDegrees[0] + ); // [lon, lat] const label = { // eslint-disable-next-line diff --git a/src/common/config/index.ts b/src/common/config/index.ts index b289d321c..3fd48ee1c 100644 --- a/src/common/config/index.ts +++ b/src/common/config/index.ts @@ -1,6 +1,12 @@ -import { CesiumGeographicTilingScheme, Proj } from '@map-colonies/react-components'; +import { + CesiumGeographicTilingScheme, + Proj, +} from '@map-colonies/react-components'; import { IRasterLayer } from '@map-colonies/react-components/dist/cesium-map/layers-manager'; -import { IBaseMaps, IBaseMap } from '@map-colonies/react-components/dist/cesium-map/map'; +import { + IBaseMaps, + IBaseMap, +} from '@map-colonies/react-components/dist/cesium-map/map'; import { LinkType } from '../models/link-type.enum'; import { IRasterIngestionFilesStructureConfig } from '../models/raster-ingestion-files-structure'; @@ -22,28 +28,33 @@ const MAP = (window as any)._env_.MAP; const JOB_MANAGER = (window as any)._env_.JOB_MANAGER; const DEFAULT_USER = (window as any)._env_.DEFAULT_USER; const BASE_MAPS = JSON.parse((window as any)._env_.BASE_MAPS); -const DEFAULT_TERRAIN_PROVIDER_URL = (window as any)._env_.DEFAULT_TERRAIN_PROVIDER_URL; +const DEFAULT_TERRAIN_PROVIDER_URL = (window as any)._env_ + .DEFAULT_TERRAIN_PROVIDER_URL; const WEB_TOOLS_URL = (window as any)._env_.WEB_TOOLS_URL; const MODEL_VIEWER_ROUTE = (window as any)._env_.MODEL_VIEWER_ROUTE; const MODEL_VIEWER_TOKEN_VALUE = (window as any)._env_.MODEL_VIEWER_TOKEN_VALUE; const RUNNING_MODE = (window as any)._env_.RUNNING_MODE; -const NUMBER_OF_CHARACTERS_LIMIT = (window as any)._env_.NUMBER_OF_CHARACTERS_LIMIT; +const NUMBER_OF_CHARACTERS_LIMIT = (window as any)._env_ + .NUMBER_OF_CHARACTERS_LIMIT; const SERVED_ENTITY_TYPES = (window as any)._env_.SERVED_ENTITY_TYPES; const ACCESS_TOKEN = (window as any)._env_.ACCESS_TOKEN; -const RASTER_INGESTION_FILES_STRUCTURE = JSON.parse((window as any)._env_.RASTER_INGESTION_FILES_STRUCTURE); +const RASTER_INGESTION_FILES_STRUCTURE = JSON.parse( + (window as any)._env_.RASTER_INGESTION_FILES_STRUCTURE +); const PROJECT_VERSION = (window as any)._env_.PROJECT_VERSION; const WHATSNEW_URL = (window as any)._env_.WHATSNEW_URL; const SITES_CONFIG = JSON.parse((window as any)._env_.SITES_CONFIG); const BFF_PATH = (window as any)._env_.BFF_PATH; const SELECTION_MODE_DEFAULT = (window as any)._env_.SELECTION_MODE_DEFAULT; -const SHOW_SELECTION_MODE_SWITCH = (window as any)._env_.SHOW_SELECTION_MODE_SWITCH; +const SHOW_SELECTION_MODE_SWITCH = (window as any)._env_ + .SHOW_SELECTION_MODE_SWITCH; const POLYGON_PARTS = { ...(window as any)._env_.POLYGON_PARTS, highResolutionColor: '#01FF1F', mediumResolutionColor: '#fbff01', lowResolutionColor: '#ff3401', hoverColor: '#24AEE9', - billBoardStrokeColor: '#FFFF00' + billBoardStrokeColor: '#FFFF00', }; const WFS = (window as any)._env_.WFS; const GEOCODER = (window as any)._env_.GEOCODER; @@ -54,19 +65,28 @@ function enrichBaseMaps(baseMaps: IBaseMaps): IBaseMaps { maps: baseMaps.maps.map((baseMap: IBaseMap) => { return { ...baseMap, - thumbnail: baseMap.thumbnail && ACCESS_TOKEN.injectionType?.toLowerCase() === 'queryparam' ? `${baseMap.thumbnail}?${ACCESS_TOKEN.attributeName}=${ACCESS_TOKEN.tokenValue}` : baseMap.thumbnail, - baseRasterLayers: (baseMap.baseRasterLayers as IRasterLayer[]).map((rasterLayer) => { - return { - ...rasterLayer, - options: { - ...rasterLayer.options, - tilingScheme: (rasterLayer.type === LinkType.WMTS_LAYER) ? new CesiumGeographicTilingScheme() : undefined - } - }; - }) - } - }) - } + thumbnail: + baseMap.thumbnail && + ACCESS_TOKEN.injectionType?.toLowerCase() === 'queryparam' + ? `${baseMap.thumbnail}?${ACCESS_TOKEN.attributeName}=${ACCESS_TOKEN.tokenValue}` + : baseMap.thumbnail, + baseRasterLayers: (baseMap.baseRasterLayers as IRasterLayer[]).map( + (rasterLayer) => { + return { + ...rasterLayer, + options: { + ...rasterLayer.options, + tilingScheme: + rasterLayer.type === LinkType.WMTS_LAYER + ? new CesiumGeographicTilingScheme() + : undefined, + }, + }; + } + ), + }; + }), + }; } const systemJobsPriorityOptions = @@ -119,8 +139,8 @@ const APP_CONFIG = { DATE_TIME_FORMAT: `${DATE_FORMAT} HH:mm`, DATE_FNS_FORMAT: DATE_FNS_FORMAT, DATE_FNS_TIME_FORMAT: `${DATE_FNS_FORMAT} hh:mm`, - DATE_FNS_HUMAN_READABLE_DATE: "PPPP", - DATE_FNS_HUMAN_READABLE_DATE_TIME: "PPPPp", + DATE_FNS_HUMAN_READABLE_DATE: 'PPPP', + DATE_FNS_HUMAN_READABLE_DATE_TIME: 'PPPPp', }, I18N: { DEFAULT_LANGUAGE: LANGUAGE, @@ -254,10 +274,13 @@ const APP_CONFIG = { RESULTS_LIMIT: 6, }, RASTER_INGESTION: { - FILES_STRUCTURE: RASTER_INGESTION_FILES_STRUCTURE as IRasterIngestionFilesStructureConfig, + FILES_STRUCTURE: + RASTER_INGESTION_FILES_STRUCTURE as IRasterIngestionFilesStructureConfig, CHANGES_IN_SHAPE_FILES: { - TIME_DIFFERENCE_GRACE_MINUTES: CHANGES_IN_SHAPE_FILES.timeDifferenceGraceMinutes, - TIME_MODIFIED_THRESHOLD_HOURS: CHANGES_IN_SHAPE_FILES.timeModifiedThresholdHours, + TIME_DIFFERENCE_GRACE_MINUTES: + CHANGES_IN_SHAPE_FILES.timeDifferenceGraceMinutes, + TIME_MODIFIED_THRESHOLD_HOURS: + CHANGES_IN_SHAPE_FILES.timeModifiedThresholdHours, }, }, }; diff --git a/src/common/contexts/enumsMap.context.ts b/src/common/contexts/enumsMap.context.ts index cc3b0f893..9cf4991f2 100644 --- a/src/common/contexts/enumsMap.context.ts +++ b/src/common/contexts/enumsMap.context.ts @@ -35,7 +35,9 @@ export const DEFAULT_ENUM_DESCRIPTOR: IEnumDescriptor = { // eslint-disable-next-line @typescript-eslint/naming-convention const EnumsMapContext = createContext({ enumsMap: null, - setEnumsMap: (enums) => {return} + setEnumsMap: (enums) => { + return; + }, }); export default EnumsMapContext; diff --git a/src/common/contexts/lookupTables.context.ts b/src/common/contexts/lookupTables.context.ts index f1d64c4a7..afe9a3744 100644 --- a/src/common/contexts/lookupTables.context.ts +++ b/src/common/contexts/lookupTables.context.ts @@ -1,11 +1,11 @@ import { createContext } from 'react'; -import { CountryTranslation} from '@map-colonies/types' +import { CountryTranslation } from '@map-colonies/types'; export interface ILookupOption { value: string; translationCode?: string; translation?: CountryTranslation[]; - properties: Record + properties: Record; } export interface ILookupTableData { dictionary?: Record; @@ -17,5 +17,7 @@ interface ILookupTablesContext { } export default createContext({ - setLookupTablesData: () => { return } + setLookupTablesData: () => { + return; + }, }); diff --git a/src/common/helpers/array.ts b/src/common/helpers/array.ts index 9c38c1a59..86542f584 100644 --- a/src/common/helpers/array.ts +++ b/src/common/helpers/array.ts @@ -4,6 +4,8 @@ export const isArrayEqual = (x: Array, y: Array) => { return _(x).differenceWith(y, _.isEqual).isEmpty(); }; -export const is2dArray = (array: [] | [][]) => array.every(item => Array.isArray(item)); +export const is2dArray = (array: [] | [][]) => + array.every((item) => Array.isArray(item)); -export const getMax = (array: number[]): number => array.reduce((prev, current) => (prev > current) ? prev : current); +export const getMax = (array: number[]): number => + array.reduce((prev, current) => (prev > current ? prev : current)); diff --git a/src/common/helpers/enums.ts b/src/common/helpers/enums.ts index 51791a547..fa08ecd31 100644 --- a/src/common/helpers/enums.ts +++ b/src/common/helpers/enums.ts @@ -1,5 +1,6 @@ - // eslint-disable-next-line @typescript-eslint/ban-types -export function enumKeys(obj: O): K[] { - return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[]; +export function enumKeys( + obj: O +): K[] { + return Object.keys(obj).filter((k) => Number.isNaN(+k)) as K[]; } diff --git a/src/common/helpers/formatters.ts b/src/common/helpers/formatters.ts index 93f8d79dc..7e9e5c6f9 100644 --- a/src/common/helpers/formatters.ts +++ b/src/common/helpers/formatters.ts @@ -3,12 +3,20 @@ import moment from 'moment'; import { BASE_PATH } from '../../discrete-layer/components/layer-details/raster/state-machine/types'; import CONFIG from '../config'; -export const getDateformatType = (withTime = false, fnsFormat = false, humanReadable = false): string => { +export const getDateformatType = ( + withTime = false, + fnsFormat = false, + humanReadable = false +): string => { if (fnsFormat) { if (humanReadable) { - return withTime ? CONFIG.LOCALE.DATE_FNS_HUMAN_READABLE_DATE_TIME: CONFIG.LOCALE.DATE_FNS_HUMAN_READABLE_DATE; + return withTime + ? CONFIG.LOCALE.DATE_FNS_HUMAN_READABLE_DATE_TIME + : CONFIG.LOCALE.DATE_FNS_HUMAN_READABLE_DATE; } - return withTime ? CONFIG.LOCALE.DATE_FNS_TIME_FORMAT : CONFIG.LOCALE.DATE_FNS_FORMAT; + return withTime + ? CONFIG.LOCALE.DATE_FNS_TIME_FORMAT + : CONFIG.LOCALE.DATE_FNS_FORMAT; } return withTime ? CONFIG.LOCALE.DATE_TIME_FORMAT : CONFIG.LOCALE.DATE_FORMAT; }; @@ -25,7 +33,10 @@ export const stringFormatter: FormatterFunc = (val): string => { return val !== undefined ? val.toString() : ''; }; -export const dateFormatter: FormatterFunc = (date, withTime = false): string => { +export const dateFormatter: FormatterFunc = ( + date, + withTime = false +): string => { // eslint-disable-next-line return date !== undefined && 'toISOString' in (moment(date) as moment.Moment) ? moment(date).format(getDateformatType(withTime)) @@ -33,9 +44,7 @@ export const dateFormatter: FormatterFunc = (date, withTime = false): string => }; export const relativeDateFormatter: FormatterFunc = (date): string => { - return date !== undefined - ? moment(date).fromNow() - : '-'; + return date !== undefined ? moment(date).fromNow() : '-'; }; export const dateSerializer: FormatterFunc = (date): string => { @@ -48,7 +57,7 @@ export const dateSerializer: FormatterFunc = (date): string => { } if (typeof date !== 'undefined') { - return (date).toISOString(); + return date.toISOString(); } return '-'; @@ -59,7 +68,10 @@ export const emphasizeByHTML: FormatterFunc = (value): string => { }; const DEFAULT_DECIMALS = 2; -export const formatBytes = (bytes: number, decimals = DEFAULT_DECIMALS): string => { +export const formatBytes = ( + bytes: number, + decimals = DEFAULT_DECIMALS +): string => { const NONE = 0; if (!+bytes) return '0 Bytes'; diff --git a/src/common/helpers/group-by.ts b/src/common/helpers/group-by.ts index 756637926..0dcbf2e67 100644 --- a/src/common/helpers/group-by.ts +++ b/src/common/helpers/group-by.ts @@ -2,7 +2,9 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck export const resolveProperty = (obj: any, property: string): any => - property.split('.').reduce((result, prop) => (result ? result[prop] : undefined), obj); + property + .split('.') + .reduce((result, prop) => (result ? result[prop] : undefined), obj); export interface Group { key: any; @@ -28,7 +30,10 @@ export const totalRowItem = (obj: any, prop: string) => { export const flattenGroup = (group: Group): any[] => { const items = - group.items.length && group.items[0] && group.items[0].key && group.items[0].items + group.items.length && + group.items[0] && + group.items[0].key && + group.items[0].items ? flattenGroups(group.items) : group.items; @@ -44,21 +49,24 @@ export const flattenGroup = (group: Group): any[] => { return group.sum && flattenedItems && flattenedItems.length ? [ ...flattenedItems, - Object.getOwnPropertyNames(flattenedItems[0]).reduce((o, prop) => { - const val = resolveProperty(group.sum, prop); - o[prop] = val; - if (val !== undefined) { - o._sum[prop] = true; - } - return o; - }, { _sum: {} }) + Object.getOwnPropertyNames(flattenedItems[0]).reduce( + (o, prop) => { + const val = resolveProperty(group.sum, prop); + o[prop] = val; + if (val !== undefined) { + o._sum[prop] = true; + } + return o; + }, + { _sum: {} } + ), ] : flattenedItems; }; export const flattenGroups = (groups: Group[]): any[] => groups ? groups.reduce((array, group) => { - flattenGroup(group).forEach(item => array.push(item)); + flattenGroup(group).forEach((item) => array.push(item)); return array; }, []) : groups; @@ -72,10 +80,12 @@ export const sumGroup = (group: Group, sum: string[]): Group => { sum: sum.reduce( (sumObj, sumProp) => ({ ...sumObj, - [sumProp]: group.items.reduce((a, b) => resolveProperty(a, sumProp) + resolveProperty(b, sumProp)) + [sumProp]: group.items.reduce( + (a, b) => resolveProperty(a, sumProp) + resolveProperty(b, sumProp) + ), }), {} - ) + ), }; }; @@ -85,10 +95,15 @@ export const groupBy = (array: any[], grouping: GroupBy): Group[] => { } const keys = grouping.keys; const groups: Group[] = array.reduce((results: Group[], item) => { - const group = results.find(g => keys.every(({ name, predicate }) => predicate(item[name]) === predicate(g.key[name]))); + const group = results.find((g) => + keys.every( + ({ name, predicate }) => + predicate(item[name]) === predicate(g.key[name]) + ) + ); const data = Object.getOwnPropertyNames(item).reduce((o, prop) => { // if (!keys.some(key => key === prop)) { - o[prop] = item[prop]; + o[prop] = item[prop]; // } return o; }, {}); @@ -100,13 +115,13 @@ export const groupBy = (array: any[], grouping: GroupBy): Group[] => { o[key.name] = item[key.name]; return o; }, {}), - items: [data] + items: [data], }); } return results; }, []); return grouping.thenby - ? groups.map(g => ({ ...g, items: groupBy(g.items, grouping.thenby) })) + ? groups.map((g) => ({ ...g, items: groupBy(g.items, grouping.thenby) })) : groups.reduce((arr, g) => { arr.push(sumGroup(g, grouping.sum)); return arr; diff --git a/src/common/helpers/layer-url.ts b/src/common/helpers/layer-url.ts index bf334d6ea..b87d42c6a 100644 --- a/src/common/helpers/layer-url.ts +++ b/src/common/helpers/layer-url.ts @@ -1,26 +1,35 @@ /* eslint-disable */ import { get } from 'lodash'; -import { LayerMetadataMixedUnion, RecordStatus } from '../../discrete-layer/models'; +import { + LayerMetadataMixedUnion, + RecordStatus, +} from '../../discrete-layer/models'; import CONFIG from '../config'; -const getParamsString = (params: {[key: string]: string | boolean | number}) : string => { +const getParamsString = (params: { + [key: string]: string | boolean | number; +}): string => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - const paramArray = Object.keys(params).map((key: string) => `${key}=${String(params[key])}`); + const paramArray = Object.keys(params).map( + (key: string) => `${key}=${String(params[key])}` + ); return paramArray.join('&'); }; -const fullUrls : {[key : string] : string} = { +const fullUrls: { [key: string]: string } = { // eslint-disable-next-line @typescript-eslint/naming-convention - 'WMS_LAYER': `${CONFIG.WMS_LAYER.URL}?${getParamsString(CONFIG.WMS_LAYER.PARAMS)}`, + WMS_LAYER: `${CONFIG.WMS_LAYER.URL}?${getParamsString( + CONFIG.WMS_LAYER.PARAMS + )}`, // eslint-disable-next-line @typescript-eslint/naming-convention - 'WMTS_LAYER': CONFIG.WMTS_LAYER.URL, + WMTS_LAYER: CONFIG.WMTS_LAYER.URL, // eslint-disable-next-line @typescript-eslint/naming-convention - 'XYZ_LAYER': CONFIG.XYZ_LAYER.URL, + XYZ_LAYER: CONFIG.XYZ_LAYER.URL, // eslint-disable-next-line @typescript-eslint/naming-convention - 'OSM_LAYER': CONFIG.OSM_LAYER.URL + OSM_LAYER: CONFIG.OSM_LAYER.URL, }; -export const getLayerUrl = () : string => { +export const getLayerUrl = (): string => { const activeLayer = CONFIG.ACTIVE_LAYER as string; return fullUrls[activeLayer]; }; @@ -35,4 +44,4 @@ export const isBeingDeleted = (data: LayerMetadataMixedUnion): boolean => { export const isValidLayerMetadata = (data: LayerMetadataMixedUnion) => { return isExistLayerURL(data) && !isBeingDeleted(data); -} \ No newline at end of file +}; diff --git a/src/common/helpers/number.ts b/src/common/helpers/number.ts index 304018181..983c7c585 100644 --- a/src/common/helpers/number.ts +++ b/src/common/helpers/number.ts @@ -1,6 +1,8 @@ const NOT_FOUND = -1; -export const convertExponentialToDecimal = (exponentialNumber: string): string => { +export const convertExponentialToDecimal = ( + exponentialNumber: string +): string => { if (exponentialNumber.indexOf('e') !== NOT_FOUND) { const exponent = parseInt(exponentialNumber.split('-')[1], 10); const result = Number(exponentialNumber).toFixed(exponent); diff --git a/src/common/helpers/object.ts b/src/common/helpers/object.ts index 1a267e9a6..5cca0da0d 100644 --- a/src/common/helpers/object.ts +++ b/src/common/helpers/object.ts @@ -1,36 +1,44 @@ - import { isObject, cloneDeep } from 'lodash'; +import { isObject, cloneDeep } from 'lodash'; - // eslint-disable-next-line @typescript-eslint/ban-types - export function hasOwnProperty - (obj: X, prop: Y): obj is X & Record { - // eslint-disable-next-line no-prototype-builtins - return obj.hasOwnProperty(prop) - } +// eslint-disable-next-line @typescript-eslint/ban-types +export function hasOwnProperty( + obj: X, + prop: Y +): obj is X & Record { + // eslint-disable-next-line no-prototype-builtins + return obj.hasOwnProperty(prop); +} - export const mergeRecursive = (obj1: Record, obj2: Record): Record => { - const retObj = cloneDeep(obj1); - for (let p in obj2) { - try { - // Property in destination object set; update its value. - if ( isObject(obj2[p]) ) { - retObj[p] = mergeRecursive(retObj[p] as Record, obj2[p] as Record); - } else { - retObj[p] = obj2[p]; - } - } catch(e) { - // Property in destination object not set; create it and set its value. +export const mergeRecursive = ( + obj1: Record, + obj2: Record +): Record => { + const retObj = cloneDeep(obj1); + for (let p in obj2) { + try { + // Property in destination object set; update its value. + if (isObject(obj2[p])) { + retObj[p] = mergeRecursive( + retObj[p] as Record, + obj2[p] as Record + ); + } else { retObj[p] = obj2[p]; } + } catch (e) { + // Property in destination object not set; create it and set its value. + retObj[p] = obj2[p]; } - - return retObj; } - export const removePropertiesWithPrefix = (obj: any, prefix: string): any => { - for (const key in obj) { - if (key.startsWith(prefix)) { - delete obj[key]; - } + return retObj; +}; + +export const removePropertiesWithPrefix = (obj: any, prefix: string): any => { + for (const key in obj) { + if (key.startsWith(prefix)) { + delete obj[key]; } - return obj; - }; \ No newline at end of file + } + return obj; +}; diff --git a/src/common/helpers/set.ts b/src/common/helpers/set.ts index 142f2dc70..d7ec40358 100644 --- a/src/common/helpers/set.ts +++ b/src/common/helpers/set.ts @@ -3,21 +3,23 @@ export class SetWithContentEquality { private getKey: (item: T) => string; constructor(getKey: (item: T) => string) { - this.getKey = getKey; + this.getKey = getKey; } add(item: T): void { - const key = this.getKey(item); - if (!this.items.some(existing => this.getKey(existing) === key)) { - this.items.push(item); - } + const key = this.getKey(item); + if (!this.items.some((existing) => this.getKey(existing) === key)) { + this.items.push(item); + } } has(item: T): boolean { - return this.items.some(existing => this.getKey(existing) === this.getKey(item)); + return this.items.some( + (existing) => this.getKey(existing) === this.getKey(item) + ); } values(): T[] { - return [...this.items]; + return [...this.items]; } -} \ No newline at end of file +} diff --git a/src/common/helpers/siteUrl.ts b/src/common/helpers/siteUrl.ts index 84fe0aa32..0ad306b36 100644 --- a/src/common/helpers/siteUrl.ts +++ b/src/common/helpers/siteUrl.ts @@ -6,15 +6,21 @@ import CONFIG from '../config'; export const currentClientUrl = window.location.origin; export const currentSite = (): siteName => { - return CONFIG.SITES_CONFIG.slaves.map((slave: site) => slave.dns).includes(currentClientUrl) + return CONFIG.SITES_CONFIG.slaves + .map((slave: site) => slave.dns) + .includes(currentClientUrl) ? 'slave' - : CONFIG.SITES_CONFIG.masters.map((master: site) => master.dns).includes(currentClientUrl) + : CONFIG.SITES_CONFIG.masters + .map((master: site) => master.dns) + .includes(currentClientUrl) ? 'master' - : CONFIG.SITES_CONFIG.generics.map((generic: site) => generic.dns).includes(currentClientUrl) + : CONFIG.SITES_CONFIG.generics + .map((generic: site) => generic.dns) + .includes(currentClientUrl) ? 'generic' : 'undefined'; }; -export const syncSlavesClients: GraphQLClient[] = CONFIG.SITES_CONFIG.slaves?.filter((slave: site) => !slave.isAlias) - .map((slave: site) => createHttpClient(slave.dns + CONFIG.BFF_PATH) -); +export const syncSlavesClients: GraphQLClient[] = CONFIG.SITES_CONFIG.slaves + ?.filter((slave: site) => !slave.isAlias) + .map((slave: site) => createHttpClient(slave.dns + CONFIG.BFF_PATH)); diff --git a/src/common/helpers/storage.ts b/src/common/helpers/storage.ts index 6d55e464b..557b4e962 100644 --- a/src/common/helpers/storage.ts +++ b/src/common/helpers/storage.ts @@ -6,11 +6,12 @@ export interface IStorage { remove: (key: string) => void; clear: () => void; key: (index: number) => string | null; - watchMethods: ( methods: string[], - callbackBefore?: (method: string, key: string, ...args: any[]) => void, - callbackAfter?: (method: string, key: string, ...args: any[]) => void - ) => void, - unWatchMethods: () => void, + watchMethods: ( + methods: string[], + callbackBefore?: (method: string, key: string, ...args: any[]) => void, + callbackAfter?: (method: string, key: string, ...args: any[]) => void + ) => void; + unWatchMethods: () => void; length: number; } @@ -93,11 +94,19 @@ function storageFactory(storage: Storage, prefix = ''): IStorage { } let originalMethods: Record void> = {}; - - function watchMethods ( + + function watchMethods( methods: string[] = [], - callbackBefore: (method: string, key: string, ...args: any[]) => void = function () {}, - callbackAfter: (method: string, key: string, ...args: any[]) => void = function () {}, + callbackBefore: ( + method: string, + key: string, + ...args: any[] + ) => void = function () {}, + callbackAfter: ( + method: string, + key: string, + ...args: any[] + ) => void = function () {} ) { for (let method of methods) { const original = storage[method].bind(storage); @@ -114,13 +123,12 @@ function storageFactory(storage: Storage, prefix = ''): IStorage { } } - function unWatchMethods () { - Object.keys(originalMethods).forEach(method => { + function unWatchMethods() { + Object.keys(originalMethods).forEach((method) => { storage[method] = originalMethods[method]; }); - originalMethods={}; + originalMethods = {}; } - return { get, diff --git a/src/common/helpers/string.ts b/src/common/helpers/string.ts index 9e7ec8007..588ef0f86 100644 --- a/src/common/helpers/string.ts +++ b/src/common/helpers/string.ts @@ -1,17 +1,21 @@ export const camelize = (value: string): string => { - return value.toLowerCase().replace( - /^([A-Z])|[\s-_]+(\w)/g, - (match, p1: string, p2: string, offset) => { - if (p2) return p2.toUpperCase(); - return p1.toLowerCase(); - } - ); + return value + .toLowerCase() + .replace( + /^([A-Z])|[\s-_]+(\w)/g, + (match, p1: string, p2: string, offset) => { + if (p2) return p2.toUpperCase(); + return p1.toLowerCase(); + } + ); }; -export const extractJsonObjFromString = >(input: string): T | undefined => { +export const extractJsonObjFromString = >( + input: string +): T | undefined => { const FIRST_MATCH = 0; const jsonRegex = new RegExp(/\{(?:[^{}]|(R))*\}/); const match = jsonRegex.exec(input)?.[FIRST_MATCH]; if (typeof match === 'string') return JSON.parse(match) as T; -}; \ No newline at end of file +}; diff --git a/src/common/helpers/style.ts b/src/common/helpers/style.ts index 2ff6e9013..45b0d6a2c 100644 --- a/src/common/helpers/style.ts +++ b/src/common/helpers/style.ts @@ -1,5 +1,8 @@ import { get } from 'lodash'; -import { LayerMetadataMixedUnion, RecordStatus } from '../../discrete-layer/models'; +import { + LayerMetadataMixedUnion, + RecordStatus, +} from '../../discrete-layer/models'; import { DEFAULT_ID } from '../../discrete-layer/components/layer-details/entity.dialog'; import CONFIG from '../config'; import { isValidLayerMetadata } from './layer-url'; @@ -7,7 +10,8 @@ import { isValidLayerMetadata } from './layer-url'; const STATUS = 'productStatus'; const ID = 'id'; const POLYGON_PARTS_SHOWN = 'polygonPartsShown'; -const POLYGON_PARTS_SHOWN_COLOR = CONFIG.CONTEXT_MENUS.MAP.POLYGON_PARTS_FEATURE_CONFIG.outlineColor; +const POLYGON_PARTS_SHOWN_COLOR = + CONFIG.CONTEXT_MENUS.MAP.POLYGON_PARTS_FEATURE_CONFIG.outlineColor; const UNPUBLISHED_COLOR = 'var(--mdc-theme-gc-warning-high)'; const ERROR_COLOR = 'var(--mdc-theme-gc-error-high)'; @@ -20,7 +24,10 @@ export const existPolygonParts = (data: Record): boolean => { }; export const isUnpublished = (data: Record): boolean => { - return get(data, STATUS) === RecordStatus.UNPUBLISHED && get(data, ID) !== DEFAULT_ID; + return ( + get(data, STATUS) === RecordStatus.UNPUBLISHED && + get(data, ID) !== DEFAULT_ID + ); }; export const isPolygonPartsShown = (data: Record): boolean => { @@ -56,7 +63,9 @@ export const getIconStyle = ( resStyle = { [colorProperty]: UNPUBLISHED_COLOR }; } if (existPolygonParts(data) && isPolygonPartsShown(data)) { - const hasWFSLink = (data.links as Array>)?.some(link => link.protocol === 'WFS'); + const hasWFSLink = (data.links as Array>)?.some( + (link) => link.protocol === 'WFS' + ); if (hasWFSLink) { resStyle = { [colorProperty]: POLYGON_PARTS_SHOWN_COLOR }; } else { @@ -64,11 +73,13 @@ export const getIconStyle = ( } } if (existPolygonParts(data) && !isPolygonPartsShown(data)) { - const hasWFSLink = (data.links as Array>)?.some(link => link.protocol === 'WFS'); + const hasWFSLink = (data.links as Array>)?.some( + (link) => link.protocol === 'WFS' + ); if (!hasWFSLink) { resStyle = { ...resStyle, - opacity: 0.5 + opacity: 0.5, }; } } diff --git a/src/common/hooks/countdown.hook.ts b/src/common/hooks/countdown.hook.ts index c8795a79f..c3ef9d708 100644 --- a/src/common/hooks/countdown.hook.ts +++ b/src/common/hooks/countdown.hook.ts @@ -13,8 +13,11 @@ const useCountDown = (timeToCount = 60 * 1000, interval = 1000) => { timer.current.lastInterval = ts; } - const localInterval = Math.min(interval, (timer.current.timeLeft || Infinity)); - if ((ts - timer.current.lastInterval) >= localInterval) { + const localInterval = Math.min( + interval, + timer.current.timeLeft || Infinity + ); + if (ts - timer.current.lastInterval >= localInterval) { timer.current.lastInterval += localInterval; setTimeLeft((timeLeft) => { timer.current.timeLeft = timeLeft - localInterval; @@ -30,61 +33,46 @@ const useCountDown = (timeToCount = 60 * 1000, interval = 1000) => { } }; - const start = React.useCallback( - (ttc) => { - window.cancelAnimationFrame(timer.current.requestId); + const start = React.useCallback((ttc) => { + window.cancelAnimationFrame(timer.current.requestId); - const newTimeToCount = ttc !== undefined ? ttc : timeToCount - timer.current.started = null; - timer.current.lastInterval = null; - timer.current.timeToCount = newTimeToCount; - timer.current.requestId = window.requestAnimationFrame(run); + const newTimeToCount = ttc !== undefined ? ttc : timeToCount; + timer.current.started = null; + timer.current.lastInterval = null; + timer.current.timeToCount = newTimeToCount; + timer.current.requestId = window.requestAnimationFrame(run); - setTimeLeft(newTimeToCount); - }, - [], - ); + setTimeLeft(newTimeToCount); + }, []); - const pause = React.useCallback( - () => { - window.cancelAnimationFrame(timer.current.requestId); - timer.current.started = null; - timer.current.lastInterval = null; - timer.current.timeToCount = timer.current.timeLeft; - }, - [], - ); + const pause = React.useCallback(() => { + window.cancelAnimationFrame(timer.current.requestId); + timer.current.started = null; + timer.current.lastInterval = null; + timer.current.timeToCount = timer.current.timeLeft; + }, []); - const resume = React.useCallback( - () => { - if (!timer.current.started && timer.current.timeLeft > 0) { - window.cancelAnimationFrame(timer.current.requestId); - timer.current.requestId = window.requestAnimationFrame(run); - } - }, - [], - ); + const resume = React.useCallback(() => { + if (!timer.current.started && timer.current.timeLeft > 0) { + window.cancelAnimationFrame(timer.current.requestId); + timer.current.requestId = window.requestAnimationFrame(run); + } + }, []); - const reset = React.useCallback( - () => { - if (timer.current.timeLeft) { - window.cancelAnimationFrame(timer.current.requestId); - timer.current = {}; - setTimeLeft(0); - } - }, - [], - ); + const reset = React.useCallback(() => { + if (timer.current.timeLeft) { + window.cancelAnimationFrame(timer.current.requestId); + timer.current = {}; + setTimeLeft(0); + } + }, []); - const actions = React.useMemo( - () => ({ start, pause, resume, reset }), - [], - ); + const actions = React.useMemo(() => ({ start, pause, resume, reset }), []); React.useEffect(() => reset, []); return [timeLeft, actions]; -} +}; export interface IActions { start: (ttc?: any) => void; diff --git a/src/common/hooks/debounce-field.hook.ts b/src/common/hooks/debounce-field.hook.ts index 681c06213..cf937c446 100644 --- a/src/common/hooks/debounce-field.hook.ts +++ b/src/common/hooks/debounce-field.hook.ts @@ -2,27 +2,30 @@ import React, { useState, useEffect, useCallback } from 'react'; import { useDebouncedCallback } from 'use-debounce'; import { EntityFormikHandlers } from '../../discrete-layer/components/layer-details/layer-datails-form'; -export interface GCHTMLInputElement{ - [prop:string]: unknown; - persist: ()=>void; +export interface GCHTMLInputElement { + [prop: string]: unknown; + persist: () => void; currentTarget: { - [prop:string]: unknown; - value: unknown - } -}; + [prop: string]: unknown; + value: unknown; + }; +} const DEFAULT_DEBOUNCE = 500; -const useDebounceField = ( +const useDebounceField = ( formikHandlers: EntityFormikHandlers, value: T | string, debouncePeriod = DEFAULT_DEBOUNCE -): [T | string, (event: React.ChangeEvent) => void] => { +): [ + T | string, + (event: React.ChangeEvent) => void +] => { const [innerValue, setInnerValue] = useState(value); const INPUT_DELAY = debouncePeriod; useEffect(() => { - setInnerValue(value); + setInnerValue(value); }, [value]); const debouncedHandleOnChange = useDebouncedCallback( @@ -35,13 +38,14 @@ const useDebounceField = ( const handleOnChange = useCallback( (event: React.ChangeEvent) => { event.persist(); - const newValue = event.currentTarget.value as (T | string); + const newValue = event.currentTarget.value as T | string; setInnerValue(newValue); debouncedHandleOnChange(event); - - }, []); + }, + [] + ); return [innerValue, handleOnChange]; }; -export default useDebounceField; \ No newline at end of file +export default useDebounceField; diff --git a/src/common/hooks/isEllipsisActive.hook.ts b/src/common/hooks/isEllipsisActive.hook.ts index 2baeb7b98..87aa86680 100644 --- a/src/common/hooks/isEllipsisActive.hook.ts +++ b/src/common/hooks/isEllipsisActive.hook.ts @@ -1,16 +1,25 @@ import { useState, useEffect, RefObject } from 'react'; - -const useIsEllipsisActive = (containerElement: RefObject): boolean => { +const useIsEllipsisActive = ( + containerElement: RefObject +): boolean => { const [isEllipsisActive, setIsEllipsisActive] = useState(false); useEffect(() => { - if (containerElement.current !== null && containerElement.current.offsetWidth < containerElement.current.scrollWidth) { + if ( + containerElement.current !== null && + containerElement.current.offsetWidth < + containerElement.current.scrollWidth + ) { setIsEllipsisActive(true); } - }, [containerElement.current, containerElement.current?.innerText, containerElement.current?.innerHTML ]); + }, [ + containerElement.current, + containerElement.current?.innerText, + containerElement.current?.innerHTML, + ]); return isEllipsisActive; -} +}; -export default useIsEllipsisActive; \ No newline at end of file +export default useIsEllipsisActive; diff --git a/src/common/hooks/mapMenus/useGetMenuDimensions.ts b/src/common/hooks/mapMenus/useGetMenuDimensions.ts index b6a277700..c9904189c 100644 --- a/src/common/hooks/mapMenus/useGetMenuDimensions.ts +++ b/src/common/hooks/mapMenus/useGetMenuDimensions.ts @@ -1,38 +1,59 @@ import { get } from 'lodash'; import { useMemo } from 'react'; import { useTheme } from '@map-colonies/react-core'; -import { TITLE_HEIGHT, SUB_MENU_MAX_HEIGHT } from '../../../discrete-layer/components/map-container/contextMenus/context-menu'; -import { IMapMenuProperties, isMenuItemGroup } from '../../../discrete-layer/models/mapMenusManagerStore'; +import { + TITLE_HEIGHT, + SUB_MENU_MAX_HEIGHT, +} from '../../../discrete-layer/components/map-container/contextMenus/context-menu'; +import { + IMapMenuProperties, + isMenuItemGroup, +} from '../../../discrete-layer/models/mapMenusManagerStore'; import { IDimensions } from '../useElementDimensions.hook'; - + export interface MenuDimensions extends IDimensions { dynamicHeightIncrement: number; } -const useGetMenuDimensions = (menuProperties?: IMapMenuProperties, customDynamicHeightIncrement?: number): MenuDimensions | undefined => { +const useGetMenuDimensions = ( + menuProperties?: IMapMenuProperties, + customDynamicHeightIncrement?: number +): MenuDimensions | undefined => { const theme = useTheme(); - + const menuDimensions = useMemo((): MenuDimensions | undefined => { if (typeof menuProperties === 'undefined') return undefined; const DEFAULT_HEIGHT_BUFFER = 5; - const themedMenuItemHeight = Number((get(theme, 'gcMenuItemHeight') as string).split('px')[0]); - const themedContextMenuWidth = Number((get(theme, 'gcContextMenuWidth') as string).split('px')[0]); - - const numberOfMenuItems = menuProperties.itemsList.reduce((itemsCount, menuItemOrGroup) => { - if (!isMenuItemGroup(menuItemOrGroup)) return ++itemsCount; - return itemsCount + menuItemOrGroup.items.length; - }, 0); - const calculatedMenuHeight = menuProperties.absoluteHeight ?? - ( - ((numberOfMenuItems * themedMenuItemHeight) + (menuProperties.heightBuffer ?? DEFAULT_HEIGHT_BUFFER)) + TITLE_HEIGHT + const themedMenuItemHeight = Number( + (get(theme, 'gcMenuItemHeight') as string).split('px')[0] + ); + const themedContextMenuWidth = Number( + (get(theme, 'gcContextMenuWidth') as string).split('px')[0] ); - return { width: themedContextMenuWidth, height: calculatedMenuHeight, dynamicHeightIncrement: customDynamicHeightIncrement ?? SUB_MENU_MAX_HEIGHT }; + const numberOfMenuItems = menuProperties.itemsList.reduce( + (itemsCount, menuItemOrGroup) => { + if (!isMenuItemGroup(menuItemOrGroup)) return ++itemsCount; + return itemsCount + menuItemOrGroup.items.length; + }, + 0 + ); + const calculatedMenuHeight = + menuProperties.absoluteHeight ?? + numberOfMenuItems * themedMenuItemHeight + + (menuProperties.heightBuffer ?? DEFAULT_HEIGHT_BUFFER) + + TITLE_HEIGHT; + return { + width: themedContextMenuWidth, + height: calculatedMenuHeight, + dynamicHeightIncrement: + customDynamicHeightIncrement ?? SUB_MENU_MAX_HEIGHT, + }; }, [menuProperties]); return menuDimensions; -} +}; -export default useGetMenuDimensions; \ No newline at end of file +export default useGetMenuDimensions; diff --git a/src/common/hooks/mapMenus/useGetMenuProperties.hook.ts b/src/common/hooks/mapMenus/useGetMenuProperties.hook.ts index 8891a1512..8f2bc0f4d 100644 --- a/src/common/hooks/mapMenus/useGetMenuProperties.hook.ts +++ b/src/common/hooks/mapMenus/useGetMenuProperties.hook.ts @@ -1,21 +1,32 @@ import { useEffect } from 'react'; import { IContextMenuData } from '@map-colonies/react-components'; import { useStore } from '../../../discrete-layer/models'; -import { MapMenusIds, IMapMenuProperties } from '../../../discrete-layer/models/mapMenusManagerStore'; +import { + MapMenusIds, + IMapMenuProperties, +} from '../../../discrete-layer/models/mapMenusManagerStore'; import { useHandleMapMenuTemplates } from './useHandleMapMenuTemplates.hook'; -const useGetMenuProperties = (menuId: MapMenusIds, contextProps?: IContextMenuData): IMapMenuProperties | undefined => { +const useGetMenuProperties = ( + menuId: MapMenusIds, + contextProps?: IContextMenuData +): IMapMenuProperties | undefined => { const store = useStore(); const mapMenus = store.mapMenusManagerStore.mapMenus; - const generatedByContextMenuProperties = useHandleMapMenuTemplates(mapMenus?.[menuId], contextProps); - + const generatedByContextMenuProperties = useHandleMapMenuTemplates( + mapMenus?.[menuId], + contextProps + ); + useEffect(() => { if (contextProps?.coordinates) { - store.mapMenusManagerStore.setLastMenuCoordinate(contextProps?.coordinates); + store.mapMenusManagerStore.setLastMenuCoordinate( + contextProps?.coordinates + ); } }, [contextProps?.coordinates]); return generatedByContextMenuProperties; -} +}; -export default useGetMenuProperties; \ No newline at end of file +export default useGetMenuProperties; diff --git a/src/common/hooks/mapMenus/useHandleDemHeightsRequests.ts b/src/common/hooks/mapMenus/useHandleDemHeightsRequests.ts index 6e0ecd302..a92339410 100644 --- a/src/common/hooks/mapMenus/useHandleDemHeightsRequests.ts +++ b/src/common/hooks/mapMenus/useHandleDemHeightsRequests.ts @@ -7,44 +7,54 @@ import { } from '../../../discrete-layer/models'; import { GetDemPointsHeightsInput } from '../../../discrete-layer/models/RootStore.base'; -type HandlerDemHeightsOptions = GetDemPointsHeightsInput & { onDataResolved?: (data?: PositionsWithHeightsModelType) => void }; +type HandlerDemHeightsOptions = GetDemPointsHeightsInput & { + onDataResolved?: (data?: PositionsWithHeightsModelType) => void; +}; -const DEM_POINTS_HEIGHTS_QUERY = -`data { +const DEM_POINTS_HEIGHTS_QUERY = `data { latitude longitude height }`; const useHandleDemHeightsRequests = (): { - data: { getPointsHeights: PositionsWithHeightsModelType} | undefined; + data: { getPointsHeights: PositionsWithHeightsModelType } | undefined; loading: boolean; demHeightsOptions: GetDemPointsHeightsInput | undefined; setDemHeightsOptions: (options: HandlerDemHeightsOptions) => void; } => { const store = useStore(); - const [demHeightsOptions, setDemHeightsOptions] = useState(); + const [demHeightsOptions, setDemHeightsOptions] = + useState(); const { data, loading, setQuery } = useQuery<{ - getPointsHeights: PositionsWithHeightsModelType; + getPointsHeights: PositionsWithHeightsModelType; }>(); useEffect(() => { if (demHeightsOptions) { - - setQuery(store.queryGetPointsHeights({ data: { ...demHeightsOptions } }, DEM_POINTS_HEIGHTS_QUERY)); + setQuery( + store.queryGetPointsHeights( + { data: { ...demHeightsOptions } }, + DEM_POINTS_HEIGHTS_QUERY + ) + ); } }, [demHeightsOptions]); useEffect(() => { if (demHeightsOptions && !loading && data) { - const demPositionsWithHeights = [...(data?.getPointsHeights as PositionsWithHeightsModelType)?.data as PositionWithHeightModelType[]]; - - store.mapMenusManagerStore.setCurrentPositionDemHeight(demPositionsWithHeights[0]); + const demPositionsWithHeights = [ + ...((data?.getPointsHeights as PositionsWithHeightsModelType) + ?.data as PositionWithHeightModelType[]), + ]; - demHeightsOptions.onDataResolved?.(data.getPointsHeights); - } + store.mapMenusManagerStore.setCurrentPositionDemHeight( + demPositionsWithHeights[0] + ); + demHeightsOptions.onDataResolved?.(data.getPointsHeights); + } }, [data, loading]); return { data, loading, demHeightsOptions, setDemHeightsOptions }; diff --git a/src/common/hooks/mapMenus/useHandleMapMenuTemplates.hook.ts b/src/common/hooks/mapMenus/useHandleMapMenuTemplates.hook.ts index 3c0997091..4acbb3c7f 100644 --- a/src/common/hooks/mapMenus/useHandleMapMenuTemplates.hook.ts +++ b/src/common/hooks/mapMenus/useHandleMapMenuTemplates.hook.ts @@ -8,17 +8,22 @@ import { MenuItem, MenuItemsGroup, MenuItemsList, - isMenuItemGroup + isMenuItemGroup, } from '../../../discrete-layer/models/mapMenusManagerStore'; import { useStore } from '../../../discrete-layer/models'; import { IDispatchAction } from '../../../discrete-layer/models/actionDispatcherStore'; import { DEFAULT_LAYER_HUE_FACTOR } from '../../../discrete-layer/views/components/map-action-resolver.component'; -import { ContextActionGroupProps, ContextActions, ContextActionsGroupTemplates, ContextActionsTemplates } from '../../actions/context.actions'; +import { + ContextActionGroupProps, + ContextActions, + ContextActionsGroupTemplates, + ContextActionsTemplates, +} from '../../actions/context.actions'; import CONFIG from '../../config'; export const useHandleMapMenuTemplates = ( menuProperties?: IMapMenuProperties, - contextProps?: IContextMenuData, + contextProps?: IContextMenuData ): IMapMenuProperties | undefined => { /** * The hook should be able to generate the menu properties passed as an argument, @@ -35,85 +40,114 @@ export const useHandleMapMenuTemplates = ( // Gather all of the data to be used in the process to build the complete menu. store / contexts / hooks / etc. const store = useStore(); - const activeLayersInPosition = contextProps?.data as Record[]; + const activeLayersInPosition = contextProps?.data as Record< + string, + unknown + >[]; const wfsFeatureTypesList = store.mapMenusManagerStore.wfsFeatureTypes ?? []; // This object holds the data that used to generate menu items from templates. - const dynamicMenuData: DynamicMenuData = useMemo(() => ({ - [ContextActionsGroupTemplates.ACTIVE_LAYERS_IN_POSITION]: activeLayersInPosition, - [ContextActionsTemplates.WFS_QUERY_FEATURES]: wfsFeatureTypesList - }), [activeLayersInPosition, wfsFeatureTypesList]) - - - const handleActionTemplates = (actionTemplateMenuItem: MenuItem): MenuItemsList => { + const dynamicMenuData: DynamicMenuData = useMemo( + () => ({ + [ContextActionsGroupTemplates.ACTIVE_LAYERS_IN_POSITION]: + activeLayersInPosition, + [ContextActionsTemplates.WFS_QUERY_FEATURES]: wfsFeatureTypesList, + }), + [activeLayersInPosition, wfsFeatureTypesList] + ); + + const handleActionTemplates = ( + actionTemplateMenuItem: MenuItem + ): MenuItemsList => { switch (actionTemplateMenuItem.templateId) { case ContextActionsTemplates.WFS_QUERY_FEATURES: { - const wfsFeatureTypesList = dynamicMenuData[ContextActionsTemplates.WFS_QUERY_FEATURES] as string[]; - const wfsQueryMenuItems: MenuItem[] = wfsFeatureTypesList.map((feature) => { - const featureConfig = - store.mapMenusManagerStore.getFeatureConfig(feature); - const featureTitle = featureConfig.translationId ?? feature; - - return { - title: featureTitle, - icon: featureConfig.icon, - action: { ...actionTemplateMenuItem.action }, - payloadData: { feature } - }; - }); + const wfsFeatureTypesList = dynamicMenuData[ + ContextActionsTemplates.WFS_QUERY_FEATURES + ] as string[]; + const wfsQueryMenuItems: MenuItem[] = wfsFeatureTypesList.map( + (feature) => { + const featureConfig = + store.mapMenusManagerStore.getFeatureConfig(feature); + const featureTitle = featureConfig.translationId ?? feature; + + return { + title: featureTitle, + icon: featureConfig.icon, + action: { ...actionTemplateMenuItem.action }, + payloadData: { feature }, + }; + } + ); return wfsQueryMenuItems; } default: return [actionTemplateMenuItem]; } - } + }; - const handleGroupTemplates = (groupTemplateMenuItem: MenuItemsGroup): MenuItemsList => { + const handleGroupTemplates = ( + groupTemplateMenuItem: MenuItemsGroup + ): MenuItemsList => { const generatedGroups: MenuItemsList = []; switch (groupTemplateMenuItem.templateId) { case ContextActionsGroupTemplates.ACTIVE_LAYERS_IN_POSITION: { - const activeLayersInPosition = dynamicMenuData[ContextActionsGroupTemplates.ACTIVE_LAYERS_IN_POSITION] as Record[]; + const activeLayersInPosition = dynamicMenuData[ + ContextActionsGroupTemplates.ACTIVE_LAYERS_IN_POSITION + ] as Record[]; const templateProps = groupTemplateMenuItem.groupProps; - const MAX_ACTIVE_LAYERS_TO_PRESENT = CONFIG.CONTEXT_MENUS.MAP.MAX_ACTIVE_LAYERS_TO_PRESENT; - const slicedActiveLayers = activeLayersInPosition.slice(0, MAX_ACTIVE_LAYERS_TO_PRESENT); + const MAX_ACTIVE_LAYERS_TO_PRESENT = + CONFIG.CONTEXT_MENUS.MAP.MAX_ACTIVE_LAYERS_TO_PRESENT; + const slicedActiveLayers = activeLayersInPosition.slice( + 0, + MAX_ACTIVE_LAYERS_TO_PRESENT + ); // Some pinkish color const HOVERED_LAYER_HUE_FACTOR = 30; - slicedActiveLayers.forEach(activeLayer => { + slicedActiveLayers.forEach((activeLayer) => { const groupProp: ContextActionGroupProps = { ...templateProps, id: templateProps.id + 1, // @ts-ignore - titleTranslationId: activeLayer.meta?.layerRecord?.productName as string, + titleTranslationId: activeLayer.meta?.layerRecord + ?.productName as string, }; - const mouseEnterAction: IDispatchAction = { action: ContextActions.HIGHLIGHT_ACTIVE_LAYER, - data: { ...activeLayer.meta as Record, hue: HOVERED_LAYER_HUE_FACTOR } + data: { + ...(activeLayer.meta as Record), + hue: HOVERED_LAYER_HUE_FACTOR, + }, }; const mouseLeaveAction: IDispatchAction = { action: ContextActions.HIGHLIGHT_ACTIVE_LAYER, - data: { ...activeLayer.meta as Record, hue: DEFAULT_LAYER_HUE_FACTOR } + data: { + ...(activeLayer.meta as Record), + hue: DEFAULT_LAYER_HUE_FACTOR, + }, }; const generatedGroup: MenuItemsGroup = { ...groupTemplateMenuItem, groupProps: groupProp, title: groupProp.titleTranslationId, - items: groupTemplateMenuItem.items.map(item => { + items: groupTemplateMenuItem.items.map((item) => { if (!isMenuItemGroup(item)) { - return { ...item, payloadData: activeLayer.meta as Record }; + return { + ...item, + payloadData: activeLayer.meta as Record, + }; } return item; }), mouseEnterAction, - mouseLeaveAction + mouseLeaveAction, }; generatedGroups.push(generatedGroup); @@ -126,17 +160,23 @@ export const useHandleMapMenuTemplates = ( // Check if group holds WFS actions by presence at least one such item const wfsFeature = groupTemplateMenuItem.items.find((item) => { const menuItem = item as MenuItem; - return menuItem.action ? menuItem.action.action === ContextActions.QUERY_WFS_FEATURE : false; + return menuItem.action + ? menuItem.action.action === ContextActions.QUERY_WFS_FEATURE + : false; }); if (wfsFeature) { - tempGroup.groupProps.titleTranslationId = intl.formatMessage({ - id: tempGroup.groupProps.titleTranslationId, - }, { extraInfo: `(${groupTemplateMenuItem.items.length}/${store.mapMenusManagerStore.total})` }); + tempGroup.groupProps.titleTranslationId = intl.formatMessage( + { + id: tempGroup.groupProps.titleTranslationId, + }, + { + extraInfo: `(${groupTemplateMenuItem.items.length}/${store.mapMenusManagerStore.total})`, + } + ); } return [tempGroup]; } - - } + }; // Iterate through the menu (and sub-menu) properties and handle the templates logic based on the templateId. // Returns the menu after the processing. @@ -145,7 +185,6 @@ export const useHandleMapMenuTemplates = ( const itemsList = items ?? menuProperties?.itemsList; itemsList?.forEach((item) => { - if (!isMenuItemGroup(item)) { // Handle action templates const generatedActions: MenuItemsList = handleActionTemplates(item); @@ -155,21 +194,22 @@ export const useHandleMapMenuTemplates = ( // Handle group templates const generatedGroups: MenuItemsList = handleGroupTemplates({ ...item, - items: getGeneratedMenu(item.items).itemsList + items: getGeneratedMenu(item.items).itemsList, }); menuItems.push(...generatedGroups); return; - } - }); return { ...menuProperties, itemsList: menuItems }; }; useEffect(() => { - if (typeof menuProperties !== 'undefined' && typeof contextProps !== 'undefined') { + if ( + typeof menuProperties !== 'undefined' && + typeof contextProps !== 'undefined' + ) { const newMenu = { ...getGeneratedMenu(), dynamicMenuData }; const arePrvMenuEqual = _.isEqual(newMenu, generatedMenuRef.current); if (!arePrvMenuEqual) { diff --git a/src/common/hooks/mapMenus/useHandleWfsGetFeatureRequests.ts b/src/common/hooks/mapMenus/useHandleWfsGetFeatureRequests.ts index bad801924..91bcdde60 100644 --- a/src/common/hooks/mapMenus/useHandleWfsGetFeatureRequests.ts +++ b/src/common/hooks/mapMenus/useHandleWfsGetFeatureRequests.ts @@ -7,7 +7,9 @@ import { } from '../../../discrete-layer/models'; import { WfsGetFeatureParams } from '../../../discrete-layer/models/RootStore.base'; -type HandlerGetFeatureOptions = WfsGetFeatureParams & { onDataResolved?: (data?: GetFeatureModelType) => void }; +type HandlerGetFeatureOptions = WfsGetFeatureParams & { + onDataResolved?: (data?: GetFeatureModelType) => void; +}; const useHandleWfsGetFeatureRequests = (): { data: { getFeature: GetFeatureModelType } | undefined; @@ -16,7 +18,8 @@ const useHandleWfsGetFeatureRequests = (): { setGetFeatureOptions: (options: HandlerGetFeatureOptions) => void; } => { const store = useStore(); - const [getFeatureOptions, setGetFeatureOptions] = useState(); + const [getFeatureOptions, setGetFeatureOptions] = + useState(); const { data, loading, setQuery } = useQuery<{ getFeature: GetFeatureModelType; @@ -24,11 +27,14 @@ const useHandleWfsGetFeatureRequests = (): { useEffect(() => { if (getFeatureOptions) { - - const featureConfig = store.mapMenusManagerStore.getFeatureConfig(getFeatureOptions.typeName); + const featureConfig = store.mapMenusManagerStore.getFeatureConfig( + getFeatureOptions.typeName + ); const dWithin = featureConfig.dWithin; - - setQuery(store.queryGetFeature({ data: { ...getFeatureOptions, dWithin } })); + + setQuery( + store.queryGetFeature({ data: { ...getFeatureOptions, dWithin } }) + ); } }, [getFeatureOptions]); @@ -43,7 +49,7 @@ const useHandleWfsGetFeatureRequests = (): { store.mapMenusManagerStore.setCurrentWfsFeatureInfo(featureInfo); getFeatureOptions.onDataResolved?.(featureInfo); - } + } //TODO: Handle Errors, how should we deal with them? }, [data, loading]); diff --git a/src/common/hooks/mapMenus/useHandleWfsPolygonPartsRequests.ts b/src/common/hooks/mapMenus/useHandleWfsPolygonPartsRequests.ts index 5afa39f4e..7fcea1864 100644 --- a/src/common/hooks/mapMenus/useHandleWfsPolygonPartsRequests.ts +++ b/src/common/hooks/mapMenus/useHandleWfsPolygonPartsRequests.ts @@ -8,23 +8,34 @@ import { } from '../../../discrete-layer/models'; import { WfsPolygonPartsGetFeatureParams } from '../../../discrete-layer/models/RootStore.base'; -type HandlerGetFeatureOptions = WfsPolygonPartsGetFeatureParams & { onDataResolved?: (data?: GetFeatureModelType) => void, shouldFlyToFeatures?: boolean }; +type HandlerGetFeatureOptions = WfsPolygonPartsGetFeatureParams & { + onDataResolved?: (data?: GetFeatureModelType) => void; + shouldFlyToFeatures?: boolean; +}; const useHandleWfsPolygonPartsRequests = (): { - data: { getPolygonPartsFeature: GetFeatureModelType} | undefined; + data: { getPolygonPartsFeature: GetFeatureModelType } | undefined; loading: boolean; getPolygonPartsFeatureOptions: WfsPolygonPartsGetFeatureParams | undefined; setGetPolygonPartsFeatureOptions: (options: HandlerGetFeatureOptions) => void; } => { const store = useStore(); - const [getPolygonPartsFeatureOptions, setGetPolygonPartsFeatureOptions] = useState(); + const [getPolygonPartsFeatureOptions, setGetPolygonPartsFeatureOptions] = + useState(); - const { data, loading, setQuery } = useQuery<{ getPolygonPartsFeature: GetFeatureModelType}>(); + const { data, loading, setQuery } = useQuery<{ + getPolygonPartsFeature: GetFeatureModelType; + }>(); useEffect(() => { if (getPolygonPartsFeatureOptions) { - const {onDataResolved, shouldFlyToFeatures, ...restPPOptions} = getPolygonPartsFeatureOptions; - setQuery(store.queryGetPolygonPartsFeature({ data: { ...restPPOptions, count: 100 } })); + const { onDataResolved, shouldFlyToFeatures, ...restPPOptions } = + getPolygonPartsFeatureOptions; + setQuery( + store.queryGetPolygonPartsFeature({ + data: { ...restPPOptions, count: 100 }, + }) + ); } }, [getPolygonPartsFeatureOptions]); @@ -38,26 +49,41 @@ const useHandleWfsPolygonPartsRequests = (): { store.mapMenusManagerStore.setCurrentPolygonPartsInfo(featureInfo); getPolygonPartsFeatureOptions.onDataResolved?.(featureInfo); - } + } //TODO: Handle Errors, how should we deal with them? }, [data, loading]); useEffect(() => { // After data has been received, trigger side effect logics - if (store.mapMenusManagerStore.currentPolygonPartsInfo && getPolygonPartsFeatureOptions) { - const polygonPartsFeatures = store.mapMenusManagerStore.currentPolygonPartsInfo.features; + if ( + store.mapMenusManagerStore.currentPolygonPartsInfo && + getPolygonPartsFeatureOptions + ) { + const polygonPartsFeatures = + store.mapMenusManagerStore.currentPolygonPartsInfo.features; const { shouldFlyToFeatures } = getPolygonPartsFeatureOptions; - - if (polygonPartsFeatures && polygonPartsFeatures.length > 0 && shouldFlyToFeatures) { - const featuresBBox = bbox({ type: "FeatureCollection", features: polygonPartsFeatures }); + + if ( + polygonPartsFeatures && + polygonPartsFeatures.length > 0 && + shouldFlyToFeatures + ) { + const featuresBBox = bbox({ + type: 'FeatureCollection', + features: polygonPartsFeatures, + }); store.mapMenusManagerStore.setMultiplePolygonPartsBBox(featuresBBox); } } - }, [store.mapMenusManagerStore.currentPolygonPartsInfo]); - return { data, loading, getPolygonPartsFeatureOptions, setGetPolygonPartsFeatureOptions }; + return { + data, + loading, + getPolygonPartsFeatureOptions, + setGetPolygonPartsFeatureOptions, + }; }; export default useHandleWfsPolygonPartsRequests; diff --git a/src/common/hooks/useClickOutside.ts b/src/common/hooks/useClickOutside.ts index d2e8d3948..39cb55b70 100644 --- a/src/common/hooks/useClickOutside.ts +++ b/src/common/hooks/useClickOutside.ts @@ -14,12 +14,18 @@ function isDescendant(parent: Node, child: Node) { highestParentAvailableTag = node?.nodeName ?? ''; node = node.parentNode; } - - if (node === null && highestParentAvailableTag !== '#document') { return true; } + + if (node === null && highestParentAvailableTag !== '#document') { + return true; + } return false; } -export const useClickOutside = (ref: React.RefObject, onClickOutside: (e: MouseEvent) => void, shouldHandle = true) => { +export const useClickOutside = ( + ref: React.RefObject, + onClickOutside: (e: MouseEvent) => void, + shouldHandle = true +) => { const clickHandler = useCallback((e: MouseEvent) => { if (ref.current) { if (!isDescendant(ref.current, e.target as Node)) { @@ -31,7 +37,7 @@ export const useClickOutside = (ref: React.RefObject, useEffect(() => { return () => { document.removeEventListener('click', clickHandler); - } + }; }, []); useEffect(() => { @@ -42,6 +48,5 @@ export const useClickOutside = (ref: React.RefObject, document.addEventListener('click', clickHandler); }, LISTENER_DELAY); } - }, [shouldHandle]); -} \ No newline at end of file +}; diff --git a/src/common/hooks/useDateNow.hook.ts b/src/common/hooks/useDateNow.hook.ts index 81b18d30b..385b57d29 100644 --- a/src/common/hooks/useDateNow.hook.ts +++ b/src/common/hooks/useDateNow.hook.ts @@ -3,17 +3,17 @@ import { useEffect, useRef } from 'react'; const SECOND = 1000; const useDateNow = () => { - const dateNowRef = useRef(new Date()); - - useEffect(() => { - const interval = setInterval(() => { - dateNowRef.current = new Date(); - }, SECOND); - - return () => clearInterval(interval); - }, []); - - return dateNowRef; - }; + const dateNowRef = useRef(new Date()); -export default useDateNow; \ No newline at end of file + useEffect(() => { + const interval = setInterval(() => { + dateNowRef.current = new Date(); + }, SECOND); + + return () => clearInterval(interval); + }, []); + + return dateNowRef; +}; + +export default useDateNow; diff --git a/src/common/hooks/useElementDimensions.hook.ts b/src/common/hooks/useElementDimensions.hook.ts index e674b7bcf..1d84d49e3 100644 --- a/src/common/hooks/useElementDimensions.hook.ts +++ b/src/common/hooks/useElementDimensions.hook.ts @@ -5,7 +5,9 @@ export interface IDimensions { height: number; } -export const useElementDimensions = (element: React.MutableRefObject): IDimensions | undefined => { +export const useElementDimensions = ( + element: React.MutableRefObject +): IDimensions | undefined => { const [dimensions, setDimensions] = useState(); useLayoutEffect(() => { @@ -16,4 +18,4 @@ export const useElementDimensions = (element: React.MutableRefObject { - const { enumsMap } = useContext(EnumsMapContext); - const enums = enumsMap as IEnumsMapType; - return enums; -} \ No newline at end of file + const { enumsMap } = useContext(EnumsMapContext); + const enums = enumsMap as IEnumsMapType; + return enums; +}; diff --git a/src/common/hooks/useForceEntitySelection.hook.ts b/src/common/hooks/useForceEntitySelection.hook.ts index dbdc5e7ed..9e1d85b45 100644 --- a/src/common/hooks/useForceEntitySelection.hook.ts +++ b/src/common/hooks/useForceEntitySelection.hook.ts @@ -1,6 +1,8 @@ import React, { useEffect, useState } from 'react'; -export const useForceEntitySelection = (dependencies: React.DependencyList): { entitySelected: boolean } => { +export const useForceEntitySelection = ( + dependencies: React.DependencyList +): { entitySelected: boolean } => { const RESELECTION_TIMEOUT = 0; const [entitySelected, setEntitySelected] = useState(true); @@ -13,4 +15,4 @@ export const useForceEntitySelection = (dependencies: React.DependencyList): { e }, dependencies); return { entitySelected }; -} \ No newline at end of file +}; diff --git a/src/common/hooks/useHeightFromTerrain.ts b/src/common/hooks/useHeightFromTerrain.ts index 31bf5779e..fc4a5f1d8 100644 --- a/src/common/hooks/useHeightFromTerrain.ts +++ b/src/common/hooks/useHeightFromTerrain.ts @@ -1,6 +1,10 @@ import { useEffect, useRef, useState } from 'react'; import { isEmpty } from 'lodash'; -import { CesiumCartographic, cesiumSampleTerrainMostDetailed, useCesiumMap } from '@map-colonies/react-components'; +import { + CesiumCartographic, + cesiumSampleTerrainMostDetailed, + useCesiumMap, +} from '@map-colonies/react-components'; import { is2dArray, isArrayEqual } from '../helpers/array'; export interface IPosition { @@ -14,19 +18,27 @@ interface UseHeightFromTerrainProps { interface IHeightFromTerrain { newPositions?: CesiumCartographic[] | CesiumCartographic[][]; - setCoordinates: (pos: IPosition[] | IPosition[][]) => void; + setCoordinates: (pos: IPosition[] | IPosition[][]) => void; isLoadingData: boolean; } -export const useHeightFromTerrain = (options?: UseHeightFromTerrainProps): IHeightFromTerrain => { +export const useHeightFromTerrain = ( + options?: UseHeightFromTerrainProps +): IHeightFromTerrain => { const mapViewer = useCesiumMap(); - const [newPositions, setNewPositions] = useState(); - const [coordinates, setCoordinates] = useState(); + const [newPositions, setNewPositions] = useState< + CesiumCartographic[] | CesiumCartographic[][] + >(); + const [coordinates, setCoordinates] = useState(); const [isLoadingData, setIsLoadingData] = useState(true); const prevPositions = useRef(); useEffect(() => { - if (options && (!prevPositions.current || !isArrayEqual(prevPositions.current, options.position))) { + if ( + options && + (!prevPositions.current || + !isArrayEqual(prevPositions.current, options.position)) + ) { prevPositions.current = options.position; setCoordinates(options.position); } @@ -36,24 +48,34 @@ export const useHeightFromTerrain = (options?: UseHeightFromTerrainProps): IHeig if (coordinates) { // @ts-ignore const is2dArr = is2dArray(coordinates); - const cartographicArr: CesiumCartographic[] | CesiumCartographic[][] | undefined = (is2dArr) ? - coordinates.map((ring: any) => ring.map((coord: any) => CesiumCartographic.fromDegrees(coord.longitude, coord.latitude))) - : - coordinates.map((coord: any) => CesiumCartographic.fromDegrees(coord.longitude, coord.latitude)); - + const cartographicArr: + | CesiumCartographic[] + | CesiumCartographic[][] + | undefined = is2dArr + ? coordinates.map((ring: any) => + ring.map((coord: any) => + CesiumCartographic.fromDegrees(coord.longitude, coord.latitude) + ) + ) + : coordinates.map((coord: any) => + CesiumCartographic.fromDegrees(coord.longitude, coord.latitude) + ); + setIsLoadingData(true); // const promises: Promise[] = []; - + if (is2dArr) { const promises: Promise[] = []; - - cartographicArr.forEach((ring: any): void => { + + cartographicArr.forEach((ring: any): void => { // @ts-ignore - promises.push(cesiumSampleTerrainMostDetailed( - mapViewer.terrainProvider, - ring as CesiumCartographic[] - )); + promises.push( + cesiumSampleTerrainMostDetailed( + mapViewer.terrainProvider, + ring as CesiumCartographic[] + ) + ); }); Promise.all(promises) @@ -70,9 +92,10 @@ export const useHeightFromTerrain = (options?: UseHeightFromTerrainProps): IHeig }); } else { void cesiumSampleTerrainMostDetailed( - mapViewer.terrainProvider, - cartographicArr as CesiumCartographic[] - ).then( + mapViewer.terrainProvider, + cartographicArr as CesiumCartographic[] + ) + .then( (updatedPositions) => { if (!isEmpty(updatedPositions)) { setNewPositions([...updatedPositions] as CesiumCartographic[]); @@ -81,7 +104,8 @@ export const useHeightFromTerrain = (options?: UseHeightFromTerrainProps): IHeig () => { setNewPositions(cartographicArr); } - ).finally(() => { + ) + .finally(() => { setIsLoadingData(false); }); } diff --git a/src/common/hooks/useSessionStoreWatcherDirectory.ts b/src/common/hooks/useSessionStoreWatcherDirectory.ts index b53da280b..1dffc04d9 100644 --- a/src/common/hooks/useSessionStoreWatcherDirectory.ts +++ b/src/common/hooks/useSessionStoreWatcherDirectory.ts @@ -1,6 +1,9 @@ import { useEffect, useState } from 'react'; import { useIntl } from 'react-intl'; -import { getValidationMessage, ValidationMessage } from '../../discrete-layer/components/layer-details/utils'; +import { + getValidationMessage, + ValidationMessage, +} from '../../discrete-layer/components/layer-details/utils'; import { SYNC_QUERY_NAME } from '../../syncHttpClientGql'; import { sessionStore } from '../helpers/storage'; @@ -29,7 +32,11 @@ const useSessionStoreWatcherDirectory = () => { } }; - sessionStore.watchMethods(['setItem', 'removeItem'], () => {}, callbackAfter); + sessionStore.watchMethods( + ['setItem', 'removeItem'], + () => {}, + callbackAfter + ); return () => { sessionStore.unWatchMethods(); @@ -39,4 +46,4 @@ const useSessionStoreWatcherDirectory = () => { return validationWarn; }; -export default useSessionStoreWatcherDirectory; \ No newline at end of file +export default useSessionStoreWatcherDirectory; diff --git a/src/common/hooks/useSessionStoreWatcherForm.ts b/src/common/hooks/useSessionStoreWatcherForm.ts index 128d16d9b..eb073ae1d 100644 --- a/src/common/hooks/useSessionStoreWatcherForm.ts +++ b/src/common/hooks/useSessionStoreWatcherForm.ts @@ -1,6 +1,9 @@ import { useEffect, useState } from 'react'; import { useIntl } from 'react-intl'; -import { getValidationMessage, ValidationMessage } from '../../discrete-layer/components/layer-details/utils'; +import { + getValidationMessage, + ValidationMessage, +} from '../../discrete-layer/components/layer-details/utils'; import { SYNC_QUERY_NAME } from '../../syncHttpClientGql'; import { sessionStore } from '../helpers/storage'; @@ -30,8 +33,14 @@ const useSessionStoreWatcherForm = () => { case key.includes(SYNC_QUERY_NAME.VALIDATE_SOURCE): { switch (method) { case 'setItem': { - const data = sessionStore.getObject(SYNC_QUERY_NAME.VALIDATE_SOURCE); - if (data && !data.isValid && !sessionStore.getObject(SYNC_QUERY_NAME.GET_PRODUCT)) { + const data = sessionStore.getObject( + SYNC_QUERY_NAME.VALIDATE_SOURCE + ); + if ( + data && + !data.isValid && + !sessionStore.getObject(SYNC_QUERY_NAME.GET_PRODUCT) + ) { setValidationWarn(getValidationMessage(data, intl)); } break; @@ -48,7 +57,11 @@ const useSessionStoreWatcherForm = () => { } }; - sessionStore.watchMethods(['setItem', 'removeItem'], () => {}, callbackAfter); + sessionStore.watchMethods( + ['setItem', 'removeItem'], + () => {}, + callbackAfter + ); return () => { sessionStore.unWatchMethods(); diff --git a/src/common/hooks/useStaticHtml.ts b/src/common/hooks/useStaticHtml.ts index 35d9798a6..19f8b1a4f 100644 --- a/src/common/hooks/useStaticHtml.ts +++ b/src/common/hooks/useStaticHtml.ts @@ -8,16 +8,21 @@ interface UseStaticHTMLProps { props: T; } -function useStaticHTML({ FunctionalComp, props }: UseStaticHTMLProps): string { +function useStaticHTML({ + FunctionalComp, + props, +}: UseStaticHTMLProps): string { const [html, setHTML] = useState(''); useEffect(() => { // @ts-ignore - const htmlString = renderToStaticMarkup(React.createElement(FunctionalComp, {...props})); + const htmlString = renderToStaticMarkup( + React.createElement(FunctionalComp, { ...props }) + ); setHTML(htmlString); }, [FunctionalComp, props]); return html; } -export default useStaticHTML; \ No newline at end of file +export default useStaticHTML; diff --git a/src/common/hooks/useWfsPolygonPartsRequests.ts b/src/common/hooks/useWfsPolygonPartsRequests.ts index 36d95fcd4..923f96ccd 100644 --- a/src/common/hooks/useWfsPolygonPartsRequests.ts +++ b/src/common/hooks/useWfsPolygonPartsRequests.ts @@ -18,17 +18,22 @@ const useWfsPolygonPartsRequests = (): { setQueryPolygonPartsFeatureOptions: (options: GetFeatureOptions) => void; } => { const store = useStore(); - const [queryPolygonPartsFeatureOptions, setQueryPolygonPartsFeatureOptions] = useState(); + const [queryPolygonPartsFeatureOptions, setQueryPolygonPartsFeatureOptions] = + useState(); - const { data, loading, setQuery } = useQuery<{ getPolygonPartsFeature: GetFeatureModelType }>(); + const { data, loading, setQuery } = useQuery<{ + getPolygonPartsFeature: GetFeatureModelType; + }>(); useEffect(() => { if (queryPolygonPartsFeatureOptions) { - setQuery(store.queryGetPolygonPartsFeature({ - data: { - ...queryPolygonPartsFeatureOptions - } - })); + setQuery( + store.queryGetPolygonPartsFeature({ + data: { + ...queryPolygonPartsFeatureOptions, + }, + }) + ); } }, [queryPolygonPartsFeatureOptions]); @@ -39,22 +44,31 @@ const useWfsPolygonPartsRequests = (): { feature: queryPolygonPartsFeatureOptions.feature, }; if (queryPolygonPartsFeatureOptions.startIndex === 0) { - store.discreteLayersStore.setPolygonPartsInfo(featureInfo.features as Feature[]); + store.discreteLayersStore.setPolygonPartsInfo( + featureInfo.features as Feature[] + ); } else { - store.discreteLayersStore.addPolygonPartsInfo(featureInfo.features as Feature[]); + store.discreteLayersStore.addPolygonPartsInfo( + featureInfo.features as Feature[] + ); } if (data.getPolygonPartsFeature.numberReturned !== 0) { const startIndex = queryPolygonPartsFeatureOptions.startIndex as number; const nextPage = startIndex / CONFIG.POLYGON_PARTS.MAX.WFS_FEATURES + 1; setQueryPolygonPartsFeatureOptions({ ...queryPolygonPartsFeatureOptions, - startIndex: nextPage * CONFIG.POLYGON_PARTS.MAX.WFS_FEATURES + startIndex: nextPage * CONFIG.POLYGON_PARTS.MAX.WFS_FEATURES, }); } - } + } }, [data, loading]); - return { data, loading, queryPolygonPartsFeatureOptions, setQueryPolygonPartsFeatureOptions }; + return { + data, + loading, + queryPolygonPartsFeatureOptions, + setQueryPolygonPartsFeatureOptions, + }; }; -export default useWfsPolygonPartsRequests; \ No newline at end of file +export default useWfsPolygonPartsRequests; diff --git a/src/common/hooks/useZoomLevels.ts b/src/common/hooks/useZoomLevels.ts index f153828d7..85e1c5a23 100644 --- a/src/common/hooks/useZoomLevels.ts +++ b/src/common/hooks/useZoomLevels.ts @@ -1,19 +1,27 @@ import { get } from 'lodash'; import { useContext } from 'react'; -import lookupTablesContext, { ILookupOption } from '../contexts/lookupTables.context'; +import lookupTablesContext, { + ILookupOption, +} from '../contexts/lookupTables.context'; export interface IZoomLevelData { - resolutionDeg:number; - resolutionMeter:number + resolutionDeg: number; + resolutionMeter: number; } -export const useZoomLevels = (): Record => { - const zoomlevelresolutions = {} as Record; +export const useZoomLevels = (): Record => { + const zoomlevelresolutions = {} as Record; const { lookupTablesData } = useContext(lookupTablesContext); - const lookupOptions = get(lookupTablesData?.dictionary, 'zoomlevelresolutions') as ILookupOption[] ?? []; + const lookupOptions = + (get( + lookupTablesData?.dictionary, + 'zoomlevelresolutions' + ) as ILookupOption[]) ?? []; lookupOptions?.forEach((option) => { - zoomlevelresolutions[option.value] = {...option.properties} as unknown as IZoomLevelData; + zoomlevelresolutions[option.value] = { + ...option.properties, + } as unknown as IZoomLevelData; }); - + return zoomlevelresolutions; -} +}; diff --git a/src/common/i18n/en.json b/src/common/i18n/en.json index 093962271..925ae19b5 100644 --- a/src/common/i18n/en.json +++ b/src/common/i18n/en.json @@ -267,7 +267,7 @@ "ingestion.job.validationTaskProgress": "Validation progress", "ingestion.job.report": "Validation results", "ingestion.job.report-in-progress": "Report in progress", - + "validationReport.geometryValidity": "Invalid geometry", "validationReport.vertices": "Polygons with too many vertices", "validationReport.metadata": "Invalid metadata", @@ -770,7 +770,7 @@ "Units.dms": "DMS", "Units.arc_seconds": "ARC_SECONDS", "Units.unknown": "UNKNOWN", - + "UndulationModel.msl_egm96": "MSL_EGM96", "UndulationModel.msl_egm2008": "MSL_EGM2008", "UndulationModel.msl_dma10": "MSL_DMA10", @@ -812,7 +812,7 @@ "lookupTable.hotAreas.sderot": "Sderot", "lookupTable.hotAreas.syria": "Syria", "lookupTable.hotAreas.telAviv": "Tel Aviv", - + "Transparency.transparent": "Transparent", "Transparency.opaque": "Opaque", @@ -839,10 +839,10 @@ "export-layer.exportSuccessContainer.jobId.title": "Job ID", "export-layer.export.button": "Export Layer", "export-layer.preview.button": "Evaluate Export", - "export-layer.selection-index.text":"Selection", - "export-layer.generalFields.text":"General Fields", - "export-layer.fileError.text":"Imported File", - "export-layer.serviceError.text":"Service Error", + "export-layer.selection-index.text": "Selection", + "export-layer.generalFields.text": "General Fields", + "export-layer.fileError.text": "Imported File", + "export-layer.serviceError.text": "Service Error", "export-layer.generalError.text": "General Error", "export-layer.description.field": "Description", "export-layer.zoomLevel.field": "Zoom Level", diff --git a/src/common/i18n/grid.en.ts b/src/common/i18n/grid.en.ts index 173e3a628..8aa253ac4 100644 --- a/src/common/i18n/grid.en.ts +++ b/src/common/i18n/grid.en.ts @@ -2,268 +2,268 @@ const AG_GRID_LOCALE_EN = { // Set Filter - "selectAll": '(Select All)', - "selectAllSearchResults": '(Select All Search Results)', - "searchOoo": 'Search...', - "blanks": '(Blanks)', - "noMatches": 'No matches', + selectAll: '(Select All)', + selectAllSearchResults: '(Select All Search Results)', + searchOoo: 'Search...', + blanks: '(Blanks)', + noMatches: 'No matches', // Number Filter & Text Filter - "filterOoo": 'Filter...', - "equals": 'Equals', - "notEqual": 'Not equal', - "empty": 'Choose One', + filterOoo: 'Filter...', + equals: 'Equals', + notEqual: 'Not equal', + empty: 'Choose One', // Number Filter - "lessThan": 'Less than', - "greaterThan": 'Greater than', - "lessThanOrEqual": 'Less than or equal', - "greaterThanOrEqual": 'Greater than or equal', - "inRange": 'In range', - "inRangeStart": 'to', - "inRangeEnd": 'from', + lessThan: 'Less than', + greaterThan: 'Greater than', + lessThanOrEqual: 'Less than or equal', + greaterThanOrEqual: 'Greater than or equal', + inRange: 'In range', + inRangeStart: 'to', + inRangeEnd: 'from', // Text Filter - "contains": 'Contains', - "notContains": 'Not contains', - "startsWith": 'Starts with', - "endsWith": 'Ends with', + contains: 'Contains', + notContains: 'Not contains', + startsWith: 'Starts with', + endsWith: 'Ends with', // Date Filter - "dateFormatOoo": 'yyyy-mm-dd', + dateFormatOoo: 'yyyy-mm-dd', // Filter Conditions - "andCondition": 'AND', - "orCondition": 'OR', + andCondition: 'AND', + orCondition: 'OR', // Filter Buttons - "applyFilter": 'Apply', - "resetFilter": 'Reset', - "clearFilter": 'Clear', - "cancelFilter": 'Cancel', + applyFilter: 'Apply', + resetFilter: 'Reset', + clearFilter: 'Clear', + cancelFilter: 'Cancel', // Filter Titles - "textFilter": 'Text Filter', - "numberFilter": 'Number Filter', - "dateFilter": 'Date Filter', - "setFilter": 'Set Filter', + textFilter: 'Text Filter', + numberFilter: 'Number Filter', + dateFilter: 'Date Filter', + setFilter: 'Set Filter', // Side Bar - "columns": 'Columns', - "filters": 'Filters', + columns: 'Columns', + filters: 'Filters', // columns tool panel - "pivotMode": 'Pivot Mode', - "groups": 'Row Groups', - "rowGroupColumnsEmptyMessage": 'Drag here to set row groups', - "values": 'Values', - "valueColumnsEmptyMessage": 'Drag here to aggregate', - "pivots": 'Column Labels', - "pivotColumnsEmptyMessage": 'Drag here to set column labels', + pivotMode: 'Pivot Mode', + groups: 'Row Groups', + rowGroupColumnsEmptyMessage: 'Drag here to set row groups', + values: 'Values', + valueColumnsEmptyMessage: 'Drag here to aggregate', + pivots: 'Column Labels', + pivotColumnsEmptyMessage: 'Drag here to set column labels', // Header of the Default Group Column - "group": 'Group', + group: 'Group', // Other - "loadingOoo": 'Loading...', - "noRowsToShow": 'No Rows To Show', - "enabled": 'Enabled', + loadingOoo: 'Loading...', + noRowsToShow: 'No Rows To Show', + enabled: 'Enabled', // Menu - "pinColumn": 'Pin Column', - "pinLeft": 'Pin Left', - "pinRight": 'Pin Right', - "noPin": 'No Pin', - "valueAggregation": 'Value Aggregation', - "autosizeThiscolumn": 'Autosize This Column', - "autosizeAllColumns": 'Autosize All Columns', - "groupBy": 'Group by', - "ungroupBy": 'Un-Group by', - "resetColumns": 'Reset Columns', - "expandAll": 'Expand All', - "collapseAll": 'Close All', - "copy": 'Copy', - "ctrlC": 'Ctrl+C', - "copyWithHeaders": 'Copy With Headers', - "paste": 'Paste', - "ctrlV": 'Ctrl+V', - "export": 'Export', - "csvExport": 'CSV Export', - "excelExport": 'Excel Export', + pinColumn: 'Pin Column', + pinLeft: 'Pin Left', + pinRight: 'Pin Right', + noPin: 'No Pin', + valueAggregation: 'Value Aggregation', + autosizeThiscolumn: 'Autosize This Column', + autosizeAllColumns: 'Autosize All Columns', + groupBy: 'Group by', + ungroupBy: 'Un-Group by', + resetColumns: 'Reset Columns', + expandAll: 'Expand All', + collapseAll: 'Close All', + copy: 'Copy', + ctrlC: 'Ctrl+C', + copyWithHeaders: 'Copy With Headers', + paste: 'Paste', + ctrlV: 'Ctrl+V', + export: 'Export', + csvExport: 'CSV Export', + excelExport: 'Excel Export', // Enterprise Menu Aggregation and Status Bar - "sum": 'Sum', - "min": 'Min', - "max": 'Max', - "none": 'None', - "count": 'Count', - "avg": 'Average', - "filteredRows": 'Filtered', - "selectedRows": 'Selected', - "totalRows": 'Total Rows', - "totalAndFilteredRows": 'Rows', - "more": 'More', - "to": 'to', - "of": 'of', - "page": 'Page', - "nextPage": 'Next Page', - "lastPage": 'Last Page', - "firstPage": 'First Page', - "previousPage": 'Previous Page', + sum: 'Sum', + min: 'Min', + max: 'Max', + none: 'None', + count: 'Count', + avg: 'Average', + filteredRows: 'Filtered', + selectedRows: 'Selected', + totalRows: 'Total Rows', + totalAndFilteredRows: 'Rows', + more: 'More', + to: 'to', + of: 'of', + page: 'Page', + nextPage: 'Next Page', + lastPage: 'Last Page', + firstPage: 'First Page', + previousPage: 'Previous Page', // Enterprise Menu (Charts) - "pivotChartAndPivotMode": 'Pivot Chart & Pivot Mode', - "pivotChart": 'Pivot Chart', - "chartRange": 'Chart Range', + pivotChartAndPivotMode: 'Pivot Chart & Pivot Mode', + pivotChart: 'Pivot Chart', + chartRange: 'Chart Range', - "columnChart": 'Column', - "groupedColumn": 'Grouped', - "stackedColumn": 'Stacked', - "normalizedColumn": '100% Stacked', + columnChart: 'Column', + groupedColumn: 'Grouped', + stackedColumn: 'Stacked', + normalizedColumn: '100% Stacked', - "barChart": 'Bar', - "groupedBar": 'Grouped', - "stackedBar": 'Stacked', - "normalizedBar": '100% Stacked', + barChart: 'Bar', + groupedBar: 'Grouped', + stackedBar: 'Stacked', + normalizedBar: '100% Stacked', - "pieChart": 'Pie', - "pie": 'Pie', - "doughnut": 'Doughnut', + pieChart: 'Pie', + pie: 'Pie', + doughnut: 'Doughnut', - "line": 'Line', + line: 'Line', - "xyChart": 'X Y (Scatter)', - "scatter": 'Scatter', - "bubble": 'Bubble', + xyChart: 'X Y (Scatter)', + scatter: 'Scatter', + bubble: 'Bubble', - "areaChart": 'Area', - "area": 'Area', - "stackedArea": 'Stacked', - "normalizedArea": '100% Stacked', + areaChart: 'Area', + area: 'Area', + stackedArea: 'Stacked', + normalizedArea: '100% Stacked', - "histogramChart": 'Histogram', + histogramChart: 'Histogram', // Charts - "pivotChartTitle": 'Pivot Chart', - "rangeChartTitle": 'Range Chart', - "settings": 'Settings', - "data": 'Data', - "format": 'Format', - "categories": 'Categories', - "defaultCategory": '(None)', - "series": 'Series', - "xyValues": 'X Y Values', - "paired": 'Paired Mode', - "axis": 'Axis', - "navigator": 'Navigator', - "color": 'Color', - "thickness": 'Thickness', - "xType": 'X Type', - "automatic": 'Automatic', - "category": 'Category', - "number": 'Number', - "time": 'Time', - "xRotation": 'X Rotation', - "yRotation": 'Y Rotation', - "ticks": 'Ticks', - "width": 'Width', - "height": 'Height', - "length": 'Length', - "padding": 'Padding', - "spacing": 'Spacing', - "chart": 'Chart', - "title": 'Title', - "titlePlaceholder": 'Chart title - double click to edit', - "background": 'Background', - "font": 'Font', - "top": 'Top', - "right": 'Right', - "bottom": 'Bottom', - "left": 'Left', - "labels": 'Labels', - "size": 'Size', - "minSize": 'Minimum Size', - "maxSize": 'Maximum Size', - "legend": 'Legend', - "position": 'Position', - "markerSize": 'Marker Size', - "markerStroke": 'Marker Stroke', - "markerPadding": 'Marker Padding', - "itemSpacing": 'Item Spacing', - "itemPaddingX": 'Item Padding X', - "itemPaddingY": 'Item Padding Y', - "layoutHorizontalSpacing": 'Horizontal Spacing', - "layoutVerticalSpacing": 'Vertical Spacing', - "strokeWidth": 'Stroke Width', - "offset": 'Offset', - "offsets": 'Offsets', - "tooltips": 'Tooltips', - "callout": 'Callout', - "markers": 'Markers', - "shadow": 'Shadow', - "blur": 'Blur', - "xOffset": 'X Offset', - "yOffset": 'Y Offset', - "lineWidth": 'Line Width', - "normal": 'Normal', - "bold": 'Bold', - "italic": 'Italic', - "boldItalic": 'Bold Italic', - "predefined": 'Predefined', - "fillOpacity": 'Fill Opacity', - "strokeOpacity": 'Line Opacity', - "histogramBinCount": 'Bin count', - "columnGroup": 'Column', - "barGroup": 'Bar', - "pieGroup": 'Pie', - "lineGroup": 'Line', - "scatterGroup": 'X Y (Scatter)', - "areaGroup": 'Area', - "histogramGroup": 'Histogram', - "groupedColumnTooltip": 'Grouped', - "stackedColumnTooltip": 'Stacked', - "normalizedColumnTooltip": '100% Stacked', - "groupedBarTooltip": 'Grouped', - "stackedBarTooltip": 'Stacked', - "normalizedBarTooltip": '100% Stacked', - "pieTooltip": 'Pie', - "doughnutTooltip": 'Doughnut', - "lineTooltip": 'Line', - "groupedAreaTooltip": 'Area', - "stackedAreaTooltip": 'Stacked', - "normalizedAreaTooltip": '100% Stacked', - "scatterTooltip": 'Scatter', - "bubbleTooltip": 'Bubble', - "histogramTooltip": 'Histogram', - "noDataToChart": 'No data available to be charted.', - "pivotChartRequiresPivotMode": 'Pivot Chart requires Pivot Mode enabled.', - "chartSettingsToolbarTooltip": 'Menu', - "chartLinkToolbarTooltip": 'Linked to Grid', - "chartUnlinkToolbarTooltip": 'Unlinked from Grid', - "chartDownloadToolbarTooltip": 'Download Chart', + pivotChartTitle: 'Pivot Chart', + rangeChartTitle: 'Range Chart', + settings: 'Settings', + data: 'Data', + format: 'Format', + categories: 'Categories', + defaultCategory: '(None)', + series: 'Series', + xyValues: 'X Y Values', + paired: 'Paired Mode', + axis: 'Axis', + navigator: 'Navigator', + color: 'Color', + thickness: 'Thickness', + xType: 'X Type', + automatic: 'Automatic', + category: 'Category', + number: 'Number', + time: 'Time', + xRotation: 'X Rotation', + yRotation: 'Y Rotation', + ticks: 'Ticks', + width: 'Width', + height: 'Height', + length: 'Length', + padding: 'Padding', + spacing: 'Spacing', + chart: 'Chart', + title: 'Title', + titlePlaceholder: 'Chart title - double click to edit', + background: 'Background', + font: 'Font', + top: 'Top', + right: 'Right', + bottom: 'Bottom', + left: 'Left', + labels: 'Labels', + size: 'Size', + minSize: 'Minimum Size', + maxSize: 'Maximum Size', + legend: 'Legend', + position: 'Position', + markerSize: 'Marker Size', + markerStroke: 'Marker Stroke', + markerPadding: 'Marker Padding', + itemSpacing: 'Item Spacing', + itemPaddingX: 'Item Padding X', + itemPaddingY: 'Item Padding Y', + layoutHorizontalSpacing: 'Horizontal Spacing', + layoutVerticalSpacing: 'Vertical Spacing', + strokeWidth: 'Stroke Width', + offset: 'Offset', + offsets: 'Offsets', + tooltips: 'Tooltips', + callout: 'Callout', + markers: 'Markers', + shadow: 'Shadow', + blur: 'Blur', + xOffset: 'X Offset', + yOffset: 'Y Offset', + lineWidth: 'Line Width', + normal: 'Normal', + bold: 'Bold', + italic: 'Italic', + boldItalic: 'Bold Italic', + predefined: 'Predefined', + fillOpacity: 'Fill Opacity', + strokeOpacity: 'Line Opacity', + histogramBinCount: 'Bin count', + columnGroup: 'Column', + barGroup: 'Bar', + pieGroup: 'Pie', + lineGroup: 'Line', + scatterGroup: 'X Y (Scatter)', + areaGroup: 'Area', + histogramGroup: 'Histogram', + groupedColumnTooltip: 'Grouped', + stackedColumnTooltip: 'Stacked', + normalizedColumnTooltip: '100% Stacked', + groupedBarTooltip: 'Grouped', + stackedBarTooltip: 'Stacked', + normalizedBarTooltip: '100% Stacked', + pieTooltip: 'Pie', + doughnutTooltip: 'Doughnut', + lineTooltip: 'Line', + groupedAreaTooltip: 'Area', + stackedAreaTooltip: 'Stacked', + normalizedAreaTooltip: '100% Stacked', + scatterTooltip: 'Scatter', + bubbleTooltip: 'Bubble', + histogramTooltip: 'Histogram', + noDataToChart: 'No data available to be charted.', + pivotChartRequiresPivotMode: 'Pivot Chart requires Pivot Mode enabled.', + chartSettingsToolbarTooltip: 'Menu', + chartLinkToolbarTooltip: 'Linked to Grid', + chartUnlinkToolbarTooltip: 'Unlinked from Grid', + chartDownloadToolbarTooltip: 'Download Chart', // ARIA - "ariaHidden": 'hidden', - "ariaVisible": 'visible', - "ariaChecked": 'checked', - "ariaUnchecked": 'unchecked', - "ariaIndeterminate":'indeterminate', - "ariaColumnSelectAll": 'Toggle Select All Columns', - "ariaInputEditor": 'Input Editor', - "ariaDateFilterInput": 'Date Filter Input', - "ariaFilterInput": 'Filter Input', - "ariaFilterColumnsInput": 'Filter Columns Input', - "ariaFilterValue": 'Filter Value', - "ariaFilterFromValue": 'Filter from value', - "ariaFilterToValue": 'Filter to value', - "ariaFilteringOperator": 'Filtering Operator', - "ariaColumnToggleVisibility": 'column toggle visibility', - "ariaColumnGroupToggleVisibility": 'column group toggle visibility', - "ariaRowSelect": 'Press SPACE to select this row', - "ariaRowDeselect": 'Press SPACE to deselect this row', - "ariaRowToggleSelection": 'Press Space to toggle row selection', - "ariaRowSelectAll": 'Press Space to toggle all rows selection', - "ariaSearch": 'Search', - "ariaSearchFilterValues": 'Search filter values' -} -export default AG_GRID_LOCALE_EN; \ No newline at end of file + ariaHidden: 'hidden', + ariaVisible: 'visible', + ariaChecked: 'checked', + ariaUnchecked: 'unchecked', + ariaIndeterminate: 'indeterminate', + ariaColumnSelectAll: 'Toggle Select All Columns', + ariaInputEditor: 'Input Editor', + ariaDateFilterInput: 'Date Filter Input', + ariaFilterInput: 'Filter Input', + ariaFilterColumnsInput: 'Filter Columns Input', + ariaFilterValue: 'Filter Value', + ariaFilterFromValue: 'Filter from value', + ariaFilterToValue: 'Filter to value', + ariaFilteringOperator: 'Filtering Operator', + ariaColumnToggleVisibility: 'column toggle visibility', + ariaColumnGroupToggleVisibility: 'column group toggle visibility', + ariaRowSelect: 'Press SPACE to select this row', + ariaRowDeselect: 'Press SPACE to deselect this row', + ariaRowToggleSelection: 'Press Space to toggle row selection', + ariaRowSelectAll: 'Press Space to toggle all rows selection', + ariaSearch: 'Search', + ariaSearchFilterValues: 'Search filter values', +}; +export default AG_GRID_LOCALE_EN; diff --git a/src/common/i18n/grid.he.ts b/src/common/i18n/grid.he.ts index 1f2002539..f8a507412 100644 --- a/src/common/i18n/grid.he.ts +++ b/src/common/i18n/grid.he.ts @@ -2,23 +2,23 @@ const AG_GRID_LOCALE_HE = { // Enterprise Menu Aggregation and Status Bar - "sum": 'Sum', - "min": 'Min', - "max": 'Max', - "none": 'None', - "count": 'Count', - "avg": 'Average', - "filteredRows": 'סוננו', - "selectedRows": 'נבחרו', - "totalRows": "מס' כולל", - "totalAndFilteredRows": 'רשומות', - "more": 'עוד', - "to": 'עד', - "of": 'מ', - "page": 'דף', - "nextPage": 'דף הבא', - "lastPage": 'דף אחרון', - "firstPage": 'דף ראשון', - "previousPage": 'דף קודם', -} -export default AG_GRID_LOCALE_HE; \ No newline at end of file + sum: 'Sum', + min: 'Min', + max: 'Max', + none: 'None', + count: 'Count', + avg: 'Average', + filteredRows: 'סוננו', + selectedRows: 'נבחרו', + totalRows: "מס' כולל", + totalAndFilteredRows: 'רשומות', + more: 'עוד', + to: 'עד', + of: 'מ', + page: 'דף', + nextPage: 'דף הבא', + lastPage: 'דף אחרון', + firstPage: 'דף ראשון', + previousPage: 'דף קודם', +}; +export default AG_GRID_LOCALE_HE; diff --git a/src/common/i18n/he.json b/src/common/i18n/he.json index 61fbcade5..ca930b056 100644 --- a/src/common/i18n/he.json +++ b/src/common/i18n/he.json @@ -172,7 +172,7 @@ "publish-unpublish.dialog.publish.action": "פרסום", "publish-unpublish.dialog.unpublish.message": "הפעולה תוביל ל{action} המוצר ולהסתרתו
ועלולה להשפיע על מערכות הצורכות את המוצר", "publish-unpublish.dialog.unpublish.action": "ביטול פרסום", - + "delete.dialog.message": "הפעולה תוביל ל{action} המוצר וכל חומריו ועלולה להשפיע על מערכות הצורכות את המוצר", "delete.dialog.action": "מחיקת", "delete.dialog.checkbox": "אישור מחיקה", @@ -770,7 +770,7 @@ "Units.dms": "DMS", "Units.arc_seconds": "ARC_SECONDS", "Units.unknown": "UNKNOWN", - + "UndulationModel.msl_egm96": "MSL_EGM96", "UndulationModel.msl_egm2008": "MSL_EGM2008", "UndulationModel.msl_dma10": "MSL_DMA10", @@ -812,7 +812,7 @@ "lookupTable.hotAreas.sderot": "שדרות", "lookupTable.hotAreas.syria": "סוריה", "lookupTable.hotAreas.telAviv": "תל אביב", - + "Transparency.transparent": "Transparent", "Transparency.opaque": "Opaque", @@ -839,10 +839,10 @@ "export-layer.exportSuccessContainer.jobId.title": "מזהה משימה", "export-layer.export.button": "ייצא שכבה", "export-layer.preview.button": "שערך ייצוא", - "export-layer.selection-index.text":"בחירה", - "export-layer.generalFields.text":"שדות כלליים", - "export-layer.fileError.text":"בחירה מקובץ", - "export-layer.serviceError.text":"שגיאה מהשרת", + "export-layer.selection-index.text": "בחירה", + "export-layer.generalFields.text": "שדות כלליים", + "export-layer.fileError.text": "בחירה מקובץ", + "export-layer.serviceError.text": "שגיאה מהשרת", "export-layer.generalError.text": "שגיאה כללית", "export-layer.description.field": "תיאור", "export-layer.zoomLevel.field": "רמת זום", diff --git a/src/common/models/country.dictionary.ts b/src/common/models/country.dictionary.ts index 7885f0d5b..829c9650c 100644 --- a/src/common/models/country.dictionary.ts +++ b/src/common/models/country.dictionary.ts @@ -2,225 +2,741 @@ import { IDictionary } from './dictionary'; /* eslint-disable @typescript-eslint/naming-convention */ export const CountryDictionary: IDictionary = { - UGA: { en: "UGANDA", he: "אוגנדה", icon: "mc-icon-Close glow-missing-icon"}, - UZB: { en: "UZBEKISTAN", he: "אוזבקיסטן", icon: "mc-icon-Close glow-missing-icon"}, - AUT: { en: "AUSTRIA", he: "אוסטריה", icon: "mc-icon-Close glow-missing-icon"}, - AUS: { en: "AUSTRALIA", he: "אוסטרליה", icon: "mc-icon-Close glow-missing-icon"}, - UKR: { en: "UKRAINE", he: "אוקראינה", icon: "mc-icon-Close glow-missing-icon"}, - URY: { en: "URUGUAY", he: "אורגוואי", icon: "mc-icon-Close glow-missing-icon"}, - AZE: { en: "AZERBAIJAN", he: "אזרביג'אן", icon: "mc-icon-Close glow-missing-icon"}, - ARE: { en: "UNITED ARAB EMIR", he: "איחוד האמירויות הערבית", icon: "mc-icon-Close glow-missing-icon"}, - ITA: { en: "ITALY", he: "איטליה", icon: "mc-icon-Close glow-missing-icon"}, - VIR: { en: "VIRGIN ISLAND", he: "איי הבתולה", icon: "mc-icon-Close glow-missing-icon"}, - WLF: { en: "WALLIS FUTUNA ISL", he: "איי ווליס ופוטונה", icon: "mc-icon-Close glow-missing-icon"}, - TCA: { en: "TORKAS ISLAND", he: "איי טורקס וקייקוס", icon: "mc-icon-Close glow-missing-icon"}, - MHL: { en: "MARSHALL ISLANDS", he: "איי מרשל", icon: "mc-icon-Close glow-missing-icon"}, - NFK: { en: "NORFOLK ISLA", he: "איי נורפולק", icon: "mc-icon-Close glow-missing-icon"}, - SYC: { en: "SEYCHELLES", he: "איי סיישל", icon: "mc-icon-Close glow-missing-icon"}, - FLK: { en: "FALKLAND", he: "איי פוקלנד", icon: "mc-icon-Close glow-missing-icon"}, - FJI: { en: "FIJI", he: "איי פיגי", icon: "mc-icon-Close glow-missing-icon"}, - COM: { en: "COMOROS ISLANDS", he: "איי קומורו", icon: "mc-icon-Close glow-missing-icon"}, - COK: { en: "COOK ISL", he: "איי קוק", icon: "mc-icon-Close glow-missing-icon"}, - CYM: { en: "CAYMAN ISLANDS", he: "איי קיימן", icon: "mc-icon-Close glow-missing-icon"}, - CPV: { en: "CAPE VERDE ISLANDS", he: "איי קייפ וורדה", icon: "mc-icon-Close glow-missing-icon"}, - SLB: { en: "SOLOMON ISLANDS", he: "איי שלמה הבריטיים", icon: "mc-icon-Close glow-missing-icon"}, - IDN: { en: "INDONESIA", he: "אינדונזיה", icon: "mc-icon-Close glow-missing-icon"}, - ISL: { en: "ICELAND", he: "איסלנד", icon: "mc-icon-Close glow-missing-icon"}, - IRL: { en: "IRELAND", he: "אירלנד", icon: "mc-icon-Close glow-missing-icon"}, - IRN: { en: "IRAN", he: "אירן", icon: "mc-icon-Close glow-missing-icon"}, - SLV: { en: "EL SALVADOR", he: "אל סלבדור", icon: "mc-icon-Close glow-missing-icon"}, - ALB: { en: "ALBANIA", he: "אלבניה", icon: "mc-icon-Close glow-missing-icon"}, - DZA: { en: "ALGERIA", he: "אלג'יריה", icon: "mc-icon-Close glow-missing-icon"}, - AGO: { en: "ANGOLA", he: "אנגולה", icon: "mc-icon-Close glow-missing-icon"}, - AND: { en: "ANDORRA", he: "אנדורה", icon: "mc-icon-Close glow-missing-icon"}, - ATG: { en: "ANTIGUA AND BARBUDA", he: "אנטיגואה וברבודה", icon: "mc-icon-Close glow-missing-icon"}, - EST: { en: "ESTONIA", he: "אסטוניה", icon: "mc-icon-Close glow-missing-icon"}, - AFG: { en: "AFGHANISTAN", he: "אפגניסטן", icon: "mc-icon-Close glow-missing-icon"}, - ECU: { en: "ECUADOR", he: "אקוואדור", icon: "mc-icon-Close glow-missing-icon"}, - ARG: { en: "ARGENTINA", he: "ארגנטינה", icon: "mc-icon-Close glow-missing-icon"}, - ERI: { en: "ERITREA", he: "אריתראה", icon: "mc-icon-Close glow-missing-icon"}, - ARM: { en: "ARM ENIA", he: "ארמניה", icon: "mc-icon-Close glow-missing-icon"}, - USA: { en: "UNITED STATES", he: "ארצות הברית", icon: "mc-icon-Close glow-missing-icon"}, - ETH: { en: "ETHIOPIA", he: "אתיופיה", icon: "mc-icon-Close glow-missing-icon"}, - BHS: { en: "BAHAMAS", he: "בהמס", icon: "mc-icon-Close glow-missing-icon"}, - BTN: { en: "BHUTAN", he: "בוטן", icon: "mc-icon-Close glow-missing-icon"}, - BWA: { en: "BOTSWANA", he: "בוטסוואנה", icon: "mc-icon-Close glow-missing-icon"}, - BGR: { en: "BULGARIA", he: "בולגריה", icon: "mc-icon-Close glow-missing-icon"}, - BOL: { en: "BOLIVIA", he: "בוליביה", icon: "mc-icon-Close glow-missing-icon"}, - BIH: { en: "BOSNIA HERZEGOVINA", he: "בוסניה הרצגובינה", icon: "mc-icon-Close glow-missing-icon"}, - BDI: { en: "BURUNDI", he: "בורונדי", icon: "mc-icon-Close glow-missing-icon"}, - BFA: { en: "BURKINA FASSO", he: "בורקינה פאסו", icon: "mc-icon-Close glow-missing-icon"}, - BHR: { en: "BAHREIN", he: "בחריין", icon: "mc-icon-Close glow-missing-icon"}, - BLR: { en: "BELARUS", he: "בלורוסיה", icon: "mc-icon-Close glow-missing-icon"}, - BEL: { en: "BELGIUM", he: "בלגיה", icon: "mc-icon-Close glow-missing-icon"}, - BLZ: { en: "BELIZE", he: "בליז", icon: "mc-icon-Close glow-missing-icon"}, - BGD: { en: "BANGLADESH", he: "בנגלדש", icon: "mc-icon-Close glow-missing-icon"}, - BEN: { en: "BENIN DAHOMEY", he: "בנין דהומ", icon: "mc-icon-Close glow-missing-icon"}, - BRB: { en: "BARBADOS", he: "ברבדוס", icon: "mc-icon-Close glow-missing-icon"}, - BRN: { en: "BRUNEI", he: "ברוניי", icon: "mc-icon-Close glow-missing-icon"}, - BRA: { en: "BRAZIL", he: "ברזיל", icon: "mc-icon-Close glow-missing-icon"}, - BMU: { en: "BERMUDA", he: "ברמודה", icon: "mc-icon-Close glow-missing-icon"}, - GEO: { en: "GEORGIA", he: "גאורגיה", icon: "mc-icon-Close glow-missing-icon"}, - GHA: { en: "GHANA", he: "גאנה", icon: "mc-icon-Close glow-missing-icon"}, - GAB: { en: "GABON", he: "גבון", icon: "mc-icon-Close glow-missing-icon"}, - GLP: { en: "GUADELOUPE", he: "גואדאלופ", icon: "mc-icon-Close glow-missing-icon"}, - GUM: { en: "GUAM", he: "גואם", icon: "mc-icon-Close glow-missing-icon"}, - GTM: { en: "GUATEMALA", he: "גווטאמלה", icon: "mc-icon-Close glow-missing-icon"}, - GUY: { en: "GUYANA", he: "גויאנה", icon: "mc-icon-Close glow-missing-icon"}, - GUF: { en: "FRENCH GUIANA", he: "גויאנה הצרפתית", icon: "mc-icon-Close glow-missing-icon"}, - DJI: { en: "DJIBOUTI", he: "גיבוטי", icon: "mc-icon-Close glow-missing-icon"}, - GIB: { en: "GIBRALTAR", he: "גיברלטר", icon: "mc-icon-Close glow-missing-icon"}, - GIN: { en: "GUINEA", he: "גינאה", icon: "mc-icon-Close glow-missing-icon"}, - GNB: { en: "GUINEA BISSAU", he: "גינאה ביסאו", icon: "mc-icon-Close glow-missing-icon"}, - GNQ: { en: "GUINEA EQ", he: "גינאה המשוונית", icon: "mc-icon-Close glow-missing-icon"}, - GMB: { en: "GAMBIA", he: "גמביה", icon: "mc-icon-Close glow-missing-icon"}, - JAM: { en: "JAMAICA", he: "ג'מייקה", icon: "mc-icon-Close glow-missing-icon"}, - DEU: { en: "GERMANY", he: "גרמניה", icon: "mc-icon-Close glow-missing-icon"}, - GRD: { en: "GRENADA", he: "גרנדה", icon: "mc-icon-Close glow-missing-icon"}, - DMA: { en: "DOMINICA", he: "דומיניקה", icon: "mc-icon-Close glow-missing-icon"}, - DNK: { en: "DENMARK", he: "דנמרק", icon: "mc-icon-Close glow-missing-icon"}, - ZAF: { en: "SOUTH AFRICA", he: "דרום אפריקה", icon: "mc-icon-Close glow-missing-icon"}, - SSD: { en: "REPUBLIC OF SOUTH SUDAN", he: "דרום סודאן", icon: "mc-icon-Close glow-missing-icon"}, - HTI: { en: "HAITI", he: "האיטי", icon: "mc-icon-Close glow-missing-icon"}, - IND: { en: "INDIA", he: "הודו", icon: "mc-icon-Close glow-missing-icon"}, - NLD: { en: "NETHERLANDS", he: "הולנד", icon: "mc-icon-Close glow-missing-icon"}, - HKG: { en: "HONG KONG", he: "הונג קונג", icon: "mc-icon-Close glow-missing-icon"}, - HUN: { en: "HUNGARY", he: "הונגריה", icon: "mc-icon-Close glow-missing-icon"}, - HND: { en: "HONDURAS", he: "הונדורס", icon: "mc-icon-Close glow-missing-icon"}, - GBR: { en: "UNITED KINGDOM", he: "הממלכה המאוחדת", icon: "mc-icon-Close glow-missing-icon"}, - DOM: { en: "DOMINICAN REPUBLIC", he: "הרפובליקה הדומיניקנית", icon: "mc-icon-Close glow-missing-icon"}, - CAF: { en: "CENTRAL AFRICAN REPUBLIC", he: "הרפובליקה המרכז אפריקנית", icon: "mc-icon-Close glow-missing-icon"}, - AYOSH: { en: "PALESTINIAN AUTHORITY AYOSH", he: "הרשות הפלסטינית איוש", icon: "mc-icon-Close glow-missing-icon"}, - GAZA: { en: "PALESTINIAN AUTHORITY GAZA", he: "הרשות הפלסטינית עזה", icon: "mc-icon-Close glow-missing-icon"}, - VNM: { en: "VIETNAM", he: "ויטנאם", icon: "mc-icon-Close glow-missing-icon"}, - VUT: { en: "VANUATU", he: "ונואטו", icon: "mc-icon-Close glow-missing-icon"}, - VEN: { en: "VENEZUELA", he: "ונצואלה", icon: "mc-icon-Close glow-missing-icon"}, - ZWE: { en: "ZIMBABWE", he: "זימבאבווה", icon: "mc-icon-Close glow-missing-icon"}, - ZMB: { en: "ZAMBIA", he: "זמביה", icon: "mc-icon-Close glow-missing-icon"}, - CIV: { en: "IVORY COAST", he: "חוף השנהב", icon: "mc-icon-Close glow-missing-icon"}, - TJK: { en: "TAJIKISTAN", he: "טג'יקיסטאן", icon: "mc-icon-Close glow-missing-icon"}, - TUV: { en: "TUVALU", he: "טובלו", icon: "mc-icon-Close glow-missing-icon"}, - TGO: { en: "TOGO", he: "טוגו", icon: "mc-icon-Close glow-missing-icon"}, - TON: { en: "TONGA", he: "טונגה", icon: "mc-icon-Close glow-missing-icon"}, - TWN: { en: "TAIWAN", he: "טיוואן", icon: "mc-icon-Close glow-missing-icon"}, - TZA: { en: "TANZANIA", he: "טנזניה", icon: "mc-icon-Close glow-missing-icon"}, - TTO: { en: "TRINIDAD AND TOBAGO", he: "טרינידד וטובגו", icon: "mc-icon-Close glow-missing-icon"}, - SER: { en: "YUGOSLAVIA", he: "יוגוסלביה", icon: "mc-icon-Close glow-missing-icon"}, - GRC: { en: "GREECE", he: "יוון", icon: "mc-icon-Close glow-missing-icon"}, - JPN: { en: "JAPAN", he: "יפן", icon: "mc-icon-Close glow-missing-icon"}, - JOR: { en: "JORDAN", he: "ירדן", icon: "mc-icon-Close glow-missing-icon"}, - ISR: { en: "ISRAEL", he: "ישראל", icon: "mc-icon-Close glow-missing-icon"}, - KWT: { en: "KUWAIT", he: "כווית", icon: "mc-icon-Close glow-missing-icon"}, - UNKNOWN: { en: "UNKNOWN", he: "לא ידוע", icon: "mc-icon-Close glow-missing-icon"}, - LAO: { en: "LAOS", he: "לאוס", icon: "mc-icon-Close glow-missing-icon"}, - LBN: { en: "LEBANON", he: "לבנון", icon: "mc-icon-Close glow-missing-icon"}, - LBY: { en: "LIBYA", he: "לוב", icon: "mc-icon-Close glow-missing-icon"}, - LUX: { en: "LUXEMBOURG", he: "לוכסמבורג", icon: "mc-icon-Close glow-missing-icon"}, - LVA: { en: "LATVIA", he: "לטביה", icon: "mc-icon-Close glow-missing-icon"}, - LBR: { en: "LIBERIA", he: "ליבריה", icon: "mc-icon-Close glow-missing-icon"}, - LTU: { en: "LITHUANIA", he: "ליטא", icon: "mc-icon-Close glow-missing-icon"}, - LIE: { en: "LIECHTENSTEIN", he: "ליכטנשטיין", icon: "mc-icon-Close glow-missing-icon"}, - LSO: { en: "LESOTHO", he: "לסוטו", icon: "mc-icon-Close glow-missing-icon"}, - MRT: { en: "MAURITANIA", he: "מאוריטניה", icon: "mc-icon-Close glow-missing-icon"}, - MUS: { en: "MAURITIUS", he: "מאוריציוס", icon: "mc-icon-Close glow-missing-icon"}, - MLI: { en: "MALI", he: "מאלי", icon: "mc-icon-Close glow-missing-icon"}, - MDG: { en: "MADAGASCAR", he: "מדגסקר", icon: "mc-icon-Close glow-missing-icon"}, - MOZ: { en: "MOZAMBIQUE", he: "מוזמביק", icon: "mc-icon-Close glow-missing-icon"}, - MDA: { en: "MOLDOVA", he: "מולדובה", icon: "mc-icon-Close glow-missing-icon"}, - MNG: { en: "MONGOLIA", he: "מונגוליה", icon: "mc-icon-Close glow-missing-icon"}, - MNE: { en: "MONTENEGRO", he: "מונטנגרו", icon: "mc-icon-Close glow-missing-icon"}, - MSR: { en: "MONTSERRAT", he: "מונסרת", icon: "mc-icon-Close glow-missing-icon"}, - MCO: { en: "MONACO", he: "מונקו", icon: "mc-icon-Close glow-missing-icon"}, - TMP: { en: "EAST TIMOR", he: "מזרח טימור", icon: "mc-icon-Close glow-missing-icon"}, - MMR: { en: "MYANMAR BURMA", he: "מיאנמר בורמה", icon: "mc-icon-Close glow-missing-icon"}, - FSM: { en: "MICRONESIA", he: "מיקרונזיה", icon: "mc-icon-Close glow-missing-icon"}, - MWI: { en: "MALAWI", he: "מלאווי", icon: "mc-icon-Close glow-missing-icon"}, - MDV: { en: "MALADIVES", he: "מלדיבים", icon: "mc-icon-Close glow-missing-icon"}, - MYS: { en: "MALAYSIA", he: "מלזיה", icon: "mc-icon-Close glow-missing-icon"}, - MLT: { en: "MALTA", he: "מלטה", icon: "mc-icon-Close glow-missing-icon"}, - EGY: { en: "EGYPT", he: "מצרים", icon: "mc-icon-Close glow-missing-icon"}, - MAC: { en: "MACAO", he: "מקאו", icon: "mc-icon-Close glow-missing-icon"}, - MKD: { en: "MACEDONIA", he: "מקדוניה", icon: "mc-icon-Close glow-missing-icon"}, - MEX: { en: "MEXICO", he: "מקסיקו", icon: "mc-icon-Close glow-missing-icon"}, - MAR: { en: "MOROCCO", he: "מרוקו", icon: "mc-icon-Close glow-missing-icon"}, - MTQ: { en: "MARTINIQUE", he: "מרטיניק", icon: "mc-icon-Close glow-missing-icon"}, - NRU: { en: "NAURU", he: "נאורו", icon: "mc-icon-Close glow-missing-icon"}, - NOR: { en: "NORWAY", he: "נורבגיה", icon: "mc-icon-Close glow-missing-icon"}, - NER: { en: "NIGER", he: "ניגר", icon: "mc-icon-Close glow-missing-icon"}, - NGA: { en: "NIGERIA", he: "ניגריה", icon: "mc-icon-Close glow-missing-icon"}, - NZL: { en: "NEW ZEALAND", he: "ניו זילנד", icon: "mc-icon-Close glow-missing-icon"}, - NIC: { en: "NICARAGUA", he: "ניקרגואה", icon: "mc-icon-Close glow-missing-icon"}, - NAM: { en: "NAMIBIA", he: "נמיביה", icon: "mc-icon-Close glow-missing-icon"}, - NPL: { en: "NEPAL", he: "נפאל", icon: "mc-icon-Close glow-missing-icon"}, - STP: { en: "SAO TOME AND PRINCIP", he: "סאו טומה ופרינציפה", icon: "mc-icon-Close glow-missing-icon"}, - SDN: { en: "SUDAN", he: "סודן", icon: "mc-icon-Close glow-missing-icon"}, - SWZ: { en: "SWAZILAND", he: "סווזילנד", icon: "mc-icon-Close glow-missing-icon"}, - SOM: { en: "SOMALIA", he: "סומליה", icon: "mc-icon-Close glow-missing-icon"}, - SYR: { en: "SYRIA", he: "סוריה", icon: "mc-icon-Close glow-missing-icon"}, - SUR: { en: "SURINAME", he: "סורינם", icon: "mc-icon-Close glow-missing-icon"}, - SHN: { en: "ST HELENA", he: "סט הלנה", icon: "mc-icon-Close glow-missing-icon"}, - VCT: { en: "ST VINCENT", he: "סט וינסנט", icon: "mc-icon-Close glow-missing-icon"}, - LCA: { en: "ST LUCIA", he: "סט לוציה", icon: "mc-icon-Close glow-missing-icon"}, - KNA: { en: "ST KITTS NEVIS", he: "סט קיטס ונביס", icon: "mc-icon-Close glow-missing-icon"}, - SLE: { en: "SIERRA LEONE", he: "סיירה ליאונה", icon: "mc-icon-Close glow-missing-icon"}, - CHN: { en: "CHINA", he: "סין", icon: "mc-icon-Close glow-missing-icon"}, - SGP: { en: "SINGAPORE", he: "סינגפור", icon: "mc-icon-Close glow-missing-icon"}, - SIK: { en: "SIKKIM", he: "סיקים", icon: "mc-icon-Close glow-missing-icon"}, - SVN: { en: "SLOVENIA", he: "סלובניה", icon: "mc-icon-Close glow-missing-icon"}, - SVK: { en: "SLOVAKIA", he: "סלובקיה", icon: "mc-icon-Close glow-missing-icon"}, - WSM: { en: "SAMOA", he: "סמואה", icon: "mc-icon-Close glow-missing-icon"}, - ASM: { en: "AMERICAN SAMOA", he: "סמואה האמריקאי", icon: "mc-icon-Close glow-missing-icon"}, - SMR: { en: "SAN MARINO", he: "סן מרינו", icon: "mc-icon-Close glow-missing-icon"}, - SEN: { en: "SENEGAL", he: "סנגל", icon: "mc-icon-Close glow-missing-icon"}, - ESP: { en: "SPAIN", he: "ספרד", icon: "mc-icon-Close glow-missing-icon"}, - SRB: { en: "SERBIA", he: "סרביה", icon: "mc-icon-Close glow-missing-icon"}, - LKA: { en: "SRI-LANKA", he: "סרי לנקה צילו", icon: "mc-icon-Close glow-missing-icon"}, - OMN: { en: "OMAN", he: "עומן", icon: "mc-icon-Close glow-missing-icon"}, - IRQ: { en: "IRAQ", he: "עירק", icon: "mc-icon-Close glow-missing-icon"}, - SAU: { en: "SAUDI ARABIA", he: "ערב הסעודית", icon: "mc-icon-Close glow-missing-icon"}, - POL: { en: "POLAND", he: "פולין", icon: "mc-icon-Close glow-missing-icon"}, - PYF: { en: "FRENCH POLYNESIA", he: "פולינזיה הצרפתית", icon: "mc-icon-Close glow-missing-icon"}, - PRI: { en: "PUERTO RICO", he: "פורטו ריקו", icon: "mc-icon-Close glow-missing-icon"}, - PRT: { en: "PORTUGAL", he: "פורטוגל", icon: "mc-icon-Close glow-missing-icon"}, - PHL: { en: "PHILIPPINES", he: "פיליפינים", icon: "mc-icon-Close glow-missing-icon"}, - FIN: { en: "FINLAND", he: "פינלנד", icon: "mc-icon-Close glow-missing-icon"}, - PLW: { en: "PALAU", he: "פלאו", icon: "mc-icon-Close glow-missing-icon"}, - PAN: { en: "PANAMA", he: "פנמה", icon: "mc-icon-Close glow-missing-icon"}, - PNG: { en: "PAPUA NEW GUINEA", he: "פפואה גינאה החדשה", icon: "mc-icon-Close glow-missing-icon"}, - PAK: { en: "PAKISTAN", he: "פקיסטן", icon: "mc-icon-Close glow-missing-icon"}, - PRY: { en: "PARAGUAY", he: "פרגוואי", icon: "mc-icon-Close glow-missing-icon"}, - PER: { en: "PERU", he: "פרו", icon: "mc-icon-Close glow-missing-icon"}, - TCD: { en: "CHAD", he: "צ'אד", icon: "mc-icon-Close glow-missing-icon"}, - CHL: { en: "CHILE", he: "צ'ילה", icon: "mc-icon-Close glow-missing-icon"}, - CSK: { en: "CZECHOSLOVAKIA", he: "צ'כוסלובקיה", icon: "mc-icon-Close glow-missing-icon"}, - CZE: { en: "CZECH REPUBLIC", he: "צ'כיה", icon: "mc-icon-Close glow-missing-icon"}, - FRA: { en: "FRANCE", he: "צרפת", icon: "mc-icon-Close glow-missing-icon"}, - CUB: { en: "CUBA", he: "קובה", icon: "mc-icon-Close glow-missing-icon"}, - COL: { en: "COLOMBIA", he: "קולומביה", icon: "mc-icon-Close glow-missing-icon"}, - COG: { en: "CONGO DEMO REP", he: "קונגו רפובליקה דמוקרטית", icon: "mc-icon-Close glow-missing-icon"}, - CRI: { en: "COSTA RICA", he: "קוסטה ריקה", icon: "mc-icon-Close glow-missing-icon"}, - KOR: { en: "S KOREA", he: "קוריאה הדרומית", icon: "mc-icon-Close glow-missing-icon"}, - PRK: { en: "N KOREA", he: "קוריאה הצפונית", icon: "mc-icon-Close glow-missing-icon"}, - KAZ: { en: "KAZAKHSTAN", he: "קזחסטאן", icon: "mc-icon-Close glow-missing-icon"}, - QAT: { en: "QATAR", he: "קטר", icon: "mc-icon-Close glow-missing-icon"}, - KGZ: { en: "KIRGHIZSTAN", he: "קירגיזסטאן", icon: "mc-icon-Close glow-missing-icon"}, - KIR: { en: "KIRIBATI", he: "קיריבטי", icon: "mc-icon-Close glow-missing-icon"}, - NCL: { en: "NEW CALEDONIA", he: "קלדוניה החדשה", icon: "mc-icon-Close glow-missing-icon"}, - KHM: { en: "CAMBODIA", he: "קמבודיה", icon: "mc-icon-Close glow-missing-icon"}, - CMR: { en: "CAMEROON", he: "קמרון", icon: "mc-icon-Close glow-missing-icon"}, - CAN: { en: "CANADA", he: "קנדה", icon: "mc-icon-Close glow-missing-icon"}, - KEN: { en: "KENYA", he: "קניה", icon: "mc-icon-Close glow-missing-icon"}, - CYP: { en: "CYPRUS", he: "קפריסין", icon: "mc-icon-Close glow-missing-icon"}, - HRV: { en: "CROATIA", he: "קרואטיה", icon: "mc-icon-Close glow-missing-icon"}, - REU: { en: "REUNION", he: "ראוניון", icon: "mc-icon-Close glow-missing-icon"}, - RWA: { en: "RWANDA", he: "רואנדה", icon: "mc-icon-Close glow-missing-icon"}, - ROM: { en: "ROMANIA", he: "רומניה", icon: "mc-icon-Close glow-missing-icon"}, - RUS: { en: "RUSSIAN FEDERATION", he: "רוסיה", icon: "mc-icon-Close glow-missing-icon"}, - SWE: { en: "SWEDEN", he: "שוודיה", icon: "mc-icon-Close glow-missing-icon"}, - CHE: { en: "SWITZERLAND", he: "שוויץ", icon: "mc-icon-Close glow-missing-icon"}, - THA: { en: "THAILAND", he: "תאילנד", icon: "mc-icon-Close glow-missing-icon"}, - TUN: { en: "TUNISIA", he: "תוניסיה", icon: "mc-icon-Close glow-missing-icon"}, - TUR: { en: "TURKEY", he: "תורכיה", icon: "mc-icon-Close glow-missing-icon"}, - TKM: { en: "TURKMENISTAN", he: "תורכמניסטאן", icon: "mc-icon-Close glow-missing-icon"}, - YEM: { en: "YEMEN", he: "תימן", icon: "mc-icon-Close glow-missing-icon"} -}; \ No newline at end of file + UGA: { en: 'UGANDA', he: 'אוגנדה', icon: 'mc-icon-Close glow-missing-icon' }, + UZB: { + en: 'UZBEKISTAN', + he: 'אוזבקיסטן', + icon: 'mc-icon-Close glow-missing-icon', + }, + AUT: { + en: 'AUSTRIA', + he: 'אוסטריה', + icon: 'mc-icon-Close glow-missing-icon', + }, + AUS: { + en: 'AUSTRALIA', + he: 'אוסטרליה', + icon: 'mc-icon-Close glow-missing-icon', + }, + UKR: { + en: 'UKRAINE', + he: 'אוקראינה', + icon: 'mc-icon-Close glow-missing-icon', + }, + URY: { + en: 'URUGUAY', + he: 'אורגוואי', + icon: 'mc-icon-Close glow-missing-icon', + }, + AZE: { + en: 'AZERBAIJAN', + he: "אזרביג'אן", + icon: 'mc-icon-Close glow-missing-icon', + }, + ARE: { + en: 'UNITED ARAB EMIR', + he: 'איחוד האמירויות הערבית', + icon: 'mc-icon-Close glow-missing-icon', + }, + ITA: { en: 'ITALY', he: 'איטליה', icon: 'mc-icon-Close glow-missing-icon' }, + VIR: { + en: 'VIRGIN ISLAND', + he: 'איי הבתולה', + icon: 'mc-icon-Close glow-missing-icon', + }, + WLF: { + en: 'WALLIS FUTUNA ISL', + he: 'איי ווליס ופוטונה', + icon: 'mc-icon-Close glow-missing-icon', + }, + TCA: { + en: 'TORKAS ISLAND', + he: 'איי טורקס וקייקוס', + icon: 'mc-icon-Close glow-missing-icon', + }, + MHL: { + en: 'MARSHALL ISLANDS', + he: 'איי מרשל', + icon: 'mc-icon-Close glow-missing-icon', + }, + NFK: { + en: 'NORFOLK ISLA', + he: 'איי נורפולק', + icon: 'mc-icon-Close glow-missing-icon', + }, + SYC: { + en: 'SEYCHELLES', + he: 'איי סיישל', + icon: 'mc-icon-Close glow-missing-icon', + }, + FLK: { + en: 'FALKLAND', + he: 'איי פוקלנד', + icon: 'mc-icon-Close glow-missing-icon', + }, + FJI: { en: 'FIJI', he: 'איי פיגי', icon: 'mc-icon-Close glow-missing-icon' }, + COM: { + en: 'COMOROS ISLANDS', + he: 'איי קומורו', + icon: 'mc-icon-Close glow-missing-icon', + }, + COK: { + en: 'COOK ISL', + he: 'איי קוק', + icon: 'mc-icon-Close glow-missing-icon', + }, + CYM: { + en: 'CAYMAN ISLANDS', + he: 'איי קיימן', + icon: 'mc-icon-Close glow-missing-icon', + }, + CPV: { + en: 'CAPE VERDE ISLANDS', + he: 'איי קייפ וורדה', + icon: 'mc-icon-Close glow-missing-icon', + }, + SLB: { + en: 'SOLOMON ISLANDS', + he: 'איי שלמה הבריטיים', + icon: 'mc-icon-Close glow-missing-icon', + }, + IDN: { + en: 'INDONESIA', + he: 'אינדונזיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + ISL: { en: 'ICELAND', he: 'איסלנד', icon: 'mc-icon-Close glow-missing-icon' }, + IRL: { en: 'IRELAND', he: 'אירלנד', icon: 'mc-icon-Close glow-missing-icon' }, + IRN: { en: 'IRAN', he: 'אירן', icon: 'mc-icon-Close glow-missing-icon' }, + SLV: { + en: 'EL SALVADOR', + he: 'אל סלבדור', + icon: 'mc-icon-Close glow-missing-icon', + }, + ALB: { en: 'ALBANIA', he: 'אלבניה', icon: 'mc-icon-Close glow-missing-icon' }, + DZA: { + en: 'ALGERIA', + he: "אלג'יריה", + icon: 'mc-icon-Close glow-missing-icon', + }, + AGO: { en: 'ANGOLA', he: 'אנגולה', icon: 'mc-icon-Close glow-missing-icon' }, + AND: { en: 'ANDORRA', he: 'אנדורה', icon: 'mc-icon-Close glow-missing-icon' }, + ATG: { + en: 'ANTIGUA AND BARBUDA', + he: 'אנטיגואה וברבודה', + icon: 'mc-icon-Close glow-missing-icon', + }, + EST: { + en: 'ESTONIA', + he: 'אסטוניה', + icon: 'mc-icon-Close glow-missing-icon', + }, + AFG: { + en: 'AFGHANISTAN', + he: 'אפגניסטן', + icon: 'mc-icon-Close glow-missing-icon', + }, + ECU: { + en: 'ECUADOR', + he: 'אקוואדור', + icon: 'mc-icon-Close glow-missing-icon', + }, + ARG: { + en: 'ARGENTINA', + he: 'ארגנטינה', + icon: 'mc-icon-Close glow-missing-icon', + }, + ERI: { + en: 'ERITREA', + he: 'אריתראה', + icon: 'mc-icon-Close glow-missing-icon', + }, + ARM: { + en: 'ARM ENIA', + he: 'ארמניה', + icon: 'mc-icon-Close glow-missing-icon', + }, + USA: { + en: 'UNITED STATES', + he: 'ארצות הברית', + icon: 'mc-icon-Close glow-missing-icon', + }, + ETH: { + en: 'ETHIOPIA', + he: 'אתיופיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + BHS: { en: 'BAHAMAS', he: 'בהמס', icon: 'mc-icon-Close glow-missing-icon' }, + BTN: { en: 'BHUTAN', he: 'בוטן', icon: 'mc-icon-Close glow-missing-icon' }, + BWA: { + en: 'BOTSWANA', + he: 'בוטסוואנה', + icon: 'mc-icon-Close glow-missing-icon', + }, + BGR: { + en: 'BULGARIA', + he: 'בולגריה', + icon: 'mc-icon-Close glow-missing-icon', + }, + BOL: { + en: 'BOLIVIA', + he: 'בוליביה', + icon: 'mc-icon-Close glow-missing-icon', + }, + BIH: { + en: 'BOSNIA HERZEGOVINA', + he: 'בוסניה הרצגובינה', + icon: 'mc-icon-Close glow-missing-icon', + }, + BDI: { + en: 'BURUNDI', + he: 'בורונדי', + icon: 'mc-icon-Close glow-missing-icon', + }, + BFA: { + en: 'BURKINA FASSO', + he: 'בורקינה פאסו', + icon: 'mc-icon-Close glow-missing-icon', + }, + BHR: { en: 'BAHREIN', he: 'בחריין', icon: 'mc-icon-Close glow-missing-icon' }, + BLR: { + en: 'BELARUS', + he: 'בלורוסיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + BEL: { en: 'BELGIUM', he: 'בלגיה', icon: 'mc-icon-Close glow-missing-icon' }, + BLZ: { en: 'BELIZE', he: 'בליז', icon: 'mc-icon-Close glow-missing-icon' }, + BGD: { + en: 'BANGLADESH', + he: 'בנגלדש', + icon: 'mc-icon-Close glow-missing-icon', + }, + BEN: { + en: 'BENIN DAHOMEY', + he: 'בנין דהומ', + icon: 'mc-icon-Close glow-missing-icon', + }, + BRB: { + en: 'BARBADOS', + he: 'ברבדוס', + icon: 'mc-icon-Close glow-missing-icon', + }, + BRN: { en: 'BRUNEI', he: 'ברוניי', icon: 'mc-icon-Close glow-missing-icon' }, + BRA: { en: 'BRAZIL', he: 'ברזיל', icon: 'mc-icon-Close glow-missing-icon' }, + BMU: { en: 'BERMUDA', he: 'ברמודה', icon: 'mc-icon-Close glow-missing-icon' }, + GEO: { + en: 'GEORGIA', + he: 'גאורגיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + GHA: { en: 'GHANA', he: 'גאנה', icon: 'mc-icon-Close glow-missing-icon' }, + GAB: { en: 'GABON', he: 'גבון', icon: 'mc-icon-Close glow-missing-icon' }, + GLP: { + en: 'GUADELOUPE', + he: 'גואדאלופ', + icon: 'mc-icon-Close glow-missing-icon', + }, + GUM: { en: 'GUAM', he: 'גואם', icon: 'mc-icon-Close glow-missing-icon' }, + GTM: { + en: 'GUATEMALA', + he: 'גווטאמלה', + icon: 'mc-icon-Close glow-missing-icon', + }, + GUY: { en: 'GUYANA', he: 'גויאנה', icon: 'mc-icon-Close glow-missing-icon' }, + GUF: { + en: 'FRENCH GUIANA', + he: 'גויאנה הצרפתית', + icon: 'mc-icon-Close glow-missing-icon', + }, + DJI: { + en: 'DJIBOUTI', + he: 'גיבוטי', + icon: 'mc-icon-Close glow-missing-icon', + }, + GIB: { + en: 'GIBRALTAR', + he: 'גיברלטר', + icon: 'mc-icon-Close glow-missing-icon', + }, + GIN: { en: 'GUINEA', he: 'גינאה', icon: 'mc-icon-Close glow-missing-icon' }, + GNB: { + en: 'GUINEA BISSAU', + he: 'גינאה ביסאו', + icon: 'mc-icon-Close glow-missing-icon', + }, + GNQ: { + en: 'GUINEA EQ', + he: 'גינאה המשוונית', + icon: 'mc-icon-Close glow-missing-icon', + }, + GMB: { en: 'GAMBIA', he: 'גמביה', icon: 'mc-icon-Close glow-missing-icon' }, + JAM: { + en: 'JAMAICA', + he: "ג'מייקה", + icon: 'mc-icon-Close glow-missing-icon', + }, + DEU: { en: 'GERMANY', he: 'גרמניה', icon: 'mc-icon-Close glow-missing-icon' }, + GRD: { en: 'GRENADA', he: 'גרנדה', icon: 'mc-icon-Close glow-missing-icon' }, + DMA: { + en: 'DOMINICA', + he: 'דומיניקה', + icon: 'mc-icon-Close glow-missing-icon', + }, + DNK: { en: 'DENMARK', he: 'דנמרק', icon: 'mc-icon-Close glow-missing-icon' }, + ZAF: { + en: 'SOUTH AFRICA', + he: 'דרום אפריקה', + icon: 'mc-icon-Close glow-missing-icon', + }, + SSD: { + en: 'REPUBLIC OF SOUTH SUDAN', + he: 'דרום סודאן', + icon: 'mc-icon-Close glow-missing-icon', + }, + HTI: { en: 'HAITI', he: 'האיטי', icon: 'mc-icon-Close glow-missing-icon' }, + IND: { en: 'INDIA', he: 'הודו', icon: 'mc-icon-Close glow-missing-icon' }, + NLD: { + en: 'NETHERLANDS', + he: 'הולנד', + icon: 'mc-icon-Close glow-missing-icon', + }, + HKG: { + en: 'HONG KONG', + he: 'הונג קונג', + icon: 'mc-icon-Close glow-missing-icon', + }, + HUN: { + en: 'HUNGARY', + he: 'הונגריה', + icon: 'mc-icon-Close glow-missing-icon', + }, + HND: { + en: 'HONDURAS', + he: 'הונדורס', + icon: 'mc-icon-Close glow-missing-icon', + }, + GBR: { + en: 'UNITED KINGDOM', + he: 'הממלכה המאוחדת', + icon: 'mc-icon-Close glow-missing-icon', + }, + DOM: { + en: 'DOMINICAN REPUBLIC', + he: 'הרפובליקה הדומיניקנית', + icon: 'mc-icon-Close glow-missing-icon', + }, + CAF: { + en: 'CENTRAL AFRICAN REPUBLIC', + he: 'הרפובליקה המרכז אפריקנית', + icon: 'mc-icon-Close glow-missing-icon', + }, + AYOSH: { + en: 'PALESTINIAN AUTHORITY AYOSH', + he: 'הרשות הפלסטינית איוש', + icon: 'mc-icon-Close glow-missing-icon', + }, + GAZA: { + en: 'PALESTINIAN AUTHORITY GAZA', + he: 'הרשות הפלסטינית עזה', + icon: 'mc-icon-Close glow-missing-icon', + }, + VNM: { en: 'VIETNAM', he: 'ויטנאם', icon: 'mc-icon-Close glow-missing-icon' }, + VUT: { en: 'VANUATU', he: 'ונואטו', icon: 'mc-icon-Close glow-missing-icon' }, + VEN: { + en: 'VENEZUELA', + he: 'ונצואלה', + icon: 'mc-icon-Close glow-missing-icon', + }, + ZWE: { + en: 'ZIMBABWE', + he: 'זימבאבווה', + icon: 'mc-icon-Close glow-missing-icon', + }, + ZMB: { en: 'ZAMBIA', he: 'זמביה', icon: 'mc-icon-Close glow-missing-icon' }, + CIV: { + en: 'IVORY COAST', + he: 'חוף השנהב', + icon: 'mc-icon-Close glow-missing-icon', + }, + TJK: { + en: 'TAJIKISTAN', + he: "טג'יקיסטאן", + icon: 'mc-icon-Close glow-missing-icon', + }, + TUV: { en: 'TUVALU', he: 'טובלו', icon: 'mc-icon-Close glow-missing-icon' }, + TGO: { en: 'TOGO', he: 'טוגו', icon: 'mc-icon-Close glow-missing-icon' }, + TON: { en: 'TONGA', he: 'טונגה', icon: 'mc-icon-Close glow-missing-icon' }, + TWN: { en: 'TAIWAN', he: 'טיוואן', icon: 'mc-icon-Close glow-missing-icon' }, + TZA: { + en: 'TANZANIA', + he: 'טנזניה', + icon: 'mc-icon-Close glow-missing-icon', + }, + TTO: { + en: 'TRINIDAD AND TOBAGO', + he: 'טרינידד וטובגו', + icon: 'mc-icon-Close glow-missing-icon', + }, + SER: { + en: 'YUGOSLAVIA', + he: 'יוגוסלביה', + icon: 'mc-icon-Close glow-missing-icon', + }, + GRC: { en: 'GREECE', he: 'יוון', icon: 'mc-icon-Close glow-missing-icon' }, + JPN: { en: 'JAPAN', he: 'יפן', icon: 'mc-icon-Close glow-missing-icon' }, + JOR: { en: 'JORDAN', he: 'ירדן', icon: 'mc-icon-Close glow-missing-icon' }, + ISR: { en: 'ISRAEL', he: 'ישראל', icon: 'mc-icon-Close glow-missing-icon' }, + KWT: { en: 'KUWAIT', he: 'כווית', icon: 'mc-icon-Close glow-missing-icon' }, + UNKNOWN: { + en: 'UNKNOWN', + he: 'לא ידוע', + icon: 'mc-icon-Close glow-missing-icon', + }, + LAO: { en: 'LAOS', he: 'לאוס', icon: 'mc-icon-Close glow-missing-icon' }, + LBN: { en: 'LEBANON', he: 'לבנון', icon: 'mc-icon-Close glow-missing-icon' }, + LBY: { en: 'LIBYA', he: 'לוב', icon: 'mc-icon-Close glow-missing-icon' }, + LUX: { + en: 'LUXEMBOURG', + he: 'לוכסמבורג', + icon: 'mc-icon-Close glow-missing-icon', + }, + LVA: { en: 'LATVIA', he: 'לטביה', icon: 'mc-icon-Close glow-missing-icon' }, + LBR: { en: 'LIBERIA', he: 'ליבריה', icon: 'mc-icon-Close glow-missing-icon' }, + LTU: { en: 'LITHUANIA', he: 'ליטא', icon: 'mc-icon-Close glow-missing-icon' }, + LIE: { + en: 'LIECHTENSTEIN', + he: 'ליכטנשטיין', + icon: 'mc-icon-Close glow-missing-icon', + }, + LSO: { en: 'LESOTHO', he: 'לסוטו', icon: 'mc-icon-Close glow-missing-icon' }, + MRT: { + en: 'MAURITANIA', + he: 'מאוריטניה', + icon: 'mc-icon-Close glow-missing-icon', + }, + MUS: { + en: 'MAURITIUS', + he: 'מאוריציוס', + icon: 'mc-icon-Close glow-missing-icon', + }, + MLI: { en: 'MALI', he: 'מאלי', icon: 'mc-icon-Close glow-missing-icon' }, + MDG: { + en: 'MADAGASCAR', + he: 'מדגסקר', + icon: 'mc-icon-Close glow-missing-icon', + }, + MOZ: { + en: 'MOZAMBIQUE', + he: 'מוזמביק', + icon: 'mc-icon-Close glow-missing-icon', + }, + MDA: { + en: 'MOLDOVA', + he: 'מולדובה', + icon: 'mc-icon-Close glow-missing-icon', + }, + MNG: { + en: 'MONGOLIA', + he: 'מונגוליה', + icon: 'mc-icon-Close glow-missing-icon', + }, + MNE: { + en: 'MONTENEGRO', + he: 'מונטנגרו', + icon: 'mc-icon-Close glow-missing-icon', + }, + MSR: { + en: 'MONTSERRAT', + he: 'מונסרת', + icon: 'mc-icon-Close glow-missing-icon', + }, + MCO: { en: 'MONACO', he: 'מונקו', icon: 'mc-icon-Close glow-missing-icon' }, + TMP: { + en: 'EAST TIMOR', + he: 'מזרח טימור', + icon: 'mc-icon-Close glow-missing-icon', + }, + MMR: { + en: 'MYANMAR BURMA', + he: 'מיאנמר בורמה', + icon: 'mc-icon-Close glow-missing-icon', + }, + FSM: { + en: 'MICRONESIA', + he: 'מיקרונזיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + MWI: { en: 'MALAWI', he: 'מלאווי', icon: 'mc-icon-Close glow-missing-icon' }, + MDV: { + en: 'MALADIVES', + he: 'מלדיבים', + icon: 'mc-icon-Close glow-missing-icon', + }, + MYS: { en: 'MALAYSIA', he: 'מלזיה', icon: 'mc-icon-Close glow-missing-icon' }, + MLT: { en: 'MALTA', he: 'מלטה', icon: 'mc-icon-Close glow-missing-icon' }, + EGY: { en: 'EGYPT', he: 'מצרים', icon: 'mc-icon-Close glow-missing-icon' }, + MAC: { en: 'MACAO', he: 'מקאו', icon: 'mc-icon-Close glow-missing-icon' }, + MKD: { + en: 'MACEDONIA', + he: 'מקדוניה', + icon: 'mc-icon-Close glow-missing-icon', + }, + MEX: { en: 'MEXICO', he: 'מקסיקו', icon: 'mc-icon-Close glow-missing-icon' }, + MAR: { en: 'MOROCCO', he: 'מרוקו', icon: 'mc-icon-Close glow-missing-icon' }, + MTQ: { + en: 'MARTINIQUE', + he: 'מרטיניק', + icon: 'mc-icon-Close glow-missing-icon', + }, + NRU: { en: 'NAURU', he: 'נאורו', icon: 'mc-icon-Close glow-missing-icon' }, + NOR: { en: 'NORWAY', he: 'נורבגיה', icon: 'mc-icon-Close glow-missing-icon' }, + NER: { en: 'NIGER', he: 'ניגר', icon: 'mc-icon-Close glow-missing-icon' }, + NGA: { en: 'NIGERIA', he: 'ניגריה', icon: 'mc-icon-Close glow-missing-icon' }, + NZL: { + en: 'NEW ZEALAND', + he: 'ניו זילנד', + icon: 'mc-icon-Close glow-missing-icon', + }, + NIC: { + en: 'NICARAGUA', + he: 'ניקרגואה', + icon: 'mc-icon-Close glow-missing-icon', + }, + NAM: { en: 'NAMIBIA', he: 'נמיביה', icon: 'mc-icon-Close glow-missing-icon' }, + NPL: { en: 'NEPAL', he: 'נפאל', icon: 'mc-icon-Close glow-missing-icon' }, + STP: { + en: 'SAO TOME AND PRINCIP', + he: 'סאו טומה ופרינציפה', + icon: 'mc-icon-Close glow-missing-icon', + }, + SDN: { en: 'SUDAN', he: 'סודן', icon: 'mc-icon-Close glow-missing-icon' }, + SWZ: { + en: 'SWAZILAND', + he: 'סווזילנד', + icon: 'mc-icon-Close glow-missing-icon', + }, + SOM: { en: 'SOMALIA', he: 'סומליה', icon: 'mc-icon-Close glow-missing-icon' }, + SYR: { en: 'SYRIA', he: 'סוריה', icon: 'mc-icon-Close glow-missing-icon' }, + SUR: { + en: 'SURINAME', + he: 'סורינם', + icon: 'mc-icon-Close glow-missing-icon', + }, + SHN: { + en: 'ST HELENA', + he: 'סט הלנה', + icon: 'mc-icon-Close glow-missing-icon', + }, + VCT: { + en: 'ST VINCENT', + he: 'סט וינסנט', + icon: 'mc-icon-Close glow-missing-icon', + }, + LCA: { + en: 'ST LUCIA', + he: 'סט לוציה', + icon: 'mc-icon-Close glow-missing-icon', + }, + KNA: { + en: 'ST KITTS NEVIS', + he: 'סט קיטס ונביס', + icon: 'mc-icon-Close glow-missing-icon', + }, + SLE: { + en: 'SIERRA LEONE', + he: 'סיירה ליאונה', + icon: 'mc-icon-Close glow-missing-icon', + }, + CHN: { en: 'CHINA', he: 'סין', icon: 'mc-icon-Close glow-missing-icon' }, + SGP: { + en: 'SINGAPORE', + he: 'סינגפור', + icon: 'mc-icon-Close glow-missing-icon', + }, + SIK: { en: 'SIKKIM', he: 'סיקים', icon: 'mc-icon-Close glow-missing-icon' }, + SVN: { + en: 'SLOVENIA', + he: 'סלובניה', + icon: 'mc-icon-Close glow-missing-icon', + }, + SVK: { + en: 'SLOVAKIA', + he: 'סלובקיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + WSM: { en: 'SAMOA', he: 'סמואה', icon: 'mc-icon-Close glow-missing-icon' }, + ASM: { + en: 'AMERICAN SAMOA', + he: 'סמואה האמריקאי', + icon: 'mc-icon-Close glow-missing-icon', + }, + SMR: { + en: 'SAN MARINO', + he: 'סן מרינו', + icon: 'mc-icon-Close glow-missing-icon', + }, + SEN: { en: 'SENEGAL', he: 'סנגל', icon: 'mc-icon-Close glow-missing-icon' }, + ESP: { en: 'SPAIN', he: 'ספרד', icon: 'mc-icon-Close glow-missing-icon' }, + SRB: { en: 'SERBIA', he: 'סרביה', icon: 'mc-icon-Close glow-missing-icon' }, + LKA: { + en: 'SRI-LANKA', + he: 'סרי לנקה צילו', + icon: 'mc-icon-Close glow-missing-icon', + }, + OMN: { en: 'OMAN', he: 'עומן', icon: 'mc-icon-Close glow-missing-icon' }, + IRQ: { en: 'IRAQ', he: 'עירק', icon: 'mc-icon-Close glow-missing-icon' }, + SAU: { + en: 'SAUDI ARABIA', + he: 'ערב הסעודית', + icon: 'mc-icon-Close glow-missing-icon', + }, + POL: { en: 'POLAND', he: 'פולין', icon: 'mc-icon-Close glow-missing-icon' }, + PYF: { + en: 'FRENCH POLYNESIA', + he: 'פולינזיה הצרפתית', + icon: 'mc-icon-Close glow-missing-icon', + }, + PRI: { + en: 'PUERTO RICO', + he: 'פורטו ריקו', + icon: 'mc-icon-Close glow-missing-icon', + }, + PRT: { + en: 'PORTUGAL', + he: 'פורטוגל', + icon: 'mc-icon-Close glow-missing-icon', + }, + PHL: { + en: 'PHILIPPINES', + he: 'פיליפינים', + icon: 'mc-icon-Close glow-missing-icon', + }, + FIN: { en: 'FINLAND', he: 'פינלנד', icon: 'mc-icon-Close glow-missing-icon' }, + PLW: { en: 'PALAU', he: 'פלאו', icon: 'mc-icon-Close glow-missing-icon' }, + PAN: { en: 'PANAMA', he: 'פנמה', icon: 'mc-icon-Close glow-missing-icon' }, + PNG: { + en: 'PAPUA NEW GUINEA', + he: 'פפואה גינאה החדשה', + icon: 'mc-icon-Close glow-missing-icon', + }, + PAK: { + en: 'PAKISTAN', + he: 'פקיסטן', + icon: 'mc-icon-Close glow-missing-icon', + }, + PRY: { + en: 'PARAGUAY', + he: 'פרגוואי', + icon: 'mc-icon-Close glow-missing-icon', + }, + PER: { en: 'PERU', he: 'פרו', icon: 'mc-icon-Close glow-missing-icon' }, + TCD: { en: 'CHAD', he: "צ'אד", icon: 'mc-icon-Close glow-missing-icon' }, + CHL: { en: 'CHILE', he: "צ'ילה", icon: 'mc-icon-Close glow-missing-icon' }, + CSK: { + en: 'CZECHOSLOVAKIA', + he: "צ'כוסלובקיה", + icon: 'mc-icon-Close glow-missing-icon', + }, + CZE: { + en: 'CZECH REPUBLIC', + he: "צ'כיה", + icon: 'mc-icon-Close glow-missing-icon', + }, + FRA: { en: 'FRANCE', he: 'צרפת', icon: 'mc-icon-Close glow-missing-icon' }, + CUB: { en: 'CUBA', he: 'קובה', icon: 'mc-icon-Close glow-missing-icon' }, + COL: { + en: 'COLOMBIA', + he: 'קולומביה', + icon: 'mc-icon-Close glow-missing-icon', + }, + COG: { + en: 'CONGO DEMO REP', + he: 'קונגו רפובליקה דמוקרטית', + icon: 'mc-icon-Close glow-missing-icon', + }, + CRI: { + en: 'COSTA RICA', + he: 'קוסטה ריקה', + icon: 'mc-icon-Close glow-missing-icon', + }, + KOR: { + en: 'S KOREA', + he: 'קוריאה הדרומית', + icon: 'mc-icon-Close glow-missing-icon', + }, + PRK: { + en: 'N KOREA', + he: 'קוריאה הצפונית', + icon: 'mc-icon-Close glow-missing-icon', + }, + KAZ: { + en: 'KAZAKHSTAN', + he: 'קזחסטאן', + icon: 'mc-icon-Close glow-missing-icon', + }, + QAT: { en: 'QATAR', he: 'קטר', icon: 'mc-icon-Close glow-missing-icon' }, + KGZ: { + en: 'KIRGHIZSTAN', + he: 'קירגיזסטאן', + icon: 'mc-icon-Close glow-missing-icon', + }, + KIR: { + en: 'KIRIBATI', + he: 'קיריבטי', + icon: 'mc-icon-Close glow-missing-icon', + }, + NCL: { + en: 'NEW CALEDONIA', + he: 'קלדוניה החדשה', + icon: 'mc-icon-Close glow-missing-icon', + }, + KHM: { + en: 'CAMBODIA', + he: 'קמבודיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + CMR: { en: 'CAMEROON', he: 'קמרון', icon: 'mc-icon-Close glow-missing-icon' }, + CAN: { en: 'CANADA', he: 'קנדה', icon: 'mc-icon-Close glow-missing-icon' }, + KEN: { en: 'KENYA', he: 'קניה', icon: 'mc-icon-Close glow-missing-icon' }, + CYP: { en: 'CYPRUS', he: 'קפריסין', icon: 'mc-icon-Close glow-missing-icon' }, + HRV: { + en: 'CROATIA', + he: 'קרואטיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + REU: { + en: 'REUNION', + he: 'ראוניון', + icon: 'mc-icon-Close glow-missing-icon', + }, + RWA: { en: 'RWANDA', he: 'רואנדה', icon: 'mc-icon-Close glow-missing-icon' }, + ROM: { en: 'ROMANIA', he: 'רומניה', icon: 'mc-icon-Close glow-missing-icon' }, + RUS: { + en: 'RUSSIAN FEDERATION', + he: 'רוסיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + SWE: { en: 'SWEDEN', he: 'שוודיה', icon: 'mc-icon-Close glow-missing-icon' }, + CHE: { + en: 'SWITZERLAND', + he: 'שוויץ', + icon: 'mc-icon-Close glow-missing-icon', + }, + THA: { + en: 'THAILAND', + he: 'תאילנד', + icon: 'mc-icon-Close glow-missing-icon', + }, + TUN: { + en: 'TUNISIA', + he: 'תוניסיה', + icon: 'mc-icon-Close glow-missing-icon', + }, + TUR: { en: 'TURKEY', he: 'תורכיה', icon: 'mc-icon-Close glow-missing-icon' }, + TKM: { + en: 'TURKMENISTAN', + he: 'תורכמניסטאן', + icon: 'mc-icon-Close glow-missing-icon', + }, + YEM: { en: 'YEMEN', he: 'תימן', icon: 'mc-icon-Close glow-missing-icon' }, +}; diff --git a/src/common/models/country.enum.ts b/src/common/models/country.enum.ts index 793215960..b1e84c6db 100644 --- a/src/common/models/country.enum.ts +++ b/src/common/models/country.enum.ts @@ -220,4 +220,4 @@ export enum Country { TUR = 'TUR', TKM = 'TKM', YEM = 'YEM', -}; \ No newline at end of file +} diff --git a/src/common/models/dictionary.ts b/src/common/models/dictionary.ts index eae0a0476..db3a9ae3a 100644 --- a/src/common/models/dictionary.ts +++ b/src/common/models/dictionary.ts @@ -6,4 +6,4 @@ export interface IDictionaryValue { export interface IDictionary { [key: string]: IDictionaryValue; -} \ No newline at end of file +} diff --git a/src/common/models/domain.ts b/src/common/models/domain.ts index 46246cb1a..0928394e2 100644 --- a/src/common/models/domain.ts +++ b/src/common/models/domain.ts @@ -6,4 +6,4 @@ export enum Domain { '3D' = '3D', DEM = 'DEM', VECTOR = 'VECTOR', -} \ No newline at end of file +} diff --git a/src/common/models/job-errors-summary.raster.ts b/src/common/models/job-errors-summary.raster.ts index 5f23b31de..fea6aba61 100644 --- a/src/common/models/job-errors-summary.raster.ts +++ b/src/common/models/job-errors-summary.raster.ts @@ -40,11 +40,11 @@ export type RasterErrorsSummary = { smallGeometries: { exceeded: boolean; }; - } + }; }; // #endregion to be removed export type RasterErrorCount = { count?: number; exceeded?: boolean; -} +}; diff --git a/src/common/models/link-type.enum.ts b/src/common/models/link-type.enum.ts index 8a20f8940..3916dbd5b 100644 --- a/src/common/models/link-type.enum.ts +++ b/src/common/models/link-type.enum.ts @@ -14,5 +14,5 @@ export enum LinkType { THUMBNAIL_L = 'THUMBNAIL_L', LEGEND_DOC = 'LEGEND_DOC', LEGEND_IMG = 'LEGEND_IMG', - LEGEND = 'LEGEND' -} \ No newline at end of file + LEGEND = 'LEGEND', +} diff --git a/src/common/models/mode.enum.ts b/src/common/models/mode.enum.ts index 19200eb42..d6668d732 100644 --- a/src/common/models/mode.enum.ts +++ b/src/common/models/mode.enum.ts @@ -4,5 +4,5 @@ export enum Mode { EDIT = 'Edit', UPDATE = 'Update', EXPORT = 'Export', - DELETE = 'Delete' + DELETE = 'Delete', } diff --git a/src/common/models/raster-ingestion-files-structure.ts b/src/common/models/raster-ingestion-files-structure.ts index 5fc757c8b..bdde0e811 100644 --- a/src/common/models/raster-ingestion-files-structure.ts +++ b/src/common/models/raster-ingestion-files-structure.ts @@ -1,6 +1,6 @@ // RASTER GENERAL CONFIGURATION -export type RasterFileTypeConfig = "data" | "product" | "shapeMetadata"; +export type RasterFileTypeConfig = 'data' | 'product' | 'shapeMetadata'; // FIELD selectablePattern can receive letters, and may optionally end with an '*' character, // which acts as a wildcard to match any sequence of characters following the prefix in the file name. @@ -12,4 +12,7 @@ interface IRasterFileGroupConfig { selectablePattern: string; } -export type IRasterIngestionFilesStructureConfig = Record; \ No newline at end of file +export type IRasterIngestionFilesStructureConfig = Record< + RasterFileTypeConfig, + IRasterFileGroupConfig +>; diff --git a/src/common/models/raster-job.ts b/src/common/models/raster-job.ts index 072343748..eadaebf86 100644 --- a/src/common/models/raster-job.ts +++ b/src/common/models/raster-job.ts @@ -1,5 +1,5 @@ export enum RasterIngestionJobType { NEW = 'Ingestion_New', UPDATE = 'Ingestion_Update', - SWAP_UPDATE = 'Ingestion_Swap_Update' -} \ No newline at end of file + SWAP_UPDATE = 'Ingestion_Swap_Update', +} diff --git a/src/common/ui-descriptors/helper.ts b/src/common/ui-descriptors/helper.ts index 863fe9436..6ebdc060e 100644 --- a/src/common/ui-descriptors/helper.ts +++ b/src/common/ui-descriptors/helper.ts @@ -2,6 +2,8 @@ import { LinkModelType } from '../../discrete-layer/models'; import { ILayerImage } from '../../discrete-layer/models/layerImage'; import { UiDescriptorsTypeName, UiFieldDescriptor } from './type'; -export const isUiDescriptor = (layerRecord?: ILayerImage | LinkModelType | null | UiFieldDescriptor): layerRecord is UiFieldDescriptor => { +export const isUiDescriptor = ( + layerRecord?: ILayerImage | LinkModelType | null | UiFieldDescriptor +): layerRecord is UiFieldDescriptor => { return layerRecord?.__typename === UiDescriptorsTypeName; }; diff --git a/src/common/ui-descriptors/resolution/resolutionDegree.ts b/src/common/ui-descriptors/resolution/resolutionDegree.ts index 6443cf4ab..e08371f1e 100644 --- a/src/common/ui-descriptors/resolution/resolutionDegree.ts +++ b/src/common/ui-descriptors/resolution/resolutionDegree.ts @@ -1,82 +1,82 @@ export const resolutionDegree = { - "uiDescriptorFieldType": "resolution", - "autocomplete": null, - "lookupTable": "zoomlevelresolutions", - "lookupExcludeFields": null, - "fieldName": "resolutionDegree", - "queryableName": "", - "label": "field-names.raster.maxResolutionDeg", - "order": 999, - "fullWidth": null, - "rows": null, - "infoMsgCode": [ - "info-field-tooltip.maxResolutionDeg.tooltip", - "info-general-tooltip.required", - "info-field-tooltip.maxResolutionDeg.min", - "info-field-tooltip.maxResolutionDeg.max" + uiDescriptorFieldType: 'resolution', + autocomplete: null, + lookupTable: 'zoomlevelresolutions', + lookupExcludeFields: null, + fieldName: 'resolutionDegree', + queryableName: '', + label: 'field-names.raster.maxResolutionDeg', + order: 999, + fullWidth: null, + rows: null, + infoMsgCode: [ + 'info-field-tooltip.maxResolutionDeg.tooltip', + 'info-general-tooltip.required', + 'info-field-tooltip.maxResolutionDeg.min', + 'info-field-tooltip.maxResolutionDeg.max', ], - "isManuallyEditable": null, - "isSortable": null, - "isRequired": false, - "isAutoGenerated": null, - "isLifecycleEnvolved": true, - "isCopyable": null, - "isDisabled": null, - "isCreateEssential": null, - "isUpdateEssential": null, - "isMultiSelection": null, - "dateGranularity": null, - "shapeFileMapping": null, - "updateRules": null, - "enumValues": null, - "subFields": null, - "validation": [ + isManuallyEditable: null, + isSortable: null, + isRequired: false, + isAutoGenerated: null, + isLifecycleEnvolved: true, + isCopyable: null, + isDisabled: null, + isCreateEssential: null, + isUpdateEssential: null, + isMultiSelection: null, + dateGranularity: null, + shapeFileMapping: null, + updateRules: null, + enumValues: null, + subFields: null, + validation: [ { - "valueType": "FIELD", - "errorMsgCode": "DUMMY_NOT_IN_USE", - "min": null, - "max": "resolutionDegreeMaxValue", - "minLength": null, - "maxLength": null, - "pattern": null, - "errorMsgTranslation": null, - "required": null, - "json": null + valueType: 'FIELD', + errorMsgCode: 'DUMMY_NOT_IN_USE', + min: null, + max: 'resolutionDegreeMaxValue', + minLength: null, + maxLength: null, + pattern: null, + errorMsgTranslation: null, + required: null, + json: null, }, { - "valueType": "VALUE", - "errorMsgCode": "validation-field.maxResolutionDeg.min", - "min": "1.67638063430786e-7", - "max": null, - "minLength": null, - "maxLength": null, - "pattern": null, - "errorMsgTranslation": null, - "required": null, - "json": null + valueType: 'VALUE', + errorMsgCode: 'validation-field.maxResolutionDeg.min', + min: '1.67638063430786e-7', + max: null, + minLength: null, + maxLength: null, + pattern: null, + errorMsgTranslation: null, + required: null, + json: null, }, { - "valueType": "VALUE", - "errorMsgCode": "validation-field.maxResolutionDeg.max", - "min": null, - "max": "0.703125", - "minLength": null, - "maxLength": null, - "pattern": null, - "errorMsgTranslation": null, - "required": null, - "json": null - } + valueType: 'VALUE', + errorMsgCode: 'validation-field.maxResolutionDeg.max', + min: null, + max: '0.703125', + minLength: null, + maxLength: null, + pattern: null, + errorMsgTranslation: null, + required: null, + json: null, + }, ], - "isFilterable": null, - "isBriefField": null, - "isInfoTooltip": null, - "lookupTableBinding": { - "valueFromPropertyName": "resolutionDeg" + isFilterable: null, + isBriefField: null, + isInfoTooltip: null, + lookupTableBinding: { + valueFromPropertyName: 'resolutionDeg', }, - "dependentField": { - "name": "resolutionMeter", - "valueFromPropertyName": "resolutionMeter" + dependentField: { + name: 'resolutionMeter', + valueFromPropertyName: 'resolutionMeter', }, - "default": null + default: null, }; diff --git a/src/common/ui-descriptors/resolution/resolutionMeter.ts b/src/common/ui-descriptors/resolution/resolutionMeter.ts index d2c315b8a..646998505 100644 --- a/src/common/ui-descriptors/resolution/resolutionMeter.ts +++ b/src/common/ui-descriptors/resolution/resolutionMeter.ts @@ -1,66 +1,66 @@ export const resolutionMeter = { - "uiDescriptorFieldType": "number", - "autocomplete": null, - "lookupTable": null, - "lookupExcludeFields": null, - "fieldName": "resolutionMeter", - "queryableName": "", - "label": "field-names.raster.maxResolutionMeter", - "order": 999, - "fullWidth": null, - "rows": null, - "infoMsgCode": [ - "info-general-tooltip.required", - "info-field-tooltip.maxResolutionMeter.min", - "info-field-tooltip.maxResolutionMeter.max" + uiDescriptorFieldType: 'number', + autocomplete: null, + lookupTable: null, + lookupExcludeFields: null, + fieldName: 'resolutionMeter', + queryableName: '', + label: 'field-names.raster.maxResolutionMeter', + order: 999, + fullWidth: null, + rows: null, + infoMsgCode: [ + 'info-general-tooltip.required', + 'info-field-tooltip.maxResolutionMeter.min', + 'info-field-tooltip.maxResolutionMeter.max', ], - "isManuallyEditable": null, - "isSortable": null, - "isRequired": false, - "isAutoGenerated": null, - "isLifecycleEnvolved": true, - "isCopyable": null, - "isDisabled": true, - "isCreateEssential": null, - "isUpdateEssential": null, - "isMultiSelection": null, - "dateGranularity": null, - "shapeFileMapping": null, - "updateRules": null, - "enumValues": null, - "subFields": null, - "validation": [ + isManuallyEditable: null, + isSortable: null, + isRequired: false, + isAutoGenerated: null, + isLifecycleEnvolved: true, + isCopyable: null, + isDisabled: true, + isCreateEssential: null, + isUpdateEssential: null, + isMultiSelection: null, + dateGranularity: null, + shapeFileMapping: null, + updateRules: null, + enumValues: null, + subFields: null, + validation: [ { - "valueType": "VALUE", - "errorMsgCode": "validation-field.maxResolutionMeter.min", - "min": "0.0185", - "max": null, - "minLength": null, - "maxLength": null, - "pattern": null, - "errorMsgTranslation": null, - "required": null, - "json": null + valueType: 'VALUE', + errorMsgCode: 'validation-field.maxResolutionMeter.min', + min: '0.0185', + max: null, + minLength: null, + maxLength: null, + pattern: null, + errorMsgTranslation: null, + required: null, + json: null, }, { - "valueType": "VALUE", - "errorMsgCode": "validation-field.maxResolutionMeter.max", - "min": null, - "max": "78271.52", - "minLength": null, - "maxLength": null, - "pattern": null, - "errorMsgTranslation": null, - "required": null, - "json": null - } + valueType: 'VALUE', + errorMsgCode: 'validation-field.maxResolutionMeter.max', + min: null, + max: '78271.52', + minLength: null, + maxLength: null, + pattern: null, + errorMsgTranslation: null, + required: null, + json: null, + }, ], - "isFilterable": null, - "isBriefField": { - "order": 7 + isFilterable: null, + isBriefField: { + order: 7, }, - "isInfoTooltip": true, - "lookupTableBinding": null, - "dependentField": null, - "default": null + isInfoTooltip: true, + lookupTableBinding: null, + dependentField: null, + default: null, }; diff --git a/src/common/ui-descriptors/type.ts b/src/common/ui-descriptors/type.ts index 96a511e29..1af0e6b23 100644 --- a/src/common/ui-descriptors/type.ts +++ b/src/common/ui-descriptors/type.ts @@ -1,3 +1,3 @@ export const UiDescriptorsTypeName = 'UiDescriptors'; export type UiDescriptorsType = 'UiDescriptors'; -export type UiFieldDescriptor = { "__typename": UiDescriptorsType }; +export type UiFieldDescriptor = { __typename: UiDescriptorsType }; diff --git a/src/common/utils/geo.tools.ts b/src/common/utils/geo.tools.ts index cd938cf59..61199c7cc 100644 --- a/src/common/utils/geo.tools.ts +++ b/src/common/utils/geo.tools.ts @@ -16,45 +16,53 @@ export const DEGREES_PER_METER = 0.00001; export const ZERO_MERIDIAN = 0; export const ANTI_MERIDIAN = 180; -export type geoArgs = {name: string, value: any}[]; +export type geoArgs = { name: string; value: any }[]; export type geoCustomChecks = { - validationFunc: ((value: string, args: geoArgs) => geoJSONValidation | undefined)[], - validationFuncArgs: geoArgs + validationFunc: (( + value: string, + args: geoArgs + ) => geoJSONValidation | undefined)[]; + validationFuncArgs: geoArgs; }; const checkPolygon = (coordinates: Position[][], meridian: number) => { - for (const ring of coordinates) { - for (let i = 0; i < ring.length - 1; i++) { - const start = ring[i]; - const end = ring[i + 1]; - - // Check if one point is on one side of the meridian and the other point is on the other side - if ((start[0] < meridian && end[0] > meridian) || (start[0] > meridian && end[0] < meridian)) { - return true; - } - } + for (const ring of coordinates) { + for (let i = 0; i < ring.length - 1; i++) { + const start = ring[i]; + const end = ring[i + 1]; + + // Check if one point is on one side of the meridian and the other point is on the other side + if ( + (start[0] < meridian && end[0] > meridian) || + (start[0] > meridian && end[0] < meridian) + ) { + return true; + } } - return false; -} - -export const crossesMeridian = (geometry: Polygon | MultiPolygon, meridian: number) => { - if (!geometry) - return true; - - const type = geometry.type; - - if (type === 'Polygon') { - return checkPolygon(geometry.coordinates, meridian); - } else if (type === 'MultiPolygon') { - for (const polygon of geometry.coordinates) { - if (checkPolygon(polygon, meridian)) { - return true; - } - } + } + return false; +}; + +export const crossesMeridian = ( + geometry: Polygon | MultiPolygon, + meridian: number +) => { + if (!geometry) return true; + + const type = geometry.type; + + if (type === 'Polygon') { + return checkPolygon(geometry.coordinates, meridian); + } else if (type === 'MultiPolygon') { + for (const polygon of geometry.coordinates) { + if (checkPolygon(polygon, meridian)) { + return true; + } } - return false; -} + } + return false; +}; /* ****** Current solution is using TURF MASK @@ -71,104 +79,137 @@ There is 2 alternatives to get perimeter(outlined feature) const convexHullFromUnion: Feature = convex(unitedPolygon.geometry); */ const QUANTIZATION_TOLERANCE = 1e6; -const SIMPLIFY_TOLERANCE = 0.0001; // maximum allowed deviation(degrees) of simplified points from the original geometry -// 0.0001 works good for geometries from ~200m(linear dimensions) -// but for a large geometries number of vertices might be relatively big and not so relevant for UI -export const getOutlinedFeature = (features: Feature[]) => { - const masked = mask({ - type: 'FeatureCollection', - features: applyTopology(features, QUANTIZATION_TOLERANCE) - }); - // Remove whole world geometry - masked.geometry.coordinates = masked.geometry.coordinates.slice(1); - - return simplify( - polygonToLine(masked), - {tolerance: SIMPLIFY_TOLERANCE, highQuality: false} - ); -} - -export const applyTopology = (features: Feature[], quantization: number): Feature[] => { - const polygons: Record = {}; - features.forEach((feat, idx) => { - polygons[idx] = { - ...feat.geometry - } as unknown as Geometry; - }); +const SIMPLIFY_TOLERANCE = 0.0001; // maximum allowed deviation(degrees) of simplified points from the original geometry +// 0.0001 works good for geometries from ~200m(linear dimensions) +// but for a large geometries number of vertices might be relatively big and not so relevant for UI +export const getOutlinedFeature = ( + features: Feature[] +) => { + const masked = mask({ + type: 'FeatureCollection', + features: applyTopology(features, QUANTIZATION_TOLERANCE), + }); + // Remove whole world geometry + masked.geometry.coordinates = masked.geometry.coordinates.slice(1); - const pp_topology = topology(polygons, quantization ); - const ret_features: Feature[] = []; + return simplify(polygonToLine(masked), { + tolerance: SIMPLIFY_TOLERANCE, + highQuality: false, + }); +}; - Object.entries(polygons).forEach(([key, val]) => { - const topo_feat = feature(pp_topology, pp_topology.objects[key]); - ret_features.push(topo_feat as never); - }); +export const applyTopology = ( + features: Feature[], + quantization: number +): Feature[] => { + const polygons: Record = {}; + features.forEach((feat, idx) => { + polygons[idx] = { + ...feat.geometry, + } as unknown as Geometry; + }); - return ret_features; -} + const pp_topology = topology(polygons, quantization); + const ret_features: Feature[] = []; -export const isGeometryPolygon = (geometry: Geometry) => geometry ? geometry.type === 'Polygon' : true; + Object.entries(polygons).forEach(([key, val]) => { + const topo_feat = feature(pp_topology, pp_topology.objects[key]); + ret_features.push(topo_feat as never); + }); -export const polygonVertexDensityFactor = (polygon: Feature, tolerance: number): number => { - const vertices_org = explode(polygon as AllGeoJSON).features.map(f => f.geometry.coordinates); - const vertices_simpl = explode(turf.simplify( - polygon as AllGeoJSON, - {tolerance, highQuality: false} - )) - .features.map(f => f.geometry.coordinates); - console.log("simple vs org vertices count:", vertices_org.length, "to:", vertices_simpl.length, `(${vertices_simpl.length/vertices_org.length})`); + return ret_features; +}; - return vertices_simpl.length/vertices_org.length; -} +export const isGeometryPolygon = (geometry: Geometry) => + geometry ? geometry.type === 'Polygon' : true; + +export const polygonVertexDensityFactor = ( + polygon: Feature, + tolerance: number +): number => { + const vertices_org = explode(polygon as AllGeoJSON).features.map( + (f) => f.geometry.coordinates + ); + const vertices_simpl = explode( + turf.simplify(polygon as AllGeoJSON, { tolerance, highQuality: false }) + ).features.map((f) => f.geometry.coordinates); + console.log( + 'simple vs org vertices count:', + vertices_org.length, + 'to:', + vertices_simpl.length, + `(${vertices_simpl.length / vertices_org.length})` + ); + + return vertices_simpl.length / vertices_org.length; +}; -export const isPolygonContainsPolygon = (polygon: Feature, polygonToCheck: Feature): boolean => { - const polygonBBox = bbox(polygon); - const polygonBBoxPolygon = bboxPolygon(polygonBBox); +export const isPolygonContainsPolygon = ( + polygon: Feature, + polygonToCheck: Feature +): boolean => { + const polygonBBox = bbox(polygon); + const polygonBBoxPolygon = bboxPolygon(polygonBBox); - const polygonToCheckBBox = bbox(polygonToCheck); - const polygonToCheckBBoxPolygon = bboxPolygon(polygonToCheckBBox); - return booleanContains(polygonBBoxPolygon, polygonToCheckBBoxPolygon); + const polygonToCheckBBox = bbox(polygonToCheck); + const polygonToCheckBBoxPolygon = bboxPolygon(polygonToCheckBBox); + return booleanContains(polygonBBoxPolygon, polygonToCheckBBoxPolygon); }; export const getFirstPoint = (geojson: Geometry): Position => { - // @ts-ignore - const { type, coordinates } = geojson; - - switch (type) { - case "Point": - return coordinates; - - case "LineString": - case "MultiPoint": - return coordinates[0]; - - case "Polygon": - case "MultiLineString": - return coordinates[0][0]; - - case "MultiPolygon": - return coordinates[0][0][0]; - - default: - throw new Error("Unsupported GeoJSON geometry type"); - } -} + // @ts-ignore + const { type, coordinates } = geojson; + + switch (type) { + case 'Point': + return coordinates; + + case 'LineString': + case 'MultiPoint': + return coordinates[0]; + + case 'Polygon': + case 'MultiLineString': + return coordinates[0][0]; + + case 'MultiPolygon': + return coordinates[0][0][0]; + + default: + throw new Error('Unsupported GeoJSON geometry type'); + } +}; export const explode = (geometry: AllGeoJSON) => { - return turf.explode(geometry) -} + return turf.explode(geometry); +}; export const area = (geometry: AllGeoJSON) => { - return turf.area(geometry as unknown as Feature | FeatureCollection | turf.helpers.Geometry); -} + return turf.area( + geometry as unknown as + | Feature + | FeatureCollection + | turf.helpers.Geometry + ); +}; -export const isSmallArea = (area: number, pixelAreaThreshold: number, resolutionMeter: number): boolean => { +export const isSmallArea = ( + area: number, + pixelAreaThreshold: number, + resolutionMeter: number +): boolean => { //IF($area > (sqrt(10) * to_real("resolution")) ^ 2 , 'Good', 'Small') - return (area > Math.pow((Math.sqrt(pixelAreaThreshold) * resolutionMeter), 2)) ? false : true; -} + return area > Math.pow(Math.sqrt(pixelAreaThreshold) * resolutionMeter, 2) + ? false + : true; +}; // Function to detect small holes in Polygon and MultiPolygon -export const countSmallHoles = (feature: Feature, threshold: number, resolution: number) => { +export const countSmallHoles = ( + feature: Feature, + threshold: number, + resolution: number +) => { let ret = 0; const featureGeometry = feature.geometry ?? feature; const type = featureGeometry.type; @@ -183,13 +224,17 @@ export const countSmallHoles = (feature: Feature, threshold: number, resol console.log('Feature is not a Polygon or MultiPolygon.'); } - if (ret > 0){ + if (ret > 0) { console.log('Feature has holes', ret); } return ret; -} +}; -const countPolygonHoles = (coordinates: Position[][], threshold: number, resolution: number): number => { +const countPolygonHoles = ( + coordinates: Position[][], + threshold: number, + resolution: number +): number => { let ret = 0; // eslint-disable-next-line @typescript-eslint/no-unused-vars const [outerRing, ...holes] = coordinates; @@ -201,25 +246,30 @@ const countPolygonHoles = (coordinates: Position[][], threshold: number, resolut } }); return ret; -} +}; export const getGapsByConvexHull = (polygonsData: { - [x: string]: PolygonPartRecordModelType; + [x: string]: PolygonPartRecordModelType; }) => { - const polygonsCoordinates = Object.values(polygonsData).map( - (poly: PolygonPartRecordModelType) => poly.footprint.coordinates); - const turfPolygons = polygonsCoordinates.map( - (coordinate) => turf.polygon(coordinate)); - const polygonsCollection = turf.featureCollection(turfPolygons); - // @ts-ignore - const mergedPolygons = polygonsCollection.features.reduce((acc, curr) => { - return acc ? turf.union(acc, curr) : curr; - }, null); - const convexHull = turf.convex(polygonsCollection); - return convexHull? turf.difference(convexHull, mergedPolygons): null; + const polygonsCoordinates = Object.values(polygonsData).map( + (poly: PolygonPartRecordModelType) => poly.footprint.coordinates + ); + const turfPolygons = polygonsCoordinates.map((coordinate) => + turf.polygon(coordinate) + ); + const polygonsCollection = turf.featureCollection(turfPolygons); + // @ts-ignore + const mergedPolygons = polygonsCollection.features.reduce((acc, curr) => { + return acc ? turf.union(acc, curr) : curr; + }, null); + const convexHull = turf.convex(polygonsCollection); + return convexHull ? turf.difference(convexHull, mergedPolygons) : null; }; -export const shrinkExtremeCoordinatesInOuterRing = (geometry: Geometry, factor = 0.99) => { +export const shrinkExtremeCoordinatesInOuterRing = ( + geometry: Geometry, + factor = 0.99 +) => { const LAT_THRESHOLD = 84.9; const LON_THRESHOLD = 179; @@ -245,23 +295,26 @@ export const shrinkExtremeCoordinatesInOuterRing = (geometry: Geometry, factor = return processed; } - if (geometry.type === "Polygon") { + if (geometry.type === 'Polygon') { const [outer, ...holes] = geometry.coordinates; return { - type: "Polygon", - coordinates: [processRing(outer), ...holes] + type: 'Polygon', + coordinates: [processRing(outer), ...holes], } as Geometry; } - if (geometry.type === "MultiPolygon") { + if (geometry.type === 'MultiPolygon') { return { - type: "MultiPolygon", - coordinates: geometry.coordinates.map(polygon => { + type: 'MultiPolygon', + coordinates: geometry.coordinates.map((polygon) => { const [outer, ...holes] = polygon; return [processRing(outer), ...holes]; - }) + }), } as Geometry; } - throw new Error("[shrinkExtremeCoordinatesInOuterRing] Unsupported geometry type: " + geometry.type); -} \ No newline at end of file + throw new Error( + '[shrinkExtremeCoordinatesInOuterRing] Unsupported geometry type: ' + + geometry.type + ); +}; diff --git a/src/common/utils/geojson.validation.ts b/src/common/utils/geojson.validation.ts index 29e0c2ebc..501bf7f0b 100644 --- a/src/common/utils/geojson.validation.ts +++ b/src/common/utils/geojson.validation.ts @@ -6,8 +6,18 @@ import { Geometry, Position } from 'geojson'; import { geoCustomChecks } from './geo.tools'; const gpsi = require('geojson-polygon-self-intersections'); -export type severityLevel = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL'; -export type geoJSONValidation = {valid: boolean, severity_level: severityLevel, reason: string}; +export type severityLevel = + | 'TRACE' + | 'DEBUG' + | 'INFO' + | 'WARN' + | 'ERROR' + | 'FATAL'; +export type geoJSONValidation = { + valid: boolean; + severity_level: severityLevel; + reason: string; +}; export const EMPTY_JSON_STRING_VALUE = '{}'; const INTERSECTION_TOLLERANCE = 1e-11; // 0.01mm @@ -18,17 +28,17 @@ const hasTooManyVerteces = (geom: Geometry): boolean => { let totalVertices = 0; if (isValidGeometryType(geom)) { //@ts-ignore - const polygons = (geom.type === 'Polygon') ? [geom.coordinates] : geom.coordinates; + const polygons = + geom.type === 'Polygon' ? [geom.coordinates] : geom.coordinates; polygons.forEach((polygon: Position[][]) => { - polygon.forEach(ring => { + polygon.forEach((ring) => { totalVertices += ring.length; }); }); - } - return totalVertices >= MAX_VERTECES ; -} + return totalVertices >= MAX_VERTECES; +}; // export const hasSelfIntersections = (json: Geometry): boolean => { // return kinks(json as any).features.length > 0; @@ -36,74 +46,108 @@ const hasTooManyVerteces = (geom: Geometry): boolean => { export const hasSelfIntersections = (json: Geometry): boolean => { //@ts-ignore - const filterFunc = (isect, ring0, edge0, start0, end0, frac0, ring1, edge1, start1, end1, frac1, unique) => { + const filterFunc = ( + isect, + ring0, + edge0, + start0, + end0, + frac0, + ring1, + edge1, + start1, + end1, + frac1, + unique + ) => { const firstLine = lineString([start0, end0]); const secondLine = lineString([start1, end1]); - const isPointOnFirstLine = booleanPointOnLine(isect, firstLine, { epsilon: INTERSECTION_TOLLERANCE }); - const isPointOnSecondLine = booleanPointOnLine(isect, secondLine, { epsilon: INTERSECTION_TOLLERANCE }); + const isPointOnFirstLine = booleanPointOnLine(isect, firstLine, { + epsilon: INTERSECTION_TOLLERANCE, + }); + const isPointOnSecondLine = booleanPointOnLine(isect, secondLine, { + epsilon: INTERSECTION_TOLLERANCE, + }); if (isPointOnFirstLine && isPointOnSecondLine) { console.log('Intersection point(by gpsi): ', isect); - return { isect, ring0, edge0, start0, end0, frac0, ring1, edge1, start1, end1, frac1, unique }; + return { + isect, + ring0, + edge0, + start0, + end0, + frac0, + ring1, + edge1, + start1, + end1, + frac1, + unique, + }; } return undefined; - } + }; const isects = gpsi( { - type: "Feature", + type: 'Feature', geometry: json, }, - filterFunc, + filterFunc ); const isectsLength = isects.filter((obj: any) => obj !== undefined).length; - + return isectsLength > 0; -} +}; const isValidGeometryType = (json: Geometry): boolean => { - return json.type === 'Polygon' || json.type === 'MultiPolygon'; -} + return json.type === 'Polygon' || json.type === 'MultiPolygon'; +}; const isAllGeometryLinearRingsValid = (geom: Geometry): geoJSONValidation => { if (isValidGeometryType(geom)) { //@ts-ignore - const polygons = (geom.type === 'Polygon') ? [geom.coordinates] : geom.coordinates; - + const polygons = + geom.type === 'Polygon' ? [geom.coordinates] : geom.coordinates; + for (const polygon of polygons) { for (const ring of polygon as Position[][]) { if (ring.length < LINEARING_MIN_POSITIONS) { return { valid: false, severity_level: 'ERROR', - reason: 'geo_json-geometry-not-enough-points' + reason: 'geo_json-geometry-not-enough-points', }; } - if (ring[0][0] !== ring[ring.length - 1][0] || ring[0][1] !== ring[ring.length - 1][1]) { - return { + if ( + ring[0][0] !== ring[ring.length - 1][0] || + ring[0][1] !== ring[ring.length - 1][1] + ) { + return { valid: false, severity_level: 'ERROR', - reason: 'geo_json-geometry-not-closed-linear_ring' + reason: 'geo_json-geometry-not-closed-linear_ring', }; } } } - return { + return { valid: true, severity_level: 'INFO', - reason: '' + reason: '', }; } else { return { valid: false, severity_level: 'ERROR', - reason: 'geo_json-geometry-not-supported' + reason: 'geo_json-geometry-not-supported', }; } -} +}; // Validate coordinates within the WGS84 range (-180 to 180 for longitude, -90 to 90 for latitude) const isValidWGS84Coordinates = (geom: Geometry) => { @@ -124,7 +168,7 @@ const isValidWGS84Coordinates = (geom: Geometry) => { } } return true; - } + }; if (geom && geom.type) { if (geom.type === 'Polygon') { @@ -140,16 +184,22 @@ const isValidWGS84Coordinates = (geom: Geometry) => { } } - return true; -} + return true; +}; -export const validateGeoJSONString = (jsonValue: string, geoCustomChecks?: geoCustomChecks): geoJSONValidation => { +export const validateGeoJSONString = ( + jsonValue: string, + geoCustomChecks?: geoCustomChecks +): geoJSONValidation => { const res = { - valid: jsonValue !== undefined && jsonValue !== EMPTY_JSON_STRING_VALUE && jsonValue !== '', + valid: + jsonValue !== undefined && + jsonValue !== EMPTY_JSON_STRING_VALUE && + jsonValue !== '', severity_level: 'INFO', - reason: '' + reason: '', } as geoJSONValidation; - + try { if (res.valid) { const geoJson = JSON.parse(jsonValue); @@ -157,22 +207,22 @@ export const validateGeoJSONString = (jsonValue: string, geoCustomChecks?: geoCu return { valid: false, severity_level: 'ERROR', - reason: 'not-geo_json' - } + reason: 'not-geo_json', + }; } if (!isValidGeometryType(geoJson)) { return { valid: false, severity_level: 'ERROR', - reason: 'geo_json-geometry-not-supported' - } + reason: 'geo_json-geometry-not-supported', + }; } if (!isValidWGS84Coordinates(geoJson)) { return { valid: false, severity_level: 'ERROR', - reason: 'geo_json-geometry-coordinates-not-wgs84' - } + reason: 'geo_json-geometry-coordinates-not-wgs84', + }; } const linearRingsCheck = isAllGeometryLinearRingsValid(geoJson); if (linearRingsCheck.severity_level !== 'INFO') { @@ -182,34 +232,36 @@ export const validateGeoJSONString = (jsonValue: string, geoCustomChecks?: geoCu return { valid: true, severity_level: 'WARN', - reason: 'geo_json-too_many_verteces' - } + reason: 'geo_json-too_many_verteces', + }; } if (hasSelfIntersections(geoJson)) { return { valid: false, severity_level: 'ERROR', - reason: 'geo_json-has_self_intersections' - } + reason: 'geo_json-has_self_intersections', + }; } - let validationArr: geoJSONValidation[] = [] as unknown as geoJSONValidation[]; - + let validationArr: geoJSONValidation[] = + [] as unknown as geoJSONValidation[]; + if (geoCustomChecks) { - validationArr = geoCustomChecks.validationFunc.map((func) => func(geoJson, geoCustomChecks.validationFuncArgs)).filter(u => u !== undefined) as geoJSONValidation[]; + validationArr = geoCustomChecks.validationFunc + .map((func) => func(geoJson, geoCustomChecks.validationFuncArgs)) + .filter((u) => u !== undefined) as geoJSONValidation[]; } if (validationArr && validationArr.length) { return validationArr[0]; } } - } - catch (e) { + } catch (e) { return { valid: false, severity_level: 'ERROR', - reason: 'not-json' + reason: 'not-json', }; } return res; -}; \ No newline at end of file +}; diff --git a/src/discrete-layer/components/bbox/bbox-corner-indicator.tsx b/src/discrete-layer/components/bbox/bbox-corner-indicator.tsx index 31a8bc7f6..1bdaa5154 100644 --- a/src/discrete-layer/components/bbox/bbox-corner-indicator.tsx +++ b/src/discrete-layer/components/bbox/bbox-corner-indicator.tsx @@ -102,10 +102,10 @@ export const BBoxCorner: React.FC = ({ className, }) => { const classes = useStyle(); - const bboxCorner = useMemo(() => getCornerClass(classes, corner), [ - classes, - corner, - ]); + const bboxCorner = useMemo( + () => getCornerClass(classes, corner), + [classes, corner] + ); return (
); diff --git a/src/discrete-layer/components/catalog-tree/catalog-tree.css b/src/discrete-layer/components/catalog-tree/catalog-tree.css index f990bbfe4..b91cfba86 100644 --- a/src/discrete-layer/components/catalog-tree/catalog-tree.css +++ b/src/discrete-layer/components/catalog-tree/catalog-tree.css @@ -3,7 +3,9 @@ margin: 12px 12px 0 12px; } -body[dir='rtl'] .catalogContainer .ReactVirtualized__Grid__innerScrollContainer { +body[dir='rtl'] + .catalogContainer + .ReactVirtualized__Grid__innerScrollContainer { margin-right: -12px; } diff --git a/src/discrete-layer/components/catalog-tree/catalog-tree.tsx b/src/discrete-layer/components/catalog-tree/catalog-tree.tsx index 197afe770..ace458741 100644 --- a/src/discrete-layer/components/catalog-tree/catalog-tree.tsx +++ b/src/discrete-layer/components/catalog-tree/catalog-tree.tsx @@ -1,12 +1,7 @@ /* eslint-disable */ /* tslint:disable */ -import React, { - useEffect, - useState, - useMemo, - useCallback, -} from 'react'; +import React, { useEffect, useState, useMemo, useCallback } from 'react'; import { observer } from 'mobx-react'; import { changeNodeAtPath, @@ -50,13 +45,14 @@ interface CatalogTreeComponentProps { isFiltered: boolean; } -export const CatalogTreeComponent: React.FC = observer( - ({ refresh, isFiltered }) => { +export const CatalogTreeComponent: React.FC = + observer(({ refresh, isFiltered }) => { const store = useStore(); const theme = useTheme(); const [hoveredNode, setHoveredNode] = useState(); const [isHoverAllowed, setIsHoverAllowed] = useState(true); - const [isBestInEditDialogOpen, setBestInEditDialogOpen] = useState(false); + const [isBestInEditDialogOpen, setBestInEditDialogOpen] = + useState(false); const intl = useIntl(); const { isLoading: loading, @@ -75,7 +71,10 @@ export const CatalogTreeComponent: React.FC = observe ), }); @@ -94,10 +93,10 @@ export const CatalogTreeComponent: React.FC = observe useEffect(() => { void store.catalogTreeStore.initTree(); }, []); - + const areActionsAllowed = (rowInfo: ExtendedNodeData) => { return isValidLayerMetadata(rowInfo.node as LayerMetadataMixedUnion); - } + }; const entityPermittedActions = useMemo(() => { const entityActions: Record = {}; @@ -108,7 +107,8 @@ export const CatalogTreeComponent: React.FC = observe 'VectorBestRecord', 'QuantizedMeshBestRecord', ].forEach((entityName) => { - const allGroupsActions = store.actionDispatcherStore.getEntityActionGroups(entityName); + const allGroupsActions = + store.actionDispatcherStore.getEntityActionGroups(entityName); const permittedGroupsActions = allGroupsActions.map((actionGroup) => { return { titleTranslationId: actionGroup.titleTranslationId, @@ -142,71 +142,75 @@ export const CatalogTreeComponent: React.FC = observe }); const currentTreeData = useMemo(() => { - return !isFiltered - ? treeRawData - : getFilteredCatalogTreeData().length > 0 - ? getFilteredCatalogTreeData() - : treeRawData; + return !isFiltered + ? treeRawData + : getFilteredCatalogTreeData().length > 0 + ? getFilteredCatalogTreeData() + : treeRawData; }, [treeRawData, isFiltered]); - const handleRowClick = useCallback((evt: MouseEvent, rowInfo: ExtendedNodeData) => { - if (!rowInfo.node.isGroup) { - let newTreeData = currentTreeData; - if (!evt.ctrlKey) { - // Remove prev selection - const selection = find({ - treeData: newTreeData, - getNodeKey: keyFromTreeIndex, - searchMethod: (data) => data.node.isSelected, - }); - - selection.matches.forEach(match => { - const selRowInfo = getNodeAtPath({ + const handleRowClick = useCallback( + (evt: MouseEvent, rowInfo: ExtendedNodeData) => { + if (!rowInfo.node.isGroup) { + let newTreeData = currentTreeData; + if (!evt.ctrlKey) { + // Remove prev selection + const selection = find({ treeData: newTreeData, - path: match.path, getNodeKey: keyFromTreeIndex, - // ignoreCollapsed: false, + searchMethod: (data) => data.node.isSelected, }); - newTreeData = changeNodeAtPath({ - treeData: newTreeData, - path: match.path, - newNode: { - ...selRowInfo?.node, - isSelected: false - }, - getNodeKey: keyFromTreeIndex + selection.matches.forEach((match) => { + const selRowInfo = getNodeAtPath({ + treeData: newTreeData, + path: match.path, + getNodeKey: keyFromTreeIndex, + // ignoreCollapsed: false, + }); + + newTreeData = changeNodeAtPath({ + treeData: newTreeData, + path: match.path, + newNode: { + ...selRowInfo?.node, + isSelected: false, + }, + getNodeKey: keyFromTreeIndex, + }); }); + } + + newTreeData = changeNodeAtPath({ + treeData: newTreeData, + path: rowInfo.path, + newNode: { + ...rowInfo.node, + isSelected: !rowInfo.node.isSelected, + }, + getNodeKey: keyFromTreeIndex, }); - } - newTreeData = changeNodeAtPath({ - treeData: newTreeData, - path: rowInfo.path, - newNode: { - ...rowInfo.node, - isSelected: !rowInfo.node.isSelected - }, - getNodeKey: keyFromTreeIndex - }); + // console.log('*** MOUSE ROW CLICK *****', (evt.target as any).className); + if ( + evt.target !== null && + actionDismissibleRegex.test((evt.target as any).className) + ) { + setHoveredNode(undefined); + setIsHoverAllowed(false); + } - // console.log('*** MOUSE ROW CLICK *****', (evt.target as any).className); - if (evt.target !== null && actionDismissibleRegex.test((evt.target as any).className)) { - setHoveredNode(undefined); - setIsHoverAllowed(false); + setCatalogTreeData(newTreeData, isFiltered); + store.discreteLayersStore.selectLayer(rowInfo.node as ILayerImage); } - - setCatalogTreeData(newTreeData, isFiltered); - store.discreteLayersStore.selectLayer( - rowInfo.node as ILayerImage - ); - } - }, [treeRawData, isFiltered]); + }, + [treeRawData, isFiltered] + ); const dispatchAction = (action: Record): void => { store.actionDispatcherStore.dispatchAction({ action: action.action, - data: action.data + data: action.data, } as IDispatchAction); }; @@ -215,7 +219,9 @@ export const CatalogTreeComponent: React.FC = observe ); } @@ -227,7 +233,7 @@ export const CatalogTreeComponent: React.FC = observe {!loading && ( { + onChange={(treeData) => { // console.log('****** UPDATE TREE DATA ******'); setCatalogTreeData(treeData, isFiltered); }} @@ -239,9 +245,9 @@ export const CatalogTreeComponent: React.FC = observe return false; // return !nextParent || nextParent.isDirectory }} - generateNodeProps={rowInfo => ({ + generateNodeProps={(rowInfo) => ({ onClick: (e: MouseEvent) => { - handleRowClick(e, rowInfo) + handleRowClick(e, rowInfo); }, onMouseOver: (evt: MouseEvent) => { if (!rowInfo.node.isGroup && isHoverAllowed) { @@ -268,32 +274,48 @@ export const CatalogTreeComponent: React.FC = observe setHoveredNode(undefined); } }, - style: rowInfo.node.isGroup ? (()=> { - return (rowInfo?.node.children as ILayerImage[]).some((elem) => elem.footprintShown || elem.layerImageShown || (elem as any).polygonPartsShown ) ? {color: theme.primary, fontWeight: '600'} : {}; - })() : getTextStyle(rowInfo.node, 'color'), + style: rowInfo.node.isGroup + ? (() => { + return (rowInfo?.node.children as ILayerImage[]).some( + (elem) => + elem.footprintShown || + elem.layerImageShown || + (elem as any).polygonPartsShown + ) + ? { color: theme.primary, fontWeight: '600' } + : {}; + })() + : getTextStyle(rowInfo.node, 'color'), icons: rowInfo.node.isGroup ? [] : [ { dispatchAction({ action: UserAction.SYSTEM_CALLBACK_SHOWFOOTPRINT, - data: { selectedLayer: { ...data, footprintShown: value } } + data: { + selectedLayer: { ...data, footprintShown: value }, + }, }); }} />, { dispatchAction({ action: UserAction.SYSTEM_CALLBACK_SHOWLAYERIMAGE, - data: { selectedLayer: { ...data, layerImageShown: value } } + data: { + selectedLayer: { + ...data, + layerImageShown: value, + }, + }, }); }} />, = observe onClick={(data: ILayerImage, value: boolean) => { dispatchAction({ action: UserAction.SYSTEM_CALLBACK_SHOWPOLYGONPARTS, - data: { selectedLayer: {...data, polygonPartsShown: value } } + data: { + selectedLayer: { + ...data, + polygonPartsShown: value, + }, + }, }); }} />, ], buttons: [ <> - { - areActionsAllowed(rowInfo) && + {areActionsAllowed(rowInfo) && hoveredNode !== undefined && - hoveredNode.id === rowInfo.node.id && - hoveredNode.parentPath === rowInfo.path.slice(0, -1).toString() && ( + hoveredNode.id === rowInfo.node.id && + hoveredNode.parentPath === + rowInfo.path.slice(0, -1).toString() && ( = observe entity={rowInfo.node.__typename} actionHandler={dispatchAction} /> - ) - } + )} , ], })} /> )} - { - isBestInEditDialogOpen && + {isBestInEditDialogOpen && ( - } + )} ); - } -); + }); diff --git a/src/discrete-layer/components/dialogs/best-in-edit.dialog.tsx b/src/discrete-layer/components/dialogs/best-in-edit.dialog.tsx index 9bb5df029..02fca55ae 100644 --- a/src/discrete-layer/components/dialogs/best-in-edit.dialog.tsx +++ b/src/discrete-layer/components/dialogs/best-in-edit.dialog.tsx @@ -1,7 +1,13 @@ import React, { useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; import { DialogContent } from '@material-ui/core'; -import { Button, Dialog, DialogActions, DialogTitle, IconButton } from '@map-colonies/react-core'; +import { + Button, + Dialog, + DialogActions, + DialogTitle, + IconButton, +} from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import './best-in-edit.dialog.css'; @@ -11,33 +17,41 @@ interface BestInEditDialogProps { onSetOpen: (open: boolean) => void; } -export const BestInEditDialog: React.FC = ({ isOpen, onSetOpen }) => { - const closeDialog = useCallback( - () => { - onSetOpen(false); - }, - [onSetOpen] - ); +export const BestInEditDialog: React.FC = ({ + isOpen, + onSetOpen, +}) => { + const closeDialog = useCallback(() => { + onSetOpen(false); + }, [onSetOpen]); return ( - + { closeDialog(); } } + onClick={(): void => { + closeDialog(); + }} /> - + - diff --git a/src/discrete-layer/components/dialogs/close-without-save.dialog.tsx b/src/discrete-layer/components/dialogs/close-without-save.dialog.tsx index 37f62a703..ed9c0eb88 100644 --- a/src/discrete-layer/components/dialogs/close-without-save.dialog.tsx +++ b/src/discrete-layer/components/dialogs/close-without-save.dialog.tsx @@ -2,7 +2,13 @@ import React, { useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; import { observer } from 'mobx-react'; import { DialogContent } from '@material-ui/core'; -import { Button, Dialog, DialogActions, DialogTitle, IconButton } from '@map-colonies/react-core'; +import { + Button, + Dialog, + DialogActions, + DialogTitle, + IconButton, +} from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { useStore } from '../../models'; @@ -13,41 +19,55 @@ interface CloseWithoutSaveDialogProps { onSetOpen: (open: boolean) => void; } -export const CloseWithoutSaveDialog: React.FC = observer(({ isOpen, onSetOpen }) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const store = useStore(); - - const closeDialog = useCallback(() => { - onSetOpen(false); - }, [onSetOpen]); +export const CloseWithoutSaveDialog: React.FC = + observer(({ isOpen, onSetOpen }) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const store = useStore(); - const closeWithoutSaving = useCallback(() => { - onSetOpen(false); - }, [onSetOpen]); - - return ( - - - - - { closeDialog(); } } - /> - - - - - - - - - - - ); -}); + const closeDialog = useCallback(() => { + onSetOpen(false); + }, [onSetOpen]); + + const closeWithoutSaving = useCallback(() => { + onSetOpen(false); + }, [onSetOpen]); + + return ( + + + + + { + closeDialog(); + }} + /> + + + + + + + + + + + ); + }); diff --git a/src/discrete-layer/components/dialogs/file-picker.dialog.css b/src/discrete-layer/components/dialogs/file-picker.dialog.css index c2a77d5c4..f5d72d2b1 100644 --- a/src/discrete-layer/components/dialogs/file-picker.dialog.css +++ b/src/discrete-layer/components/dialogs/file-picker.dialog.css @@ -32,10 +32,10 @@ body[dir='rtl'] #filePickerDialog .MuiPopover-root { } #filePickerDialog .buttons { - display: flex; - align-self: flex-start; + display: flex; + align-self: flex-start; } #filePickerDialog .mdc-dialog__actions { justify-content: space-between; -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/dialogs/file-picker.dialog.tsx b/src/discrete-layer/components/dialogs/file-picker.dialog.tsx index 459c4dec5..5a224e84e 100644 --- a/src/discrete-layer/components/dialogs/file-picker.dialog.tsx +++ b/src/discrete-layer/components/dialogs/file-picker.dialog.tsx @@ -52,7 +52,10 @@ interface FilePickerDialogProps { } const getSuffixFromFolderChain = (folderChain: FileData[]): string => { - return BASE_PATH_SUFFIX + folderChain.map((file) => normalizePath(file.name)).join('/'); + return ( + BASE_PATH_SUFFIX + + folderChain.map((file) => normalizePath(file.name)).join('/') + ); }; export const FilePickerDialog: React.FC = observer( @@ -63,7 +66,7 @@ export const FilePickerDialog: React.FC = observer( onFilesSelection, selection: currentSelection, fetchMetaData = true, - rasterIngestionFilesTypeConfig = undefined + rasterIngestionFilesTypeConfig = undefined, }) => { const filePickerRef = useRef(null); const [files, setFiles] = useState([]); @@ -71,17 +74,27 @@ export const FilePickerDialog: React.FC = observer( const [path, setPath] = useState( getSuffixFromFolderChain(currentSelection.folderChain) ); - const [graphQLError, setGraphQLError] = useState | null>(null); + const [graphQLError, setGraphQLError] = useState | null>(null); const [selection, setSelection] = useState(currentSelection); const store = useStore(); const queryDirectory = useCallback( - () => useQuery<{ getDirectory: FileModelType[] }>(), [])(); + () => useQuery<{ getDirectory: FileModelType[] }>(), + [] + )(); const queryMetadata = useCallback( - () => useQuery<{ getFile: LayerMetadataMixedUnion }>(), [])(); + () => useQuery<{ getFile: LayerMetadataMixedUnion }>(), + [] + )(); const intl = useIntl(); useEffect(() => { - if (files.length === EMPTY || files.some((f: FileData | null) => f !== null)) { + if ( + files.length === EMPTY || + files.some((f: FileData | null) => f !== null) + ) { setFiles(new Array(NUMBER_OF_TEMPLATE_FILES).fill(null)); } queryDirectory.setQuery( @@ -89,7 +102,7 @@ export const FilePickerDialog: React.FC = observer( data: { path, type: recordType, - rasterIngestionFilesTypeConfig + rasterIngestionFilesTypeConfig, }, }) ); @@ -106,10 +119,12 @@ export const FilePickerDialog: React.FC = observer( useEffect(() => { if (queryDirectory.data) { - const dirContent = cloneDeep(queryDirectory.data.getDirectory) as FileData[]; - + const dirContent = cloneDeep( + queryDirectory.data.getDirectory + ) as FileData[]; + const shouldAutoSelectMountDir = - AUTO_SELECT_SINGLE_MOUNT as boolean && + (AUTO_SELECT_SINGLE_MOUNT as boolean) && path === BASE_PATH_SUFFIX && dirContent.length === 1 && (dirContent[0].isDir as boolean); @@ -117,7 +132,7 @@ export const FilePickerDialog: React.FC = observer( if (shouldAutoSelectMountDir) { void filePickerRef.current?.requestFileAction( FilePickerActions.OpenFiles, - {targetFile: dirContent[0], files:[dirContent[0]]} + { targetFile: dirContent[0], files: [dirContent[0]] } ); } else { setFiles(dirContent); @@ -161,7 +176,7 @@ export const FilePickerDialog: React.FC = observer( useEffect(() => { /* eslint-disable */ - if (!isEmpty(get(queryMetadata, "error"))) { + if (!isEmpty(get(queryMetadata, 'error'))) { const metadataError = [ { message: intl.formatMessage({ @@ -176,7 +191,7 @@ export const FilePickerDialog: React.FC = observer( queryError.response.errors = metadataError; const prevSelection = filePickerRef.current?.getFileSelection(); - + setSelection({ ...prevSelection, metadata: { @@ -185,7 +200,7 @@ export const FilePickerDialog: React.FC = observer( }, } as Selection); } - /* eslint-enable */ + /* eslint-enable */ }, [queryMetadata.error]); const closeDialog = useCallback(() => { diff --git a/src/discrete-layer/components/export-layer/common/export-field-label.component.tsx b/src/discrete-layer/components/export-layer/common/export-field-label.component.tsx index 0badfc8c4..5523bb38b 100644 --- a/src/discrete-layer/components/export-layer/common/export-field-label.component.tsx +++ b/src/discrete-layer/components/export-layer/common/export-field-label.component.tsx @@ -9,7 +9,11 @@ interface ExportFieldLabelProps { required?: boolean; } -const ExportFieldLabel: React.FC = ({fieldName, fieldId, required}) => { +const ExportFieldLabel: React.FC = ({ + fieldName, + fieldId, + required, +}) => { const intl = useIntl(); const fieldLabel = intl.formatMessage({ @@ -17,11 +21,15 @@ const ExportFieldLabel: React.FC = ({fieldName, fieldId, }); return ( - + {fieldLabel} - { required as boolean && * } + {(required as boolean) && ( + + * + + )} ); }; diff --git a/src/discrete-layer/components/export-layer/common/fields/export-enum-selection-field.component.tsx b/src/discrete-layer/components/export-layer/common/fields/export-enum-selection-field.component.tsx index 7825ec91c..4464111c3 100644 --- a/src/discrete-layer/components/export-layer/common/fields/export-enum-selection-field.component.tsx +++ b/src/discrete-layer/components/export-layer/common/fields/export-enum-selection-field.component.tsx @@ -29,7 +29,12 @@ const ExportEnumSelectionField: React.FC = ({ selectionIdx, fieldName, fieldValue, - fieldInfo: { placeholderValue, helperTextValue, rhfValidation, validationAgainstField }, + fieldInfo: { + placeholderValue, + helperTextValue, + rhfValidation, + validationAgainstField, + }, type, }) => { const intl = useIntl(); @@ -39,49 +44,60 @@ const ExportEnumSelectionField: React.FC = ({ const [innerValue, setInnerValue] = useState(fieldValue); const enums = enumsMap as IEnumsMapType; const locale = CONFIG.I18N.DEFAULT_LANGUAGE; - + const getFormFieldId = (name: string): string => { - return `${selectionIdx}_${name}_${selectionId}` - } + return `${selectionIdx}_${name}_${selectionId}`; + }; const fieldId = getFormFieldId(fieldName); - + useEffect(() => { const registerValidation = { ...(rhfValidation ?? {}), validate: { - ...((rhfValidation?.validate) ?? {}), - validationAgainstField: (value: unknown): string | boolean |undefined => { + ...(rhfValidation?.validate ?? {}), + validationAgainstField: ( + value: unknown + ): string | boolean | undefined => { if (typeof validationAgainstField !== 'undefined') { - return validationAgainstField.validate(value, formMethods.watch(getFormFieldId(validationAgainstField.watch))); + return validationAgainstField.validate( + value, + formMethods.watch(getFormFieldId(validationAgainstField.watch)) + ); } - } + }, }, }; - - formMethods.register(fieldId, {...registerValidation}); - + + formMethods.register(fieldId, { ...registerValidation }); + // Mitigate errors on init - formMethods.setValue(fieldId, fieldValue, { shouldValidate: fieldValue.length > NONE }); + formMethods.setValue(fieldId, fieldValue, { + shouldValidate: fieldValue.length > NONE, + }); // Revalidate fields void formMethods.trigger(); - + return (): void => { formMethods.unregister(fieldId); - } + }; }, [fieldId]); return ( - + - + ); }; diff --git a/src/discrete-layer/components/export-layer/common/fields/export-general-field.component.tsx b/src/discrete-layer/components/export-layer/common/fields/export-general-field.component.tsx index 645c7a571..5f215b9c5 100644 --- a/src/discrete-layer/components/export-layer/common/fields/export-general-field.component.tsx +++ b/src/discrete-layer/components/export-layer/common/fields/export-general-field.component.tsx @@ -18,38 +18,50 @@ const ExportGeneralFieldComponent: React.FC = ({ selectionIdx, fieldName, fieldValue, - fieldInfo: {placeholderValue, helperTextValue, rhfValidation, validationAgainstField, rows, maxLength}, + fieldInfo: { + placeholderValue, + helperTextValue, + rhfValidation, + validationAgainstField, + rows, + maxLength, + }, type, isLoading, }) => { const store = useStore(); const formMethods = useFormContext(); - + const getFormFieldId = (name: string): string => { - return `${selectionIdx}_${name}_${selectionId}` - } + return `${selectionIdx}_${name}_${selectionId}`; + }; const fieldId = getFormFieldId(fieldName); - - const placeholderVal = useMemo(() => - typeof placeholderValue !== 'undefined' - ? typeof placeholderValue === 'string' - ? placeholderValue - : placeholderValue() - : '', + + const placeholderVal = useMemo( + () => + typeof placeholderValue !== 'undefined' + ? typeof placeholderValue === 'string' + ? placeholderValue + : placeholderValue() + : '', [placeholderValue] ); - const handleOnChange = useCallback((e: React.ChangeEvent): void => { - const newFieldVal = rhfValidation?.valueAsNumber as boolean ? e.target.valueAsNumber : e.target.value; + const handleOnChange = useCallback( + (e: React.ChangeEvent): void => { + const newFieldVal = (rhfValidation?.valueAsNumber as boolean) + ? e.target.valueAsNumber + : e.target.value; - store.exportStore.setSelectionProperty( - selectionId, - fieldName, - newFieldVal - ); - - }, [store.exportStore.setSelectionProperty, selectionId, fieldName]) + store.exportStore.setSelectionProperty( + selectionId, + fieldName, + newFieldVal + ); + }, + [store.exportStore.setSelectionProperty, selectionId, fieldName] + ); const [innerValue, handleFieldChange] = useDebounceField( { handleChange: handleOnChange } as EntityFormikHandlers, @@ -61,29 +73,35 @@ const ExportGeneralFieldComponent: React.FC = ({ const registerValidation = { ...(rhfValidation ?? {}), validate: { - ...((rhfValidation?.validate) ?? {}), - validationAgainstField: (value: unknown): string | boolean |undefined => { + ...(rhfValidation?.validate ?? {}), + validationAgainstField: ( + value: unknown + ): string | boolean | undefined => { if (typeof validationAgainstField !== 'undefined') { - return validationAgainstField.validate(value, formMethods.watch(getFormFieldId(validationAgainstField.watch))); + return validationAgainstField.validate( + value, + formMethods.watch(getFormFieldId(validationAgainstField.watch)) + ); } - } + }, }, }; - - formMethods.register(fieldId, {...registerValidation}); - + + formMethods.register(fieldId, { ...registerValidation }); + // Mitigate errors on init - formMethods.setValue(fieldId, fieldValue, { shouldValidate: fieldValue.length > NONE }); + formMethods.setValue(fieldId, fieldValue, { + shouldValidate: fieldValue.length > NONE, + }); // Revalidate fields void formMethods.trigger(); - + return (): void => { formMethods.unregister(fieldId); - } + }; }, [fieldId]); - return ( = ({ invalid={!isEmpty(formMethods.errors[fieldId])} /> - + ); }; diff --git a/src/discrete-layer/components/export-layer/common/fields/export-options-field.component.tsx b/src/discrete-layer/components/export-layer/common/fields/export-options-field.component.tsx index 9d0301f57..68438ca16 100644 --- a/src/discrete-layer/components/export-layer/common/fields/export-options-field.component.tsx +++ b/src/discrete-layer/components/export-layer/common/fields/export-options-field.component.tsx @@ -23,54 +23,74 @@ const ExportOptionsField: React.FC = ({ selectionIdx, fieldName, fieldValue, - fieldInfo: { placeholderValue, helperTextValue, rhfValidation, validationAgainstField }, + fieldInfo: { + placeholderValue, + helperTextValue, + rhfValidation, + validationAgainstField, + }, valueToPresentPredicate = (value): string => value, }) => { const store = useStore(); const formMethods = useFormContext(); - const [innerValue, setInnerValue] = useState(isEmpty(fieldValue) ? defaultValue ?? '' : fieldValue); + const [innerValue, setInnerValue] = useState( + isEmpty(fieldValue) ? defaultValue ?? '' : fieldValue + ); const getFormFieldId = (name: string): string => { - return `${selectionIdx}_${name}_${selectionId}` - } + return `${selectionIdx}_${name}_${selectionId}`; + }; const fieldId = getFormFieldId(fieldName); useEffect(() => { const registerValidation = { ...(rhfValidation ?? {}), validate: { - ...((rhfValidation?.validate) ?? {}), - validationAgainstField: (value: unknown): string | boolean |undefined => { + ...(rhfValidation?.validate ?? {}), + validationAgainstField: ( + value: unknown + ): string | boolean | undefined => { if (typeof validationAgainstField !== 'undefined') { - return validationAgainstField.validate(value, formMethods.watch(getFormFieldId(validationAgainstField.watch))); + return validationAgainstField.validate( + value, + formMethods.watch(getFormFieldId(validationAgainstField.watch)) + ); } - } + }, }, }; - - formMethods.register(fieldId, {...registerValidation}); - + + formMethods.register(fieldId, { ...registerValidation }); + // Mitigate errors on init - formMethods.setValue(fieldId, innerValue, { shouldValidate: innerValue.length > NONE }); + formMethods.setValue(fieldId, innerValue, { + shouldValidate: innerValue.length > NONE, + }); // Revalidate fields void formMethods.trigger(); return (): void => { formMethods.unregister(fieldId); - } + }; }, [fieldId]); return ( - + - + ); }; diff --git a/src/discrete-layer/components/export-layer/constants.ts b/src/discrete-layer/components/export-layer/constants.ts index 99f5d5b23..d7b781704 100644 --- a/src/discrete-layer/components/export-layer/constants.ts +++ b/src/discrete-layer/components/export-layer/constants.ts @@ -1,6 +1,6 @@ export const GENERAL_FIELDS_IDX = 0; -export const GENERAL_FIELDS_ID = "0"; +export const GENERAL_FIELDS_ID = '0'; export const DEBOUNCE_PERIOD_EXPORT_FIELDS = 1000; -export const SELECTION_ERROR_CLASSNAME = 'erroredSelection'; \ No newline at end of file +export const SELECTION_ERROR_CLASSNAME = 'erroredSelection'; diff --git a/src/discrete-layer/components/export-layer/export-drawing-handler.component.tsx b/src/discrete-layer/components/export-layer/export-drawing-handler.component.tsx index fd6430d93..199f959b1 100644 --- a/src/discrete-layer/components/export-layer/export-drawing-handler.component.tsx +++ b/src/discrete-layer/components/export-layer/export-drawing-handler.component.tsx @@ -14,7 +14,9 @@ import { useStore } from '../../models'; import { applyFactor } from '../helpers/layersUtils'; const DRAWING_MATERIAL_OPACITY = 0.5; -const DRAWING_MATERIAL_COLOR = CesiumColor.CYAN.withAlpha(DRAWING_MATERIAL_OPACITY); +const DRAWING_MATERIAL_COLOR = CesiumColor.CYAN.withAlpha( + DRAWING_MATERIAL_OPACITY +); export interface IDrawingState { drawing: boolean; @@ -25,7 +27,7 @@ const ExportDrawingHandler: React.FC = observer(() => { const store = useStore(); const cesiumViewer = useCesiumMap(); const { drawing, type } = store.exportStore.drawingState as IDrawingState; - + useEffect(() => { return (): void => { store.exportStore.resetDrawingState(); @@ -35,8 +37,8 @@ const ExportDrawingHandler: React.FC = observer(() => { useEffect(() => { if (store.exportStore.hasExportPreviewed) { const selectedRoi = store.exportStore.geometrySelectionsCollection; - const features = [ ...selectedRoi.features ]; - + const features = [...selectedRoi.features]; + // *********************************************************************************************************** // ***** Currentlty exported layer footprint not added to calculation of export preview, might be reconsidered // *********************************************************************************************************** diff --git a/src/discrete-layer/components/export-layer/export-entity-selections-fields/dem-selection-field.component.tsx b/src/discrete-layer/components/export-layer/export-entity-selections-fields/dem-selection-field.component.tsx index 996e29b82..59136cc14 100644 --- a/src/discrete-layer/components/export-layer/export-entity-selections-fields/dem-selection-field.component.tsx +++ b/src/discrete-layer/components/export-layer/export-entity-selections-fields/dem-selection-field.component.tsx @@ -1,5 +1,7 @@ import React, { useContext } from 'react'; -import EnumsMapContext, { IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import EnumsMapContext, { + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { useStore } from '../../../models'; import ExportGeneralFieldComponent from '../common/fields/export-general-field.component'; import ExportOptionsField from '../common/fields/export-options-field.component'; @@ -10,7 +12,9 @@ import { ExportFieldProps } from '../types/interfaces'; const DemSelectionField: React.FC = (props) => { const { fieldName, selectionIdx } = props; - const {exportStore: { layerToExport, geometrySelectionsCollection }} = useStore(); + const { + exportStore: { layerToExport, geometrySelectionsCollection }, + } = useStore(); const { enumsMap } = useContext(EnumsMapContext); const enums = enumsMap as IEnumsMapType; @@ -23,62 +27,71 @@ const DemSelectionField: React.FC = (props) => { ); } case 'projection': { - const PROJECTION_OPTIONS = [DEMExportProjection.WGS84, DEMExportProjection.UTM]; + const PROJECTION_OPTIONS = [ + DEMExportProjection.WGS84, + DEMExportProjection.UTM, + ]; const DEFAULT_PROJECTION = DEMExportProjection.WGS84; - const valueFromEntityProps = (get( - geometrySelectionsCollection.features[selectionIdx - 1], - `properties.projection` - ) as number | undefined)?.toString(); + const valueFromEntityProps = ( + get( + geometrySelectionsCollection.features[selectionIdx - 1], + `properties.projection` + ) as number | undefined + )?.toString(); return ( <> - + - ) + ); } case 'resampleMethod': { - const options = getEnumRealValues(enums, "ResamplingMethod"); + const options = getEnumRealValues(enums, 'ResamplingMethod'); const defaultResamplingMethod = 'near'; - const valueFromEntityProps = (get( - geometrySelectionsCollection.features[selectionIdx - 1], - `properties.resampleMethod` - ) as number | undefined)?.toString(); + const valueFromEntityProps = ( + get( + geometrySelectionsCollection.features[selectionIdx - 1], + `properties.resampleMethod` + ) as number | undefined + )?.toString(); return ( <> - + - ) + ); } case 'dataType': { - const options = getEnumRealValues(enums, "DEMDataType"); + const options = getEnumRealValues(enums, 'DEMDataType'); const defaultValueFromLayer = get(layerToExport, 'dataType') as string; const defaultValue = get(enums, defaultValueFromLayer).realValue; - const valueFromEntityProps = (get( - geometrySelectionsCollection.features[selectionIdx - 1], - `properties.dataType` - ) as number | undefined)?.toString(); - + const valueFromEntityProps = ( + get( + geometrySelectionsCollection.features[selectionIdx - 1], + `properties.dataType` + ) as number | undefined + )?.toString(); + return ( <> - + - ) + ); } case 'description': { return ( diff --git a/src/discrete-layer/components/export-layer/export-entity-selections-fields/raster-selection-field.component.tsx b/src/discrete-layer/components/export-layer/export-entity-selections-fields/raster-selection-field.component.tsx index bd8ad7a83..a9e3e764c 100644 --- a/src/discrete-layer/components/export-layer/export-entity-selections-fields/raster-selection-field.component.tsx +++ b/src/discrete-layer/components/export-layer/export-entity-selections-fields/raster-selection-field.component.tsx @@ -17,23 +17,26 @@ const RasterSelectionField: React.FC = (props) => { switch (fieldName) { case 'minResolutionDeg': { - const currentRes = (get( - exportStore.geometrySelectionsCollection.features[selectionIdx - 1], - `properties.minResolutionDeg` - ) as number | undefined)?.toString(); + const currentRes = ( + get( + exportStore.geometrySelectionsCollection.features[selectionIdx - 1], + `properties.minResolutionDeg` + ) as number | undefined + )?.toString(); - const maxResFromLayer = (get( - exportStore.layerToExport, - `maxResolutionDeg` - ) as number | undefined)?.toString(); + const maxResFromLayer = ( + get(exportStore.layerToExport, `maxResolutionDeg`) as number | undefined + )?.toString(); const getValidResolutions = (): string[] => { return Object.values(ZOOM_LEVELS_TABLE) - .map((res) => res.toString()) - .filter((res) => { - return typeof maxResFromLayer !== 'undefined' ? +res >= +maxResFromLayer : res; - }) - } + .map((res) => res.toString()) + .filter((res) => { + return typeof maxResFromLayer !== 'undefined' + ? +res >= +maxResFromLayer + : res; + }); + }; const options = getValidResolutions(); @@ -46,52 +49,75 @@ const RasterSelectionField: React.FC = (props) => { const [integers, decimals] = value.split('.'); const substrStart = 0; const numberOfDecimals = 8; - const resString = `${integers}.${decimals.substring(substrStart, numberOfDecimals)}`; - const zoomLevel = degreesPerPixelToZoomLevel(Number.parseFloat(value)); - return `${resString.padEnd(MAX_PADDING_LENGTH + (MAX_VALUE_LENGTH - resString.length),' ')}${zoomLevel}`; + const resString = `${integers}.${decimals.substring( + substrStart, + numberOfDecimals + )}`; + const zoomLevel = degreesPerPixelToZoomLevel( + Number.parseFloat(value) + ); + return `${resString.padEnd( + MAX_PADDING_LENGTH + (MAX_VALUE_LENGTH - resString.length), + ' ' + )}${zoomLevel}`; }} - {...props} /> + {...props} + /> - ) + ); } case 'maxResolutionDeg': { - const currentRes = (get( - exportStore.layerToExport, - fieldInfo.defaultsFromEntityField as LayerMetadataMixedUnionKeys - ) as number).toString(); + const currentRes = ( + get( + exportStore.layerToExport, + fieldInfo.defaultsFromEntityField as LayerMetadataMixedUnionKeys + ) as number + ).toString(); - const resFromEntityProps = (get( - exportStore.geometrySelectionsCollection.features[selectionIdx - 1], - `properties.maxResolutionDeg` - ) as number | undefined)?.toString(); + const resFromEntityProps = ( + get( + exportStore.geometrySelectionsCollection.features[selectionIdx - 1], + `properties.maxResolutionDeg` + ) as number | undefined + )?.toString(); const getValidResolutions = (): string[] => { return Object.values(ZOOM_LEVELS_TABLE) - .map((res) => res.toString()) - .filter((res) => { - const resolutionPrecision = currentRes.split('.')[1].length; - const samePrecisionResFromTable = Number(res).toFixed( - resolutionPrecision - ); - - return Number(currentRes) <= Number(samePrecisionResFromTable); - }) - } + .map((res) => res.toString()) + .filter((res) => { + const resolutionPrecision = currentRes.split('.')[1].length; + const samePrecisionResFromTable = + Number(res).toFixed(resolutionPrecision); + + return Number(currentRes) <= Number(samePrecisionResFromTable); + }); + }; return ( <> - { const [integers, decimals] = value.split('.'); const substrStart = 0; const numberOfDecimals = 8; - const resString = `${integers}.${decimals.substring(substrStart, numberOfDecimals)}`; - const zoomLevel = degreesPerPixelToZoomLevel(Number.parseFloat(value)); - return `${resString.padEnd(MAX_PADDING_LENGTH + (MAX_VALUE_LENGTH - resString.length),' ')}${zoomLevel}`; + const resString = `${integers}.${decimals.substring( + substrStart, + numberOfDecimals + )}`; + const zoomLevel = degreesPerPixelToZoomLevel( + Number.parseFloat(value) + ); + return `${resString.padEnd( + MAX_PADDING_LENGTH + (MAX_VALUE_LENGTH - resString.length), + ' ' + )}${zoomLevel}`; }} - {...props} /> + {...props} + /> ); } diff --git a/src/discrete-layer/components/export-layer/export-layer-footer.component.tsx b/src/discrete-layer/components/export-layer/export-layer-footer.component.tsx index 68d85e01e..df83c132d 100644 --- a/src/discrete-layer/components/export-layer/export-layer-footer.component.tsx +++ b/src/discrete-layer/components/export-layer/export-layer-footer.component.tsx @@ -22,8 +22,8 @@ interface ExportLayerFooterProps { } export enum ExportMode { - PREVIEW = "preview", - EXPORT = "export", + PREVIEW = 'preview', + EXPORT = 'export', } const NONE = 0; @@ -32,18 +32,32 @@ const SERVICE_ERROR_IDX = -2; const GENERAL_ERROR_IDX = -3; const NOT_AVAILABLE_TEXT = 'N/A'; -const ExportFormValidationErrors: React.FC<{errors: FieldErrors>}> = ({errors}) => { +const ExportFormValidationErrors: React.FC<{ + errors: FieldErrors>; +}> = ({ errors }) => { const intl = useIntl(); - const [validationErrors, setValidationErrors] = useState>(new Map()); - - const selectionText = intl.formatMessage({ id: 'export-layer.selection-index.text' }); - const generalFieldsText = intl.formatMessage({ id: 'export-layer.generalFields.text' }); - const importedFileErrorTitle = intl.formatMessage({ id: 'export-layer.fileError.text' }); - const serviceErrorTitle = intl.formatMessage({ id: 'export-layer.serviceError.text' }); - const generalErrorTitle = intl.formatMessage({ id: 'export-layer.generalError.text' }); + const [validationErrors, setValidationErrors] = useState< + Map + >(new Map()); + + const selectionText = intl.formatMessage({ + id: 'export-layer.selection-index.text', + }); + const generalFieldsText = intl.formatMessage({ + id: 'export-layer.generalFields.text', + }); + const importedFileErrorTitle = intl.formatMessage({ + id: 'export-layer.fileError.text', + }); + const serviceErrorTitle = intl.formatMessage({ + id: 'export-layer.serviceError.text', + }); + const generalErrorTitle = intl.formatMessage({ + id: 'export-layer.generalError.text', + }); const getSelectionKey = (selectionIdx: string): string => { - switch(+selectionIdx) { + switch (+selectionIdx) { case GENERAL_FIELDS_IDX: return generalFieldsText; case FILE_ERROR_IDX: @@ -59,19 +73,28 @@ const ExportFormValidationErrors: React.FC<{errors: FieldErrors { if (!isEmpty(errors)) { - const errorsBySelection: Map = new Map(); + const errorsBySelection: Map = new Map< + string, + string[] + >(); Object.entries(errors).forEach(([erroredFieldName, errorMsg]) => { const [selectionIdx, fieldName] = erroredFieldName.split('_'); - const fieldLabel = intl.formatMessage({ id: `export-layer.${fieldName}.field` }); + const fieldLabel = intl.formatMessage({ + id: `export-layer.${fieldName}.field`, + }); const selectionKey = getSelectionKey(selectionIdx); - const currentSelectionErrors = errorsBySelection.get(selectionKey) ?? []; + const currentSelectionErrors = + errorsBySelection.get(selectionKey) ?? []; const newSelectionError = +selectionIdx > GENERAL_FIELDS_IDX ? `${fieldLabel}: ${errorMsg?.message as string}` - : (errorMsg?.message as string) - - errorsBySelection.set(selectionKey,[...currentSelectionErrors, newSelectionError]); + : (errorMsg?.message as string); + + errorsBySelection.set(selectionKey, [ + ...currentSelectionErrors, + newSelectionError, + ]); }); setValidationErrors(errorsBySelection); @@ -81,212 +104,260 @@ const ExportFormValidationErrors: React.FC<{errors: FieldErrors - {validationErrors.size > NONE && + + {validationErrors.size > NONE && Array.from(validationErrors).map(([key, val], i) => { - return - {key}: - {val.map(error => {error})} + return ( + + + {key}: + + {val.map((error) => ( + + {error} + + ))} - }) - } + ); + })} - ) -} - -const ExportLayerFooter: React.FC = observer(({ handleTabViewChange, onExportSuccess }) => { - const { formState, handleSubmit } = useFormContext(); - const { exportStore, actionDispatcherStore } = useStore(); - const intl = useIntl(); - const [insufficientSpaceError, setIsInsufficientSpaceError] = useState(); - const mode = exportStore.hasExportPreviewed ? ExportMode.EXPORT : ExportMode.PREVIEW; - - const { data: freeDiskSpaceRes, loading: isExportFreeDiskSpaceLoading } = useGetFreeDiskSpace(); - - const { - setSelection: setExportDataToEstimateSize, - data: exportSizeEstimationRes, - loading: isExportSizeEstimationLoading - } = useEstimatedSize(); - - const [exportSizeEstimation, setExportSizeEstimation] = useState(); - - const { - setFormValues: setFormValuesToQuery, - data: exportTriggerRes, - error: exportTriggerError, - loading: isExportTriggerLoading, - } = useExportTrigger(); - - const exportTriggerErrorMsg = get(exportTriggerError, 'response.errors[0].serverResponse.data.message') as string | undefined; - - useEffect(() => { - if (typeof exportTriggerErrorMsg !== 'undefined') { - const issuedSelection = extractJsonObjFromString(exportTriggerErrorMsg); - - if (typeof issuedSelection !== 'undefined') { - const issuedSelectionId = exportStore.getFeatureIdByGeom(issuedSelection); - exportStore.setServerErroredSelectionId(issuedSelectionId); - } - - } else { - exportStore.setServerErroredSelectionId(undefined); - } - }, [exportTriggerErrorMsg]); - - useEffect(() => { - setExportSizeEstimation(undefined); - }, [exportStore.geometrySelectionsCollection]); - - useEffect(() => { - setExportSizeEstimation(exportSizeEstimationRes); - }, [exportSizeEstimationRes]); - - useEffect(() => { - if (typeof exportSizeEstimation === 'number' && typeof freeDiskSpaceRes === 'number') { - if (exportSizeEstimation > freeDiskSpaceRes) { - const insufficientSizeErrorText = intl.formatMessage({ id: 'export-layer.insufficient-space.error' }); - setIsInsufficientSpaceError(insufficientSizeErrorText); + ); +}; + +const ExportLayerFooter: React.FC = observer( + ({ handleTabViewChange, onExportSuccess }) => { + const { formState, handleSubmit } = useFormContext(); + const { exportStore, actionDispatcherStore } = useStore(); + const intl = useIntl(); + const [insufficientSpaceError, setIsInsufficientSpaceError] = useState< + string | undefined + >(); + const mode = exportStore.hasExportPreviewed + ? ExportMode.EXPORT + : ExportMode.PREVIEW; + + const { data: freeDiskSpaceRes, loading: isExportFreeDiskSpaceLoading } = + useGetFreeDiskSpace(); + + const { + setSelection: setExportDataToEstimateSize, + data: exportSizeEstimationRes, + loading: isExportSizeEstimationLoading, + } = useEstimatedSize(); + + const [exportSizeEstimation, setExportSizeEstimation] = useState< + number | null + >(); + + const { + setFormValues: setFormValuesToQuery, + data: exportTriggerRes, + error: exportTriggerError, + loading: isExportTriggerLoading, + } = useExportTrigger(); + + const exportTriggerErrorMsg = get( + exportTriggerError, + 'response.errors[0].serverResponse.data.message' + ) as string | undefined; + + useEffect(() => { + if (typeof exportTriggerErrorMsg !== 'undefined') { + const issuedSelection = extractJsonObjFromString( + exportTriggerErrorMsg + ); + + if (typeof issuedSelection !== 'undefined') { + const issuedSelectionId = + exportStore.getFeatureIdByGeom(issuedSelection); + exportStore.setServerErroredSelectionId(issuedSelectionId); + } } else { - setIsInsufficientSpaceError(undefined); + exportStore.setServerErroredSelectionId(undefined); } - } - }, [exportSizeEstimation, freeDiskSpaceRes]); - - useEffect(() => { - if (exportStore.hasExportPreviewed) { - setExportDataToEstimateSize(exportStore.geometrySelectionsCollection); - } - }, [exportStore.hasExportPreviewed]); - - useEffect(() => { - setIsInsufficientSpaceError(undefined); - }, [exportStore.geometrySelectionsCollection]); - - useEffect(() => { - if (typeof exportTriggerRes !== 'undefined' && typeof exportTriggerRes.jobId !== 'undefined') { - onExportSuccess(exportTriggerRes.jobId); - } - }, [exportTriggerRes]); - - const formattedFileError = - exportStore.importedFileError !== null - ? { [`${FILE_ERROR_IDX}_`]: { message: exportStore.importedFileError } } - : {}; - - const serviceError = - exportTriggerError as boolean - ? { [`${SERVICE_ERROR_IDX}_`]: { message: exportTriggerErrorMsg as string} } - : {}; - - const insufficientSpaceErrorObj = - !isEmpty(insufficientSpaceError) - ? { [`${GENERAL_ERROR_IDX}_`]: { message: insufficientSpaceError as string } } - : {}; - - const endExportSession = useCallback(() => { - actionDispatcherStore.dispatchAction({ - action: ExportActions.END_EXPORT_SESSION, - data: {} - }); - }, []); + }, [exportTriggerErrorMsg]); + + useEffect(() => { + setExportSizeEstimation(undefined); + }, [exportStore.geometrySelectionsCollection]); + + useEffect(() => { + setExportSizeEstimation(exportSizeEstimationRes); + }, [exportSizeEstimationRes]); + + useEffect(() => { + if ( + typeof exportSizeEstimation === 'number' && + typeof freeDiskSpaceRes === 'number' + ) { + if (exportSizeEstimation > freeDiskSpaceRes) { + const insufficientSizeErrorText = intl.formatMessage({ + id: 'export-layer.insufficient-space.error', + }); + setIsInsufficientSpaceError(insufficientSizeErrorText); + } else { + setIsInsufficientSpaceError(undefined); + } + } + }, [exportSizeEstimation, freeDiskSpaceRes]); - const renderPreviewOrSubmit = useMemo((): JSX.Element => { - const handleButtonClick = (): void => { + useEffect(() => { if (exportStore.hasExportPreviewed) { - const formSubmitHandler = handleSubmit((data) => { - setFormValuesToQuery(data); - }); - - void formSubmitHandler(); - - return; + setExportDataToEstimateSize(exportStore.geometrySelectionsCollection); } + }, [exportStore.hasExportPreviewed]); + + useEffect(() => { + setIsInsufficientSpaceError(undefined); + }, [exportStore.geometrySelectionsCollection]); + + useEffect(() => { + if ( + typeof exportTriggerRes !== 'undefined' && + typeof exportTriggerRes.jobId !== 'undefined' + ) { + onExportSuccess(exportTriggerRes.jobId); + } + }, [exportTriggerRes]); + + const formattedFileError = + exportStore.importedFileError !== null + ? { [`${FILE_ERROR_IDX}_`]: { message: exportStore.importedFileError } } + : {}; + + const serviceError = (exportTriggerError as boolean) + ? { + [`${SERVICE_ERROR_IDX}_`]: { + message: exportTriggerErrorMsg as string, + }, + } + : {}; - // Handle Preview logic such as estimated size and free disk space - exportStore.setHasExportPreviewed(true); - }; - - const isExportBtnDisabled = - isEmpty(exportStore.geometrySelectionsCollection.features) || - !isEmpty(formState.errors) || - !isEmpty(insufficientSpaceError) || - isExportTriggerLoading; - - return ( - - ); - }, [mode, handleSubmit, formState, insufficientSpaceError, exportStore.geometrySelectionsCollection, isExportTriggerLoading]); - - - const sizeEstimationsContainer = useMemo(() => { - return ( - - - - {intl.formatMessage({ id: 'export-layer.freeDiskSpace.label' })} - + const insufficientSpaceErrorObj = !isEmpty(insufficientSpaceError) + ? { + [`${GENERAL_ERROR_IDX}_`]: { + message: insufficientSpaceError as string, + }, + } + : {}; - - {isExportFreeDiskSpaceLoading ? ( - - ) : typeof freeDiskSpaceRes === 'number' ? ( - formatBytes(freeDiskSpaceRes) - ) : ( - NOT_AVAILABLE_TEXT - )} + const endExportSession = useCallback(() => { + actionDispatcherStore.dispatchAction({ + action: ExportActions.END_EXPORT_SESSION, + data: {}, + }); + }, []); + + const renderPreviewOrSubmit = useMemo((): JSX.Element => { + const handleButtonClick = (): void => { + if (exportStore.hasExportPreviewed) { + const formSubmitHandler = handleSubmit((data) => { + setFormValuesToQuery(data); + }); + + void formSubmitHandler(); + + return; + } + + // Handle Preview logic such as estimated size and free disk space + exportStore.setHasExportPreviewed(true); + }; + + const isExportBtnDisabled = + isEmpty(exportStore.geometrySelectionsCollection.features) || + !isEmpty(formState.errors) || + !isEmpty(insufficientSpaceError) || + isExportTriggerLoading; + + return ( + + ); + }, [ + mode, + handleSubmit, + formState, + insufficientSpaceError, + exportStore.geometrySelectionsCollection, + isExportTriggerLoading, + ]); + + const sizeEstimationsContainer = useMemo(() => { + return ( + + + + {intl.formatMessage({ id: 'export-layer.freeDiskSpace.label' })} + + + + {isExportFreeDiskSpaceLoading ? ( + + ) : typeof freeDiskSpaceRes === 'number' ? ( + formatBytes(freeDiskSpaceRes) + ) : ( + NOT_AVAILABLE_TEXT + )} + - - - - {intl.formatMessage({ id: 'export-layer.sizeEstimation.label' })} + + + {intl.formatMessage({ id: 'export-layer.sizeEstimation.label' })} + + + + {isExportSizeEstimationLoading ? ( + + ) : typeof exportSizeEstimation === 'number' ? ( + formatBytes(exportSizeEstimation) + ) : ( + NOT_AVAILABLE_TEXT + )} + + + ); + }, [ + isExportFreeDiskSpaceLoading, + isExportSizeEstimationLoading, + freeDiskSpaceRes, + exportSizeEstimation, + ]); - - {isExportSizeEstimationLoading ? ( - - ) : typeof exportSizeEstimation === 'number' ? ( - formatBytes(exportSizeEstimation) - ) : ( - NOT_AVAILABLE_TEXT - )} - - + return ( + + > + } + /> + {sizeEstimationsContainer} + + {renderPreviewOrSubmit} + + ); - }, [ - isExportFreeDiskSpaceLoading, - isExportSizeEstimationLoading, - freeDiskSpaceRes, - exportSizeEstimation, - ]); - - return ( - - > } - /> - {sizeEstimationsContainer} - - {renderPreviewOrSubmit} - - - - ); -}); + } +); -export default ExportLayerFooter; \ No newline at end of file +export default ExportLayerFooter; diff --git a/src/discrete-layer/components/export-layer/export-layer-header.component.tsx b/src/discrete-layer/components/export-layer/export-layer-header.component.tsx index 0b2e7ed7c..866f83522 100644 --- a/src/discrete-layer/components/export-layer/export-layer-header.component.tsx +++ b/src/discrete-layer/components/export-layer/export-layer-header.component.tsx @@ -14,14 +14,13 @@ interface ExportLayerHeaderProps {} const ExportLayerHeader: React.FC = observer(() => { const store = useStore(); const layerToExport = store.exportStore.layerToExport; - const entityDescriptors = store.discreteLayersStore.entityDescriptors as EntityDescriptorModelType[]; + const entityDescriptors = store.discreteLayersStore + .entityDescriptors as EntityDescriptorModelType[]; return ( - - + + = observer(() => { ); }); -export default ExportLayerHeader; \ No newline at end of file +export default ExportLayerHeader; diff --git a/src/discrete-layer/components/export-layer/export-layer-toolbar.component.tsx b/src/discrete-layer/components/export-layer/export-layer-toolbar.component.tsx index 4781c20f8..95581658c 100644 --- a/src/discrete-layer/components/export-layer/export-layer-toolbar.component.tsx +++ b/src/discrete-layer/components/export-layer/export-layer-toolbar.component.tsx @@ -1,7 +1,15 @@ import React, { useMemo, useState } from 'react'; import { Box } from '@map-colonies/react-components'; import { observer } from 'mobx-react-lite'; -import { Checkbox, IconButton, Menu, MenuItem, MenuSurfaceAnchor, Tooltip, Typography } from '@map-colonies/react-core'; +import { + Checkbox, + IconButton, + Menu, + MenuItem, + MenuSurfaceAnchor, + Tooltip, + Typography, +} from '@map-colonies/react-core'; import { useIntl } from 'react-intl'; import { FeatureCollection, lineString } from '@turf/helpers'; import { Feature, Point } from 'geojson'; @@ -11,8 +19,9 @@ import bboxPolygon from '@turf/bbox-polygon'; import { IDispatchAction } from '../../models/actionDispatcherStore'; import { useStore } from '../../models'; import { BBoxDialog } from '../map-container/bbox.dialog'; -import useDomainExportActionsConfig, { ExportAction } from './hooks/useDomainExportActionsConfig'; - +import useDomainExportActionsConfig, { + ExportAction, +} from './hooks/useDomainExportActionsConfig'; interface ExportLayerToolbarProps { disableAll?: boolean; @@ -32,7 +41,8 @@ const MenuActionPresentor: React.FC = ({ const intl = useIntl(); const [isActionMenuOpen, setIsActionMenuOpen] = useState(false); - if (action === 'SEPARATOR' || isEmpty(action.menuActionOptions?.items)) return null; + if (action === 'SEPARATOR' || isEmpty(action.menuActionOptions?.items)) + return null; return ( <> @@ -50,7 +60,7 @@ const MenuActionPresentor: React.FC = ({ {Array.from(action.menuActionOptions.items).map( ([actionKey, value], i) => { return ( - { const actionToDispatch = { @@ -59,7 +69,8 @@ const MenuActionPresentor: React.FC = ({ }; dispatchAction(actionToDispatch); - }}> + }} + > {actionKey} @@ -68,7 +79,9 @@ const MenuActionPresentor: React.FC = ({ } )} - + = ({ action, listKey, data = {}, - dispatchAction + dispatchAction, }) => { const intl = useIntl(); const store = useStore(); - if (action === 'SEPARATOR' || typeof action.toggleExportStoreFieldOptions === 'undefined') + if ( + action === 'SEPARATOR' || + typeof action.toggleExportStoreFieldOptions === 'undefined' + ) return null; const toggleOptions = action.toggleExportStoreFieldOptions; @@ -109,7 +125,9 @@ const ToggleActionPresentor: React.FC = ({ checked={isChecked} onClick={(): void => dispatchAction({ action: action.action, data })} label={checkboxLabel} - className={`exportAction exportToggle ${action.disabled ? 'disabled' : ''} ${action.class}`} + className={`exportAction exportToggle ${ + action.disabled ? 'disabled' : '' + } ${action.class}`} key={listKey} disabled={action.disabled} /> @@ -119,13 +137,14 @@ const ToggleActionPresentor: React.FC = ({ const ActionPresentor: React.FC = (props) => { const { action, listKey, data, dispatchAction } = props; const intl = useIntl(); - - const getActionPresentorByProps = useMemo(() => { - if (action === 'SEPARATOR') { - return ; - } - const shouldRenderToggle = typeof action.toggleExportStoreFieldOptions !== 'undefined'; + const getActionPresentorByProps = useMemo(() => { + if (action === 'SEPARATOR') { + return ; + } + + const shouldRenderToggle = + typeof action.toggleExportStoreFieldOptions !== 'undefined'; const shouldRenderMenu = typeof action.menuActionOptions !== 'undefined'; let presentor: JSX.Element; @@ -151,59 +170,71 @@ const ActionPresentor: React.FC = (props) => { } /> ); - + break; } - return ( - - {presentor} - - ); - }, [action]); - + return ( + + {presentor} + + ); + }, [action]); return getActionPresentorByProps; }; -const ExportLayerToolbar: React.FC = observer(({ disableAll }) => { - const store = useStore(); - const exportStore = store.exportStore; - const exportActions = useDomainExportActionsConfig(); - - const dispatchAction = (action: Record): void => { - store.actionDispatcherStore.dispatchAction({ - action: action.action, - data: action.data, - } as IDispatchAction); - }; - - return ( - - {exportActions.map((action, i) => { - const actionToDisplay = - action === 'SEPARATOR' - ? action - : { - ...action, - disabled: disableAll as boolean || action.disabled, - }; - - return ; - })} - - { - const lineStr = lineString((selection.geojson as FeatureCollection).features.map(feature => (feature.geometry as Point).coordinates)); - const lineStrBBox = bbox(lineStr); - const selectionPolygon = bboxPolygon(lineStrBBox); - exportStore.setTempRawSelection(selectionPolygon); - }} - /> - - ); -}); +const ExportLayerToolbar: React.FC = observer( + ({ disableAll }) => { + const store = useStore(); + const exportStore = store.exportStore; + const exportActions = useDomainExportActionsConfig(); + + const dispatchAction = (action: Record): void => { + store.actionDispatcherStore.dispatchAction({ + action: action.action, + data: action.data, + } as IDispatchAction); + }; + + return ( + + {exportActions.map((action, i) => { + const actionToDisplay = + action === 'SEPARATOR' + ? action + : { + ...action, + disabled: (disableAll as boolean) || action.disabled, + }; + + return ( + + ); + })} + + { + const lineStr = lineString( + (selection.geojson as FeatureCollection).features.map( + (feature) => (feature.geometry as Point).coordinates + ) + ); + const lineStrBBox = bbox(lineStr); + const selectionPolygon = bboxPolygon(lineStrBBox); + exportStore.setTempRawSelection(selectionPolygon); + }} + /> + + ); + } +); export default ExportLayerToolbar; diff --git a/src/discrete-layer/components/export-layer/export-layer.component.css b/src/discrete-layer/components/export-layer/export-layer.component.css index 69900ca68..9b64d3cba 100644 --- a/src/discrete-layer/components/export-layer/export-layer.component.css +++ b/src/discrete-layer/components/export-layer/export-layer.component.css @@ -62,7 +62,6 @@ width: 100%; } - .exportAction.exportToggle > label { width: 3rem; } @@ -100,7 +99,7 @@ .selectionLoading { width: 80px; - height: 80px; + height: 80px; z-index: 9999; } @@ -113,18 +112,15 @@ display: flex; justify-content: center; align-items: center; - } .exportSelectionsContainer .selectionContainer:hover { box-shadow: -14px 0px 0px -12px var(--mdc-theme-text-primary-on-dark); - ; - } +} - body[dir="rtl"] .exportSelectionsContainer .selectionContainer:hover { +body[dir='rtl'] .exportSelectionsContainer .selectionContainer:hover { box-shadow: 14px 0px 0px -12px var(--mdc-theme-text-primary-on-dark); - - } +} .exportSelectionsContainer .selectionContainer .selectionIndex { margin: 0; @@ -176,7 +172,9 @@ width: 14rem; } -.exportSelectionField .exportOptionsSelect .mdc-ripple-upgraded.mdc-select__selected-text{ +.exportSelectionField + .exportOptionsSelect + .mdc-ripple-upgraded.mdc-select__selected-text { direction: ltr; overflow: hidden; } @@ -198,15 +196,15 @@ user-select: none; } .selectionContainer.backdrop::after { - content: ""; + content: ''; display: block; - position: absolute; + position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 10; - background-color: rgba(0,0,0,0.3); + background-color: rgba(0, 0, 0, 0.3); } .selectionTitleContainer { @@ -237,12 +235,13 @@ body[dir='rtl'] .exportOptionsSelect .mdc-select__dropdown-icon { left: 16px; } -.exportOptionsSelect [aria-hidden="true"] { +.exportOptionsSelect [aria-hidden='true'] { display: none; transition: none; } -.exportOptionsSelect .mdc-menu.mdc-select__menu.mdc-menu-surface.mdc-menu-surface--open { +.exportOptionsSelect + .mdc-menu.mdc-select__menu.mdc-menu-surface.mdc-menu-surface--open { max-height: 120px !important; overflow: overlay; width: 15rem; @@ -296,7 +295,7 @@ body[dir='rtl'] .exportOptionsSelect .mdc-select__dropdown-icon { display: flex; flex: 1; flex-direction: row; - background-color: rgba(5,5,5,0.1); + background-color: rgba(5, 5, 5, 0.1); padding: 4px; border-radius: 2px; height: 60px; @@ -306,7 +305,8 @@ body[dir='rtl'] .exportOptionsSelect .mdc-select__dropdown-icon { text-align: center; } -.freeDiskSpaceContainer, .sizeEstimationContainer { +.freeDiskSpaceContainer, +.sizeEstimationContainer { display: flex; justify-content: flex-start; align-items: center; @@ -317,39 +317,42 @@ body[dir='rtl'] .exportOptionsSelect .mdc-select__dropdown-icon { flex: 1; } -body[dir="rtl"] .freeDiskSpaceContainer, .sizeEstimationContainer { +body[dir='rtl'] .freeDiskSpaceContainer, +.sizeEstimationContainer { text-align: right; } -.freeDiskSpaceLabel, .sizeEstimationLabel { +.freeDiskSpaceLabel, +.sizeEstimationLabel { margin: 0; padding: 0; } -.freeDiskSpaceValue, .sizeEstimationValue { +.freeDiskSpaceValue, +.sizeEstimationValue { height: 1rem; width: 10ch; line-height: 1.4; } -.sizeEstimationLoading, .freeDiskSpaceLoading { +.sizeEstimationLoading, +.freeDiskSpaceLoading { align-self: center; } -.freeDiskSpaceLoading, .sizeEstimationLoading { +.freeDiskSpaceLoading, +.sizeEstimationLoading { width: 1rem; height: 1rem; margin-inline: 10px; } - .exportLayerSuccessContainer .mdc-dialog__surface { width: 400px; } - .exportLayerSuccessContainer .closeIcon { - font-size: 1rem; + font-size: 1rem; } .exportLayerSuccessContainer { @@ -403,4 +406,4 @@ body[dir="rtl"] .freeDiskSpaceContainer, .sizeEstimationContainer { .erroredSelection { border: 1px solid var(--mdc-theme-gc-error-high); -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/export-layer/export-layer.component.tsx b/src/discrete-layer/components/export-layer/export-layer.component.tsx index 215fd4b1a..6927476c6 100644 --- a/src/discrete-layer/components/export-layer/export-layer.component.tsx +++ b/src/discrete-layer/components/export-layer/export-layer.component.tsx @@ -21,26 +21,33 @@ interface ExportLayerComponentProps { handleTabViewChange: (tabView: TabViews) => void; } -export const ExportLayerComponent: React.FC = observer( - ({ style, handleFlyTo, handleTabViewChange }) => { +export const ExportLayerComponent: React.FC = + observer(({ style, handleFlyTo, handleTabViewChange }) => { const store = useStore(); const formMethods = useForm({ mode: 'onBlur', - reValidateMode: 'onBlur' + reValidateMode: 'onBlur', }); const layerToExport = store.exportStore.layerToExport; const finalJobId = store.exportStore.finalJobId; - + useGeneralExportBehavior(() => { if (isEmpty(store.exportStore.geometrySelectionsCollection.features)) { - if (!isPolygonContainedInLayer(store.discreteLayersStore.mapViewerExtentPolygon as Feature, layerToExport as LayerMetadataMixedUnion)){ + if ( + !isPolygonContainedInLayer( + store.discreteLayersStore.mapViewerExtentPolygon as Feature, + layerToExport as LayerMetadataMixedUnion + ) + ) { handleFlyTo(); } } }); - const {formState: { isSubmitted }} = formMethods; + const { + formState: { isSubmitted }, + } = formMethods; useEffect(() => { return (): void => { @@ -50,19 +57,24 @@ export const ExportLayerComponent: React.FC = observe } else { store.exportStore.resetFormData(); } - } + }; }, [isSubmitted]); const endExportSession = useCallback(() => { store.actionDispatcherStore.dispatchAction({ action: ExportActions.END_EXPORT_SESSION, - data: {} + data: {}, }); }, []); const tabContentByMode = (): JSX.Element => { if (!isEmpty(finalJobId)) { - return ; + return ( + + ); } return ( @@ -90,5 +102,4 @@ export const ExportLayerComponent: React.FC = observe )} ); - } -); + }); diff --git a/src/discrete-layer/components/export-layer/export-layer.finalStage.component.tsx b/src/discrete-layer/components/export-layer/export-layer.finalStage.component.tsx index 520a320e9..5b6a9c08a 100644 --- a/src/discrete-layer/components/export-layer/export-layer.finalStage.component.tsx +++ b/src/discrete-layer/components/export-layer/export-layer.finalStage.component.tsx @@ -7,51 +7,46 @@ import { Button, Tooltip, Typography } from '@map-colonies/react-core'; const ExportLayerFinalStage: React.FC<{ onClose: () => void; jobId: string; - }> = ({ onClose, jobId }) => { - const intl = useIntl(); const [hasCopied, setHasCopied] = useState(false); - const textCopyTooltip = intl.formatMessage({id: hasCopied ? 'action.copied.tooltip' : 'action.copy.tooltip'}); + const textCopyTooltip = intl.formatMessage({ + id: hasCopied ? 'action.copied.tooltip' : 'action.copy.tooltip', + }); return ( - - - {intl.formatMessage({ - id: 'export-layer.exportSuccessContainer.jobId.title', - })} - + + + {intl.formatMessage({ + id: 'export-layer.exportSuccessContainer.jobId.title', + })} + - setHasCopied(false)}> - - { - setHasCopied(true); - }} - > - - {jobId} - - - - - - - - - - + + {jobId} + + + + + + + + + + ); }; diff --git a/src/discrete-layer/components/export-layer/export-layer.highlight-selection.tsx b/src/discrete-layer/components/export-layer/export-layer.highlight-selection.tsx index aabaef113..ae42b67ab 100644 --- a/src/discrete-layer/components/export-layer/export-layer.highlight-selection.tsx +++ b/src/discrete-layer/components/export-layer/export-layer.highlight-selection.tsx @@ -1,5 +1,9 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -import { CesiumColor, CesiumConstantProperty, CesiumGeojsonLayer } from '@map-colonies/react-components'; +import { + CesiumColor, + CesiumConstantProperty, + CesiumGeojsonLayer, +} from '@map-colonies/react-components'; import { FeatureCollection } from 'geojson'; import { observer } from 'mobx-react-lite'; import React, { useEffect, useState } from 'react'; @@ -11,15 +15,22 @@ const SELECTION_OUTLINE_COLOR = CesiumColor.DODGERBLUE; const ExportLayerHighLightSelection: React.FC = observer(() => { const { exportStore } = useStore(); const { highlightedSelection } = exportStore; - const [highlightCollection, setHighlightCollection] = useState(); - + const [highlightCollection, setHighlightCollection] = + useState(); + useEffect(() => { - const highlightCollection: FeatureCollection = {type: 'FeatureCollection', features: []}; + const highlightCollection: FeatureCollection = { + type: 'FeatureCollection', + features: [], + }; if (highlightedSelection) { if (highlightedSelection.type === 'FeatureCollection') { setHighlightCollection({ ...highlightedSelection }); } else { - setHighlightCollection({...highlightCollection, features: [highlightedSelection]}); + setHighlightCollection({ + ...highlightCollection, + features: [highlightedSelection], + }); } } else { setHighlightCollection({ ...highlightCollection }); @@ -28,23 +39,25 @@ const ExportLayerHighLightSelection: React.FC = observer(() => { return ( <> - { - highlightCollection?.features && + {highlightCollection?.features && ( { - geoJsonDataSource.entities.values.forEach(item => { + geoJsonDataSource.entities.values.forEach((item) => { if (item.polyline) { - (item.polyline.width as CesiumConstantProperty).setValue(HIGHLIGHT_OUTLINE_WIDTH); + (item.polyline.width as CesiumConstantProperty).setValue( + HIGHLIGHT_OUTLINE_WIDTH + ); // @ts-ignore item.polyline.material = SELECTION_OUTLINE_COLOR; } }); }} /> - } - ); + )} + + ); }); -export default ExportLayerHighLightSelection; \ No newline at end of file +export default ExportLayerHighLightSelection; diff --git a/src/discrete-layer/components/export-layer/export-polygons-renderer.component.tsx b/src/discrete-layer/components/export-layer/export-polygons-renderer.component.tsx index 145f20169..67a604ff8 100644 --- a/src/discrete-layer/components/export-layer/export-polygons-renderer.component.tsx +++ b/src/discrete-layer/components/export-layer/export-polygons-renderer.component.tsx @@ -21,9 +21,10 @@ const SELECTION_POLYGON_LINE_WIDTH = 2; const ExportPolygonsRenderer: React.FC = observer(() => { const store = useStore(); - const exportGeometrySelections = store.exportStore.geometrySelectionsCollection; + const exportGeometrySelections = + store.exportStore.geometrySelectionsCollection; const getEntityLabel = useGetEntityLabelForDomain(); - + return ( <> { geoJsonDataSource.entities.values.forEach((item, i) => { if (item.polygon) { // @ts-ignore - (item.polygon.outlineColor as CesiumConstantProperty).setValue(CesiumColor.fromCssColorString(SELECTION_POLYGON_OUTLINE_COLOR)); - (item.polygon.outlineWidth as CesiumConstantProperty).setValue(SELECTION_POLYGON_LINE_WIDTH); - + (item.polygon.outlineColor as CesiumConstantProperty).setValue( + CesiumColor.fromCssColorString(SELECTION_POLYGON_OUTLINE_COLOR) + ); + (item.polygon.outlineWidth as CesiumConstantProperty).setValue( + SELECTION_POLYGON_LINE_WIDTH + ); + // @ts-ignore - item.polygon.material = CesiumColor.CYAN.withAlpha(SELECTION_POLYGON_OPACITY); + item.polygon.material = CesiumColor.CYAN.withAlpha( + SELECTION_POLYGON_OPACITY + ); const centerInDegrees = center( points( // @ts-ignore - ((item.polygon.hierarchy.getValue() as Record) - .positions as CesiumCartesian3[]).map((pos) => { - const cartographicPos = CesiumCartographic.fromCartesian(pos); + ( + ( + item.polygon.hierarchy.getValue() as Record< + string, + unknown + > + ).positions as CesiumCartesian3[] + ).map((pos) => { + const cartographicPos = + CesiumCartographic.fromCartesian(pos); return [ CesiumMath.toDegrees(cartographicPos.latitude), CesiumMath.toDegrees(cartographicPos.longitude), @@ -54,7 +68,10 @@ const ExportPolygonsRenderer: React.FC = observer(() => { ).geometry.coordinates; // @ts-ignore - item.position = CesiumCartesian3.fromDegrees(centerInDegrees[1], centerInDegrees[0]); // [lon, lat] + item.position = CesiumCartesian3.fromDegrees( + centerInDegrees[1], + centerInDegrees[0] + ); // [lon, lat] const label = { // eslint-disable-next-line @@ -64,7 +81,7 @@ const ExportPolygonsRenderer: React.FC = observer(() => { outlineColor: CesiumColor.BLACK, outlineWidth: 2, showBackground: true, - disableDepthTestDistance: Number.POSITIVE_INFINITY + disableDepthTestDistance: Number.POSITIVE_INFINITY, }; // @ts-ignore diff --git a/src/discrete-layer/components/export-layer/export-selection-fields-container.component.tsx b/src/discrete-layer/components/export-layer/export-selection-fields-container.component.tsx index cbdfb8433..64d1be94f 100644 --- a/src/discrete-layer/components/export-layer/export-selection-fields-container.component.tsx +++ b/src/discrete-layer/components/export-layer/export-selection-fields-container.component.tsx @@ -9,7 +9,11 @@ import { useStore } from '../../models'; import './export-layer.component.css'; import { get, isEmpty } from 'lodash'; import useGetSelectionFieldForDomain from './hooks/useGetSelectionFieldForDomain'; -import { GENERAL_FIELDS_ID, GENERAL_FIELDS_IDX, SELECTION_ERROR_CLASSNAME } from './constants'; +import { + GENERAL_FIELDS_ID, + GENERAL_FIELDS_IDX, + SELECTION_ERROR_CLASSNAME, +} from './constants'; import ExportSelectionComponent from './export-selection.component'; import { usePrevious } from '../../../common/hooks/previous.hook'; @@ -19,21 +23,19 @@ const scrollToElement = (elem?: Element | null): void => { behavior: 'smooth', }); }, NONE); -} +}; const NONE = 0; const ExportSelectionFieldsContainer: React.FC = observer(() => { const store = useStore(); const selectionsContainerRef = useRef(null); - const exportGeometrySelections = store.exportStore.geometrySelectionsCollection; + const exportGeometrySelections = + store.exportStore.geometrySelectionsCollection; const selectionServerError = store.exportStore.serverErroredSelectionId; - const { - externalFields, - internalFields, - propsForDomain, - } = useAddFeatureWithProps(); + const { externalFields, internalFields, propsForDomain } = + useAddFeatureWithProps(); const SelectionFieldPerDomainRenderer = useGetSelectionFieldForDomain(); @@ -45,7 +47,7 @@ const ExportSelectionFieldsContainer: React.FC = observer(() => { return featuresWithProps.map((feature, selectionIdx) => { return ( { useLayoutEffect(() => { if (typeof selectionServerError !== 'undefined') { - const erroredSelection = selectionsContainerRef.current?.querySelector(`.${SELECTION_ERROR_CLASSNAME}`); - + const erroredSelection = selectionsContainerRef.current?.querySelector( + `.${SELECTION_ERROR_CLASSNAME}` + ); + if (!isEmpty(erroredSelection)) { scrollToElement(erroredSelection); } @@ -75,8 +79,9 @@ const ExportSelectionFieldsContainer: React.FC = observer(() => { const generalExportFields = Object.entries( externalFields as Record ).map(([key]) => { - const formFieldValue = Object.entries(store.exportStore.formData) - .reduce((storedValue, [fieldName, value]): string => { + const formFieldValue = Object.entries( + store.exportStore.formData + ).reduce((storedValue, [fieldName, value]): string => { if (fieldName.includes(key)) { return value as string; } @@ -101,9 +106,7 @@ const ExportSelectionFieldsContainer: React.FC = observer(() => { <> {propsForDomain && externalFields && internalFields && (
- - {externalExportFields} - + {externalExportFields} {renderExportSelectionsFields}
)} diff --git a/src/discrete-layer/components/export-layer/export-selection.component.tsx b/src/discrete-layer/components/export-layer/export-selection.component.tsx index 23dc1cb40..4e1a6ad12 100644 --- a/src/discrete-layer/components/export-layer/export-selection.component.tsx +++ b/src/discrete-layer/components/export-layer/export-selection.component.tsx @@ -1,6 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Box } from '@map-colonies/react-components'; -import { CircularProgress, IconButton, Typography } from '@map-colonies/react-core'; +import { + CircularProgress, + IconButton, + Typography, +} from '@map-colonies/react-core'; import { Feature } from 'geojson'; import { get, isEmpty, isEqual } from 'lodash'; import { observer } from 'mobx-react-lite'; @@ -28,62 +32,70 @@ interface ExportSelectionComponentProps { const NONE = 0; -const ExportSelectionComponent: React.FC = observer(({ - feature, - selectionIdx, - internalFields, - propsForDomain, -}) => { - const intl = useIntl(); - const store = useStore(); - const SelectionFieldPerDomainRenderer = useGetSelectionFieldForDomain(); - const { onSelectionMouseOver, onSelectionMouseOut } = useHighlightSelection(); - const featProps = feature.properties as Record; - const selectionId = featProps.id; - const prevFeature = usePrevious(feature); - const [newFeature, setNewFeature] = useState(feature); - const isSelectionServerError = store.exportStore.serverErroredSelectionId === feature.properties?.id as string; - - const {data: estimatedSizeRes, error, loading, setSelection} = useEstimatedSize(feature); - - useEffect(() => { - const prevFeatureProps = prevFeature?.properties; - const newFeatureProps = feature.properties; - - if (prevFeatureProps) { +const ExportSelectionComponent: React.FC = + observer(({ feature, selectionIdx, internalFields, propsForDomain }) => { + const intl = useIntl(); + const store = useStore(); + const SelectionFieldPerDomainRenderer = useGetSelectionFieldForDomain(); + const { onSelectionMouseOver, onSelectionMouseOut } = + useHighlightSelection(); + const featProps = feature.properties as Record; + const selectionId = featProps.id; + const prevFeature = usePrevious(feature); + const [newFeature, setNewFeature] = useState(feature); + const isSelectionServerError = + store.exportStore.serverErroredSelectionId === + (feature.properties?.id as string); + + const { + data: estimatedSizeRes, + error, + loading, + setSelection, + } = useEstimatedSize(feature); + + useEffect(() => { + const prevFeatureProps = prevFeature?.properties; + const newFeatureProps = feature.properties; + + if (prevFeatureProps) { if (!isEqual(prevFeatureProps, newFeatureProps)) { - setNewFeature(feature); + setNewFeature(feature); } - } else { + } else { setNewFeature(feature); - } - },[feature]); + } + }, [feature]); - useEffect(() => { - // Estimate size. - setSelection(newFeature); - - }, [newFeature]); + useEffect(() => { + // Estimate size. + setSelection(newFeature); + }, [newFeature]); - const estimatedSizeText = useMemo(() => { - const NOT_AVAILABLE_TEXT = 'N/A'; - const estimatedSizeValue = typeof estimatedSizeRes === 'number' ? formatBytes(estimatedSizeRes) : NOT_AVAILABLE_TEXT; + const estimatedSizeText = useMemo(() => { + const NOT_AVAILABLE_TEXT = 'N/A'; + const estimatedSizeValue = + typeof estimatedSizeRes === 'number' + ? formatBytes(estimatedSizeRes) + : NOT_AVAILABLE_TEXT; - const estimatedSizeLabel = intl.formatMessage({ id: 'export-layer.sizeEstimation.label' }); + const estimatedSizeLabel = intl.formatMessage({ + id: 'export-layer.sizeEstimation.label', + }); - return ( - - - {estimatedSizeLabel} + return ( + - {loading ? '' : estimatedSizeValue} + {estimatedSizeLabel} + + {loading ? '' : estimatedSizeValue} + - - - ); - }, [estimatedSizeRes, error, loading]); - - const selection = useMemo(() => { +
+ ); + }, [estimatedSizeRes, error, loading]); + + const selection = useMemo(() => { const selectionFields = Object.entries(featProps) .filter(([key]) => key in (internalFields ?? {})) .map(([key, val]) => { @@ -98,17 +110,19 @@ const ExportSelectionComponent: React.FC = observ /> ); }); - + const hasPropsSign = selectionFields.length > NONE ? ':' : '.'; const selectionTextId = isEmpty(featProps.label) ? 'export-layer.selection-index.text' : (featProps.label as string); - + const customOrGeneralSelectionText = intl.formatMessage({ id: selectionTextId, }); - const selectionTitle = `${selectionIdx + 1}. ${customOrGeneralSelectionText}${hasPropsSign}`; - + const selectionTitle = `${ + selectionIdx + 1 + }. ${customOrGeneralSelectionText}${hasPropsSign}`; + return ( = observ
); - }, [newFeature, estimatedSizeRes, error, loading, selectionIdx, isSelectionServerError]); + }, [ + newFeature, + estimatedSizeRes, + error, + loading, + selectionIdx, + isSelectionServerError, + ]); - return selection; -}); + return selection; + }); export default ExportSelectionComponent; diff --git a/src/discrete-layer/components/export-layer/hooks/useAddFeatureWithProps.ts b/src/discrete-layer/components/export-layer/hooks/useAddFeatureWithProps.ts index 9279125dd..907970f57 100644 --- a/src/discrete-layer/components/export-layer/hooks/useAddFeatureWithProps.ts +++ b/src/discrete-layer/components/export-layer/hooks/useAddFeatureWithProps.ts @@ -3,7 +3,10 @@ import { get, isEmpty } from 'lodash'; import { useContext, useEffect, useMemo, useState } from 'react'; import { RegisterOptions } from 'react-hook-form'; import { useIntl } from 'react-intl'; -import EnumsMapContext, { IEnumDescriptor, IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import EnumsMapContext, { + IEnumDescriptor, + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { RecordType, useStore, FieldConfigModelType } from '../../../models'; import { LayerMetadataMixedUnionKeys } from '../../layer-details/entity-types-keys'; import useZoomLevelsTable from './useZoomLevelsTable'; @@ -18,12 +21,15 @@ export type AvailableProperties = | 'maxResolutionDeg' | 'minResolutionDeg'; -export type ExportFieldOptions = Partial & { +export type ExportFieldOptions = Partial & { defaultsFromEntityField?: LayerMetadataMixedUnionKeys; defaultValue?: unknown; validationAgainstField?: { - watch: AvailableProperties, - validate: (fieldVal: unknown, otherFieldVal: unknown) => string | boolean | undefined + watch: AvailableProperties; + validate: ( + fieldVal: unknown, + otherFieldVal: unknown + ) => string | boolean | undefined; }; formatValueFunc?: (val: unknown) => unknown; isExternal?: boolean; @@ -32,14 +38,11 @@ export type ExportFieldOptions = Partial & { placeholderValue?: string | (() => string); rows?: number; maxLength?: number; -} +}; -export type ExportEntityProp = Record< - AvailableProperties, - ExportFieldOptions ->; +export type ExportEntityProp = Record; -interface IUseAddFeatureWithProps { +interface IUseAddFeatureWithProps { externalFields?: Record; internalFields?: Record; propsForDomain?: ExportEntityProp; @@ -47,7 +50,9 @@ interface IUseAddFeatureWithProps { const FIRST = 0; -const useAddFeatureWithProps = (shouldAddFeature = true): IUseAddFeatureWithProps => { +const useAddFeatureWithProps = ( + shouldAddFeature = true +): IUseAddFeatureWithProps => { const store = useStore(); const intl = useIntl(); const { enumsMap } = useContext(EnumsMapContext); @@ -55,14 +60,18 @@ const useAddFeatureWithProps = (shouldAddFeature = true): IUseAddFeatureWithProp const enums = enumsMap as IEnumsMapType; const [propsForDomain, setPropsForDomain] = useState(); - const [internalPropsForDomain, setInternalPropsForDomain] = useState>({} as Record); - const [externalPropsForDomain, setExternalPropsForDomain] = useState>({} as Record); + const [internalPropsForDomain, setInternalPropsForDomain] = useState< + Record + >({} as Record); + const [externalPropsForDomain, setExternalPropsForDomain] = useState< + Record + >({} as Record); const tempRawSelection = store.exportStore.tempRawSelection; const layerToExport = store.exportStore.layerToExport; // Get min and max values from field config validations - + // const getStaticMinMaxForField = useCallback(( // layerRecordType: LayerRecordTypes, // fieldName: LayerMetadataMixedUnionKeys @@ -87,178 +96,280 @@ const useAddFeatureWithProps = (shouldAddFeature = true): IUseAddFeatureWithProp // return minMaxValues; // }, [store.discreteLayersStore.getFieldConfig]); - const PROPS_PER_DOMAIN = useMemo(() => new Map>([ - [ - RecordType.RECORD_RASTER, - { - description: { - isExternal: true, - rows: 4, - maxLength: 50 - }, - maxResolutionDeg: { - defaultsFromEntityField: 'maxResolutionDeg', - placeholderValue: (): string => { - const minResolutionDeg = get(layerToExport, 'maxResolutionDeg') as number; - const placeholderValue = intl.formatMessage({id: 'export-layer.minimum.placeholder'}, {min: minResolutionDeg}); - - return placeholderValue; - }, - // helperTextValue: (value): string => { - // let zoomLevel: number; - // try { - // zoomLevel = degreesPerPixelToZoomLevel(value as number); - // } catch(e) { - // console.error(e); - // zoomLevel = NaN; - // } - - // const helperTextVal = intl.formatMessage({id: 'export-layer.zoomLevel.helper-text'}, { zoomLevel }); - // return helperTextVal; - - // }, - rhfValidation: { - validate: { - checkMinVal: (val): string | boolean => { - const minResolutionDeg = get(layerToExport, 'maxResolutionDeg') as number; - const minimumErrMsg = intl.formatMessage({id: 'export-layer.validations.min'}, {min: minResolutionDeg}); - - return val !== '' && +val < minResolutionDeg ? minimumErrMsg : true; + const PROPS_PER_DOMAIN = useMemo( + () => + new Map>([ + [ + RecordType.RECORD_RASTER, + { + description: { + isExternal: true, + rows: 4, + maxLength: 50, + }, + maxResolutionDeg: { + defaultsFromEntityField: 'maxResolutionDeg', + placeholderValue: (): string => { + const minResolutionDeg = get( + layerToExport, + 'maxResolutionDeg' + ) as number; + const placeholderValue = intl.formatMessage( + { id: 'export-layer.minimum.placeholder' }, + { min: minResolutionDeg } + ); + + return placeholderValue; + }, + // helperTextValue: (value): string => { + // let zoomLevel: number; + // try { + // zoomLevel = degreesPerPixelToZoomLevel(value as number); + // } catch(e) { + // console.error(e); + // zoomLevel = NaN; + // } + + // const helperTextVal = intl.formatMessage({id: 'export-layer.zoomLevel.helper-text'}, { zoomLevel }); + // return helperTextVal; + + // }, + rhfValidation: { + validate: { + checkMinVal: (val): string | boolean => { + const minResolutionDeg = get( + layerToExport, + 'maxResolutionDeg' + ) as number; + const minimumErrMsg = intl.formatMessage( + { id: 'export-layer.validations.min' }, + { min: minResolutionDeg } + ); + + return val !== '' && +val < minResolutionDeg + ? minimumErrMsg + : true; + }, + }, + valueAsNumber: true, + required: { + value: true, + message: intl.formatMessage({ + id: 'export-layer.validations.required', + }), + }, }, }, - valueAsNumber: true, - required: {value: true, message: intl.formatMessage({id: 'export-layer.validations.required'})} - } - }, - minResolutionDeg: { - defaultValue: ZOOM_LEVELS_TABLE[FIRST], - // helperTextValue: (value): string => { - // let zoomLevel: number; - // try { - // zoomLevel = degreesPerPixelToZoomLevel(value as number); - // } catch(e) { - // console.error(e); - // zoomLevel = NaN; - // } - - // const helperTextVal = intl.formatMessage({id: 'export-layer.zoomLevel.helper-text'}, { zoomLevel }); - // return helperTextVal; - - // }, - validationAgainstField: { - watch: 'maxResolutionDeg', - validate: (minResolutionValue, maxResolutionValue): string | undefined => { - const validationRelationText = intl.formatMessage({id: 'export-layer.validations.relations.largerOrEqual'}); - const maxResDegFieldName = intl.formatMessage({id: 'export-layer.maxResolutionDeg.field'}); - const validationErrorMsg = intl.formatMessage({id: 'export-layer.validations.againstOtherField'}, {relation: validationRelationText, fieldName: maxResDegFieldName}); - - if (Number(minResolutionValue) < Number(maxResolutionValue)) { - return validationErrorMsg; - } - } - }, - rhfValidation: { - validate: { - checkMinVal: (val): string | boolean => { - const minResolutionDeg = get(layerToExport, 'minResolutionDeg') as number; - const minimumErrMsg = intl.formatMessage({id: 'export-layer.validations.min'}, {min: minResolutionDeg}); + minResolutionDeg: { + defaultValue: ZOOM_LEVELS_TABLE[FIRST], + // helperTextValue: (value): string => { + // let zoomLevel: number; + // try { + // zoomLevel = degreesPerPixelToZoomLevel(value as number); + // } catch(e) { + // console.error(e); + // zoomLevel = NaN; + // } + + // const helperTextVal = intl.formatMessage({id: 'export-layer.zoomLevel.helper-text'}, { zoomLevel }); + // return helperTextVal; - return val !== '' && +val < minResolutionDeg ? minimumErrMsg : true; + // }, + validationAgainstField: { + watch: 'maxResolutionDeg', + validate: ( + minResolutionValue, + maxResolutionValue + ): string | undefined => { + const validationRelationText = intl.formatMessage({ + id: 'export-layer.validations.relations.largerOrEqual', + }); + const maxResDegFieldName = intl.formatMessage({ + id: 'export-layer.maxResolutionDeg.field', + }); + const validationErrorMsg = intl.formatMessage( + { id: 'export-layer.validations.againstOtherField' }, + { + relation: validationRelationText, + fieldName: maxResDegFieldName, + } + ); + + if (Number(minResolutionValue) < Number(maxResolutionValue)) { + return validationErrorMsg; + } + }, + }, + rhfValidation: { + validate: { + checkMinVal: (val): string | boolean => { + const minResolutionDeg = get( + layerToExport, + 'minResolutionDeg' + ) as number; + const minimumErrMsg = intl.formatMessage( + { id: 'export-layer.validations.min' }, + { min: minResolutionDeg } + ); + + return val !== '' && +val < minResolutionDeg + ? minimumErrMsg + : true; + }, + }, + valueAsNumber: true, }, }, - valueAsNumber: true, - } - }, - }, - ], - [RecordType.RECORD_3D, { - description: { - isExternal: true, - rows: 4, - maxLength: 50 - }, - }], - [RecordType.RECORD_DEM, { - resolution: { - defaultsFromEntityField: 'resolutionMeter', - placeholderValue: (): string => { - const minResolutionMeter = get(layerToExport, 'resolutionMeter') as number; - const placeholderValue = intl.formatMessage({id: 'export-layer.minimum.placeholder'}, {min: minResolutionMeter}); - - return placeholderValue; - }, - helperTextValue: intl.formatMessage({id: 'export-layer.resolution.helper-text'}), - rhfValidation: { - validate: { - checkMinVal: (val): string | boolean => { - const minResolutionDeg = get(layerToExport, 'resolutionMeter') as number; - const minimumErrMsg = intl.formatMessage({id: 'export-layer.validations.min'}, {min: minResolutionDeg}) - - return val !== '' && +val < minResolutionDeg ? minimumErrMsg : true; - } }, - valueAsNumber: true, - required: {value: true, message: intl.formatMessage({id: 'export-layer.validations.required'})} - } - }, - description: { - isExternal: true, - rows: 4, - maxLength: 50 - }, - projection: { - isExternal: true, - rhfValidation: { - required: {value: true, message: intl.formatMessage({id: 'export-layer.validations.required'})} - } - }, - resampleMethod: { - isExternal: true, - rhfValidation: { - required: {value: true, message: intl.formatMessage({id: 'export-layer.validations.required'})} - } - }, - dataType: { - isExternal: true, - rhfValidation: { - required: {value: true, message: intl.formatMessage({id: 'export-layer.validations.required'})} - } - } + ], + [ + RecordType.RECORD_3D, + { + description: { + isExternal: true, + rows: 4, + maxLength: 50, + }, + }, + ], + [ + RecordType.RECORD_DEM, + { + resolution: { + defaultsFromEntityField: 'resolutionMeter', + placeholderValue: (): string => { + const minResolutionMeter = get( + layerToExport, + 'resolutionMeter' + ) as number; + const placeholderValue = intl.formatMessage( + { id: 'export-layer.minimum.placeholder' }, + { min: minResolutionMeter } + ); + + return placeholderValue; + }, + helperTextValue: intl.formatMessage({ + id: 'export-layer.resolution.helper-text', + }), + rhfValidation: { + validate: { + checkMinVal: (val): string | boolean => { + const minResolutionDeg = get( + layerToExport, + 'resolutionMeter' + ) as number; + const minimumErrMsg = intl.formatMessage( + { id: 'export-layer.validations.min' }, + { min: minResolutionDeg } + ); - }], - ]), [layerToExport]); + return val !== '' && +val < minResolutionDeg + ? minimumErrMsg + : true; + }, + }, + valueAsNumber: true, + required: { + value: true, + message: intl.formatMessage({ + id: 'export-layer.validations.required', + }), + }, + }, + }, + description: { + isExternal: true, + rows: 4, + maxLength: 50, + }, + projection: { + isExternal: true, + rhfValidation: { + required: { + value: true, + message: intl.formatMessage({ + id: 'export-layer.validations.required', + }), + }, + }, + }, + resampleMethod: { + isExternal: true, + rhfValidation: { + required: { + value: true, + message: intl.formatMessage({ + id: 'export-layer.validations.required', + }), + }, + }, + }, + dataType: { + isExternal: true, + rhfValidation: { + required: { + value: true, + message: intl.formatMessage({ + id: 'export-layer.validations.required', + }), + }, + }, + }, + }, + ], + ]), + [layerToExport] + ); - const getPropsForFeature = (predicate: (fieldOptions: ExportFieldOptions) => boolean): Record => { + const getPropsForFeature = ( + predicate: (fieldOptions: ExportFieldOptions) => boolean + ): Record => { const featureProps: Record = {}; - for(const [fieldName, fieldOptions] of Object.entries(propsForDomain ?? {})) { + for (const [fieldName, fieldOptions] of Object.entries( + propsForDomain ?? {} + )) { if (predicate(fieldOptions)) { - let fieldValue = fieldOptions.defaultValue as string | undefined ?? - (get(layerToExport, fieldOptions.defaultsFromEntityField as string) as string | undefined ?? ''); - + let fieldValue = + (fieldOptions.defaultValue as string | undefined) ?? + (get( + layerToExport, + fieldOptions.defaultsFromEntityField as string + ) as string | undefined) ?? + ''; + if (typeof fieldOptions.formatValueFunc !== 'undefined' && fieldValue) { - const formattedVal = fieldOptions.formatValueFunc(fieldValue) as string | undefined; - fieldValue = formattedVal ?? '' + const formattedVal = fieldOptions.formatValueFunc(fieldValue) as + | string + | undefined; + fieldValue = formattedVal ?? ''; } featureProps[fieldName] = fieldValue; } } - return featureProps; - } + return featureProps; + }; const getInternalPropsForFeature = (): Record => { - return getPropsForFeature((options) => !(options.isExternal as boolean)); + return getPropsForFeature((options) => !(options.isExternal as boolean)); }; const getExternalPropsForEntity = (): Record => { - return getPropsForFeature((options) => options.isExternal as boolean); + return getPropsForFeature((options) => options.isExternal as boolean); }; useEffect(() => { - const layerRecordType = (get(enums, layerToExport?.productType as string) as IEnumDescriptor | undefined)?.parentDomain as RecordType; + const layerRecordType = ( + get(enums, layerToExport?.productType as string) as + | IEnumDescriptor + | undefined + )?.parentDomain as RecordType; - setPropsForDomain(PROPS_PER_DOMAIN.get(layerRecordType) as ExportEntityProp); + setPropsForDomain( + PROPS_PER_DOMAIN.get(layerRecordType) as ExportEntityProp + ); }, [layerToExport]); useEffect(() => { @@ -270,8 +381,13 @@ const useAddFeatureWithProps = (shouldAddFeature = true): IUseAddFeatureWithProp if (tempRawSelection && shouldAddFeature) { // Add entity related properties to the raw selection. const tempRawSelectionProps = tempRawSelection.properties ?? {}; - const currentSelectionLabelProp = !isEmpty(tempRawSelectionProps.label) ? {label: tempRawSelectionProps.label as string} : {}; - const selectionWithProps: Feature = {...tempRawSelection, properties: {...currentSelectionLabelProp, ...internalPropsForDomain}}; + const currentSelectionLabelProp = !isEmpty(tempRawSelectionProps.label) + ? { label: tempRawSelectionProps.label as string } + : {}; + const selectionWithProps: Feature = { + ...tempRawSelection, + properties: { ...currentSelectionLabelProp, ...internalPropsForDomain }, + }; // Add the enhanced feature to the feature collection. store.exportStore.addFeatureSelection(selectionWithProps); @@ -279,7 +395,11 @@ const useAddFeatureWithProps = (shouldAddFeature = true): IUseAddFeatureWithProp } }, [tempRawSelection]); - return { propsForDomain, externalFields: externalPropsForDomain, internalFields: internalPropsForDomain }; + return { + propsForDomain, + externalFields: externalPropsForDomain, + internalFields: internalPropsForDomain, + }; }; export default useAddFeatureWithProps; diff --git a/src/discrete-layer/components/export-layer/hooks/useDomainExportActionsConfig.ts b/src/discrete-layer/components/export-layer/hooks/useDomainExportActionsConfig.ts index 96179f6f5..42938584d 100644 --- a/src/discrete-layer/components/export-layer/hooks/useDomainExportActionsConfig.ts +++ b/src/discrete-layer/components/export-layer/hooks/useDomainExportActionsConfig.ts @@ -1,42 +1,48 @@ import { useContext, useEffect, useMemo, useState } from 'react'; import { get, isEmpty } from 'lodash'; -import EnumsMapContext, { IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import EnumsMapContext, { + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { RecordType, useStore } from '../../../models'; import { TabViews } from '../../../views/tab-views'; import { IAction } from '../../../../common/actions/entity.actions'; -import lookupTablesContext, { ILookupOption } from '../../../../common/contexts/lookupTables.context'; +import lookupTablesContext, { + ILookupOption, +} from '../../../../common/contexts/lookupTables.context'; import { HOT_AREAS_TABLES_KEY } from '../../../views/components/data-fetchers/lookup-tables-fetcher.component'; import { Feature } from 'geojson'; import { useIntl } from 'react-intl'; export enum ExportActions { - DRAW_RECTANGLE = 'export-draw-rectangle', - DRAW_FOOTPRINT = 'export-draw-footprint', - DRAW_POLYGON = 'export-draw-polygon', - DRAW_BY_COORDINATES = 'export-draw-coordinates', - CLEAR_DRAWINGS = 'export-clear-drawings', - IMPORT_FROM_SHAPE_FILE = 'import-from-shape-file', - TOGGLE_FULL_LAYER_EXPORT = 'toggle-full-layer-export', - OPEN_HOT_AREAS_MENU = 'export-open-hot-areas-menu', - EXPORT_HOT_AREA_SELECTION = 'export-hot_area_selection', - END_EXPORT_SESSION = 'end_export_session', -}; - -export type ExportAction = (IAction & { - disabled: boolean; - toggleExportStoreFieldOptions?: { + DRAW_RECTANGLE = 'export-draw-rectangle', + DRAW_FOOTPRINT = 'export-draw-footprint', + DRAW_POLYGON = 'export-draw-polygon', + DRAW_BY_COORDINATES = 'export-draw-coordinates', + CLEAR_DRAWINGS = 'export-clear-drawings', + IMPORT_FROM_SHAPE_FILE = 'import-from-shape-file', + TOGGLE_FULL_LAYER_EXPORT = 'toggle-full-layer-export', + OPEN_HOT_AREAS_MENU = 'export-open-hot-areas-menu', + EXPORT_HOT_AREA_SELECTION = 'export-hot_area_selection', + END_EXPORT_SESSION = 'end_export_session', +} + +export type ExportAction = + | (IAction & { + disabled: boolean; + toggleExportStoreFieldOptions?: { field: string; labelChecked: string; labelUnchecked: string; - }; - menuActionOptions?: { - items: Map; - dispatchOnItemClick: { - action: ExportActions; - data?: unknown; }; - } -}) | 'SEPARATOR'; + menuActionOptions?: { + items: Map; + dispatchOnItemClick: { + action: ExportActions; + data?: unknown; + }; + }; + }) + | 'SEPARATOR'; const EXPORT_ACTIONS: ExportAction[] = [ { @@ -44,16 +50,16 @@ const EXPORT_ACTIONS: ExportAction[] = [ frequent: true, icon: '', class: '', - toggleExportStoreFieldOptions: { - field: 'isFullLayerExportEnabled', + toggleExportStoreFieldOptions: { + field: 'isFullLayerExportEnabled', labelChecked: 'action.export.full-layer.label', - labelUnchecked: 'action.export.full-layer.label' + labelUnchecked: 'action.export.full-layer.label', }, titleTranslationId: 'action.export.full-layer.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, - "SEPARATOR", + 'SEPARATOR', { action: ExportActions.DRAW_FOOTPRINT, frequent: true, @@ -61,7 +67,7 @@ const EXPORT_ACTIONS: ExportAction[] = [ class: 'mc-icon-Map-Orthophoto', titleTranslationId: 'action.export.footprint.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, { action: ExportActions.DRAW_RECTANGLE, @@ -70,7 +76,7 @@ const EXPORT_ACTIONS: ExportAction[] = [ class: 'mc-icon-Rectangle', titleTranslationId: 'action.export.box.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, { action: ExportActions.DRAW_POLYGON, @@ -79,7 +85,7 @@ const EXPORT_ACTIONS: ExportAction[] = [ class: 'mc-icon-Polygon', titleTranslationId: 'action.export.polygon.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, { action: ExportActions.DRAW_BY_COORDINATES, @@ -88,7 +94,7 @@ const EXPORT_ACTIONS: ExportAction[] = [ class: 'mc-icon-Coordinates', titleTranslationId: 'action.export.bbox-corners.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, { action: ExportActions.IMPORT_FROM_SHAPE_FILE, @@ -97,7 +103,7 @@ const EXPORT_ACTIONS: ExportAction[] = [ class: 'mc-icon-Upload', titleTranslationId: 'action.export.import-shape.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, { action: ExportActions.OPEN_HOT_AREAS_MENU, @@ -108,13 +114,13 @@ const EXPORT_ACTIONS: ExportAction[] = [ menuActionOptions: { items: new Map(), dispatchOnItemClick: { - action: ExportActions.EXPORT_HOT_AREA_SELECTION - } + action: ExportActions.EXPORT_HOT_AREA_SELECTION, + }, }, disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, - "SEPARATOR", + 'SEPARATOR', { action: ExportActions.CLEAR_DRAWINGS, frequent: true, @@ -122,7 +128,7 @@ const EXPORT_ACTIONS: ExportAction[] = [ class: 'mc-icon-Delete', titleTranslationId: 'action.clear.tooltip', disabled: false, - views: [TabViews.EXPORT_LAYER] + views: [TabViews.EXPORT_LAYER], }, ]; @@ -133,34 +139,60 @@ const EXPORT_ACTIONS: ExportAction[] = [ const useDomainExportActionsConfig = (): ExportAction[] => { const store = useStore(); const intl = useIntl(); - const {exportStore: { layerToExport, geometrySelectionsCollection, isFullLayerExportEnabled, setIsMultiSelectionAllowed }} = store; + const { + exportStore: { + layerToExport, + geometrySelectionsCollection, + isFullLayerExportEnabled, + setIsMultiSelectionAllowed, + }, + } = store; const { enumsMap } = useContext(EnumsMapContext); const { lookupTablesData } = useContext(lookupTablesContext); const enums = enumsMap as IEnumsMapType; - const layerRecordType = useMemo(() => get(enums, layerToExport?.productType as string).parentDomain as RecordType, [layerToExport]); + const layerRecordType = useMemo( + () => + get(enums, layerToExport?.productType as string) + .parentDomain as RecordType, + [layerToExport] + ); const selectionsFeatures = geometrySelectionsCollection.features; const initExportActions = useMemo((): ExportAction[] => { - const initializedActions = [...EXPORT_ACTIONS].map(action => { + const initializedActions = [...EXPORT_ACTIONS].map((action) => { if (action === 'SEPARATOR') return action; if (action.menuActionOptions) { - switch(action.action) { + switch (action.action) { case ExportActions.OPEN_HOT_AREAS_MENU: { if (!lookupTablesData?.dictionary) { return action; } - - const hotAreasTable = (lookupTablesData.dictionary[HOT_AREAS_TABLES_KEY] as ILookupOption[] | undefined) ?? []; + + const hotAreasTable = + (lookupTablesData.dictionary[HOT_AREAS_TABLES_KEY] as + | ILookupOption[] + | undefined) ?? []; const hotAreasMenuItems = new Map(); - for(const hotAreaOption of hotAreasTable) { - const areaTranslation = intl.formatMessage({ id: hotAreaOption.translationCode }); - hotAreasMenuItems.set(areaTranslation, hotAreaOption.properties.footprint as Feature); - } - - return {...action, menuActionOptions: {...action.menuActionOptions, items: hotAreasMenuItems }}; + for (const hotAreaOption of hotAreasTable) { + const areaTranslation = intl.formatMessage({ + id: hotAreaOption.translationCode, + }); + hotAreasMenuItems.set( + areaTranslation, + hotAreaOption.properties.footprint as Feature + ); + } + + return { + ...action, + menuActionOptions: { + ...action.menuActionOptions, + items: hotAreasMenuItems, + }, + }; } default: @@ -169,121 +201,143 @@ const useDomainExportActionsConfig = (): ExportAction[] => { } return action; - }) + }); return initializedActions; - }, []); - const [domainActionList, setDomainActionList] = useState(initExportActions); + const [domainActionList, setDomainActionList] = + useState(initExportActions); useEffect(() => { - switch(layerRecordType) { - case RecordType.RECORD_RASTER: { - // Multi selection is allowed. - // While there is at least one selection, full export should be disabled. - // If full export ticked, all other drawing actions should be disabled. - - const multiSelectionAllowed = true; - setIsMultiSelectionAllowed(multiSelectionAllowed); - - const newActionList = domainActionList.map((action) => { - if (action === 'SEPARATOR' || action.action === ExportActions.CLEAR_DRAWINGS) return action; - const rasterAction: ExportAction = { - ...action, - class: - action.action === ExportActions.DRAW_FOOTPRINT - ? 'mc-icon-Map-Orthophoto' - : action.class, - }; - - if (!isEmpty(selectionsFeatures)) { - if (action.action === ExportActions.TOGGLE_FULL_LAYER_EXPORT && !isFullLayerExportEnabled) { - return { ...rasterAction, disabled: true }; - } - - if (isFullLayerExportEnabled) { - return { ...rasterAction, disabled: action.action !== ExportActions.TOGGLE_FULL_LAYER_EXPORT }; - } - - return { ...rasterAction, disabled: !multiSelectionAllowed }; - } else { - return { ...rasterAction, disabled: false }; - } - }); - - setDomainActionList(newActionList); - - break; - } - case RecordType.RECORD_3D: { - // Only full export is allowed, all other actions are disabled. (including clear selections and full export.) - // Full export toggle should be ticked automatically. - - const multiSelectionAllowed = false; - setIsMultiSelectionAllowed(multiSelectionAllowed); - - const newActionList = domainActionList.map((action) => { - if (action === 'SEPARATOR') return action; - - const action3D: ExportAction = { - ...action, - class: - action.action === ExportActions.DRAW_FOOTPRINT - ? 'mc-icon-Map-3D' - : action.class, - }; - - return ({ ...action3D, disabled: true }); - }); + switch (layerRecordType) { + case RecordType.RECORD_RASTER: { + // Multi selection is allowed. + // While there is at least one selection, full export should be disabled. + // If full export ticked, all other drawing actions should be disabled. + + const multiSelectionAllowed = true; + setIsMultiSelectionAllowed(multiSelectionAllowed); + + const newActionList = domainActionList.map((action) => { + if ( + action === 'SEPARATOR' || + action.action === ExportActions.CLEAR_DRAWINGS + ) + return action; + const rasterAction: ExportAction = { + ...action, + class: + action.action === ExportActions.DRAW_FOOTPRINT + ? 'mc-icon-Map-Orthophoto' + : action.class, + }; + + if (!isEmpty(selectionsFeatures)) { + if ( + action.action === ExportActions.TOGGLE_FULL_LAYER_EXPORT && + !isFullLayerExportEnabled + ) { + return { ...rasterAction, disabled: true }; + } - setDomainActionList(newActionList); + if (isFullLayerExportEnabled) { + return { + ...rasterAction, + disabled: + action.action !== ExportActions.TOGGLE_FULL_LAYER_EXPORT, + }; + } - break; + return { ...rasterAction, disabled: !multiSelectionAllowed }; + } else { + return { ...rasterAction, disabled: false }; } - case RecordType.RECORD_DEM: { - // Multi selection is not allowed. - // After the first selection all drawing actions should be disabled. - - const multiSelectionAllowed = false; - setIsMultiSelectionAllowed(multiSelectionAllowed); - - const newActionList = domainActionList.map((action) => { - if (action === 'SEPARATOR' || action.action === ExportActions.CLEAR_DRAWINGS) return action; - const demAction: ExportAction = { - ...action, - class: - action.action === ExportActions.DRAW_FOOTPRINT - ? 'mc-icon-Map-DTM' - : action.class, - }; - - if (!isEmpty(selectionsFeatures)) { - if (action.action === ExportActions.TOGGLE_FULL_LAYER_EXPORT && !isFullLayerExportEnabled) { - return { ...demAction, disabled: true }; - } - - if (isFullLayerExportEnabled) { - return { ...demAction, disabled: action.action !== ExportActions.TOGGLE_FULL_LAYER_EXPORT }; - } - - return { ...demAction, disabled: !multiSelectionAllowed }; - } else { - return { ...demAction, disabled: false }; - } - }); - - setDomainActionList(newActionList); - - break; + }); + + setDomainActionList(newActionList); + + break; + } + case RecordType.RECORD_3D: { + // Only full export is allowed, all other actions are disabled. (including clear selections and full export.) + // Full export toggle should be ticked automatically. + + const multiSelectionAllowed = false; + setIsMultiSelectionAllowed(multiSelectionAllowed); + + const newActionList = domainActionList.map((action) => { + if (action === 'SEPARATOR') return action; + + const action3D: ExportAction = { + ...action, + class: + action.action === ExportActions.DRAW_FOOTPRINT + ? 'mc-icon-Map-3D' + : action.class, + }; + + return { ...action3D, disabled: true }; + }); + + setDomainActionList(newActionList); + + break; + } + case RecordType.RECORD_DEM: { + // Multi selection is not allowed. + // After the first selection all drawing actions should be disabled. + + const multiSelectionAllowed = false; + setIsMultiSelectionAllowed(multiSelectionAllowed); + + const newActionList = domainActionList.map((action) => { + if ( + action === 'SEPARATOR' || + action.action === ExportActions.CLEAR_DRAWINGS + ) + return action; + const demAction: ExportAction = { + ...action, + class: + action.action === ExportActions.DRAW_FOOTPRINT + ? 'mc-icon-Map-DTM' + : action.class, + }; + + if (!isEmpty(selectionsFeatures)) { + if ( + action.action === ExportActions.TOGGLE_FULL_LAYER_EXPORT && + !isFullLayerExportEnabled + ) { + return { ...demAction, disabled: true }; + } + + if (isFullLayerExportEnabled) { + return { + ...demAction, + disabled: + action.action !== ExportActions.TOGGLE_FULL_LAYER_EXPORT, + }; + } + + return { ...demAction, disabled: !multiSelectionAllowed }; + } else { + return { ...demAction, disabled: false }; } + }); - default: - break; + setDomainActionList(newActionList); + + break; } + + default: + break; + } }, [layerRecordType, geometrySelectionsCollection]); - + return domainActionList; }; -export default useDomainExportActionsConfig; \ No newline at end of file +export default useDomainExportActionsConfig; diff --git a/src/discrete-layer/components/export-layer/hooks/useEstimatedSize.ts b/src/discrete-layer/components/export-layer/hooks/useEstimatedSize.ts index 64cfb3edd..01945a6a9 100644 --- a/src/discrete-layer/components/export-layer/hooks/useEstimatedSize.ts +++ b/src/discrete-layer/components/export-layer/hooks/useEstimatedSize.ts @@ -1,52 +1,71 @@ import { useContext, useEffect, useState } from 'react'; import { Feature, FeatureCollection } from 'geojson'; -import { EstimatedSizeModelType, RecordType, useQuery, useStore } from '../../../models'; -import EnumsMapContext, { IEnumDescriptor, IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import { + EstimatedSizeModelType, + RecordType, + useQuery, + useStore, +} from '../../../models'; +import EnumsMapContext, { + IEnumDescriptor, + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { get, isEmpty } from 'lodash'; import { GeojsonFeatureCollectionInput } from '../../../models/RootStore.base'; -export const useEstimatedSize = (initSelection: Feature | FeatureCollection = {} as Feature): { +export const useEstimatedSize = ( + initSelection: Feature | FeatureCollection = {} as Feature +): { setSelection: (selection: Feature | FeatureCollection) => void; - data: number | null | undefined, - loading: boolean, + data: number | null | undefined; + loading: boolean; refetch?: () => Promise<{ getEstimatedSize: EstimatedSizeModelType; - }>, - error?: string, + }>; + error?: string; } => { const store = useStore(); - const { exportStore: { layerToExport } } = store; + const { + exportStore: { layerToExport }, + } = store; const { enumsMap } = useContext(EnumsMapContext); const enums = enumsMap as IEnumsMapType; - const layerRecordType = (get(enums, layerToExport?.productType as string) as IEnumDescriptor | undefined)?.parentDomain as RecordType; + const layerRecordType = ( + get(enums, layerToExport?.productType as string) as + | IEnumDescriptor + | undefined + )?.parentDomain as RecordType; const [selection, setSelection] = useState(initSelection); - const { data, loading, setQuery, query } = useQuery<{ getEstimatedSize: EstimatedSizeModelType }>(); - + const { data, loading, setQuery, query } = useQuery<{ + getEstimatedSize: EstimatedSizeModelType; + }>(); useEffect(() => { if (!isEmpty(selection)) { const selectionFeatureCollection: GeojsonFeatureCollectionInput = - selection.type === "Feature" + selection.type === 'Feature' ? { - type: "FeatureCollection", - features: [ - { - ...selection, - id: `${(get(selection.properties, "id") as string | undefined) ?? "" - }` - } - ] - } - : selection as GeojsonFeatureCollectionInput; + type: 'FeatureCollection', + features: [ + { + ...selection, + id: `${ + (get(selection.properties, 'id') as string | undefined) ?? + '' + }`, + }, + ], + } + : (selection as GeojsonFeatureCollectionInput); setQuery( store.queryGetEstimatedSize({ data: { type: layerRecordType, - selections: selectionFeatureCollection - } + selections: selectionFeatureCollection, + }, }) ); } @@ -57,6 +76,6 @@ export const useEstimatedSize = (initSelection: Feature | FeatureCollection = {} data: data?.getEstimatedSize.estimatedSizeBytes, loading, refetch: query?.refetch, - error: get(query?.error, "response.errors[0].message") as string + error: get(query?.error, 'response.errors[0].message') as string, }; -}; \ No newline at end of file +}; diff --git a/src/discrete-layer/components/export-layer/hooks/useExportTrigger.ts b/src/discrete-layer/components/export-layer/hooks/useExportTrigger.ts index ddedc5224..d088945f8 100644 --- a/src/discrete-layer/components/export-layer/hooks/useExportTrigger.ts +++ b/src/discrete-layer/components/export-layer/hooks/useExportTrigger.ts @@ -1,7 +1,15 @@ import { get, isEmpty } from 'lodash'; import { useContext, useEffect, useState } from 'react'; -import EnumsMapContext, { IEnumDescriptor, IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; -import { RecordType, TriggerExportTaskModelType, useQuery, useStore } from '../../../models'; +import EnumsMapContext, { + IEnumDescriptor, + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; +import { + RecordType, + TriggerExportTaskModelType, + useQuery, + useStore, +} from '../../../models'; export interface ExportTriggerParams { catalogRecordID: string; @@ -14,52 +22,73 @@ const EXTERNAL_FIELDS_IDX = 0; interface ExportTriggerOpts { setFormValues: (values: Record) => void; - data: TriggerExportTaskModelType | undefined, - loading: boolean, - error: unknown + data: TriggerExportTaskModelType | undefined; + loading: boolean; + error: unknown; } export const useExportTrigger = (): ExportTriggerOpts => { const store = useStore(); - const { exportStore: { geometrySelectionsCollection, layerToExport, isFullLayerExportEnabled } } = store; + const { + exportStore: { + geometrySelectionsCollection, + layerToExport, + isFullLayerExportEnabled, + }, + } = store; const [formValues, setFormValues] = useState>({}); const { enumsMap } = useContext(EnumsMapContext); const enums = enumsMap as IEnumsMapType; - const layerRecordType = (get(enums, layerToExport?.productType as string) as IEnumDescriptor | undefined)?.parentDomain as RecordType; + const layerRecordType = ( + get(enums, layerToExport?.productType as string) as + | IEnumDescriptor + | undefined + )?.parentDomain as RecordType; - const { data, loading, setQuery, query } = useQuery<{ triggerExportTask: TriggerExportTaskModelType }>(); + const { data, loading, setQuery, query } = useQuery<{ + triggerExportTask: TriggerExportTaskModelType; + }>(); useEffect(() => { if (!isEmpty(formValues)) { - const externalFields = Object.entries(formValues).filter(([key,]) => { + const externalFields = Object.entries(formValues).filter(([key]) => { const [selectionIdx, , selectionId] = key.split('_'); // selectionIdx_fieldName_selectionId; - return +selectionIdx === EXTERNAL_FIELDS_IDX && +selectionId === EXTERNAL_FIELDS_ID; + return ( + +selectionIdx === EXTERNAL_FIELDS_IDX && + +selectionId === EXTERNAL_FIELDS_ID + ); }); - const exportPayload = externalFields.reduce((payloadObj, [key, value]) => { - const [, fieldName,] = key.split('_'); - return ({ - ...payloadObj, + const exportPayload = externalFields.reduce( + (payloadObj, [key, value]) => { + const [, fieldName] = key.split('_'); + return { + ...payloadObj, + parameters: { + ...payloadObj.parameters, + [fieldName]: value, + }, + }; + }, + { + catalogRecordID: layerToExport?.id, + type: layerRecordType, parameters: { - ...payloadObj.parameters, - [fieldName]: value - } - }) - }, { - catalogRecordID: layerToExport?.id, - type: layerRecordType, - parameters: { - roi: geometrySelectionsCollection, - isFullLayerExport: isFullLayerExportEnabled - } - } as ExportTriggerParams); + roi: geometrySelectionsCollection, + isFullLayerExport: isFullLayerExportEnabled, + }, + } as ExportTriggerParams + ); setQuery(store.queryTriggerExportTask({ data: { ...exportPayload } })); } }, [formValues]); - - return { setFormValues, data: data?.triggerExportTask, loading, error: query?.error as unknown } - -} \ No newline at end of file + return { + setFormValues, + data: data?.triggerExportTask, + loading, + error: query?.error as unknown, + }; +}; diff --git a/src/discrete-layer/components/export-layer/hooks/useGeneralExportBehavior.ts b/src/discrete-layer/components/export-layer/hooks/useGeneralExportBehavior.ts index 075064547..152f01369 100644 --- a/src/discrete-layer/components/export-layer/hooks/useGeneralExportBehavior.ts +++ b/src/discrete-layer/components/export-layer/hooks/useGeneralExportBehavior.ts @@ -1,13 +1,16 @@ import { useContext, useEffect, useMemo } from 'react'; import { get } from 'lodash'; -import EnumsMapContext, { IEnumDescriptor, IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import EnumsMapContext, { + IEnumDescriptor, + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { RecordType, useStore } from '../../../models'; import { ExportActions } from './useDomainExportActionsConfig'; /** * Set selected layer and layersImages (Only one layer). * Show the layer's tiles and fly to it. - * + * * For 3D: * Toggle full export mode. */ @@ -17,8 +20,15 @@ export const useGeneralExportBehavior = (cbFunction: () => void): void => { const { enumsMap } = useContext(EnumsMapContext); const enums = enumsMap as IEnumsMapType; - const layerRecordType = useMemo(() => (get(enums, layerToExport?.productType as string) as IEnumDescriptor | undefined)?.parentDomain as RecordType, [layerToExport]); - + const layerRecordType = useMemo( + () => + ( + get(enums, layerToExport?.productType as string) as + | IEnumDescriptor + | undefined + )?.parentDomain as RecordType, + [layerToExport] + ); useEffect(() => { if (layerToExport) { @@ -27,19 +37,19 @@ export const useGeneralExportBehavior = (cbFunction: () => void): void => { store.discreteLayersStore.setLayersImages([layerToExport], true); store.discreteLayersStore.showLayer(layerToExport.id, true, null); store.discreteLayersStore.showPolygonParts(layerToExport.id, true); - + cbFunction(); - switch(layerRecordType) { + switch (layerRecordType) { case RecordType.RECORD_3D: { const INVOKE_ON_CLEAN_STACK = 0; - + setTimeout(() => { store.actionDispatcherStore.dispatchAction({ action: ExportActions.TOGGLE_FULL_LAYER_EXPORT, data: { is3DInit: true, - } + }, }); }, INVOKE_ON_CLEAN_STACK); break; diff --git a/src/discrete-layer/components/export-layer/hooks/useGetEntityLabelForDomain.ts b/src/discrete-layer/components/export-layer/hooks/useGetEntityLabelForDomain.ts index 2b44b2883..f7b78832b 100644 --- a/src/discrete-layer/components/export-layer/hooks/useGetEntityLabelForDomain.ts +++ b/src/discrete-layer/components/export-layer/hooks/useGetEntityLabelForDomain.ts @@ -2,31 +2,55 @@ import { useCallback, useContext, useMemo } from 'react'; import { get } from 'lodash'; import { degreesPerPixelToZoomLevel } from '@map-colonies/mc-utils'; import { RCesiumEntityProps } from '@map-colonies/react-components'; -import EnumsMapContext, { IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import EnumsMapContext, { + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { RecordType, useStore } from '../../../models'; -const useGetEntityLabelForDomain = (): (item: RCesiumEntityProps) => string => { - const {exportStore: { layerToExport }} = useStore(); - const { enumsMap } = useContext(EnumsMapContext); - const enums = enumsMap as IEnumsMapType; - const layerRecordType = useMemo(() => get(enums, `${layerToExport?.productType as string}.parentDomain`) as unknown as RecordType, [layerToExport]); +const useGetEntityLabelForDomain = (): (( + item: RCesiumEntityProps +) => string) => { + const { + exportStore: { layerToExport }, + } = useStore(); + const { enumsMap } = useContext(EnumsMapContext); + const enums = enumsMap as IEnumsMapType; + const layerRecordType = useMemo( + () => + get( + enums, + `${layerToExport?.productType as string}.parentDomain` + ) as unknown as RecordType, + [layerToExport] + ); - const getEntityLabel = useCallback((item: RCesiumEntityProps): string => { - /* eslint-disable */ - switch(layerRecordType) { - case RecordType.RECORD_RASTER: - const maxVal = item.properties?.maxResolutionDeg.getValue(); - const minVal = item.properties?.minResolutionDeg.getValue(); - return (maxVal && minVal) ? `${degreesPerPixelToZoomLevel(minVal as number)} - ${degreesPerPixelToZoomLevel(maxVal as number)}` : ''; - case RecordType.RECORD_DEM: - return item.properties?.resolution.getValue().toString() as string | null ?? ''; - default: - return ''; - } - /* eslint-enable */ - }, [layerRecordType]); + const getEntityLabel = useCallback( + (item: RCesiumEntityProps): string => { + /* eslint-disable */ + switch (layerRecordType) { + case RecordType.RECORD_RASTER: + const maxVal = item.properties?.maxResolutionDeg.getValue(); + const minVal = item.properties?.minResolutionDeg.getValue(); + return maxVal && minVal + ? `${degreesPerPixelToZoomLevel( + minVal as number + )} - ${degreesPerPixelToZoomLevel(maxVal as number)}` + : ''; + case RecordType.RECORD_DEM: + return ( + (item.properties?.resolution.getValue().toString() as + | string + | null) ?? '' + ); + default: + return ''; + } + /* eslint-enable */ + }, + [layerRecordType] + ); - return getEntityLabel; -} + return getEntityLabel; +}; -export default useGetEntityLabelForDomain; \ No newline at end of file +export default useGetEntityLabelForDomain; diff --git a/src/discrete-layer/components/export-layer/hooks/useGetFreeDiskSpace.ts b/src/discrete-layer/components/export-layer/hooks/useGetFreeDiskSpace.ts index 02a87431f..431686609 100644 --- a/src/discrete-layer/components/export-layer/hooks/useGetFreeDiskSpace.ts +++ b/src/discrete-layer/components/export-layer/hooks/useGetFreeDiskSpace.ts @@ -1,34 +1,52 @@ import { useContext, useEffect } from 'react'; -import {FreeDiskSpaceModelType, RecordType, useQuery, useStore } from '../../../models'; -import EnumsMapContext, { IEnumDescriptor, IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import { + FreeDiskSpaceModelType, + RecordType, + useQuery, + useStore, +} from '../../../models'; +import EnumsMapContext, { + IEnumDescriptor, + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { get } from 'lodash'; export const useGetFreeDiskSpace = (): { - data: number | null | undefined, - loading: boolean, - refetch?: () => Promise<{getFreeDiskSpace: FreeDiskSpaceModelType}>, - error?: string, + data: number | null | undefined; + loading: boolean; + refetch?: () => Promise<{ getFreeDiskSpace: FreeDiskSpaceModelType }>; + error?: string; } => { - const store = useStore(); - const { exportStore: { layerToExport } } = store; - const { enumsMap } = useContext(EnumsMapContext); - const enums = enumsMap as IEnumsMapType; - const layerRecordType = (get(enums, layerToExport?.productType as string) as IEnumDescriptor | undefined)?.parentDomain as RecordType; + const store = useStore(); + const { + exportStore: { layerToExport }, + } = store; + const { enumsMap } = useContext(EnumsMapContext); + const enums = enumsMap as IEnumsMapType; + const layerRecordType = ( + get(enums, layerToExport?.productType as string) as + | IEnumDescriptor + | undefined + )?.parentDomain as RecordType; - const { data, loading, query, setQuery } = useQuery<{ getFreeDiskSpace: FreeDiskSpaceModelType}>(); + const { data, loading, query, setQuery } = useQuery<{ + getFreeDiskSpace: FreeDiskSpaceModelType; + }>(); - useEffect(() => { - setQuery(store.queryGetFreeDiskSpace({ - data: { - type: layerRecordType - } - })) - }, []); + useEffect(() => { + setQuery( + store.queryGetFreeDiskSpace({ + data: { + type: layerRecordType, + }, + }) + ); + }, []); - return { - data: data?.getFreeDiskSpace.freeDiskSpaceBytes, - loading, - refetch: query?.refetch, - error: get(query?.error, "response.errors[0].message") as string - }; -}; \ No newline at end of file + return { + data: data?.getFreeDiskSpace.freeDiskSpaceBytes, + loading, + refetch: query?.refetch, + error: get(query?.error, 'response.errors[0].message') as string, + }; +}; diff --git a/src/discrete-layer/components/export-layer/hooks/useGetSelectionFieldForDomain.ts b/src/discrete-layer/components/export-layer/hooks/useGetSelectionFieldForDomain.ts index 63a17ac14..7eeb85af5 100644 --- a/src/discrete-layer/components/export-layer/hooks/useGetSelectionFieldForDomain.ts +++ b/src/discrete-layer/components/export-layer/hooks/useGetSelectionFieldForDomain.ts @@ -17,7 +17,8 @@ const useGetSelectionFieldForDomain = (): React.FC => { const { layerToExport } = exportStore; const getSelectionByDomain = useMemo(() => { - const layerRecordType = get(enums, layerToExport?.productType as string).parentDomain as RecordType; + const layerRecordType = get(enums, layerToExport?.productType as string) + .parentDomain as RecordType; switch (layerRecordType) { case RecordType.RECORD_RASTER: @@ -25,11 +26,11 @@ const useGetSelectionFieldForDomain = (): React.FC => { case RecordType.RECORD_DEM: return DemSelectionField; default: - return ExportStringFieldComponent; + return ExportStringFieldComponent; } - }, []) + }, []); - return getSelectionByDomain; + return getSelectionByDomain; }; export default useGetSelectionFieldForDomain; diff --git a/src/discrete-layer/components/export-layer/hooks/useHighlightSelection.ts b/src/discrete-layer/components/export-layer/hooks/useHighlightSelection.ts index bd186f577..10e37b93b 100644 --- a/src/discrete-layer/components/export-layer/hooks/useHighlightSelection.ts +++ b/src/discrete-layer/components/export-layer/hooks/useHighlightSelection.ts @@ -8,26 +8,30 @@ import { useStore } from '../../../models'; const HIGHLIGHT_BUFFER_METERS = 2; interface IHighlightSelectionUtils { - onSelectionMouseOver: (selectionId: string) => void; - onSelectionMouseOut: () => void; + onSelectionMouseOver: (selectionId: string) => void; + onSelectionMouseOut: () => void; } const useHighlightSelection = (): IHighlightSelectionUtils => { - const { exportStore } = useStore(); + const { exportStore } = useStore(); - const onSelectionMouseOver = useCallback((selectionId: string) => { - const hoveredSelection = exportStore.getFeatureById(selectionId); - const bufferedSelection = buffer(hoveredSelection as Feature, HIGHLIGHT_BUFFER_METERS, {units: 'meters'}); - const selectionLine = polygonToLine(bufferedSelection as Feature); - - exportStore.setHighlightedFeature(selectionLine as Feature); - }, []); + const onSelectionMouseOver = useCallback((selectionId: string) => { + const hoveredSelection = exportStore.getFeatureById(selectionId); + const bufferedSelection = buffer( + hoveredSelection as Feature, + HIGHLIGHT_BUFFER_METERS, + { units: 'meters' } + ); + const selectionLine = polygonToLine(bufferedSelection as Feature); - const onSelectionMouseOut = useCallback(() => { - exportStore.resetHighlightedFeature(); - }, []); + exportStore.setHighlightedFeature(selectionLine as Feature); + }, []); - return { onSelectionMouseOver, onSelectionMouseOut }; -} + const onSelectionMouseOut = useCallback(() => { + exportStore.resetHighlightedFeature(); + }, []); + + return { onSelectionMouseOver, onSelectionMouseOut }; +}; -export default useHighlightSelection; \ No newline at end of file +export default useHighlightSelection; diff --git a/src/discrete-layer/components/export-layer/hooks/useZoomLevelsTable.ts b/src/discrete-layer/components/export-layer/hooks/useZoomLevelsTable.ts index 7624df2f2..554f27439 100644 --- a/src/discrete-layer/components/export-layer/hooks/useZoomLevelsTable.ts +++ b/src/discrete-layer/components/export-layer/hooks/useZoomLevelsTable.ts @@ -1,17 +1,25 @@ import { get } from 'lodash'; import { useContext } from 'react'; -import lookupTablesContext, { ILookupOption } from '../../../../common/contexts/lookupTables.context'; +import lookupTablesContext, { + ILookupOption, +} from '../../../../common/contexts/lookupTables.context'; -const useZoomLevelsTable = (): Record => { - const zoomlevelresolutions = {} as Record; +const useZoomLevelsTable = (): Record => { + const zoomlevelresolutions = {} as Record; const { lookupTablesData } = useContext(lookupTablesContext); - const lookupOptions = get(lookupTablesData?.dictionary, 'zoomlevelresolutions') as ILookupOption[] ?? []; + const lookupOptions = + (get( + lookupTablesData?.dictionary, + 'zoomlevelresolutions' + ) as ILookupOption[]) ?? []; lookupOptions?.forEach((option) => { - zoomlevelresolutions[option.value] = option.properties['resolutionDeg'] as number; + zoomlevelresolutions[option.value] = option.properties[ + 'resolutionDeg' + ] as number; }); - + return zoomlevelresolutions; -} +}; -export default useZoomLevelsTable; \ No newline at end of file +export default useZoomLevelsTable; diff --git a/src/discrete-layer/components/export-layer/types/enums.ts b/src/discrete-layer/components/export-layer/types/enums.ts index e07cc76b7..8520a48fa 100644 --- a/src/discrete-layer/components/export-layer/types/enums.ts +++ b/src/discrete-layer/components/export-layer/types/enums.ts @@ -1,4 +1,4 @@ export enum DEMExportProjection { - WGS84 = "EPSG:4326", - UTM = "UTM", -} \ No newline at end of file + WGS84 = 'EPSG:4326', + UTM = 'UTM', +} diff --git a/src/discrete-layer/components/export-layer/types/interfaces.ts b/src/discrete-layer/components/export-layer/types/interfaces.ts index fc28c9b36..c407d63aa 100644 --- a/src/discrete-layer/components/export-layer/types/interfaces.ts +++ b/src/discrete-layer/components/export-layer/types/interfaces.ts @@ -1,4 +1,7 @@ -import { AvailableProperties, ExportFieldOptions } from '../hooks/useAddFeatureWithProps'; +import { + AvailableProperties, + ExportFieldOptions, +} from '../hooks/useAddFeatureWithProps'; export interface ExportFieldProps { selectionId: string; @@ -9,4 +12,3 @@ export interface ExportFieldProps { isLoading?: boolean; type?: 'text' | 'number'; } - \ No newline at end of file diff --git a/src/discrete-layer/components/export-layer/utils/export-layer-utils.ts b/src/discrete-layer/components/export-layer/utils/export-layer-utils.ts index 8ab62e3ee..5e350ffa6 100644 --- a/src/discrete-layer/components/export-layer/utils/export-layer-utils.ts +++ b/src/discrete-layer/components/export-layer/utils/export-layer-utils.ts @@ -3,16 +3,21 @@ import { get } from 'lodash'; import { IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; import { AvailableProperties } from '../hooks/useAddFeatureWithProps'; -export function sanitizeFeaturesWithProps(features: Feature[], internalPropsForDomain: Record): Feature[] { +export function sanitizeFeaturesWithProps( + features: Feature[], + internalPropsForDomain: Record +): Feature[] { const otherValidFeatureProps = ['label']; - const getNewFeatureProps = (feature: Feature): Record => { + const getNewFeatureProps = ( + feature: Feature + ): Record => { const internalProps = [ ...otherValidFeatureProps, - ...Object.keys(internalPropsForDomain) + ...Object.keys(internalPropsForDomain), ].reduce( (props, key) => ({ ...props, - [key]: (get(internalPropsForDomain, key) as string | undefined) ?? "" + [key]: (get(internalPropsForDomain, key) as string | undefined) ?? '', }), {} as Record ); @@ -20,21 +25,27 @@ export function sanitizeFeaturesWithProps(features: Feature[], internalPropsForD const featureProps = (feature.properties ?? {}) as Record; const newFeatureProps = {} as Record; - for(const [internalPropKey, internalPropValue] of Object.entries(internalProps)) { - newFeatureProps[internalPropKey] = featureProps[internalPropKey] ?? internalPropValue; + for (const [internalPropKey, internalPropValue] of Object.entries( + internalProps + )) { + newFeatureProps[internalPropKey] = + featureProps[internalPropKey] ?? internalPropValue; } return newFeatureProps; - } + }; - return features.map(feature => ({ ...feature, properties: getNewFeatureProps(feature) })); + return features.map((feature) => ({ + ...feature, + properties: getNewFeatureProps(feature), + })); } export const getEnumRealValues = ( enums: IEnumsMapType, - enumName: string, + enumName: string ): string[] => { const options = Object.entries(enums) .filter(([key, enumDescriptor]) => enumDescriptor.enumName === enumName) .map(([, enumProps]) => enumProps.realValue); return options; -}; \ No newline at end of file +}; diff --git a/src/discrete-layer/components/filters/filters.tsx b/src/discrete-layer/components/filters/filters.tsx index ac6eac25d..49c6282ca 100644 --- a/src/discrete-layer/components/filters/filters.tsx +++ b/src/discrete-layer/components/filters/filters.tsx @@ -2,10 +2,12 @@ /* tslint:disable */ // TOFO: Remove when implemented import React, { useEffect, useRef } from 'react'; +import { TextField } from '@map-colonies/react-core'; import { - TextField, -} from '@map-colonies/react-core'; -import { Box, DateTimeRangePickerFormControl, SupportedLocales } from '@map-colonies/react-components'; + Box, + DateTimeRangePickerFormControl, + SupportedLocales, +} from '@map-colonies/react-components'; import { useIntl } from 'react-intl'; import { Formik, FormikProps } from 'formik'; import CONFIG from '../../../common/config'; @@ -16,24 +18,19 @@ export interface FiltersProps { filtersView: number; } -export const Filters: React.FC = ( - props -) => { - const { - isFiltersOpened, - filtersView, - } = props; +export const Filters: React.FC = (props) => { + const { isFiltersOpened, filtersView } = props; const prevFiltersView = usePrevious(filtersView); const intl = useIntl(); let formikRef = useRef>() as any; - const [filterValues, setFilterValues] = React.useState({sensor: ''}); + const [filterValues, setFilterValues] = React.useState({ sensor: '' }); const getFilters = (view: number) => { return { sensor: 'SENSOR FOR ' + filtersView.toString(), - } + }; }; useEffect(() => { @@ -41,63 +38,79 @@ export const Filters: React.FC = ( console.log('***** RE-STORE FILTERS FOR: ', filtersView); setFilterValues(getFilters(filtersView)); - } - else { + } else { console.log('***** STORE FILTERS FOR: ', filtersView, formikRef); } }, [isFiltersOpened]); useEffect(() => { - if (isFiltersOpened && prevFiltersView !== undefined && filtersView !== prevFiltersView) { + if ( + isFiltersOpened && + prevFiltersView !== undefined && + filtersView !== prevFiltersView + ) { console.log('***** STORE FILTERS FOR: ', prevFiltersView); - + console.log('***** RE-STORE FILTERS FOR: ', filtersView); setFilterValues(getFilters(filtersView)); } }, [filtersView, prevFiltersView, isFiltersOpened]); - return ( - isFiltersOpened ? -
- - - { - console.log('DateTimeRangePickerFormControl--->',dateRange.from, dateRange.to); - }} - local={{ - setText: intl.formatMessage({ id: 'filters.date-picker.set-btn.text' }), - startPlaceHolderText: intl.formatMessage({ id: 'filters.date-picker.start-time.label' }), - endPlaceHolderText: intl.formatMessage({ id: 'filters.date-picker.end-time.label' }), - calendarLocale: SupportedLocales[CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() as keyof typeof SupportedLocales] - }} - /> - { - if (instance) { - formikRef.current=instance; - } - }} - onSubmit={(values, actions) => { - // setTimeout(() => { - // alert(JSON.stringify(values, null, 2)); - // actions.setSubmitting(false); - // }, 1000); - }} - > - {props => ( + right: '0', + width: '20%', + position: 'absolute', + height: '80%', + }} + > + + { + console.log( + 'DateTimeRangePickerFormControl--->', + dateRange.from, + dateRange.to + ); + }} + local={{ + setText: intl.formatMessage({ + id: 'filters.date-picker.set-btn.text', + }), + startPlaceHolderText: intl.formatMessage({ + id: 'filters.date-picker.start-time.label', + }), + endPlaceHolderText: intl.formatMessage({ + id: 'filters.date-picker.end-time.label', + }), + calendarLocale: + SupportedLocales[ + CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() as keyof typeof SupportedLocales + ], + }} + /> + { + if (instance) { + formikRef.current = instance; + } + }} + onSubmit={(values, actions) => { + // setTimeout(() => { + // alert(JSON.stringify(values, null, 2)); + // actions.setSubmitting(false); + // }, 1000); + }} + > + {(props) => (
= ( )}
- -
-
- : - <> +
+
+ ) : ( + <> ); }; diff --git a/src/discrete-layer/components/helpers/errorUtils.ts b/src/discrete-layer/components/helpers/errorUtils.ts index 8bc9bf851..b8d513540 100644 --- a/src/discrete-layer/components/helpers/errorUtils.ts +++ b/src/discrete-layer/components/helpers/errorUtils.ts @@ -4,4 +4,4 @@ export interface IError { code?: string; message?: string; level?: ErrorLevel; -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/helpers/layersUtils.ts b/src/discrete-layer/components/helpers/layersUtils.ts index ebbdacd9a..6feac5a68 100644 --- a/src/discrete-layer/components/helpers/layersUtils.ts +++ b/src/discrete-layer/components/helpers/layersUtils.ts @@ -8,7 +8,7 @@ import { CesiumGeographicTilingScheme, CesiumRectangle, CesiumResource, - RCesiumWMTSLayerOptions + RCesiumWMTSLayerOptions, } from '@map-colonies/react-components'; import CONFIG from '../../../common/config'; import { LinkType } from '../../../common/models/link-type.enum'; @@ -18,7 +18,7 @@ import { LayerRasterRecordModelType, LinkModelType, StyleModelType, - TileMatrixSetModelType + TileMatrixSetModelType, } from '../../models'; import { ILayerImage } from '../../models/layerImage'; import { ResourceUrlModelType } from '../../models/ResourceUrlModel'; @@ -26,38 +26,61 @@ import { ResourceUrlModelType } from '../../models/ResourceUrlModel'; const DEFAULT_RECTANGLE_FACTOR = 0.2; const EARTH_AREA = 509000000; //whole EARTH surface, in square km -export const isPolygonContainedInLayer = (polygon: Feature, layer: LayerMetadataMixedUnion): boolean => { +export const isPolygonContainedInLayer = ( + polygon: Feature, + layer: LayerMetadataMixedUnion +): boolean => { const layerFootprintBBox = bbox(layer.footprint); const layerFootprintBBoxPolygon = bboxPolygon(layerFootprintBBox); return booleanContains(layerFootprintBBoxPolygon, polygon); }; -export const generateLayerRectangle = (layer: LayerMetadataMixedUnion): CesiumRectangle => { +export const generateLayerRectangle = ( + layer: LayerMetadataMixedUnion +): CesiumRectangle => { // eslint-disable-next-line - return CesiumRectangle.fromDegrees(...bbox(layer.footprint)) as CesiumRectangle; + return CesiumRectangle.fromDegrees( + ...bbox(layer.footprint) + ) as CesiumRectangle; }; -export const applyFactor = (rect: CesiumRectangle, factor = DEFAULT_RECTANGLE_FACTOR) => { +export const applyFactor = ( + rect: CesiumRectangle, + factor = DEFAULT_RECTANGLE_FACTOR +) => { rect.east = rect.east + rect.width * factor; rect.west = rect.west - rect.width * factor; rect.south = rect.south - rect.height * factor; rect.north = rect.north + rect.height * factor; -} +}; -export const generateFactoredLayerRectangle = (layer: LayerMetadataMixedUnion, factor = DEFAULT_RECTANGLE_FACTOR): CesiumRectangle => { +export const generateFactoredLayerRectangle = ( + layer: LayerMetadataMixedUnion, + factor = DEFAULT_RECTANGLE_FACTOR +): CesiumRectangle => { const rectWithBuffers = generateLayerRectangle(layer); - if (area({ type: 'Feature', properties:{}, geometry: layer.footprint})/1000000 > EARTH_AREA) { + if ( + area({ type: 'Feature', properties: {}, geometry: layer.footprint }) / + 1000000 > + EARTH_AREA + ) { factor = 0; } applyFactor(rectWithBuffers, factor); return rectWithBuffers; }; -export const findLayerLink = (layer: ILayerImage): LinkModelType | undefined => { - let wmtsLayer = layer.links?.find((link: LinkModelType) => [LinkType.WMTS_LAYER as string].includes(link.protocol as string)) as LinkModelType | undefined; +export const findLayerLink = ( + layer: ILayerImage +): LinkModelType | undefined => { + let wmtsLayer = layer.links?.find((link: LinkModelType) => + [LinkType.WMTS_LAYER as string].includes(link.protocol as string) + ) as LinkModelType | undefined; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (wmtsLayer === undefined) { - wmtsLayer = layer.links?.find((link: LinkModelType) => [LinkType.WMTS as string].includes(link.protocol as string)) as LinkModelType | undefined; + wmtsLayer = layer.links?.find((link: LinkModelType) => + [LinkType.WMTS as string].includes(link.protocol as string) + ) as LinkModelType | undefined; } return wmtsLayer; }; @@ -72,18 +95,29 @@ export const getLayerLink = (layer: ILayerImage): LinkModelType => { export const getTokenParam = (): string => { // eslint-disable-next-line - const {INJECTION_TYPE, ATTRIBUTE_NAME, TOKEN_VALUE} = CONFIG.ACCESS_TOKEN as {INJECTION_TYPE: string, ATTRIBUTE_NAME: string, TOKEN_VALUE: string}; + const { INJECTION_TYPE, ATTRIBUTE_NAME, TOKEN_VALUE } = + CONFIG.ACCESS_TOKEN as { + INJECTION_TYPE: string; + ATTRIBUTE_NAME: string; + TOKEN_VALUE: string; + }; if (INJECTION_TYPE && INJECTION_TYPE.toLowerCase() === 'queryparam') { return `?${ATTRIBUTE_NAME}=${TOKEN_VALUE}`; } return ''; }; -export const getLinkUrl = (links: LinkModelType[], protocol: string): string | undefined => { +export const getLinkUrl = ( + links: LinkModelType[], + protocol: string +): string | undefined => { return links.find((link: LinkModelType) => link.protocol === protocol)?.url; }; -export const getLinkUrlWithToken = (links: LinkModelType[], protocol?: string): string | undefined => { +export const getLinkUrlWithToken = ( + links: LinkModelType[], + protocol?: string +): string | undefined => { if (typeof links !== 'undefined') { // supporting a single link let linkUrl = links[0]?.url; @@ -91,16 +125,20 @@ export const getLinkUrlWithToken = (links: LinkModelType[], protocol?: string): if (typeof protocol !== 'undefined') { linkUrl = getLinkUrl(links, protocol); } - const urlWithToken = `${linkUrl ?? ''}${linkUrl !== undefined ? getTokenParam() : ''}`; + const urlWithToken = `${linkUrl ?? ''}${ + linkUrl !== undefined ? getTokenParam() : '' + }`; return !isEmpty(urlWithToken) ? urlWithToken : undefined; } }; -export const getLinksArrWithTokens = (links: LinkModelType[]): LinkModelType[] => { - const linksWithTokens = links.map(link => { +export const getLinksArrWithTokens = ( + links: LinkModelType[] +): LinkModelType[] => { + const linksWithTokens = links.map((link) => { return { ...link, - url: getLinkUrlWithToken([link]) + url: getLinkUrlWithToken([link]), }; }); return linksWithTokens; @@ -108,17 +146,22 @@ export const getLinksArrWithTokens = (links: LinkModelType[]): LinkModelType[] = export const getTokenResource = (url: string, ver?: string): CesiumResource => { const tokenProps: Record = { url }; - + // eslint-disable-next-line - const {INJECTION_TYPE, ATTRIBUTE_NAME, TOKEN_VALUE} = CONFIG.ACCESS_TOKEN as {INJECTION_TYPE: string, ATTRIBUTE_NAME: string, TOKEN_VALUE: string}; - + const { INJECTION_TYPE, ATTRIBUTE_NAME, TOKEN_VALUE } = + CONFIG.ACCESS_TOKEN as { + INJECTION_TYPE: string; + ATTRIBUTE_NAME: string; + TOKEN_VALUE: string; + }; + if (INJECTION_TYPE && INJECTION_TYPE.toLowerCase() === 'header') { tokenProps.headers = { - [ATTRIBUTE_NAME]: TOKEN_VALUE + [ATTRIBUTE_NAME]: TOKEN_VALUE, } as Record; } else if (INJECTION_TYPE && INJECTION_TYPE.toLowerCase() === 'queryparam') { tokenProps.queryParameters = { - [ATTRIBUTE_NAME]: TOKEN_VALUE + [ATTRIBUTE_NAME]: TOKEN_VALUE, } as Record; } @@ -127,29 +170,66 @@ export const getTokenResource = (url: string, ver?: string): CesiumResource => { // ...(typeof ver !== 'undefined' ? { ver } : {}) }; - return new CesiumResource({...tokenProps as unknown as CesiumResource}); + return new CesiumResource({ ...(tokenProps as unknown as CesiumResource) }); }; -export const getWMTSOptions = (layer: LayerRasterRecordModelType, url: string, capability: CapabilityModelType | undefined): RCesiumWMTSLayerOptions => { +export const getWMTSOptions = ( + layer: LayerRasterRecordModelType, + url: string, + capability: CapabilityModelType | undefined +): RCesiumWMTSLayerOptions => { let style = 'default'; let format = 'image/jpeg'; - let {tileMatrixSetID, tileMatrixLabels} = { + let { tileMatrixSetID, tileMatrixLabels } = { tileMatrixSetID: 'newGrids', - tileMatrixLabels: [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20' ] + tileMatrixLabels: [ + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '20', + ], }; if (capability) { - const defaultStyle = (capability.style as StyleModelType[]).find((s: StyleModelType) => s.isDefault !== undefined && s.isDefault === 'true')?.value; - style = defaultStyle !== undefined ? defaultStyle : (get(capability, 'style[0]') as StyleModelType).value as string; + const defaultStyle = (capability.style as StyleModelType[]).find( + (s: StyleModelType) => s.isDefault !== undefined && s.isDefault === 'true' + )?.value; + style = + defaultStyle !== undefined + ? defaultStyle + : ((get(capability, 'style[0]') as StyleModelType).value as string); // TODO: format should be taken from layer record from new Transparent/Opaque field if exists in capabilities, otherwise - take first (format[0]) format = get(capability, 'format[0]') as string; // (!IMPORTANT) derived from raster implementation: there is only ONE surved tiles format - const tileMatrixSet = get(capability, 'tileMatrixSet[0]') as TileMatrixSetModelType; // (!IMPORTANT) derived from raster implementation: there is only ONE surved tile matrix set + const tileMatrixSet = get( + capability, + 'tileMatrixSet[0]' + ) as TileMatrixSetModelType; // (!IMPORTANT) derived from raster implementation: there is only ONE surved tile matrix set if (tileMatrixSet.tileMatrixSetID !== undefined) { tileMatrixSetID = tileMatrixSet.tileMatrixSetID; } if (tileMatrixSet.tileMatrixLabels !== undefined) { tileMatrixLabels = tileMatrixSet.tileMatrixLabels; } - url = (capability.url as ResourceUrlModelType[]).find((u: ResourceUrlModelType) => u.format === format)?.template ?? url; + url = + (capability.url as ResourceUrlModelType[]).find( + (u: ResourceUrlModelType) => u.format === format + )?.template ?? url; } return { url: getTokenResource(url, layer.productVersion as string), @@ -159,6 +239,6 @@ export const getWMTSOptions = (layer: LayerRasterRecordModelType, url: string, c tileMatrixSetID, // tileMatrixLabels, maximumLevel: Math.max(...tileMatrixLabels.map(Number)), - tilingScheme: new CesiumGeographicTilingScheme() + tilingScheme: new CesiumGeographicTilingScheme(), }; -}; \ No newline at end of file +}; diff --git a/src/discrete-layer/components/job-errors-summary/job-errors-summary.tsx b/src/discrete-layer/components/job-errors-summary/job-errors-summary.tsx index 333ddb9ae..65949349a 100644 --- a/src/discrete-layer/components/job-errors-summary/job-errors-summary.tsx +++ b/src/discrete-layer/components/job-errors-summary/job-errors-summary.tsx @@ -1,53 +1,78 @@ import { FormattedMessage } from 'react-intl'; import { IOptions } from '@map-colonies/react-core'; import { Box } from '@material-ui/core'; -import { RasterErrorCount, RasterErrorsSummary } from '../../../common/models/job-errors-summary.raster'; +import { + RasterErrorCount, + RasterErrorsSummary, +} from '../../../common/models/job-errors-summary.raster'; interface ErrorCountProps { name: string; value: number; className: string; - color?: string + color?: string; } -const ErrorCount = ({ name, value, className, color }: ErrorCountProps): JSX.Element => { +const ErrorCount = ({ + name, + value, + className, + color, +}: ErrorCountProps): JSX.Element => { return ( - - {value} - + {value} ); }; -export const getRasterErrorCount = (errorsSummary: RasterErrorsSummary | undefined, key: string): RasterErrorCount => { +export const getRasterErrorCount = ( + errorsSummary: RasterErrorsSummary | undefined, + key: string +): RasterErrorCount => { if (!errorsSummary) { return {}; } const count = (errorsSummary.errorsCount as Record)[key]; - const exceeded = (errorsSummary.thresholds as Record)[key]?.exceeded; + const exceeded = ( + errorsSummary.thresholds as Record + )[key]?.exceeded; return { count, - exceeded + exceeded, }; }; -export const JobErrorsSummary = (theme: IOptions, errorsSummary: RasterErrorsSummary | undefined, className: string, overrideColor?: string): JSX.Element[] | undefined => { +export const JobErrorsSummary = ( + theme: IOptions, + errorsSummary: RasterErrorsSummary | undefined, + className: string, + overrideColor?: string +): JSX.Element[] | undefined => { if (!errorsSummary) { return; } return Object.entries(errorsSummary.errorsCount).map(([key, value]) => { let color = overrideColor; if (!overrideColor) { - color = value === 0 - ? theme.custom?.GC_SUCCESS - : getRasterErrorCount(errorsSummary, key)?.exceeded === false + color = + value === 0 + ? theme.custom?.GC_SUCCESS + : getRasterErrorCount(errorsSummary, key)?.exceeded === false ? theme.custom?.GC_WARNING_HIGH : theme.custom?.GC_ERROR_HIGH; } - return ; + return ( + + ); }); }; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.css b/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.css index 1ff2e6633..fa0f2138b 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.css @@ -12,7 +12,7 @@ width: 100%; } -.updateableDateCellRendererPicker .MuiInput-underline:before, +.updateableDateCellRendererPicker .MuiInput-underline:before, .updateableDateCellRendererPicker .MuiInput-underline:hover { border-bottom: 0 !important; } @@ -23,9 +23,13 @@ @keyframes soonIndicator { from { - text-shadow: 0 0 10px #fff, 0 0 12px #fff, 0 0 14px var(--mdc-theme-gc-warning-high), 0 0 15px var(--mdc-theme-gc-warning-high); + text-shadow: 0 0 10px #fff, 0 0 12px #fff, + 0 0 14px var(--mdc-theme-gc-warning-high), + 0 0 15px var(--mdc-theme-gc-warning-high); } to { - text-shadow: 0 0 12px #fff, 0 0 14px var(--mdc-theme-gc-warning-high), 0 0 16px var(--mdc-theme-gc-warning-high), 0 0 18px var(--mdc-theme-gc-warning-high); + text-shadow: 0 0 12px #fff, 0 0 14px var(--mdc-theme-gc-warning-high), + 0 0 16px var(--mdc-theme-gc-warning-high), + 0 0 18px var(--mdc-theme-gc-warning-high); } -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.tsx b/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.tsx index 6ba968c5c..8d8017151 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/date.cell-renderer.tsx @@ -1,7 +1,11 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import { ICellRendererParams } from 'ag-grid-community'; import { Tooltip } from '@map-colonies/react-core'; -import { Box, DateTimePicker, SupportedLocales } from '@map-colonies/react-components'; +import { + Box, + DateTimePicker, + SupportedLocales, +} from '@map-colonies/react-components'; import moment, { Moment } from 'moment'; import { dateFormatter, @@ -23,7 +27,7 @@ interface IDateCellRendererParams extends ICellRendererParams { disablePast?: boolean; disableFuture?: boolean; minDate?: Date; - } + }; } const FUTURE_DATE_DIFF_ANCHOR = 0; @@ -32,16 +36,32 @@ const CHANGEABLE_DATE_CSS_CLASS = 'changeable'; const DATE_GRANULARITY = DateGranularityType.DATE_AND_TIME; export const DateCellRenderer: React.FC = (props) => { - const {field, shouldShowPredicate, comingSoonDaysIndication, onChange, datePickerProps} = props; + const { + field, + shouldShowPredicate, + comingSoonDaysIndication, + onChange, + datePickerProps, + } = props; const isChangeable = typeof onChange !== 'undefined'; const currentDate = useMemo(() => { - return typeof get(props.data, field) === 'undefined' ? undefined : moment(get(props.data, field)) + return typeof get(props.data, field) === 'undefined' + ? undefined + : moment(get(props.data, field)); }, [props.data]); const [date, setDate] = useState(currentDate); const prevDate = useRef(currentDate); - const shouldShowTime = useMemo(() => DATE_GRANULARITY as DateGranularityType === DateGranularityType.DATE_AND_TIME, []); - const dateFnsFormat = useMemo(() => shouldShowTime ? 'dd/LL/yyyy HH:mm' : 'dd/LL/yyyy', [shouldShowTime]); + const shouldShowTime = useMemo( + () => + (DATE_GRANULARITY as DateGranularityType) === + DateGranularityType.DATE_AND_TIME, + [] + ); + const dateFnsFormat = useMemo( + () => (shouldShowTime ? 'dd/LL/yyyy HH:mm' : 'dd/LL/yyyy'), + [shouldShowTime] + ); useEffect(() => { setDate(currentDate); @@ -52,19 +72,28 @@ export const DateCellRenderer: React.FC = (props) => { const today = moment(); const diffFromToday = today.diff(date); - if (typeof comingSoonDaysIndication === 'undefined' || diffFromToday > FUTURE_DATE_DIFF_ANCHOR) return ''; + if ( + typeof comingSoonDaysIndication === 'undefined' || + diffFromToday > FUTURE_DATE_DIFF_ANCHOR + ) + return ''; - return moment(date).diff(today, 'days') <= comingSoonDaysIndication ? SOON_INDICATOR_CSS_CLASS : ''; - } + return moment(date).diff(today, 'days') <= comingSoonDaysIndication + ? SOON_INDICATOR_CSS_CLASS + : ''; + }; if ( typeof date !== 'undefined' && - (typeof shouldShowPredicate === 'undefined' || shouldShowPredicate(props.data)) + (typeof shouldShowPredicate === 'undefined' || + shouldShowPredicate(props.data)) ) { return ( {relativeDateFormatter(date)} @@ -91,9 +120,12 @@ export const DateCellRenderer: React.FC = (props) => { prevDate.current = date; }} onChange={(newDate: string): void => { - setDate(moment(newDate)) + setDate(moment(newDate)); + }} + local={{ + calendarLocale: CONFIG.I18N + .DEFAULT_LANGUAGE as SupportedLocales, }} - local={{ calendarLocale: CONFIG.I18N.DEFAULT_LANGUAGE as SupportedLocales }} autoOk {...(datePickerProps ?? {})} /> @@ -103,6 +135,5 @@ export const DateCellRenderer: React.FC = (props) => { ); } - return - + return ; }; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.css b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.css index f30a5a943..3a8e89a23 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.css @@ -8,16 +8,16 @@ padding: 8px; } -.jobDetailsContainer { - overflow-y: auto; +.jobDetailsContainer { + overflow-y: auto; height: 230px; width: 1300px; margin: 0px 35px; - background:var(--ag-selected-details-row-background); + background: var(--ag-selected-details-row-background); padding-left: 20px; } -body[dir="rtl"] .jobDetailsContainer { +body[dir='rtl'] .jobDetailsContainer { padding-left: unset; } @@ -31,7 +31,7 @@ body[dir="rtl"] .jobDetailsContainer { padding: 8px; } -.jobDetailsContainer .loadingContainer{ +.jobDetailsContainer .loadingContainer { grid-column: 1 / -1; height: 10em; justify-self: center; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.tsx b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.tsx index fe28f8388..faa6a835a 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.cell-renderer.tsx @@ -10,8 +10,17 @@ import { Copy } from '../../../../../common/components/copy/copy'; import { AutoDirectionBox } from '../../../../../common/components/auto-direction-box/auto-direction-box.component'; import { DETAILS_ROW_ID_SUFFIX } from '../../../../../common/components/grid'; import { Loading } from '../../../../../common/components/tree/statuses/loading'; -import { relativeDateFormatter, dateFormatter, } from '../../../../../common/helpers/formatters'; -import { JobModelType, ProductType, Status, TasksGroupModelType, useStore } from '../../../../models'; +import { + relativeDateFormatter, + dateFormatter, +} from '../../../../../common/helpers/formatters'; +import { + JobModelType, + ProductType, + Status, + TasksGroupModelType, + useStore, +} from '../../../../models'; import { useQuery } from '../../../../models/RootStore'; import { JobDetailsHeader } from './job-details.header'; import { JobDetailsExportJobData } from './job.details.export-job-data'; @@ -55,10 +64,13 @@ const taskFields: ITaskField[] = [ interface StatusPresentorParams { task: Record; - reactKey?: string + reactKey?: string; } -const StatusPresentor: React.FC = ({ task, reactKey = '' }) => { +const StatusPresentor: React.FC = ({ + task, + reactKey = '', +}) => { const intl = useIntl(); const statusText = intl.formatMessage({ @@ -70,7 +82,10 @@ const StatusPresentor: React.FC = ({ task, reactKey = '' let showPercentage = false; - if (task.counts === NUMBER_OF_TASKS_IN_GROUP && task.status === Status.InProgress) { + if ( + task.counts === NUMBER_OF_TASKS_IN_GROUP && + task.status === Status.InProgress + ) { showPercentage = true; } @@ -84,7 +99,7 @@ const StatusPresentor: React.FC = ({ task, reactKey = '' > {(task.percentage as Number).toString() + '%'} - ) + ); } }; @@ -97,7 +112,10 @@ const StatusPresentor: React.FC = ({ task, reactKey = '' }); return ( - + <> @@ -114,7 +132,7 @@ const StatusPresentor: React.FC = ({ task, reactKey = '' - + ); } @@ -150,7 +168,11 @@ const getValuePresentor = ( case 'Status': return ; default: - return {task[field.name] as string} ; + return ( + + {task[field.name] as string}{' '} + + ); } }; @@ -159,96 +181,108 @@ interface TasksRendererParams { productType: ProductType; } -const TasksRenderer: React.FC = observer(({ jobId, productType}) => { - const [tasksData, setTasksData] = useState([]); +const TasksRenderer: React.FC = observer( + ({ jobId, productType }) => { + const [tasksData, setTasksData] = useState([]); - const { loading, data } = useQuery( - (store) => - store.queryTasks({ - params: { - jobId, - }, - }), - { - fetchPolicy: 'no-cache', - } - ); + const { loading, data } = useQuery( + (store) => + store.queryTasks({ + params: { + jobId, + }, + }), + { + fetchPolicy: 'no-cache', + } + ); - useEffect(() => { - if (data?.tasks) { - setTasksData(data.tasks); - } - }, [data]); + useEffect(() => { + if (data?.tasks) { + setTasksData(data.tasks); + } + }, [data]); - if (loading) - return ( - - - - ); + if (loading) + return ( + + + + ); - return ( - <> - { - tasksData.map((task) => { + return ( + <> + {tasksData.map((task) => { return taskFields.map((field, idx) => { return getValuePresentor( - (task as unknown) as Record, + task as unknown as Record, field, idx ); }); - }) - } - - ); -}); + })} + + ); + } +); + +export const JobDetailsRenderer: React.FC = observer( + (props) => { + const store = useStore(); -export const JobDetailsRenderer: React.FC = observer((props) => { - const store = useStore(); - - const [propsWithJobParams, setPropsWithJobParams] = useState(props); - const jobId = (props.data as JobModelType).id.replace(DETAILS_ROW_ID_SUFFIX, ''); + const [propsWithJobParams, setPropsWithJobParams] = useState(props); + const jobId = (props.data as JobModelType).id.replace( + DETAILS_ROW_ID_SUFFIX, + '' + ); - const { data } = useQuery( - (store) => + const { data } = useQuery((store) => store.queryJob({ id: jobId, }) - ); + ); - useEffect(() => { - if (!data?.job) return; + useEffect(() => { + if (!data?.job) return; - setPropsWithJobParams(prev => ({ - ...prev, - data: { - ...props.data, - parameters: data.job?.parameters - }, - })); - }, [data]); + setPropsWithJobParams((prev) => ({ + ...prev, + data: { + ...props.data, + parameters: data.job?.parameters, + }, + })); + }, [data]); - const keyPrefix = `${(props.data as JobModelType).resourceId as string}`; + const keyPrefix = `${(props.data as JobModelType).resourceId as string}`; - return ( - - - - - - {taskFields.map((field) => ( - - - - ))} - + return ( + + + + + + {taskFields.map((field) => ( + + + + ))} + + - - ); -}); + ); + } +); diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.css b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.css index 26e80ed36..0722a2d66 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.css @@ -1,21 +1,20 @@ .failReasonAreaContainer { line-height: 0px; padding: 0 10px; - height:0; - display:none; + height: 0; + display: none; } -.failReasonAreaContainer.show{ - display: flex; - justify-content: center; - align-items: center; - opacity: 1; - padding: 10px; - line-height: 20px; - height: 1em; - transition: all 0.1s ease-in; +.failReasonAreaContainer.show { + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + padding: 10px; + line-height: 20px; + height: 1em; + transition: all 0.1s ease-in; } - .failReasonText { max-width: 50ch; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.tsx b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.tsx index 11d3d52dc..6dfd8f65f 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.fail-reason-area.tsx @@ -1,4 +1,4 @@ -import React,{useState, useEffect} from 'react'; +import React, { useState, useEffect } from 'react'; import { Typography } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { Copy } from '../../../../../common/components/copy/copy'; @@ -11,8 +11,14 @@ interface FailReasonAreaProps { key?: string; } -export const FailReasonArea: React.FC = ({ failReason, show, key = '' }) => { - const [containerClass, setContainerClass] = useState('failReasonAreaContainer'); +export const FailReasonArea: React.FC = ({ + failReason, + show, + key = '', +}) => { + const [containerClass, setContainerClass] = useState( + 'failReasonAreaContainer' + ); useEffect(() => { setContainerClass(`failReasonAreaContainer ${show ? 'show' : ''}`); @@ -24,7 +30,7 @@ export const FailReasonArea: React.FC = ({ failReason, show {failReason} - + ); diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.css b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.css index c179e6a98..85d4d9859 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.css @@ -26,15 +26,14 @@ } .counterField { - display:flex; - align-items: center; - justify-content: center; - + display: flex; + align-items: center; + justify-content: center; } .countLabel { - color: var(--mdc-theme-text-icon-on-dark); - margin: 0; + color: var(--mdc-theme-text-icon-on-dark); + margin: 0; } .countValue { @@ -48,7 +47,7 @@ align-items: center; font-weight: bold; font-size: 1.2em; - background:var(--ag-selected-details-row-background); + background: var(--ag-selected-details-row-background); } .failReasonText { @@ -56,20 +55,20 @@ text-overflow: ellipsis; overflow: hidden; color: var(--mdc-theme-gc-error-high); - margin:0; + margin: 0; } -.detailsField{ - max-width: 35ch; - margin: 2px 12px; - display:flex; - align-items: center; - justify-content: center; +.detailsField { + max-width: 35ch; + margin: 2px 12px; + display: flex; + align-items: center; + justify-content: center; } .detailLabel { - color: var(--mdc-theme-text-icon-on-dark); - margin:0; + color: var(--mdc-theme-text-icon-on-dark); + margin: 0; } .detailValue { diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.tsx b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.tsx index 46711d3a5..47588ba5e 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.header.tsx @@ -5,7 +5,7 @@ import { Box } from '@map-colonies/react-components'; import { Copy } from '../../../../../common/components/copy/copy'; import { AutoDirectionBox } from '../../../../../common/components/auto-direction-box/auto-direction-box.component'; import TooltippedValue from '../../../../../common/components/form/tooltipped.value'; -import {DETAILS_ROW_ID_SUFFIX} from '../../../../../common/components/grid'; +import { DETAILS_ROW_ID_SUFFIX } from '../../../../../common/components/grid'; import { JobModelType, Status } from '../../../../models'; import './job-details.header.css'; @@ -65,24 +65,24 @@ export const JobDetailsHeader: React.FC = ({ taskCountRow: { completed: { label: getStatusTranslation(Status.Completed), - value: (completedTasks as unknown) as string, + value: completedTasks as unknown as string, }, failed: { label: getStatusTranslation(Status.Failed), - value: (failedTasks as unknown) as string, + value: failedTasks as unknown as string, }, inProgress: { label: getStatusTranslation(Status.InProgress), - value: (inProgressTasks as unknown) as string, + value: inProgressTasks as unknown as string, }, pending: { label: getStatusTranslation(Status.Pending), - value: (pendingTasks as unknown) as string, + value: pendingTasks as unknown as string, }, // suspended: { expired: { label: getStatusTranslation(Status.Suspended), - value: (expiredTasks as unknown) as string, + value: expiredTasks as unknown as string, }, }, failReason: { @@ -90,44 +90,48 @@ export const JobDetailsHeader: React.FC = ({ }, }; - const generateDetailsRow = (): JSX.Element => { return ( <> - {Object.values(dataToPresent.detailsRow).map(({ label, value }, index) => { - return ( - - - {`${label}:`} - - - {value} - - - - ); - })} + {Object.values(dataToPresent.detailsRow).map( + ({ label, value }, index) => { + return ( + + + {`${label}:`} + + + {value} + + + + ); + } + )} ); }; const generateTaskCounts = (): JSX.Element => { - const localeValueWithCommas = (value: string): string => Number(value).toLocaleString(); + const localeValueWithCommas = (value: string): string => + Number(value).toLocaleString(); return ( <> - {Object.values(dataToPresent.taskCountRow).map(({ label, value },index) => { - return ( - - - {`${label}:`} - - - {localeValueWithCommas(value)} - - - ); - })} + {Object.values(dataToPresent.taskCountRow).map( + ({ label, value }, index) => { + return ( + + + {`${label}:`} + + + {localeValueWithCommas(value)} + + + ); + } + )} ); }; @@ -140,7 +144,7 @@ export const JobDetailsHeader: React.FC = ({ {failReason} - + ); }; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.raster-job-data.tsx b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.raster-job-data.tsx index 521cd419e..faaeb7010 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.raster-job-data.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.raster-job-data.tsx @@ -3,25 +3,41 @@ import { get } from 'lodash'; import React, { useCallback, useEffect, useState } from 'react'; import { useIntl } from 'react-intl'; import { Box } from '@map-colonies/react-components'; -import { CircularProgress, IconButton, Tooltip, Typography, useTheme } from '@map-colonies/react-core'; +import { + CircularProgress, + IconButton, + Tooltip, + Typography, + useTheme, +} from '@map-colonies/react-core'; import { AutoDirectionBox } from '../../../../../common/components/auto-direction-box/auto-direction-box.component'; import { DETAILS_ROW_ID_SUFFIX } from '../../../../../common/components/grid'; import { Hyperlink } from '../../../../../common/components/hyperlink/hyperlink'; import { Domain } from '../../../../../common/models/domain'; import { RasterErrorsSummary } from '../../../../../common/models/job-errors-summary.raster'; import { RasterIngestionJobType } from '../../../../../common/models/raster-job'; -import { JobModelType, Status, TaskModelType, useStore } from '../../../../models'; +import { + JobModelType, + Status, + TaskModelType, + useStore, +} from '../../../../models'; import useZoomLevelsTable from '../../../export-layer/hooks/useZoomLevelsTable'; -import { getRasterErrorCount, JobErrorsSummary } from '../../../job-errors-summary/job-errors-summary'; +import { + getRasterErrorCount, + JobErrorsSummary, +} from '../../../job-errors-summary/job-errors-summary'; import './info-area.css'; import './job-details.raster-job-data.css'; -interface JobDetailsRasterJobDataProps extends ICellRendererParams { } +interface JobDetailsRasterJobDataProps extends ICellRendererParams {} const MAX_ERRORS_SHOWN = 99; -export const JobDetailsRasterJobData: React.FC = ({ data }) => { +export const JobDetailsRasterJobData: React.FC< + JobDetailsRasterJobDataProps +> = ({ data }) => { const jobData = data as JobModelType; const store = useStore(); const intl = useIntl(); @@ -35,13 +51,18 @@ export const JobDetailsRasterJobData: React.FC = ( const isRasterJob = jobData.domain === Domain.RASTER && jobData.type && - Object.values(RasterIngestionJobType).includes(jobData.type as RasterIngestionJobType); + Object.values(RasterIngestionJobType).includes( + jobData.type as RasterIngestionJobType + ); const calculateErrorsCount = (errors: RasterErrorsSummary): number => { let count = 0; Object.keys(errors.errorsCount).forEach((key) => { const errorCount = getRasterErrorCount(errors, key); - if (errorCount.exceeded === true || typeof errorCount.exceeded === 'undefined') { + if ( + errorCount.exceeded === true || + typeof errorCount.exceeded === 'undefined' + ) { count += errorCount.count ?? 0; } }); @@ -53,8 +74,8 @@ export const JobDetailsRasterJobData: React.FC = ( const result = await store.queryFindTasks({ params: { jobId: jobData.id.replace(DETAILS_ROW_ID_SUFFIX, ''), - type: 'validation' - } + type: 'validation', + }, }); if (!result?.findTasks[0]) { return undefined; @@ -67,17 +88,20 @@ export const JobDetailsRasterJobData: React.FC = ( setErrorsCount(calculateErrorsCount(errorsCount)); } } - } catch { } + } catch {} }, [store, jobData]); const computeZoomLevel = useCallback(() => { - const ingestionResolution = get(jobData?.parameters, 'ingestionResolution')?.toString(); + const ingestionResolution = get( + jobData?.parameters, + 'ingestionResolution' + )?.toString(); if (!ingestionResolution) { return; } const index = Object.values(ZOOM_LEVELS_TABLE) .map((value) => value.toString()) - .findIndex(value => value === ingestionResolution); + .findIndex((value) => value === ingestionResolution); if (index >= 0) { setZoomLevel(index); } @@ -95,9 +119,10 @@ export const JobDetailsRasterJobData: React.FC = ( const zoomLabel = zoomLevel !== undefined ? `(${zoomLevel})` : ''; - const rasterInfo = (jobData.parameters && hasGpkgPath()) - ? `${getGpkgFilesPath()} ${zoomLabel}` - : intl.formatMessage({ id: 'general.deprecated-job.text' }); + const rasterInfo = + jobData.parameters && hasGpkgPath() + ? `${getGpkgFilesPath()} ${zoomLabel}` + : intl.formatMessage({ id: 'general.deprecated-job.text' }); const hasErrors = errorsCount > 0; const isTaskFailed = task?.status === Status.Failed; @@ -123,18 +148,16 @@ export const JobDetailsRasterJobData: React.FC = ( - { - !isLoading - ? rasterInfo - : - } + {!isLoading ? ( + rasterInfo + ) : ( + + )} - { - !isLoading && + {!isLoading && ( - { - !isTaskFailed && hasErrors && + {!isTaskFailed && hasErrors && ( = ( e.stopPropagation(); }} /> - - {JobErrorsSummary(theme, task?.parameters?.errorsSummary, "reportItem")} - - }> - + {JobErrorsSummary( + theme, + task?.parameters?.errorsSummary, + 'reportItem' + )} + + } + > + MAX_ERRORS_SHOWN ? `+${MAX_ERRORS_SHOWN}` : errorsCount} ${errorsMessage}`} - > - + label={`${ + errorsCount > MAX_ERRORS_SHOWN + ? `+${MAX_ERRORS_SHOWN}` + : errorsCount + } ${errorsMessage}`} + > - MAX_ERRORS_SHOWN ? `+${MAX_ERRORS_SHOWN}` : errorsCount} ${errorsMessage}`} - > - - + MAX_ERRORS_SHOWN + ? `+${MAX_ERRORS_SHOWN}` + : errorsCount + } ${errorsMessage}`} + > + + - } - { - !isTaskFailed && !hasErrors && hasGpkgPath() && task && + )} + {!isTaskFailed && !hasErrors && hasGpkgPath() && task && ( {intl.formatMessage({ id: 'general.no-errors.text' })} - } - { - isTaskFailed && - - {JobErrorsSummary(theme, task?.parameters?.errorsSummary, "reportItem", theme.custom?.GC_ERROR_HIGH)} - - }> + )} + {isTaskFailed && ( + + {JobErrorsSummary( + theme, + task?.parameters?.errorsSummary, + 'reportItem', + theme.custom?.GC_ERROR_HIGH + )} + + } + > - {intl.formatMessage({ id: 'ingestion.error.failed-task-report' })} + {intl.formatMessage({ + id: 'ingestion.error.failed-task-report', + })} - } + )} - } + )} ); }; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.status.filter.tsx b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.status.filter.tsx index edf9b4f84..2cafe5e14 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.status.filter.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job-details.status.filter.tsx @@ -8,17 +8,21 @@ interface IFilterOnModelChange { onModelChange: (model: any | null, additionalEventAttributes?: any) => void; } -export const JobDetailsStatusFilter: React.FC = ({ onModelChange }) => { +export const JobDetailsStatusFilter: React.FC = ({ + onModelChange, +}) => { const intl = useIntl(); + const getStatusTranslation = useCallback( + (status: Status): string => { + const statusText = intl.formatMessage({ + id: `system-status.job.status_translation.${status as string}`, + }); - const getStatusTranslation = useCallback((status: Status): string => { - const statusText = intl.formatMessage({ - id: `system-status.job.status_translation.${status as string}`, - }); - - return statusText; - }, [intl]); + return statusText; + }, + [intl] + ); const getStatusOptions = useMemo((): JSX.Element => { const statuses: Record = {}; @@ -38,7 +42,9 @@ export const JobDetailsStatusFilter: React.FC = ({ onModel placeholder={showAllStatusesText} options={statuses} onChange={(evt: React.ChangeEvent): void => { - onModelChange(evt.currentTarget.value === '' ? null : evt.currentTarget.value) + onModelChange( + evt.currentTarget.value === '' ? null : evt.currentTarget.value + ); }} /> ); diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.css b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.css index d77785beb..1a2796431 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.css @@ -12,7 +12,7 @@ gap: 12px; } -#exportJobData.jobDataContainer .exportJobLinkContainer>a:hover { +#exportJobData.jobDataContainer .exportJobLinkContainer > a:hover { filter: brightness(150%); } @@ -32,4 +32,4 @@ #exportJobData .jobDataLink { color: var(--mdc-theme-text-primary-on-dark); font-size: 1.1rem; -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.tsx b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.tsx index 596624fa8..fc4501a30 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/job-details/job.details.export-job-data.tsx @@ -16,16 +16,23 @@ interface JobDetailsExportJobDataProps extends ICellRendererParams {} const NONE = 0; -export const JobDetailsExportJobData: React.FC = ({ data }) => { +export const JobDetailsExportJobData: React.FC< + JobDetailsExportJobDataProps +> = ({ data }) => { const intl = useIntl(); const jobData = data as JobModelType; - + const isExportJob = jobData.type?.toLowerCase().includes('export'); - const jobDescription = jobData.description as string | undefined ?? ''; - const exportLinks = get(jobData, `parameters.callbackParams.links`) as Record | undefined; + const jobDescription = (jobData.description as string | undefined) ?? ''; + const exportLinks = get(jobData, `parameters.callbackParams.links`) as + | Record + | undefined; - const expirationTimeUTC: string = get(jobData, `parameters.cleanupData.cleanupExpirationTimeUTC`); + const expirationTimeUTC: string = get( + jobData, + `parameters.cleanupData.cleanupExpirationTimeUTC` + ); let formattedExpirationTime = ''; let hasExpired: boolean = false; @@ -39,24 +46,34 @@ export const JobDetailsExportJobData: React.FC = ( const jobStatus = jobData.status; // const exportLinkLabel = intl.formatMessage({id: 'system-status.export-details.link.label'}); - const jobNoDescriptionText = intl.formatMessage({id: 'system-status.export-details.no-description.text'}); - - const jobDescriptionText = intl.formatMessage({ id: 'system-status.export-details.description.label' } ); + const jobNoDescriptionText = intl.formatMessage({ + id: 'system-status.export-details.no-description.text', + }); + + const jobDescriptionText = intl.formatMessage({ + id: 'system-status.export-details.description.label', + }); if (!(isExportJob as boolean)) return null; return ( - + - { - exportLinks && expirationTimeUTC && + {exportLinks && expirationTimeUTC && ( <> - - { intl.formatMessage({id: 'system-status.export-details.expirationDate'}) + ': ' + formattedExpirationTime} + + {intl.formatMessage({ + id: 'system-status.export-details.expirationDate', + }) + + ': ' + + formattedExpirationTime} - { " | " } + {' | '} - } + )} {jobDescriptionText} @@ -72,9 +89,17 @@ export const JobDetailsExportJobData: React.FC = ( {Object.entries(exportLinks).map(([linkType, exportLink]) => { const typeToPresent = linkType.replace('URI', ''); return ( - - - + + + ); })} diff --git a/src/discrete-layer/components/job-manager/cell-renderer/placeholder.cell-renderer.tsx b/src/discrete-layer/components/job-manager/cell-renderer/placeholder.cell-renderer.tsx index 3d9389389..b966f4c8f 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/placeholder.cell-renderer.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/placeholder.cell-renderer.tsx @@ -6,4 +6,4 @@ const PlaceholderCellRenderer: React.FC = () => { return ; }; -export default PlaceholderCellRenderer; \ No newline at end of file +export default PlaceholderCellRenderer; diff --git a/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.css b/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.css index a5aff34ae..efd850515 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.css @@ -23,7 +23,7 @@ } /* Priority is binded to status field... */ -.ag-cell-value[col-id="status"] { +.ag-cell-value[col-id='status'] { overflow: visible; } @@ -55,4 +55,4 @@ .priorityCellContainer .priorityReadonlyLabel { font-size: 16px; -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.tsx b/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.tsx index e670ba1ad..f6a166a83 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/priority.cell-renderer.tsx @@ -11,7 +11,7 @@ import { } from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { JobModelType, Status } from '../../../models'; -import { FINAL_STATUSES } from '../../job-manager/job.types' +import { FINAL_STATUSES } from '../../job-manager/job.types'; import './priority.cell-renderer.css'; @@ -24,7 +24,10 @@ interface PriorityOption { interface IPriorityCellRendererParams extends ICellRendererParams { optionsData: PriorityOption[]; - onChange: (e: React.FormEvent, jobData: ICellRendererParams) => void; + onChange: ( + e: React.FormEvent, + jobData: ICellRendererParams + ) => void; readOnly?: (jobData: JobModelType) => boolean; } @@ -33,13 +36,16 @@ export const PriorityRenderer: React.FC = ( ) => { const jobData: JobModelType = props.data as JobModelType; const { optionsData } = props; - const [value, setValue] = useState((get(jobData, 'priority') as number).toString()); + const [value, setValue] = useState( + (get(jobData, 'priority') as number).toString() + ); const [loading, setLoading] = useState(false); const [disabled, setDisabled] = useState(false); useEffect(() => { - const shouldBeDisabled = loading || FINAL_STATUSES.includes(jobData.status as Status) - setDisabled(shouldBeDisabled) + const shouldBeDisabled = + loading || FINAL_STATUSES.includes(jobData.status as Status); + setDisabled(shouldBeDisabled); }, [loading, jobData.status]); interface IconObj { @@ -53,7 +59,11 @@ export const PriorityRenderer: React.FC = ( (option: PriorityOption) => option.value === val ) as PriorityOption; - return { icon: selectedOption.icon, color: selectedOption.iconcolor, label: selectedOption.label }; + return { + icon: selectedOption.icon, + color: selectedOption.iconcolor, + label: selectedOption.label, + }; }, []); const [icon, setIcon] = useState(getIconObjForVal(value)); @@ -83,7 +93,9 @@ export const PriorityRenderer: React.FC = ( label="IMPORT" /> - {icon.label} + + {icon.label} + ); } @@ -105,16 +117,15 @@ export const PriorityRenderer: React.FC = ( }} /> ); - } + }; return ( - { - loading && + {loading && ( - } + )} {renderPriorityPresentor()} ); diff --git a/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.css b/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.css index f5c35505d..eefc8ec02 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.css @@ -33,7 +33,7 @@ opacity: 0.85; } .progressSectionsContainer { - display:flex; + display: flex; align-items: flex-start; position: relative; } @@ -47,7 +47,7 @@ } .statusText { position: absolute; - top:-10px; + top: -10px; } .statusBar { border: 1px solid rgba(255, 255, 255, 0.5); @@ -62,6 +62,6 @@ top: 50%; left: 50%; transform: translate(-50%, -50%); - z-index: 1; + z-index: 1; padding-bottom: 8px; } diff --git a/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.tsx b/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.tsx index b5c99e620..fb0a03153 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/status.cell-renderer.tsx @@ -21,8 +21,8 @@ export const StatusRenderer: React.FC = (props) => { const status = jobData.status; const getProgress = (): string | null => { - if (jobData.taskCount as number === NO_DATA) { - return null; + if ((jobData.taskCount as number) === NO_DATA) { + return null; } const SUM_INIT = 0; @@ -31,8 +31,7 @@ export const StatusRenderer: React.FC = (props) => { (sum: number, finalStatus: Status) => { const lowerCasedStatus = finalStatus.toLowerCase(); const statusSum = get(jobData, `${lowerCasedStatus}Tasks`) as number; - const nextSum: number = - sum + (isNaN(statusSum) ? NO_DATA : statusSum); + const nextSum: number = sum + (isNaN(statusSum) ? NO_DATA : statusSum); return nextSum; }, @@ -49,11 +48,7 @@ export const StatusRenderer: React.FC = (props) => { id: `system-status.job.status_translation.${status as string}`, }); - return ( - - {`${statusText} ${getProgress() ?? ''}`} - - ); + return {`${statusText} ${getProgress() ?? ''}`}; }; type StatusCountType = number | null | undefined; @@ -89,18 +84,26 @@ export const StatusRenderer: React.FC = (props) => { const { percentage } = jobData; return ( - - {typeof percentage !== 'undefined' && percentage !== null - ? `${percentage}%` - : ''} - + + {typeof percentage !== 'undefined' && percentage !== null + ? `${percentage}%` + : ''} + ); }; const getProgressbarSections = (): JSX.Element | null => { - const { completedTasks, inProgressTasks, failedTasks, expiredTasks, status} = jobData; - - const jobStatusFinal = FINAL_STATUSES.find(finalStatus => finalStatus === status); + const { + completedTasks, + inProgressTasks, + failedTasks, + expiredTasks, + status, + } = jobData; + + const jobStatusFinal = FINAL_STATUSES.find( + (finalStatus) => finalStatus === status + ); // If job status is a final status - we should return a full bar with its color. if (typeof jobStatusFinal !== 'undefined') { @@ -125,15 +128,14 @@ export const StatusRenderer: React.FC = (props) => { return ( - - {getProgressComponent()} - + {getProgressComponent()} + }} + > {getPercentageView()} {getProgressbarSections()} diff --git a/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.css b/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.css index 5bc88c76a..88d3357f0 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.css +++ b/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.css @@ -1,11 +1,11 @@ #jobsDialog .tooltippedCell { - line-height: 1; + line-height: 1; } #jobsDialog .tooltippedCell > * { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - text-align: center; - padding-bottom: 1px; -} \ No newline at end of file + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + text-align: center; + padding-bottom: 1px; +} diff --git a/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.tsx b/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.tsx index 3545229f7..9130557ca 100644 --- a/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.tsx +++ b/src/discrete-layer/components/job-manager/cell-renderer/tool-tipped.cell-renderer.tsx @@ -1,28 +1,26 @@ import React from 'react'; import { Box } from '@map-colonies/react-components'; import { ICellRendererParams } from 'ag-grid-community'; -import TooltippedValue, { TooltippedValueProps } from '../../../../common/components/form/tooltipped.value'; +import TooltippedValue, { + TooltippedValueProps, +} from '../../../../common/components/form/tooltipped.value'; import './tool-tipped.cell-renderer.css'; export const TooltippedCellRenderer: React.FC< ICellRendererParams & TooltippedValueProps > = (props) => { - const { - tag, - className, - alwaysTooltip, - disableTooltip, - customTooltipText, - } = props; + const { tag, className, alwaysTooltip, disableTooltip, customTooltipText } = + props; return ( - + + className={className} + > {props.value} diff --git a/src/discrete-layer/components/job-manager/grids/job-manager-grid.common.tsx b/src/discrete-layer/components/job-manager/grids/job-manager-grid.common.tsx index 24ae11fe0..bb2832eaf 100644 --- a/src/discrete-layer/components/job-manager/grids/job-manager-grid.common.tsx +++ b/src/discrete-layer/components/job-manager/grids/job-manager-grid.common.tsx @@ -1,11 +1,17 @@ import { ColDef, ColGroupDef, GetRowIdParams } from 'ag-grid-community'; -import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import React, { + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react'; import { useIntl } from 'react-intl'; import CONFIG from '../../../../common/config'; import { GridComponent, GridComponentOptions, - GridReadyEvent + GridReadyEvent, } from '../../../../common/components/grid'; import EnumsMapContext from '../../../../common/contexts/enumsMap.context'; import { IActionGroup } from '../../../../common/actions/entity.actions'; @@ -35,10 +41,14 @@ export interface ICommonJobManagerGridProps { gridStyleOverride?: React.CSSProperties; onGridReadyCB?: (params: GridReadyEvent) => void; customColDef?: (ColDef | ColGroupDef)[]; - omitColDefsByRenderer?: { renderers: string[], preserveColWidth?: boolean }; + omitColDefsByRenderer?: { renderers: string[]; preserveColWidth?: boolean }; areJobsLoading?: boolean; focusOnJob?: Partial>; - setFocusOnJob?: (job: Partial> | undefined) => void; + setFocusOnJob?: ( + job: + | Partial> + | undefined + ) => void; handleFocusError?: (error: IError | undefined) => void; } @@ -54,7 +64,9 @@ const JobManagerGrid: React.FC = (props) => { customColDef, gridOptionsOverride = {}, gridStyleOverride = {}, - onGridReadyCB = (params): void => { return }, + onGridReadyCB = (params): void => { + return; + }, rowDataChangeCB = (): void => { return; }, @@ -62,7 +74,7 @@ const JobManagerGrid: React.FC = (props) => { areJobsLoading, focusOnJob, setFocusOnJob, - handleFocusError + handleFocusError, } = props; const store = useStore(); @@ -89,9 +101,7 @@ const JobManagerGrid: React.FC = (props) => { onGridReadyCB(params); params.api.applyColumnState({ - state: [ - {colId: 'updated', sort: 'desc'} - ], + state: [{ colId: 'updated', sort: 'desc' }], }); params.api.sizeColumnsToFit(); }; @@ -113,7 +123,8 @@ const JobManagerGrid: React.FC = (props) => { }); }, [intl]); - const primitiveValueFormatter = (params:Record):string => params.value as string || ''; + const primitiveValueFormatter = (params: Record): string => + (params.value as string) || ''; const defaultColDef = useMemo( () => [ { @@ -192,7 +203,7 @@ const JobManagerGrid: React.FC = (props) => { }, readOnly: (jobData: JobModelType): boolean => { return jobData.domain !== Domain.RASTER; - } + }, }, }, { @@ -283,7 +294,7 @@ const JobManagerGrid: React.FC = (props) => { filter: { component: JobDetailsStatusFilter, doesFilterPass: (params: any) => { - return params.model === params.handlerParams.getValue(params.node); + return params.model === params.handlerParams.getValue(params.node); }, }, }, @@ -309,16 +320,18 @@ const JobManagerGrid: React.FC = (props) => { const renderersList = omitColDefsByRenderer.renderers; if (!(omitColDefsByRenderer.preserveColWidth ?? false)) { - colDef = defaultColDef.filter(colDef => !renderersList.includes(colDef.cellRenderer as string)) as ColDef[]; + colDef = defaultColDef.filter( + (colDef) => !renderersList.includes(colDef.cellRenderer as string) + ) as ColDef[]; } else { - colDef = defaultColDef.map(colDef => { + colDef = defaultColDef.map((colDef) => { if (renderersList.includes(colDef.cellRenderer as string)) { - return ({ + return { ...colDef, cellRenderer: 'placeholderRenderer', headerName: '', pinned: undefined, - }) + }; } return colDef; }) as ColDef[]; @@ -335,64 +348,63 @@ const JobManagerGrid: React.FC = (props) => { }; const baseGridOption: GridComponentOptions = { - enableRtl: CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() === 'HE', - enableFilterHandlers: true, - suppressRowTransform: true, - pagination: pagination, - paginationPageSize: pageSize, - paginationPageSizeSelector: false,//[pageSize, 20, 50, 100], - getRowId: (params: GetRowIdParams): string => { - return (params.data as JobModelType).id; - }, - detailsRowCellRenderer: 'detailsRenderer', - detailsRowHeight: 230, - detailsRowExpanderPosition: 'start', - overlayNoRowsTemplate: intl.formatMessage({ - id: 'results.nodata', - }), - loadingOverlayComponent: 'customLoadingOverlay', - components: { - jobDetailsStatusFilter: useCallback(JobDetailsStatusFilter, []), - detailsRenderer: useCallback(JobDetailsRenderer, []), - statusRenderer: useCallback(StatusRenderer, []), - actionsRenderer: useCallback(ActionsRenderer, []), - priorityRenderer: useCallback(PriorityRenderer, []), - productTypeRenderer: useCallback(JobProductTypeRenderer, []), - dateCellRenderer: useCallback(DateCellRenderer, []), - tooltippedCellRenderer: useCallback(TooltippedCellRenderer, []), - placeholderRenderer: useCallback(PlaceholderCellRenderer, []), - customLoadingOverlay: useCallback(Loading, []) - }, - tooltipShowDelay: 0, - tooltipMouseTrack: false, - rowSelection: { - mode: 'singleRow', - checkboxes: false, - enableClickSelection: true, - }, - suppressCellFocus: true, - singleClickEdit: true, - suppressMenuHide: true, // Used to show filter icon at all times (not only when hovering the header). - defaultColDef: { - unSortIcon: true, + enableRtl: CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() === 'HE', + enableFilterHandlers: true, + suppressRowTransform: true, + pagination: pagination, + paginationPageSize: pageSize, + paginationPageSizeSelector: false, //[pageSize, 20, 50, 100], + getRowId: (params: GetRowIdParams): string => { + return (params.data as JobModelType).id; + }, + detailsRowCellRenderer: 'detailsRenderer', + detailsRowHeight: 230, + detailsRowExpanderPosition: 'start', + overlayNoRowsTemplate: intl.formatMessage({ + id: 'results.nodata', + }), + loadingOverlayComponent: 'customLoadingOverlay', + components: { + jobDetailsStatusFilter: useCallback(JobDetailsStatusFilter, []), + detailsRenderer: useCallback(JobDetailsRenderer, []), + statusRenderer: useCallback(StatusRenderer, []), + actionsRenderer: useCallback(ActionsRenderer, []), + priorityRenderer: useCallback(PriorityRenderer, []), + productTypeRenderer: useCallback(JobProductTypeRenderer, []), + dateCellRenderer: useCallback(DateCellRenderer, []), + tooltippedCellRenderer: useCallback(TooltippedCellRenderer, []), + placeholderRenderer: useCallback(PlaceholderCellRenderer, []), + customLoadingOverlay: useCallback(Loading, []), + }, + tooltipShowDelay: 0, + tooltipMouseTrack: false, + rowSelection: { + mode: 'singleRow', + checkboxes: false, + enableClickSelection: true, + }, + suppressCellFocus: true, + singleClickEdit: true, + suppressMenuHide: true, // Used to show filter icon at all times (not only when hovering the header). + defaultColDef: { + unSortIcon: true, + }, + onGridReady, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context: { + detailsRowCellRendererPresencePredicate: (rowData: any) => { + const jobData = rowData as JobModelType; + return jobData.domain === Domain.RASTER; }, - onGridReady, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - context:{ - detailsRowCellRendererPresencePredicate: (rowData: any) => { - const jobData = rowData as JobModelType; - return jobData.domain === Domain.RASTER; - } - } - }; + }, + }; const gridOptions = useMemo(() => { const combinedOptions = { ...baseGridOption, ...gridOptionsOverride }; const colDefs = customColDef ?? getColDef(combinedOptions); - return ({ ...combinedOptions, columnDefs: colDefs }) + return { ...combinedOptions, columnDefs: colDefs }; }, []); - const defaultGridStyle: React.CSSProperties = { height: '100%', padding: '12px', diff --git a/src/discrete-layer/components/job-manager/job.types.ts b/src/discrete-layer/components/job-manager/job.types.ts index bb9577436..2098bbea9 100644 --- a/src/discrete-layer/components/job-manager/job.types.ts +++ b/src/discrete-layer/components/job-manager/job.types.ts @@ -5,7 +5,7 @@ export const FINAL_STATUSES = [ Status.Expired, Status.Failed, Status.Aborted, - Status.Suspended + Status.Suspended, ]; export const FINAL_NEGATIVE_STATUSES = [ @@ -14,4 +14,4 @@ export const FINAL_NEGATIVE_STATUSES = [ Status.Aborted, ]; -export const JOB_ENTITY = 'Job'; \ No newline at end of file +export const JOB_ENTITY = 'Job'; diff --git a/src/discrete-layer/components/job-manager/jobs.dialog.css b/src/discrete-layer/components/job-manager/jobs.dialog.css index 59a8cae75..6f6c61a49 100644 --- a/src/discrete-layer/components/job-manager/jobs.dialog.css +++ b/src/discrete-layer/components/job-manager/jobs.dialog.css @@ -20,7 +20,7 @@ body[dir='rtl'] #jobsDialog .mdc-dialog__surface { gap: 32px; } -#jobsDialog .jobsBody .drpContainer > div:nth-child(-n+2) { +#jobsDialog .jobsBody .drpContainer > div:nth-child(-n + 2) { width: 160px; } @@ -138,14 +138,17 @@ body[dir='rtl'] .jobsBody .ag-pinned-right-cols-container { /* Show action buttons only for row that is being hovered. For rows which are not being hovered, hide them by setting their width and padding to 0.*/ #jobsDialog .ag-pinned-right-cols-container .ag-row:not(.ag-row-hover), -#jobsDialog .ag-pinned-right-cols-container .ag-row:not(.ag-row-hover) .ag-cell { +#jobsDialog + .ag-pinned-right-cols-container + .ag-row:not(.ag-row-hover) + .ag-cell { width: 0 !important; padding: 0 !important; border: none; } #jobsDialog .ag-pinned-right-cols-container .ag-row.ag-row-hover { - background-color: rgb(44,65,89); + background-color: rgb(44, 65, 89); border-width: 0px !important; } @@ -157,7 +160,7 @@ body[dir='rtl'] .jobsBody .ag-pinned-right-cols-container { background-color: var(--mdc-theme-gc-selection-background); } -#jobsDialog .ag-row.ag-full-width-row.ag-row-selected[row-id*="details"] { +#jobsDialog .ag-row.ag-full-width-row.ag-row-selected[row-id*='details'] { background: unset; overflow: visible; } @@ -196,7 +199,7 @@ body[dir='rtl'] .jobsBody .ag-pinned-right-cols-container { left: 536px; } -/* Not sure why I did it, it causes some problems with disappearing elements */ +/* Not sure why I did it, it causes some problems with disappearing elements */ /* .jobsBody [aria-hidden="true"]:not(.ag-paging-row-summary-panel,.ag-paging-description) { display: none; diff --git a/src/discrete-layer/components/job-manager/jobs.dialog.tsx b/src/discrete-layer/components/job-manager/jobs.dialog.tsx index d27c9eb33..a560efb42 100644 --- a/src/discrete-layer/components/job-manager/jobs.dialog.tsx +++ b/src/discrete-layer/components/job-manager/jobs.dialog.tsx @@ -5,8 +5,17 @@ import { cloneDeep, isEmpty } from 'lodash'; import { observer } from 'mobx-react'; import moment from 'moment'; import { DialogContent } from '@material-ui/core'; -import { Button, Dialog, DialogTitle, IconButton } from '@map-colonies/react-core'; -import { Box, DateTimeRangePicker, SupportedLocales } from '@map-colonies/react-components'; +import { + Button, + Dialog, + DialogTitle, + IconButton, +} from '@map-colonies/react-core'; +import { + Box, + DateTimeRangePicker, + SupportedLocales, +} from '@map-colonies/react-components'; import { IActionGroup } from '../../../common/actions/entity.actions'; import { GraphQLError } from '../../../common/components/error/graphql.error-presentor'; import { LogicError } from '../../../common/components/error/logic.error-presentor'; @@ -34,406 +43,443 @@ interface JobsDialogProps { onSetOpen: (open: boolean) => void; setRestoreFromJob: (job: JobModelType) => void; focusOnJob?: Partial>; - setFocusOnJob?: (job: Partial> | undefined) => void; + setFocusOnJob?: ( + job: + | Partial> + | undefined + ) => void; } -export const JobsDialog: React.FC = observer((props: JobsDialogProps) => { - const store = useStore(); - const intl = useIntl(); - const { isOpen, onSetOpen, setRestoreFromJob, focusOnJob, setFocusOnJob } = props; - const [ updateTaskPayload, setUpdateTaskPayload ] = useState>({}); - const [ gridRowData, setGridRowData ] = useState(undefined); - const [ gridApi, setGridApi ] = useState(); - const [ pollingCycle, setPollingCycle ] = useState(START_CYCLE_ITERATION); - const [ fromDate, setFromDate ] = useState( - moment().subtract(CONFIG.JOB_MANAGER.FILTER_DAYS_TIME_SLOT, 'days').startOf('day').toDate() - ); - const [ tillDate, setTillDate ] = useState( - moment().endOf('day').toDate() - ); - const [ focusError, setFocusError ] = useState(undefined); - const [ dateRangeError, setDateRangeError ] = useState(undefined); - const [ errorMessages, setErrorMessages ] = useState([]); - const [ timeLeft, actions ] = useCountDown(POLLING_CYCLE_INTERVAL, COUNTDOWN_REFRESH_RATE); +export const JobsDialog: React.FC = observer( + (props: JobsDialogProps) => { + const store = useStore(); + const intl = useIntl(); + const { isOpen, onSetOpen, setRestoreFromJob, focusOnJob, setFocusOnJob } = + props; + const [updateTaskPayload, setUpdateTaskPayload] = useState< + Record + >({}); + const [gridRowData, setGridRowData] = useState( + undefined + ); + const [gridApi, setGridApi] = useState(); + const [pollingCycle, setPollingCycle] = useState(START_CYCLE_ITERATION); + const [fromDate, setFromDate] = useState( + moment() + .subtract(CONFIG.JOB_MANAGER.FILTER_DAYS_TIME_SLOT, 'days') + .startOf('day') + .toDate() + ); + const [tillDate, setTillDate] = useState( + moment().endOf('day').toDate() + ); + const [focusError, setFocusError] = useState(undefined); + const [dateRangeError, setDateRangeError] = useState( + undefined + ); + const [errorMessages, setErrorMessages] = useState([]); + const [timeLeft, actions] = useCountDown( + POLLING_CYCLE_INTERVAL, + COUNTDOWN_REFRESH_RATE + ); - // start the timer during the first render - useEffect(() => { - (actions as IActions).start(); - }, []); + // start the timer during the first render + useEffect(() => { + (actions as IActions).start(); + }, []); - // eslint-disable-next-line - const { setQuery, loading, error, data, query } = useQuery((store) => - store.queryJobs({ - params: { - fromDate, - tillDate + // eslint-disable-next-line + const { setQuery, loading, error, data, query } = useQuery( + (store) => + store.queryJobs({ + params: { + fromDate, + tillDate, + }, + }), + { + fetchPolicy: 'no-cache', } - }), - { - fetchPolicy: 'no-cache' - } - ); + ); - //@ts-ignore - const { setQuery: setQueryForOneJob, data: jobData, loading: loadingJobData } = useQuery>((store) => - undefined, - { - fetchPolicy: 'no-cache' - } - ); + //@ts-ignore + const { + setQuery: setQueryForOneJob, + data: jobData, + loading: loadingJobData, + } = useQuery>((store) => undefined, { + fetchPolicy: 'no-cache', + }); - const mutationQuery = useQuery(); + const mutationQuery = useQuery(); - const getJobActions = useMemo(() => { - let actions: IActionGroup[] = store.actionDispatcherStore.getEntityActionGroups( - JOB_ENTITY - ); + const getJobActions = useMemo(() => { + let actions: IActionGroup[] = + store.actionDispatcherStore.getEntityActionGroups(JOB_ENTITY); - actions = actions.map((action) => { - const groupsWithTranslation = action.group.map((action) => { - return { - ...action, - titleTranslationId: intl.formatMessage({ - id: action.titleTranslationId, - }), - }; + actions = actions.map((action) => { + const groupsWithTranslation = action.group.map((action) => { + return { + ...action, + titleTranslationId: intl.formatMessage({ + id: action.titleTranslationId, + }), + }; + }); + return { ...action, group: groupsWithTranslation }; }); - return { ...action, group: groupsWithTranslation }; - }); - return { - [JOB_ENTITY]: actions, - }; - }, []); + return { + [JOB_ENTITY]: actions, + }; + }, []); - useEffect(() => { - if ( - typeof fromDate !== 'undefined' && - typeof tillDate !== 'undefined' - ) { - (actions as IActions).start(POLLING_CYCLE_INTERVAL); - setQuery( - (store) => + useEffect(() => { + if (typeof fromDate !== 'undefined' && typeof tillDate !== 'undefined') { + (actions as IActions).start(POLLING_CYCLE_INTERVAL); + setQuery((store) => store.queryJobs({ params: { fromDate, tillDate, }, }) - ); - } - }, [fromDate, tillDate, setQuery]); + ); + } + }, [fromDate, tillDate, setQuery]); - useEffect(() => { - if (data !== undefined) { - const jobsData = data ? cloneDeep(data.jobs) : []; - setGridRowData(jobsData); - } - }, [data]); + useEffect(() => { + if (data !== undefined) { + const jobsData = data ? cloneDeep(data.jobs) : []; + setGridRowData(jobsData); + } + }, [data]); - useEffect(() => { - if (mutationQuery.data) { - setUpdateTaskPayload({}); - setQuery((store) => - store.queryJobs({ - params: { - fromDate, - tillDate, - }, - })); - } - }, [mutationQuery.data]); + useEffect(() => { + if (mutationQuery.data) { + setUpdateTaskPayload({}); + setQuery((store) => + store.queryJobs({ + params: { + fromDate, + tillDate, + }, + }) + ); + } + }, [mutationQuery.data]); - useEffect(() => { - if (updateTaskPayload.id !== undefined) { - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-empty-function - mutationQuery.setQuery(store.mutateUpdateJob(updateTaskPayload, () => { })); - } - }, [updateTaskPayload]); + useEffect(() => { + if (updateTaskPayload.id !== undefined) { + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-empty-function + mutationQuery.setQuery( + store.mutateUpdateJob(updateTaskPayload, () => {}) + ); + } + }, [updateTaskPayload]); - useEffect(() => { - const pollingInterval = setInterval(() => { - setErrorMessages(prev => upsertOrRemoveError(prev, undefined, 'error.server-error')); - setPollingCycle(prevCycle => prevCycle + 1); - (actions as IActions).start(POLLING_CYCLE_INTERVAL); - setQuery((store) => - store.queryJobs({ - params: { - fromDate, - tillDate, - }, - }) - ); - }, POLLING_CYCLE_INTERVAL); + useEffect(() => { + const pollingInterval = setInterval(() => { + setErrorMessages((prev) => + upsertOrRemoveError(prev, undefined, 'error.server-error') + ); + setPollingCycle((prevCycle) => prevCycle + 1); + (actions as IActions).start(POLLING_CYCLE_INTERVAL); + setQuery((store) => + store.queryJobs({ + params: { + fromDate, + tillDate, + }, + }) + ); + }, POLLING_CYCLE_INTERVAL); - return (): void => { - clearInterval(pollingInterval); - }; - }, [query, pollingCycle]); + return (): void => { + clearInterval(pollingInterval); + }; + }, [query, pollingCycle]); - useEffect(() => { - if (!loadingJobData && jobData) { - downloadJSONToClient(jobData.job, `${encodeURI(jobData.job.resourceId as string)}_job_details.json`); - } - }, [jobData, loadingJobData]); + useEffect(() => { + if (!loadingJobData && jobData) { + downloadJSONToClient( + jobData.job, + `${encodeURI(jobData.job.resourceId as string)}_job_details.json` + ); + } + }, [jobData, loadingJobData]); - const upsertOrRemoveError = ( - prevErrors: IError[], - newError?: IError, - newErrorCode?: string - ): IError[] => { - if (newError) { - const filtered = prevErrors.filter(e => e.code !== newError.code); - return [...filtered, newError]; - } else { - return prevErrors.filter(e => e.code !== newErrorCode); - } - }; + const upsertOrRemoveError = ( + prevErrors: IError[], + newError?: IError, + newErrorCode?: string + ): IError[] => { + if (newError) { + const filtered = prevErrors.filter((e) => e.code !== newError.code); + return [...filtered, newError]; + } else { + return prevErrors.filter((e) => e.code !== newErrorCode); + } + }; - useEffect(() => { - let newError: IError | undefined = undefined; - if (!isEmpty(mutationQuery.error)) { - gridApi?.refreshCells({ - suppressFlash: true, - force: true - }); - const NONE = 0; - const serverError = mutationQuery.error.response.errors[0]; - const status = serverError.serverResponse?.status ?? NONE; - let message = serverError.serverResponse?.data.message ? - serverError.serverResponse.data.message : - serverError.serverResponse?.statusText ? - serverError.serverResponse?.statusText : - serverError.message.substring(+serverError.message.indexOf('; ') + 1); - newError = { - code: 'error.server-error', - message: `${(status > NONE) ? status + ' ' : ''}${message}`, - level: "error" - }; - } - setErrorMessages(prev => - upsertOrRemoveError(prev, newError, 'error.server-error') - ); - }, [mutationQuery.error]); + useEffect(() => { + let newError: IError | undefined = undefined; + if (!isEmpty(mutationQuery.error)) { + gridApi?.refreshCells({ + suppressFlash: true, + force: true, + }); + const NONE = 0; + const serverError = mutationQuery.error.response.errors[0]; + const status = serverError.serverResponse?.status ?? NONE; + let message = serverError.serverResponse?.data.message + ? serverError.serverResponse.data.message + : serverError.serverResponse?.statusText + ? serverError.serverResponse?.statusText + : serverError.message.substring( + +serverError.message.indexOf('; ') + 1 + ); + newError = { + code: 'error.server-error', + message: `${status > NONE ? status + ' ' : ''}${message}`, + level: 'error', + }; + } + setErrorMessages((prev) => + upsertOrRemoveError(prev, newError, 'error.server-error') + ); + }, [mutationQuery.error]); - useEffect(() => { - let newError: IError | undefined = undefined; - if (focusOnJob && focusError?.code) { - newError = { - code: focusError.code, - message: `${focusOnJob.resourceId} (${dateFormatter(focusOnJob.updated, true)})`, - level: focusError.level - }; - } - setErrorMessages(prev => - upsertOrRemoveError(prev, newError, 'warning.row-not-found') - ); - }, [focusError]); + useEffect(() => { + let newError: IError | undefined = undefined; + if (focusOnJob && focusError?.code) { + newError = { + code: focusError.code, + message: `${focusOnJob.resourceId} (${dateFormatter( + focusOnJob.updated, + true + )})`, + level: focusError.level, + }; + } + setErrorMessages((prev) => + upsertOrRemoveError(prev, newError, 'warning.row-not-found') + ); + }, [focusError]); - useEffect(() => { - setErrorMessages(prev => - upsertOrRemoveError(prev, dateRangeError, 'warning.exceeded-date-range') - ); - }, [dateRangeError]); + useEffect(() => { + setErrorMessages((prev) => + upsertOrRemoveError(prev, dateRangeError, 'warning.exceeded-date-range') + ); + }, [dateRangeError]); - const closeDialog = useCallback(() => { - setFocusOnJob?.(undefined); - onSetOpen(false); - }, [onSetOpen]); + const closeDialog = useCallback(() => { + setFocusOnJob?.(undefined); + onSetOpen(false); + }, [onSetOpen]); - const dispatchAction = (action: Record | undefined): void => { - const actionToDispatch = (action ? { action: action.action, data: action.data } : action) as IDispatchAction; - store.actionDispatcherStore.dispatchAction( - actionToDispatch - ); - }; + const dispatchAction = ( + action: Record | undefined + ): void => { + const actionToDispatch = ( + action ? { action: action.action, data: action.data } : action + ) as IDispatchAction; + store.actionDispatcherStore.dispatchAction(actionToDispatch); + }; - // Job actions handler + // Job actions handler - useEffect(() => { - if (typeof store.actionDispatcherStore.action !== 'undefined') { - const { action, data } = store.actionDispatcherStore.action as IDispatchAction; - switch (action) { - case 'Job.retry': - mutationQuery.setQuery( - store.mutateJobRetry({'jobRetryParams': { - id: data.id as string, - domain: data.domain as string, - type: data.type as string, - }}) - ); - break; - case 'Job.abort': { - mutationQuery.setQuery( - store.mutateJobAbort({'jobAbortParams': { - id: data.id as string, - domain: data.domain as string, - type: data.type as string, - }}) - ); - break; + useEffect(() => { + if (typeof store.actionDispatcherStore.action !== 'undefined') { + const { action, data } = store.actionDispatcherStore + .action as IDispatchAction; + switch (action) { + case 'Job.retry': + mutationQuery.setQuery( + store.mutateJobRetry({ + jobRetryParams: { + id: data.id as string, + domain: data.domain as string, + type: data.type as string, + }, + }) + ); + break; + case 'Job.abort': { + mutationQuery.setQuery( + store.mutateJobAbort({ + jobAbortParams: { + id: data.id as string, + domain: data.domain as string, + type: data.type as string, + }, + }) + ); + break; + } + case 'Job.download_details': + setQueryForOneJob((store) => + store.queryJob({ + id: data.id as string, + }) + ); + break; + case 'Job.restore': + closeDialog(); + setRestoreFromJob(data as unknown as JobModelType); + break; + default: + break; } - case 'Job.download_details': - setQueryForOneJob((store) => - store.queryJob({ - id: data.id as string - }) - ); - break; - case 'Job.restore': - closeDialog(); - setRestoreFromJob(data as unknown as JobModelType); - break; - default: - break; } - } - }, [store.actionDispatcherStore.action]); - - // Reset action value on store when unmounting + }, [store.actionDispatcherStore.action]); - useEffect(() => { - return (): void => { - dispatchAction(undefined) - }; - }, []); + // Reset action value on store when unmounting - const renderGridList = (): JSX.Element => { - return ( - - { - setGridApi(params.api) - }} - updateJobCB={setUpdateTaskPayload} - rowDataChangeCB={(): void => { }} - areJobsLoading={loading} - focusOnJob={focusOnJob} - setFocusOnJob={setFocusOnJob} - handleFocusError={(err) => { - setFocusError(err); - }} - /> - - ); - }; + useEffect(() => { + return (): void => { + dispatchAction(undefined); + }; + }, []); - const renderDateTimeRangePicker = (): JSX.Element => { - return ( - - { - setErrorMessages(prev => upsertOrRemoveError(prev, undefined, 'error.server-error')); - const from = dateRange.from; - const to = dateRange.to; - const diff = moment(to).diff(moment(from), 'days'); - if (diff > CONFIG.JOB_MANAGER.MAX_DATE_RANGE_DAYS) { - setDateRangeError({ - code: 'warning.exceeded-date-range', - message: CONFIG.JOB_MANAGER.MAX_DATE_RANGE_DAYS, - level: 'warning' - }); - } else { - setDateRangeError(undefined); - setFromDate(from); - setTillDate(to); - } - }} - from={fromDate} - to={tillDate} - local={{ - setText: intl.formatMessage({ - id: 'filters.date-picker.set-btn.text', - }), - startPlaceHolderText: intl.formatMessage({ - id: 'filters.date-picker.start-time.label', - }), - endPlaceHolderText: intl.formatMessage({ - id: 'filters.date-picker.end-time.label', - }), - calendarLocale: SupportedLocales[ - CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() as keyof typeof SupportedLocales - ], - }} - /> - - ); - }; + const renderGridList = (): JSX.Element => { + return ( + + { + setGridApi(params.api); + }} + updateJobCB={setUpdateTaskPayload} + rowDataChangeCB={(): void => {}} + areJobsLoading={loading} + focusOnJob={focusOnJob} + setFocusOnJob={setFocusOnJob} + handleFocusError={(err) => { + setFocusError(err); + }} + /> + + ); + }; - return ( - - - - - { - setErrorMessages(prev => upsertOrRemoveError(prev, undefined, 'error.server-error')); - (actions as IActions).start(POLLING_CYCLE_INTERVAL); - setQuery((store) => - store.queryJobs({ - params: { - fromDate, - tillDate, - }, - }) + const renderDateTimeRangePicker = (): JSX.Element => { + return ( + + { + setErrorMessages((prev) => + upsertOrRemoveError(prev, undefined, 'error.server-error') ); + const from = dateRange.from; + const to = dateRange.to; + const diff = moment(to).diff(moment(from), 'days'); + if (diff > CONFIG.JOB_MANAGER.MAX_DATE_RANGE_DAYS) { + setDateRangeError({ + code: 'warning.exceeded-date-range', + message: CONFIG.JOB_MANAGER.MAX_DATE_RANGE_DAYS, + level: 'warning', + }); + } else { + setDateRangeError(undefined); + setFromDate(from); + setTillDate(to); + } }} - > - - - {`${(timeLeft as number) / MILLISECONDS_IN_SEC}`} - - - { - closeDialog(); + from={fromDate} + to={tillDate} + local={{ + setText: intl.formatMessage({ + id: 'filters.date-picker.set-btn.text', + }), + startPlaceHolderText: intl.formatMessage({ + id: 'filters.date-picker.start-time.label', + }), + endPlaceHolderText: intl.formatMessage({ + id: 'filters.date-picker.end-time.label', + }), + calendarLocale: + SupportedLocales[ + CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() as keyof typeof SupportedLocales + ], }} /> - - - {renderDateTimeRangePicker()} - { - !error && - typeof fromDate !== 'undefined' && - typeof tillDate !== 'undefined' && - renderGridList() - } - { - error && - - - - } - - - + + ); + }; + + return ( + + + + + { + setErrorMessages((prev) => + upsertOrRemoveError(prev, undefined, 'error.server-error') + ); + (actions as IActions).start(POLLING_CYCLE_INTERVAL); + setQuery((store) => + store.queryJobs({ + params: { + fromDate, + tillDate, + }, + }) + ); + }} + > + + + {`${(timeLeft as number) / MILLISECONDS_IN_SEC}`} + - - { - errorMessages.length > 0 && - - } + { + closeDialog(); + }} + /> + + + {renderDateTimeRangePicker()} + {!error && + typeof fromDate !== 'undefined' && + typeof tillDate !== 'undefined' && + renderGridList()} + {error && ( + + + + )} + + + + + + {errorMessages.length > 0 && ( + + )} + - - - - - ); -}); + + + + ); + } +); diff --git a/src/discrete-layer/components/layer-details/entity-types-keys.ts b/src/discrete-layer/components/layer-details/entity-types-keys.ts index 40bce6ee8..35658b7d8 100644 --- a/src/discrete-layer/components/layer-details/entity-types-keys.ts +++ b/src/discrete-layer/components/layer-details/entity-types-keys.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/array-type */ /* eslint-disable @typescript-eslint/naming-convention */ -import { +import { FieldConfigModelType, FieldConfigModel, Layer3DRecordModel, @@ -13,47 +13,68 @@ import { VectorBestRecordModel, QuantizedMeshBestRecordModelType, QuantizedMeshBestRecordModel, - LayerMetadataMixedUnion + LayerMetadataMixedUnion, } from '../../models'; type KeysOfUnion = T extends T ? keyof T : never; export type LayerDemRecordModelArray = Array; export type Layer3DRecordModelArray = Array; -export type LayerRasterRecordModelArray = Array; +export type LayerRasterRecordModelArray = Array< + keyof LayerRasterRecordModelType +>; export type VectorBestRecordModelArray = Array; -export type QuantizedMeshBestRecordModelArray = Array; +export type QuantizedMeshBestRecordModelArray = Array< + keyof QuantizedMeshBestRecordModelType +>; export type FieldConfigModelArray = Array; -export const LayerDemRecordModelKeys: LayerDemRecordModelArray = Object.keys(LayerDemRecordModel.properties) as LayerDemRecordModelArray; +export const LayerDemRecordModelKeys: LayerDemRecordModelArray = Object.keys( + LayerDemRecordModel.properties +) as LayerDemRecordModelArray; -export const Layer3DRecordModelKeys: Layer3DRecordModelArray = Object.keys(Layer3DRecordModel.properties) as Layer3DRecordModelArray; +export const Layer3DRecordModelKeys: Layer3DRecordModelArray = Object.keys( + Layer3DRecordModel.properties +) as Layer3DRecordModelArray; -export const LayerRasterRecordModelKeys: LayerRasterRecordModelArray = Object.keys(LayerRasterRecordModel.properties) as LayerRasterRecordModelArray; +export const LayerRasterRecordModelKeys: LayerRasterRecordModelArray = + Object.keys(LayerRasterRecordModel.properties) as LayerRasterRecordModelArray; -export const VectorBestRecordModelKeys: VectorBestRecordModelArray = Object.keys(VectorBestRecordModel.properties) as VectorBestRecordModelArray; +export const VectorBestRecordModelKeys: VectorBestRecordModelArray = + Object.keys(VectorBestRecordModel.properties) as VectorBestRecordModelArray; -export const QuantizedMeshBestRecordModelKeys: QuantizedMeshBestRecordModelArray = Object.keys(QuantizedMeshBestRecordModel.properties) as QuantizedMeshBestRecordModelArray; +export const QuantizedMeshBestRecordModelKeys: QuantizedMeshBestRecordModelArray = + Object.keys( + QuantizedMeshBestRecordModel.properties + ) as QuantizedMeshBestRecordModelArray; -export const FieldConfigModelKeys: FieldConfigModelArray = Object.keys(FieldConfigModel.properties) as FieldConfigModelArray; +export const FieldConfigModelKeys: FieldConfigModelArray = Object.keys( + FieldConfigModel.properties +) as FieldConfigModelArray; // All fields from all entities. export type LayerMetadataMixedUnionKeys = KeysOfUnion; -export type LayerRecordTypes = "Layer3DRecord" | "LayerRasterRecord" | "LayerDemRecord" | "VectorBestRecord" | "QuantizedMeshBestRecord" | "PolygonPartRecord"; +export type LayerRecordTypes = + | 'Layer3DRecord' + | 'LayerRasterRecord' + | 'LayerDemRecord' + | 'VectorBestRecord' + | 'QuantizedMeshBestRecord' + | 'PolygonPartRecord'; let tempLayerRecordTypesObject: | { - [key in LayerRecordTypes]: undefined; - } + [key in LayerRecordTypes]: undefined; + } | undefined = { - Layer3DRecord: undefined, - LayerRasterRecord: undefined, - LayerDemRecord: undefined, - VectorBestRecord: undefined, - QuantizedMeshBestRecord: undefined, - PolygonPartRecord: undefined, - }; + Layer3DRecord: undefined, + LayerRasterRecord: undefined, + LayerDemRecord: undefined, + VectorBestRecord: undefined, + QuantizedMeshBestRecord: undefined, + PolygonPartRecord: undefined, +}; export const LayerRecordTypesKeys = Object.keys(tempLayerRecordTypesObject); diff --git a/src/discrete-layer/components/layer-details/entity.delete-dialog.css b/src/discrete-layer/components/layer-details/entity.delete-dialog.css index fb250d5c4..d864a3bef 100644 --- a/src/discrete-layer/components/layer-details/entity.delete-dialog.css +++ b/src/discrete-layer/components/layer-details/entity.delete-dialog.css @@ -56,7 +56,11 @@ body[dir='rtl'] #entityDeleteDialog .closeIcon { height: var(--modal-height); } - #entityDeleteDialog .mdc-dialog .mdc-dialog__surface .mdc-dialog .mdc-dialog__surface { + #entityDeleteDialog + .mdc-dialog + .mdc-dialog__surface + .mdc-dialog + .mdc-dialog__surface { max-width: var(--modal-width); height: var(--chonky-modal-height); } @@ -82,4 +86,4 @@ body[dir='rtl'] #entityDeleteDialog .closeIcon { #entityDeleteDialog .errors { width: 520px; -} \ No newline at end of file +} diff --git a/src/discrete-layer/components/layer-details/entity.delete-dialog.tsx b/src/discrete-layer/components/layer-details/entity.delete-dialog.tsx index 5454fdf36..a9047b3ef 100644 --- a/src/discrete-layer/components/layer-details/entity.delete-dialog.tsx +++ b/src/discrete-layer/components/layer-details/entity.delete-dialog.tsx @@ -1,8 +1,21 @@ import React, { useCallback, useState, useMemo, useEffect } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import { observer } from 'mobx-react'; -import { Button, Checkbox, CircularProgress, DialogActions, DialogContent, Tooltip } from '@map-colonies/react-core'; -import { Dialog, DialogTitle, Icon, IconButton, Typography } from '@map-colonies/react-core'; +import { + Button, + Checkbox, + CircularProgress, + DialogActions, + DialogContent, + Tooltip, +} from '@map-colonies/react-core'; +import { + Dialog, + DialogTitle, + Icon, + IconButton, + Typography, +} from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { GraphQLError } from '../../../common/components/error/graphql.error-presentor'; import { emphasizeByHTML } from '../../../common/helpers/formatters'; @@ -15,7 +28,7 @@ import { RecordStatus, RecordType, useQuery, - useStore + useStore, } from '../../models'; import { GeoJsonMapValuePresentorComponent } from './field-value-presentors/geojson-map.value-presentor'; import { LayersDetailsComponent } from './layer-details'; @@ -35,14 +48,15 @@ const VALID = 'ok'; export const EntityDeleteDialog: React.FC = observer( (props: EntityDeleteDialogProps) => { - const { isOpen, onSetOpen, layerRecord } = props; const store = useStore(); const mutationQuery = useQuery(); const intl = useIntl(); const [allowDeleting, setAllowDeleting] = useState(false); - const [recordType] = useState(props.recordType ?? (layerRecord?.type as RecordType)); + const [recordType] = useState( + props.recordType ?? (layerRecord?.type as RecordType) + ); const dialogTitleParam = recordType; const dialogTitleParamTranslation = intl.formatMessage({ @@ -59,23 +73,25 @@ export const EntityDeleteDialog: React.FC = observer( }, [onSetOpen, store.discreteLayersStore]); const dispatchAction = (action: Record): void => { - store.actionDispatcherStore.dispatchAction( - { - action: action.action, - data: action.data, - } as IDispatchAction - ); + store.actionDispatcherStore.dispatchAction({ + action: action.action, + data: action.data, + } as IDispatchAction); }; useEffect(() => { - if (!mutationQuery.loading && ((mutationQuery.data as { deleteLayer: string } | undefined)?.deleteLayer === VALID)) { + if ( + !mutationQuery.loading && + (mutationQuery.data as { deleteLayer: string } | undefined) + ?.deleteLayer === VALID + ) { onSetOpen(false); const payload = { action: UserAction.SYSTEM_CALLBACK_DELETE, data: { ...layerRecord, productStatus: RecordStatus.BEING_DELETED, - } + }, }; dispatchAction(payload); @@ -87,7 +103,7 @@ export const EntityDeleteDialog: React.FC = observer( store.mutateDeleteLayer({ data: { id: layerRecord.id, - type: layerRecord.type as RecordType + type: layerRecord.type as RecordType, }, }) ); @@ -96,7 +112,12 @@ export const EntityDeleteDialog: React.FC = observer( const deleteMessage = useMemo((): string => { return intl.formatMessage( { id: 'delete.dialog.message' }, - { action: emphasizeByHTML(`${intl.formatMessage({ id: 'delete.dialog.action' })}`) }); + { + action: emphasizeByHTML( + `${intl.formatMessage({ id: 'delete.dialog.action' })}` + ), + } + ); }, []); return ( @@ -114,10 +135,18 @@ export const EntityDeleteDialog: React.FC = observer( - - + + - + @@ -141,15 +170,13 @@ export const EntityDeleteDialog: React.FC = observer( /> - - + ): void => { - setAllowDeleting(evt.currentTarget.checked); - }} + onChange={(evt: React.MouseEvent): void => { + setAllowDeleting(evt.currentTarget.checked); + }} /> @@ -158,17 +185,14 @@ export const EntityDeleteDialog: React.FC = observer( + return ( + <> + + + - { - manageMetadata && - - + + {manageMetadata && ( + + - - } - - {children} + }} + > + {queryResolveMetadataAsModel.loading ? ( + + ) : ( + + )} + + + )} + {children} - - { - isFilePickerDialogOpen && - - } - - ); -}); + {isFilePickerDialogOpen && ( + + )} + + ); + } +); diff --git a/src/discrete-layer/components/layer-details/layer-datails-form.tsx b/src/discrete-layer/components/layer-details/layer-datails-form.tsx index b875e2af1..acbb8c862 100644 --- a/src/discrete-layer/components/layer-details/layer-datails-form.tsx +++ b/src/discrete-layer/components/layer-details/layer-datails-form.tsx @@ -48,7 +48,7 @@ export interface FormValues { export interface StatusError { errors: { [fieldName: string]: string[]; - } + }; } interface LayerDetailsFormCustomProps { @@ -64,9 +64,17 @@ interface LayerDetailsFormCustomProps { } export interface EntityFormikHandlers extends FormikHandlers { - setFieldValue: (field: string, value: unknown, shouldValidate?: boolean) => void; + setFieldValue: ( + field: string, + value: unknown, + shouldValidate?: boolean + ) => void; setFieldError: (field: string, message: string) => void; - setFieldTouched: (field: string, isTouched?: boolean | undefined, shouldValidate?: boolean | undefined) => void; + setFieldTouched: ( + field: string, + isTouched?: boolean | undefined, + shouldValidate?: boolean | undefined + ) => void; setStatus: (status?: StatusError | Record) => void; status: StatusError | Record; } @@ -107,32 +115,35 @@ const InnerForm = ( const intl = useIntl(); const [graphQLError, setGraphQLError] = useState(mutationQueryError); const [isSelectedFiles, setIsSelectedFiles] = useState(false); - const [firstPhaseErrors, setFirstPhaseErrors] = useState>({}); + const [firstPhaseErrors, setFirstPhaseErrors] = useState< + Record + >({}); const [showCurtain, setShowCurtain] = useState(true); // const validationWarn = useSessionStoreWatcherForm(); - const getStatusErrors = useCallback((): StatusError | Record => { + const getStatusErrors = useCallback((): + | StatusError + | Record => { return { - ...get(status, 'errors') as Record - } + ...(get(status, 'errors') as Record), + }; }, [status]); - const getYupErrors = useCallback( - (): Record => { - const validationResults: Record = {}; - Object.entries(errors).forEach(([key, value]) => { - if (getFieldMeta(key).touched) { - validationResults[key] = [value]; - } - }); - return validationResults; - }, - [errors, getFieldMeta], - ); + const getYupErrors = useCallback((): Record => { + const validationResults: Record = {}; + Object.entries(errors).forEach(([key, value]) => { + if (getFieldMeta(key).touched) { + validationResults[key] = [value]; + } + }); + return validationResults; + }, [errors, getFieldMeta]); useEffect(() => { - setShowCurtain((mode === Mode.NEW || mode === Mode.UPDATE) && !isSelectedFiles); - }, [mode, isSelectedFiles]) + setShowCurtain( + (mode === Mode.NEW || mode === Mode.UPDATE) && !isSelectedFiles + ); + }, [mode, isSelectedFiles]); useEffect(() => { setGraphQLError(mutationQueryError); @@ -141,8 +152,8 @@ const InnerForm = ( useEffect(() => { setFirstPhaseErrors({ ...getYupErrors(), - ...getStatusErrors() as { [fieldName: string]: string[]; }, - }) + ...(getStatusErrors() as { [fieldName: string]: string[] }), + }); }, [errors, getYupErrors, getStatusErrors]); const entityFormikHandlers: EntityFormikHandlers = useMemo( @@ -185,28 +196,40 @@ const InnerForm = ( status, ] ); - + const reloadFormMetadata = ( ingestionFields: FormValues, metadata: MetadataFile ): void => { setIsSelectedFiles(!!ingestionFields.fileNames); - delete ((metadata.recordModel as unknown) as Record)['__typename']; - + delete (metadata.recordModel as unknown as Record)[ + '__typename' + ]; + // Check update related fields in metadata obj - const updateFields = extractDescriptorRelatedFieldNames('updateRules', getFlatEntityDescriptors(layerRecord.__typename, entityDescriptors)); + const updateFields = extractDescriptorRelatedFieldNames( + 'updateRules', + getFlatEntityDescriptors(layerRecord.__typename, entityDescriptors) + ); for (const [key, val] of Object.entries(metadata.recordModel)) { - if (val === null || (updateFields.includes(key) && mode === Mode.UPDATE)) { - delete ((metadata.recordModel as unknown) as Record)[key]; + if ( + val === null || + (updateFields.includes(key) && mode === Mode.UPDATE) + ) { + delete (metadata.recordModel as unknown as Record)[ + key + ]; } } resetForm(); setValues({ ...values, - ...transformEntityToFormFields((isEmpty(metadata.recordModel) ? layerRecord : metadata.recordModel)), + ...transformEntityToFormFields( + isEmpty(metadata.recordModel) ? layerRecord : metadata.recordModel + ), ...ingestionFields, }); @@ -221,8 +244,7 @@ const InnerForm = ( className="form" noValidate > - { - (mode === Mode.NEW || mode === Mode.UPDATE) && + {(mode === Mode.NEW || mode === Mode.UPDATE) && ( - } + )} - { - Object.keys(firstPhaseErrors).length > NONE && - JSON.stringify(firstPhaseErrors) !== '{}' && - - } - { - (Object.keys(errors).length === NONE || JSON.stringify(errors) === '{}') && - vestValidationResults.errorCount > NONE && - - } - { - graphQLError !== undefined && + {Object.keys(firstPhaseErrors).length > NONE && + JSON.stringify(firstPhaseErrors) !== '{}' && ( + + )} + {(Object.keys(errors).length === NONE || + JSON.stringify(errors) === '{}') && + vestValidationResults.errorCount > NONE && ( + + )} + {graphQLError !== undefined && graphQLError !== null && graphQLError && JSON.stringify(graphQLError) !== '{}' && - Object.keys(graphQLError).length > NONE && - - } + Object.keys(graphQLError).length > NONE && ( + + )} - { mode !== Mode.VIEW && - - } + {mode !== Mode.VIEW && ( + + )} {filtersOpen && ( - + @@ -180,58 +201,68 @@ export const MapContainer: React.FC = (props) => { - - + { - console.log('DateTimeRangePickerFormControl--->',dateRange.from, dateRange.to); + console.log( + 'DateTimeRangePickerFormControl--->', + dateRange.from, + dateRange.to + ); }} local={{ - setText: intl.formatMessage({ id: 'filters.date-picker.set-btn.text' }), - startPlaceHolderText: intl.formatMessage({ id: 'filters.date-picker.start-time.label' }), - endPlaceHolderText: intl.formatMessage({ id: 'filters.date-picker.end-time.label' }), - calendarLocale: SupportedLocales[CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() as keyof typeof SupportedLocales] + setText: intl.formatMessage({ + id: 'filters.date-picker.set-btn.text', + }), + startPlaceHolderText: intl.formatMessage({ + id: 'filters.date-picker.start-time.label', + }), + endPlaceHolderText: intl.formatMessage({ + id: 'filters.date-picker.end-time.label', + }), + calendarLocale: + SupportedLocales[ + CONFIG.I18N.DEFAULT_LANGUAGE.toUpperCase() as keyof typeof SupportedLocales + ], }} /> - ) - } + + )} - { - resultsOpen && - + {resultsOpen && ( + RESULTS Subtitle - - + - } - - + )} +
- {props.mapContent} - - - + + + = ({longitude, latitude}) => { +export const PoiEntity: React.FC = ({ + longitude, + latitude, +}) => { const intl = useIntl(); const mapViewer = useCesiumMap(); const [position, setPosition] = useState(); @@ -27,44 +30,54 @@ export const PoiEntity: React.FC = ({longitude, latitude}) => { /* eslint-disable */ useEffect(() => { setHeight(DEFAULT_HEIGHT); - void cesiumSampleTerrainMostDetailed( - mapViewer.terrainProvider, - [ CesiumCartographic.fromDegrees(longitude, latitude) ] - ).then( - (updatedPositions) => { - if (!isEmpty(updatedPositions)) { - setHeight(updatedPositions[0].height); - } + void cesiumSampleTerrainMostDetailed(mapViewer.terrainProvider, [ + CesiumCartographic.fromDegrees(longitude, latitude), + ]).then((updatedPositions) => { + if (!isEmpty(updatedPositions)) { + setHeight(updatedPositions[0].height); } - ); + }); }, [longitude, latitude]); /* eslint-enable */ useEffect(() => { setPosition(CesiumCartesian3.fromDegrees(longitude, latitude, height)); - mapViewer.camera.flyTo({ destination: CesiumCartesian3.fromDegrees(longitude, latitude, height + CAMERA_HEIGHT_OFFSET) }); //TODO: extract to a generic component - + mapViewer.camera.flyTo({ + destination: CesiumCartesian3.fromDegrees( + longitude, + latitude, + height + CAMERA_HEIGHT_OFFSET + ), + }); //TODO: extract to a generic component }, [height, longitude, latitude]); return ( <> - { - position !== undefined && - - ${intl.formatMessage({ id: 'poi.dialog.description.latitude' }, { value: latitude })}
- ${intl.formatMessage({ id: 'poi.dialog.description.height' }, { value: height })} + {position !== undefined && ( + + ${intl.formatMessage( + { id: 'poi.dialog.description.latitude' }, + { value: latitude } + )}
+ ${intl.formatMessage( + { id: 'poi.dialog.description.height' }, + { value: height } + )} `} - /> - } + /> + )} ); -}; \ No newline at end of file +}; diff --git a/src/discrete-layer/components/map-container/poi.dialog.tsx b/src/discrete-layer/components/map-container/poi.dialog.tsx index 25158253e..190537a95 100644 --- a/src/discrete-layer/components/map-container/poi.dialog.tsx +++ b/src/discrete-layer/components/map-container/poi.dialog.tsx @@ -3,7 +3,14 @@ import { FormattedMessage, useIntl } from 'react-intl'; import { useFormik } from 'formik'; import { isEmpty } from 'lodash'; import * as Yup from 'yup'; -import { Button, Dialog, DialogContent, DialogTitle, IconButton, TextField } from '@map-colonies/react-core'; +import { + Button, + Dialog, + DialogContent, + DialogTitle, + IconButton, + TextField, +} from '@map-colonies/react-core'; import { Box } from '@map-colonies/react-components'; import { ValidationsError } from '../../../common/components/error/validations.error-presentor'; import { FieldLabelComponent } from '../../../common/components/form/field-label'; @@ -25,35 +32,32 @@ interface PoiDialogProps { poi?: IPOI; } -export const PoiDialog: React.FC = ( - { - isOpen, - onSetOpen, - onPoiUpdate, - poi: currentPoi - } -) => { +export const PoiDialog: React.FC = ({ + isOpen, + onSetOpen, + onPoiUpdate, + poi: currentPoi, +}) => { const intl = useIntl(); - - const closeDialog = useCallback( - () => { - onSetOpen(false); - }, - [onSetOpen] - ); + + const closeDialog = useCallback(() => { + onSetOpen(false); + }, [onSetOpen]); const [poi] = useState(currentPoi ?? { lon: 0, lat: 0 }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const yupSchema: Record = {}; - Object.keys(poi).forEach(fieldName => { + Object.keys(poi).forEach((fieldName) => { const fieldLabel = `poi.dialog.${fieldName}-field.label`; - yupSchema[fieldName] = Yup - .number() - .required( + yupSchema[fieldName] = Yup.number().required( intl.formatMessage( { id: 'validation-general.number' }, - { fieldName: emphasizeByHTML(`${intl.formatMessage({ id: fieldLabel })}`) } + { + fieldName: emphasizeByHTML( + `${intl.formatMessage({ id: fieldLabel })}` + ), + } ) ); }); @@ -61,23 +65,25 @@ export const PoiDialog: React.FC = ( const formik = useFormik({ initialValues: poi, validationSchema: Yup.object({ - ...yupSchema + ...yupSchema, }), onSubmit: (values) => { try { onPoiUpdate(values.lon, values.lat); closeDialog(); - } catch(e) { + } catch (e) { console.error(e); } }, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const getValidationErrors = (errors: Record): Record => { + const getValidationErrors = ( + errors: Record + ): Record => { const validationResults: Record = {}; Object.entries(errors).forEach(([key, value]) => { - validationResults[key] = [ value as string ]; + validationResults[key] = [value as string]; }); return validationResults; }; @@ -86,18 +92,24 @@ export const PoiDialog: React.FC = ( - + { closeDialog(); } } + onClick={(): void => { + closeDialog(); + }} /> - + = ( /> - + = ( - { - !isEmpty(formik.errors) && - - } + {!isEmpty(formik.errors) && ( + + )} - - diff --git a/src/discrete-layer/components/map-container/polygon-selection-ui.spec.tsx b/src/discrete-layer/components/map-container/polygon-selection-ui.spec.tsx index dce1f658a..5789b7470 100644 --- a/src/discrete-layer/components/map-container/polygon-selection-ui.spec.tsx +++ b/src/discrete-layer/components/map-container/polygon-selection-ui.spec.tsx @@ -87,14 +87,13 @@ describe('Polygon Selection component', () => { openMenuButton.simulate('click', { currentTarget: {} }); - const item = wrapper - .findWhere((n) => { - return ( - n.type() === ListItemText && - n.prop('children').props['id'] === - 'polygon-selection.box-menu_option.text' - ); - }); + const item = wrapper.findWhere((n) => { + return ( + n.type() === ListItemText && + n.prop('children').props['id'] === + 'polygon-selection.box-menu_option.text' + ); + }); item.parent().simulate('click'); expect(startDraw).toHaveBeenCalledWith(DrawType.BOX); @@ -116,14 +115,13 @@ describe('Polygon Selection component', () => { const openMenuButton = wrapper.find(Button); openMenuButton.simulate('click', { currentTarget: {} }); - const item = wrapper - .findWhere((n) => { - return ( - n.type() === ListItemText && - n.prop('children').props['id'] === - 'polygon-selection.box_coorinate-menu_option.text' - ); - }); + const item = wrapper.findWhere((n) => { + return ( + n.type() === ListItemText && + n.prop('children').props['id'] === + 'polygon-selection.box_coorinate-menu_option.text' + ); + }); item.parent().simulate('click'); expect(wrapper.find(BBoxDialog).prop('isOpen')).toBe(true); @@ -144,14 +142,13 @@ describe('Polygon Selection component', () => { const openMenuButton = wrapper.find(Button); openMenuButton.simulate('click', { currentTarget: {} }); - const item = wrapper - .findWhere((n) => { - return ( - n.type() === ListItemText && - n.prop('children').props['id'] === - 'polygon-selection.clear-menu_option.text' - ); - }); + const item = wrapper.findWhere((n) => { + return ( + n.type() === ListItemText && + n.prop('children').props['id'] === + 'polygon-selection.clear-menu_option.text' + ); + }); item.parent().simulate('click'); expect(resetDraw).toHaveBeenCalledTimes(1); diff --git a/src/discrete-layer/components/map-container/polygon-selection-ui.tsx b/src/discrete-layer/components/map-container/polygon-selection-ui.tsx index 41a1e06d6..79207c8de 100644 --- a/src/discrete-layer/components/map-container/polygon-selection-ui.tsx +++ b/src/discrete-layer/components/map-container/polygon-selection-ui.tsx @@ -1,7 +1,15 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; -import { Button, Drawer, DrawerContent, List, ListItem, ListItemGraphic, ListItemText } from '@map-colonies/react-core'; +import { + Button, + Drawer, + DrawerContent, + List, + ListItem, + ListItemGraphic, + ListItemText, +} from '@map-colonies/react-core'; import { Box, DrawType, IDrawingEvent } from '@map-colonies/react-components'; import { BBoxDialog } from './bbox.dialog'; @@ -81,15 +89,20 @@ export const PolygonSelectionUi: React.FC = ( onSetOpen={setOpen} onPolygonUpdate={onPolygonUpdate} /> - { - menuOpen && - - - + + { @@ -131,15 +144,15 @@ export const PolygonSelectionUi: React.FC = ( }} > - - - - + + + + - } + )} ); } diff --git a/src/discrete-layer/components/map-container/polygon-selection-ui_2.tsx b/src/discrete-layer/components/map-container/polygon-selection-ui_2.tsx index a99f924f2..bb3fc26ba 100644 --- a/src/discrete-layer/components/map-container/polygon-selection-ui_2.tsx +++ b/src/discrete-layer/components/map-container/polygon-selection-ui_2.tsx @@ -14,15 +14,17 @@ import './polygon-selection-ui.css'; export const Divider: React.FC = () => { const theme = useTheme(); return ( - + ); -} +}; export interface PolygonSelectionUiProps { isSelectionEnabled: boolean; @@ -43,10 +45,12 @@ enum PolygonSelectionsLabels { POLYGON = 'POLYGON', BBOX = 'BBOX', POI = 'POI', - FILTER = 'FILTER' + FILTER = 'FILTER', } -export const PolygonSelectionUi: React.FC = (props) => { +export const PolygonSelectionUi: React.FC = ( + props +) => { const { // eslint-disable-next-line @typescript-eslint/no-unused-vars isSelectionEnabled, @@ -67,8 +71,12 @@ export const PolygonSelectionUi: React.FC = (props) => const store = useStore(); const [open, setOpen] = useState(false); const [openPoiDialog, setOpenPoiDialog] = useState(false); - const [activeSelection, setActiveSelection] = useState(''); - const [lastDrawingSelectionType, setLastDrawingSelectionType] = useState(''); + const [activeSelection, setActiveSelection] = useState< + PolygonSelectionsLabels | '' + >(''); + const [lastDrawingSelectionType, setLastDrawingSelectionType] = useState< + PolygonSelectionsLabels | '' + >(''); const [isFilterPanelOpen, setIsFilterPanelOpen] = useState(false); const [isCatalogFiltersEnabled, setIsCatalogFiltersEnabled] = useState(false); @@ -80,7 +88,7 @@ export const PolygonSelectionUi: React.FC = (props) => setIsFilterPanelOpen(false); setActiveSelection(''); setLastDrawingSelectionType(''); - }, [store.userStore.user?.role]) + }, [store.userStore.user?.role]); useEffect(() => { if (poi) { @@ -91,11 +99,14 @@ export const PolygonSelectionUi: React.FC = (props) => setActiveSelection(lastDrawingSelectionType); setLastDrawingSelectionType(''); } - }, [isSelectionEnabled, poi, corners]) + }, [isSelectionEnabled, poi, corners]); - const getActiveClass = (className: string, selectionLabel: PolygonSelectionsLabels) => { - return `${className} ${activeSelection === selectionLabel ? 'active': ''}`; - } + const getActiveClass = ( + className: string, + selectionLabel: PolygonSelectionsLabels + ) => { + return `${className} ${activeSelection === selectionLabel ? 'active' : ''}`; + }; return ( <> @@ -107,7 +118,7 @@ export const PolygonSelectionUi: React.FC = (props) => pointerEvents: (disabled as boolean) ? 'none' : 'unset', }} > - + = (props) => }} /> - + = (props) => onFiltersApply(filters); }} /> - { - open && + {open && ( - } - { - openPoiDialog && + )} + {openPoiDialog && ( - } + )} { setIsCatalogFiltersEnabled(false); diff --git a/src/discrete-layer/components/map-container/selected-layers-container.tsx b/src/discrete-layer/components/map-container/selected-layers-container.tsx index 530238a55..dea9470d4 100644 --- a/src/discrete-layer/components/map-container/selected-layers-container.tsx +++ b/src/discrete-layer/components/map-container/selected-layers-container.tsx @@ -8,27 +8,34 @@ import { CesiumWMTSLayer, CesiumXYZLayer, ICesiumImageryLayer, - useCesiumMap + useCesiumMap, } from '@map-colonies/react-components'; import CONFIG from '../../../common/config'; import { usePrevious } from '../../../common/hooks/previous.hook'; import { LinkType } from '../../../common/models/link-type.enum'; import { ILayerImage } from '../../models/layerImage'; import { useStore } from '../../models/RootStore'; -import { Layer3DRecordModelType, LayerRasterRecordModelType, LinkModelType } from '../../models'; +import { + Layer3DRecordModelType, + LayerRasterRecordModelType, + LinkModelType, +} from '../../models'; import { getLayerLink, generateLayerRectangle, getTokenResource, getWMTSOptions, - getLinksArrWithTokens + getLinksArrWithTokens, } from '../helpers/layersUtils'; interface CacheMap { [key: string]: JSX.Element | undefined; } -type SearchLayerPredicate = (layer: ICesiumImageryLayer, idx: number) => boolean; +type SearchLayerPredicate = ( + layer: ICesiumImageryLayer, + idx: number +) => boolean; export const SelectedLayersContainer: React.FC = observer(() => { const store = useStore(); @@ -36,11 +43,15 @@ export const SelectedLayersContainer: React.FC = observer(() => { const prevLayersImages = usePrevious(layersImages); const cacheRef = useRef({} as CacheMap); const mapViewer = useCesiumMap(); - + useEffect(() => { if (store.discreteLayersStore.layersImages) { // @ts-ignore - setlayersImages(store.discreteLayersStore.layersImages.slice().sort((curr, next) => curr.order - next.order)); + setlayersImages( + store.discreteLayersStore.layersImages + .slice() + .sort((curr, next) => curr.order - next.order) + ); if (isEmpty(store.discreteLayersStore.layersImages)) { cacheRef.current = {}; } @@ -53,7 +64,9 @@ export const SelectedLayersContainer: React.FC = observer(() => { } }, [store.discreteLayersStore.previewedLayers]); - const generateLayerComponent = (layer: ILayerImage): JSX.Element | undefined => { + const generateLayerComponent = ( + layer: ILayerImage + ): JSX.Element | undefined => { const layerLink = getLayerLink(layer); switch (layerLink.protocol) { @@ -64,16 +77,25 @@ export const SelectedLayersContainer: React.FC = observer(() => { meta={{ id: layer.id, searchLayerPredicate: ((cesiumLayer, idx) => { - const correctLinkByProtocol = (layer.links as LinkModelType[]).find(link => link.protocol === layerLink.protocol); + const correctLinkByProtocol = ( + layer.links as LinkModelType[] + ).find((link) => link.protocol === layerLink.protocol); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return correctLinkByProtocol?.url === (cesiumLayer as any)._imageryProvider._resource._url + return ( + correctLinkByProtocol?.url === + (cesiumLayer as any)._imageryProvider._resource._url + ); }) as SearchLayerPredicate, layerRecord: { ...layer, - links: getLinksArrWithTokens([...layer.links as LinkModelType[]]) - } as ILayerImage + links: getLinksArrWithTokens([ + ...(layer.links as LinkModelType[]), + ]), + } as ILayerImage, }} - rectangle={generateLayerRectangle(layer as LayerRasterRecordModelType)} + rectangle={generateLayerRectangle( + layer as LayerRasterRecordModelType + )} options={{ url: getTokenResource(layerLink.url as string) }} /> ); @@ -81,20 +103,33 @@ export const SelectedLayersContainer: React.FC = observer(() => { case LinkType.THREE_D_LAYER: return ( ); case LinkType.WMTS_LAYER: case LinkType.WMTS: { - const capability = store.discreteLayersStore.capabilities?.find(item => layerLink.name === item.id); + const capability = store.discreteLayersStore.capabilities?.find( + (item) => layerLink.name === item.id + ); const optionsWMTS = { - ...getWMTSOptions(layer as LayerRasterRecordModelType, layerLink.url as string, capability) + ...getWMTSOptions( + layer as LayerRasterRecordModelType, + layerLink.url as string, + capability + ), }; return ( { meta={{ id: layer.id, searchLayerPredicate: ((cesiumLayer, idx) => { - const linkUrl = (optionsWMTS.url as Record)._url as string; - const cesiumLayerLinkUrl = get(cesiumLayer, '_imageryProvider._resource._url') as string; - const isBaseLayer = get(cesiumLayer, 'meta.parentBasetMapId') as string; - const isLayerFound = (linkUrl.split('?')[0] === cesiumLayerLinkUrl.split('?')[0]) && !isBaseLayer; + const linkUrl = (optionsWMTS.url as Record) + ._url as string; + const cesiumLayerLinkUrl = get( + cesiumLayer, + '_imageryProvider._resource._url' + ) as string; + const isBaseLayer = get( + cesiumLayer, + 'meta.parentBasetMapId' + ) as string; + const isLayerFound = + linkUrl.split('?')[0] === cesiumLayerLinkUrl.split('?')[0] && + !isBaseLayer; return isLayerFound; }) as SearchLayerPredicate, layerRecord: { ...layer, - links: getLinksArrWithTokens([...layer.links as LinkModelType[]]) - } as ILayerImage + links: getLinksArrWithTokens([ + ...(layer.links as LinkModelType[]), + ]), + } as ILayerImage, }} - rectangle={generateLayerRectangle(layer as LayerRasterRecordModelType)} + rectangle={generateLayerRectangle( + layer as LayerRasterRecordModelType + )} options={optionsWMTS} /> ); @@ -126,7 +174,7 @@ export const SelectedLayersContainer: React.FC = observer(() => { pageSize: CONFIG.WFS.MAX.PAGE_SIZE, zoomLevel: CONFIG.WFS.MAX.ZOOM_LEVEL, maxCacheSize: CONFIG.WFS.MAX.CACHE_SIZE, - keyField: CONFIG.WFS.KEY_FIELD + keyField: CONFIG.WFS.KEY_FIELD, }; return ( { return undefined; } }; - + const getLayer = (layer: ILayerImage): JSX.Element | null | undefined => { const cache = cacheRef.current; if (layer.layerImageShown === true) { @@ -155,7 +203,9 @@ export const SelectedLayersContainer: React.FC = observer(() => { } } } else { - const prevLayer = (prevLayersImages as []).find((item: ILayerImage) => item.id === layer.id) as ILayerImage | undefined; + const prevLayer = (prevLayersImages as []).find( + (item: ILayerImage) => item.id === layer.id + ) as ILayerImage | undefined; if (prevLayer?.layerImageShown === true) { delete cache[layer.id]; return null; @@ -165,11 +215,9 @@ export const SelectedLayersContainer: React.FC = observer(() => { return ( <> - { - layersImages.map((layer) => { - return getLayer(layer); - }) - } + {layersImages.map((layer) => { + return getLayer(layer); + })} ); }); diff --git a/src/discrete-layer/components/map-container/terrain.tsx b/src/discrete-layer/components/map-container/terrain.tsx index 7f09861be..11c547fb7 100644 --- a/src/discrete-layer/components/map-container/terrain.tsx +++ b/src/discrete-layer/components/map-container/terrain.tsx @@ -21,29 +21,36 @@ export const Terrain: React.FC = () => { mapViewer.scene.globe.depthTestAgainstTerrain = true; mapViewer.scene.globe.baseColor = CesiumColor.WHITESMOKE; - + useEffect(() => { - function isTerrainTileError (e: Record): boolean { - return e.level as number > NONE; + function isTerrainTileError(e: Record): boolean { + return (e.level as number) > NONE; } function handleTerrainError(e: unknown): void { if (!isTerrainTileError(e as Record)) { - console.error('Terrain provider error: Falling back to default terrain. ', e); + console.error( + 'Terrain provider error: Falling back to default terrain. ', + e + ); queue.notify({ body: ( ), }); // Remove the error listener after failing once - mapViewer.terrainProvider.errorEvent.removeEventListener(handleTerrainError); - + mapViewer.terrainProvider.errorEvent.removeEventListener( + handleTerrainError + ); + mapViewer.terrainProvider = new CesiumEllipsoidTerrainProvider({}); } else { console.error('Terrain provider error: Tile problem. ', e); diff --git a/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.css b/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.css index e95669532..837e841b5 100644 --- a/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.css +++ b/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.css @@ -1,5 +1,5 @@ .listsContainer { - width:80%; + width: 80%; } .externalService { @@ -33,20 +33,39 @@ content: ': '; } -.tabContent .flex-column-center .rmwc-collapsible-list--open .rmwc-collapsible-list__handle { +.tabContent + .flex-column-center + .rmwc-collapsible-list--open + .rmwc-collapsible-list__handle { background-color: var(--mdc-theme-gc-selection-background); font-weight: bold; } -#systemCoreInfoBody .tabContent .flex-column-center .rmwc-collapsible-list .rmwc-collapsible-list__handle { +#systemCoreInfoBody + .tabContent + .flex-column-center + .rmwc-collapsible-list + .rmwc-collapsible-list__handle { border-bottom: 2px solid var(--mdc-theme-gc-selection-background); } -body[dir='rtl'] #systemCoreInfoBody .tabContent .flex-column-center .rmwc-collapsible-list .rmwc-collapsible-list__handle { +body[dir='rtl'] + #systemCoreInfoBody + .tabContent + .flex-column-center + .rmwc-collapsible-list + .rmwc-collapsible-list__handle { direction: ltr; } -body[dir='rtl'] #systemCoreInfoBody .tabContent .flex-column-center .rmwc-collapsible-list .rmwc-collapsible-list__handle .mdc-list-item .mdc-list-item__meta { +body[dir='rtl'] + #systemCoreInfoBody + .tabContent + .flex-column-center + .rmwc-collapsible-list + .rmwc-collapsible-list__handle + .mdc-list-item + .mdc-list-item__meta { margin: unset !important; margin-left: auto !important; } diff --git a/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.tsx b/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.tsx index d5bd21290..38e7ea6c4 100644 --- a/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.tsx +++ b/src/discrete-layer/components/system-status/system-core-info/external-services/external-services.tsx @@ -15,37 +15,32 @@ interface ExternalServicesProps { services: CategorizedServices; } -export const ExternalServices: React.FC = ({ services }: ExternalServicesProps) => { +export const ExternalServices: React.FC = ({ + services, +}: ExternalServicesProps) => { return ( - { - Object.entries(services).map(([category, services]) => { - return ( - - } - > - {(services ?? []).map(({ url, display }) => { - return ( - - - - - - {`${url as string}`} - - - - ); - })} - - ); - }) - } + {Object.entries(services).map(([category, services]) => { + return ( + } + > + {(services ?? []).map(({ url, display }) => { + return ( + + + + + + {`${url as string}`} + + + + ); + })} + + ); + })} ); }; diff --git a/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.css b/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.css index 91e69b130..a8c494c92 100644 --- a/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.css +++ b/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.css @@ -1,25 +1,23 @@ - - #systemCoreInfoBody .statusIndicator { - width: 20px; - height: 20px; - border-radius: 50%; + width: 20px; + height: 20px; + border-radius: 50%; } .internalService { - display: flex; - align-items: center; - justify-content: space-between; - width: 80%; + display: flex; + align-items: center; + justify-content: space-between; + width: 80%; } body[dir='rtl'] #systemCoreInfoBody .internalService { - flex-direction: row-reverse; + flex-direction: row-reverse; } .internalService .serviceName { - text-align: left; - flex: 3; - margin-left: 1.5rem; - font-weight: bold; -} \ No newline at end of file + text-align: left; + flex: 3; + margin-left: 1.5rem; + font-weight: bold; +} diff --git a/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.tsx b/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.tsx index 1fa92839d..bf447ea90 100644 --- a/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.tsx +++ b/src/discrete-layer/components/system-status/system-core-info/internal-service/internal-service.tsx @@ -18,19 +18,19 @@ interface Services { export const InternalService: React.FC = ({ service: { image, services, status }, }: InternalServiceProps) => { - const theme = useTheme(); - - const svcList = (services as - | Services[] - | undefined)?.map((service) => { + const svcList = (services as Services[] | undefined)?.map((service) => { return ( diff --git a/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.css b/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.css index 587add68a..634613302 100644 --- a/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.css +++ b/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.css @@ -1,82 +1,82 @@ #systemCoreInfoDialog .mdc-dialog__surface { - max-width: unset; - right:12px; - top:20px; - overflow-y: hidden !important; - overflow-x: hidden; - } - - #systemCoreInfoDialog .mdc-dialog { - justify-content: center; - } - - #systemCoreInfoDialog #systemCoreInfoBody { - position: relative; - height: 600px; - width: 800px; - padding: 8px 8px; - display: flex; - flex-direction: column; - } + max-width: unset; + right: 12px; + top: 20px; + overflow-y: hidden !important; + overflow-x: hidden; +} - #systemCoreInfoDialog .closeIcon { - margin-left: auto; - margin-right: unset; - } - - body[dir='rtl'] #systemCoreInfoDialog .closeIcon { - margin-left: unset; - margin-right: auto; - } - - #systemCoreInfoBody .loader { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } +#systemCoreInfoDialog .mdc-dialog { + justify-content: center; +} - #systemCoreInfoBody .flex-column-center { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - height: calc(100% - var(--tab-bar-height)); - margin-top: 20px; - } - - #systemCoreInfoBody .tabContent { - overflow-y: auto; - flex: 1; - /* margin-bottom: 60px; */ - border: 2px solid var(--mdc-theme-gc-selection-background); - border-top: none; - position: relative; - } +#systemCoreInfoDialog #systemCoreInfoBody { + position: relative; + height: 600px; + width: 800px; + padding: 8px 8px; + display: flex; + flex-direction: column; +} - #systemCoreInfoDialog #closeBtn { - /* position: absolute; */ - /* bottom: 20px; +#systemCoreInfoDialog .closeIcon { + margin-left: auto; + margin-right: unset; +} + +body[dir='rtl'] #systemCoreInfoDialog .closeIcon { + margin-left: unset; + margin-right: auto; +} + +#systemCoreInfoBody .loader { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +#systemCoreInfoBody .flex-column-center { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + height: calc(100% - var(--tab-bar-height)); + margin-top: 20px; +} + +#systemCoreInfoBody .tabContent { + overflow-y: auto; + flex: 1; + /* margin-bottom: 60px; */ + border: 2px solid var(--mdc-theme-gc-selection-background); + border-top: none; + position: relative; +} + +#systemCoreInfoDialog #closeBtn { + /* position: absolute; */ + /* bottom: 20px; right: 20px; */ - width:max-content; - height:max-content; - padding:10px; - margin: 20px; - margin-top: 10px; - align-self: flex-end; - } + width: max-content; + height: max-content; + padding: 10px; + margin: 20px; + margin-top: 10px; + align-self: flex-end; +} - #systemCoreInfoBody .errorContainer { - display: flex; - align-items: center; - flex-direction: column; - } +#systemCoreInfoBody .errorContainer { + display: flex; + align-items: center; + flex-direction: column; +} - #systemCoreInfoBody .errorContainer li { - list-style: none; - text-align: center; - } \ No newline at end of file +#systemCoreInfoBody .errorContainer li { + list-style: none; + text-align: center; +} diff --git a/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.tsx b/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.tsx index 5a6c5d6ed..0facac759 100644 --- a/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.tsx +++ b/src/discrete-layer/components/system-status/system-core-info/system-core-info.dialog.tsx @@ -13,7 +13,7 @@ import { TabBar, Tab, Button, - TabBarOnActivateEventT + TabBarOnActivateEventT, } from '@map-colonies/react-core'; import { GraphQLError } from '../../../../common/components/error/graphql.error-presentor'; import { useQuery, useStore } from '../../../models/RootStore'; @@ -29,12 +29,14 @@ interface SystemCoreInfoDialogProps { onSetOpen: (open: boolean) => void; } -export type CategorizedServices = Record; +export type CategorizedServices = Record< + string, + ExternalServiceModelType[] | undefined +>; const EXTERNAL_SERVICES_TAB_INDEX = 0; const INTERNAL_SERVICES_TAB_INDEX = 1; -const INTERNAL_SERVICES_QUERY = -`name +const INTERNAL_SERVICES_QUERY = `name status image services { @@ -43,23 +45,35 @@ const INTERNAL_SERVICES_QUERY = addresses }`; -export const SystemCoreInfoDialog: React.FC = observer( - ({ isOpen, onSetOpen }: SystemCoreInfoDialogProps) => { +export const SystemCoreInfoDialog: React.FC = + observer(({ isOpen, onSetOpen }: SystemCoreInfoDialogProps) => { const store = useStore(); const clusterServicesQuery = useQuery(); const externalServicesQuery = useQuery(); - const [clusterServices, setClusterServices] = useState([]); - const [externalServices, setExternalServices] = useState({}); - const [clusterServicesError, setClusterServicesError] = useState | null>(null); - const [externalServicesError, setExternalServicesError] = useState | null>(null); - const [activeTab, setActiveTab] = useState(EXTERNAL_SERVICES_TAB_INDEX); + const [clusterServices, setClusterServices] = useState< + DeploymentWithServicesModelType[] + >([]); + const [externalServices, setExternalServices] = + useState({}); + const [clusterServicesError, setClusterServicesError] = useState | null>(null); + const [externalServicesError, setExternalServicesError] = useState | null>(null); + const [activeTab, setActiveTab] = useState( + EXTERNAL_SERVICES_TAB_INDEX + ); const [isLoading, setIsLoading] = useState(true); useEffect(() => { - clusterServicesQuery.setQuery(store.queryGetClusterServices(undefined, INTERNAL_SERVICES_QUERY)); + clusterServicesQuery.setQuery( + store.queryGetClusterServices(undefined, INTERNAL_SERVICES_QUERY) + ); externalServicesQuery.setQuery(store.queryGetExternalServices()); - }, []); useEffect(() => { @@ -77,7 +91,6 @@ export const SystemCoreInfoDialog: React.FC = observe setClusterServices(internalServices); } } - }, [ clusterServicesQuery.data, clusterServicesQuery.loading, @@ -113,7 +126,6 @@ export const SystemCoreInfoDialog: React.FC = observe setExternalServices(getCategorizedServices()); } } - }, [ externalServicesQuery.data, externalServicesQuery.loading, @@ -136,12 +148,13 @@ export const SystemCoreInfoDialog: React.FC = observe if (clusterServicesError) { renderContent = ; } else { - const sortedServicesByStatus = (clusterServices).sort( - (a, b) => { - const A_BEFORE_B = -1; - const B_BEFORE_A = 1; - return (a.status === true && b.status === false) ? A_BEFORE_B : B_BEFORE_A; - }); + const sortedServicesByStatus = clusterServices.sort((a, b) => { + const A_BEFORE_B = -1; + const B_BEFORE_A = 1; + return a.status === true && b.status === false + ? A_BEFORE_B + : B_BEFORE_A; + }); renderContent = sortedServicesByStatus.map((service) => { return ( @@ -151,7 +164,6 @@ export const SystemCoreInfoDialog: React.FC = observe } return {renderContent}; - }, [clusterServicesError, clusterServices]); const renderExternalServices = useCallback(() => { @@ -160,11 +172,10 @@ export const SystemCoreInfoDialog: React.FC = observe if (externalServicesError) { renderContent = ; } else { - renderContent = - }; + renderContent = ; + } return {renderContent}; - }, [externalServicesError, externalServices]); const renderDialogContent = useCallback(() => { @@ -187,13 +198,14 @@ export const SystemCoreInfoDialog: React.FC = observe activeTabToRender = renderClusterServices(); } - return ( - - {activeTabToRender} - - ); - - }, [isLoading, renderExternalServices, renderClusterServices, activeTab, closeDialog]); + return {activeTabToRender}; + }, [ + isLoading, + renderExternalServices, + renderClusterServices, + activeTab, + closeDialog, + ]); return ( @@ -214,7 +226,9 @@ export const SystemCoreInfoDialog: React.FC = observe > setActiveTab(evt.detail.index)} + onActivate={(evt: TabBarOnActivateEventT): void => + setActiveTab(evt.detail.index) + } > @@ -225,18 +239,17 @@ export const SystemCoreInfoDialog: React.FC = observe {renderDialogContent()} - + ); - } -); + }); diff --git a/src/discrete-layer/views/components/action-resolver.component.tsx b/src/discrete-layer/views/components/action-resolver.component.tsx index b62b93c4d..bc9389a37 100644 --- a/src/discrete-layer/views/components/action-resolver.component.tsx +++ b/src/discrete-layer/views/components/action-resolver.component.tsx @@ -4,16 +4,28 @@ import { NodeData } from 'react-sortable-tree'; import { observer } from 'mobx-react-lite'; import { Feature } from 'geojson'; import { get, isEmpty } from 'lodash'; -import { CesiumSceneMode, DrawType, useCesiumMap } from '@map-colonies/react-components'; -import { existStatus, isPolygonPartsShown, isUnpublished } from '../../../common/helpers/style'; +import { + CesiumSceneMode, + DrawType, + useCesiumMap, +} from '@map-colonies/react-components'; +import { + existStatus, + isPolygonPartsShown, + isUnpublished, +} from '../../../common/helpers/style'; import { LayerRasterRecordModelKeys, LayerDemRecordModelKeys, Layer3DRecordModelKeys, QuantizedMeshBestRecordModelKeys, - VectorBestRecordModelKeys + VectorBestRecordModelKeys, } from '../../components/layer-details/entity-types-keys'; -import { cleanUpEntity, downloadJSONToClient, importShapeFileFromClient } from '../../components/layer-details/utils' +import { + cleanUpEntity, + downloadJSONToClient, + importShapeFileFromClient, +} from '../../components/layer-details/utils'; import { IDispatchAction } from '../../models/actionDispatcherStore'; import { getLayerFootprint, ILayerImage } from '../../models/layerImage'; import { LayerRasterRecordModelType } from '../../models/LayerRasterRecordModel'; @@ -30,7 +42,11 @@ import { useEnums } from '../../../common/hooks/useEnum.hook'; import { ExportActions } from '../../components/export-layer/hooks/useDomainExportActionsConfig'; import useAddFeatureWithProps from '../../components/export-layer/hooks/useAddFeatureWithProps'; import { getWFSFeatureTypeName } from '../../components/layer-details/raster/pp-map.utils'; -import { JobModelType, LayerMetadataMixedUnion, RecordType } from '../../models'; +import { + JobModelType, + LayerMetadataMixedUnion, + RecordType, +} from '../../models'; import { TabViews } from '../tab-views'; const initialOrder = 0; @@ -43,466 +59,645 @@ interface ActionResolverProps { activeTabView: TabViews; } -export const ActionResolver: React.FC = observer((props) => { - const { handleOpenEntityDialog, handleFlyTo, handleTabViewChange, handleOpenJobDialog, activeTabView } = props; - - const store = useStore(); - const ENUMS = useEnums(); - const mapViewer = useCesiumMap(); - - const selectedLayersRef = useRef(initialOrder); - - const {internalFields: exportDomainInternalFields} = useAddFeatureWithProps(false); - - const { setGetFeatureOptions } = useHandleWfsGetFeatureRequests(); - const { setDemHeightsOptions } = useHandleDemHeightsRequests(); - const { setGetPolygonPartsFeatureOptions } = useHandleWfsPolygonPartsRequests(); //<-from context menu - - const baseUpdateEntity = useCallback( - (updatedValue: ILayerImage) => { - store.discreteLayersStore.updateLayer(updatedValue); - store.discreteLayersStore.selectLayerByID(updatedValue.id); - - store.catalogTreeStore.updateNodeById(updatedValue.id, updatedValue); - - // After updating specific item REFRESH layerImages in order to present performed changes where it is relevant - store.discreteLayersStore.updateTabviewsData(updatedValue); - store.discreteLayersStore.refreshLayersImages(); - }, - [ - store.discreteLayersStore.updateLayer, - store.discreteLayersStore.selectLayerByID, - store.catalogTreeStore.updateNodeById, - store.discreteLayersStore.updateTabviewsData, - ] - ); - - const baseUpdateEntityField = useCallback( - (updatedValue: ILayerImage, field: keyof ILayerImage, value: unknown) => { - store.discreteLayersStore.updateLayerField(updatedValue.id, field, value); - store.discreteLayersStore.selectLayerByID(updatedValue.id); - - store.catalogTreeStore.updateFieldNodeById(updatedValue.id, updatedValue, field); - - // After updating specific item REFRESH layerImages in order to present performed changes where it is relevant - store.discreteLayersStore.updateTabviewsFieldData(updatedValue, field); - store.discreteLayersStore.refreshLayersImages(); - }, - [ - store.discreteLayersStore.updateLayerField, - store.discreteLayersStore.selectLayerByID, - store.catalogTreeStore.updateFieldNodeById, - store.discreteLayersStore.updateTabviewsFieldData, - ] - ); - - const baseFootprintShow = useCallback( - (isShown: boolean, selectedLayer: ILayerImage) => { - if (!isEmpty(selectedLayer)) { - store.discreteLayersStore.showFootprint(selectedLayer.id, isShown); - - const shouldUpdateTreeNode = activeTabView === TabViews.CATALOG; - - if (shouldUpdateTreeNode) { - store.catalogTreeStore.updateNodeById(selectedLayer.id, { - ...selectedLayer, - footprintShown: isShown, - }); - } - } - }, - [ - store.discreteLayersStore.showFootprint, - store.catalogTreeStore.updateNodeById, - activeTabView - ] - ); - - const baseLayerImageShow = useCallback( - (isShown: boolean, selectedLayer: ILayerImage) => { - if (!isEmpty(selectedLayer)) { - if (isShown) { - selectedLayersRef.current++; - if (selectedLayer.type === RecordType.RECORD_3D && mapViewer.scene.mode !== CesiumSceneMode.SCENE3D) { - mapViewer.scene.morphTo3D(1); +export const ActionResolver: React.FC = observer( + (props) => { + const { + handleOpenEntityDialog, + handleFlyTo, + handleTabViewChange, + handleOpenJobDialog, + activeTabView, + } = props; + + const store = useStore(); + const ENUMS = useEnums(); + const mapViewer = useCesiumMap(); + + const selectedLayersRef = useRef(initialOrder); + + const { internalFields: exportDomainInternalFields } = + useAddFeatureWithProps(false); + + const { setGetFeatureOptions } = useHandleWfsGetFeatureRequests(); + const { setDemHeightsOptions } = useHandleDemHeightsRequests(); + const { setGetPolygonPartsFeatureOptions } = + useHandleWfsPolygonPartsRequests(); //<-from context menu + + const baseUpdateEntity = useCallback( + (updatedValue: ILayerImage) => { + store.discreteLayersStore.updateLayer(updatedValue); + store.discreteLayersStore.selectLayerByID(updatedValue.id); + + store.catalogTreeStore.updateNodeById(updatedValue.id, updatedValue); + + // After updating specific item REFRESH layerImages in order to present performed changes where it is relevant + store.discreteLayersStore.updateTabviewsData(updatedValue); + store.discreteLayersStore.refreshLayersImages(); + }, + [ + store.discreteLayersStore.updateLayer, + store.discreteLayersStore.selectLayerByID, + store.catalogTreeStore.updateNodeById, + store.discreteLayersStore.updateTabviewsData, + ] + ); + + const baseUpdateEntityField = useCallback( + (updatedValue: ILayerImage, field: keyof ILayerImage, value: unknown) => { + store.discreteLayersStore.updateLayerField( + updatedValue.id, + field, + value + ); + store.discreteLayersStore.selectLayerByID(updatedValue.id); + + store.catalogTreeStore.updateFieldNodeById( + updatedValue.id, + updatedValue, + field + ); + + // After updating specific item REFRESH layerImages in order to present performed changes where it is relevant + store.discreteLayersStore.updateTabviewsFieldData(updatedValue, field); + store.discreteLayersStore.refreshLayersImages(); + }, + [ + store.discreteLayersStore.updateLayerField, + store.discreteLayersStore.selectLayerByID, + store.catalogTreeStore.updateFieldNodeById, + store.discreteLayersStore.updateTabviewsFieldData, + ] + ); + + const baseFootprintShow = useCallback( + (isShown: boolean, selectedLayer: ILayerImage) => { + if (!isEmpty(selectedLayer)) { + store.discreteLayersStore.showFootprint(selectedLayer.id, isShown); + + const shouldUpdateTreeNode = activeTabView === TabViews.CATALOG; + + if (shouldUpdateTreeNode) { + store.catalogTreeStore.updateNodeById(selectedLayer.id, { + ...selectedLayer, + footprintShown: isShown, + }); } - } else { - const orders: number[] = []; - store.discreteLayersStore.layersImages?.forEach((item: ILayerImage) => { - if (item.layerImageShown && selectedLayer.id !== item.id) { - orders.push(item.order as number); - } - }); - selectedLayersRef.current = orders.length - ? getMax(orders) - : selectedLayersRef.current - 1; } - const order = isShown ? selectedLayersRef.current : null; + }, + [ + store.discreteLayersStore.showFootprint, + store.catalogTreeStore.updateNodeById, + activeTabView, + ] + ); - store.discreteLayersStore.showLayer(selectedLayer.id, isShown, order); + const baseLayerImageShow = useCallback( + (isShown: boolean, selectedLayer: ILayerImage) => { + if (!isEmpty(selectedLayer)) { + if (isShown) { + selectedLayersRef.current++; + if ( + selectedLayer.type === RecordType.RECORD_3D && + mapViewer.scene.mode !== CesiumSceneMode.SCENE3D + ) { + mapViewer.scene.morphTo3D(1); + } + } else { + const orders: number[] = []; + store.discreteLayersStore.layersImages?.forEach( + (item: ILayerImage) => { + if (item.layerImageShown && selectedLayer.id !== item.id) { + orders.push(item.order as number); + } + } + ); + selectedLayersRef.current = orders.length + ? getMax(orders) + : selectedLayersRef.current - 1; + } + const order = isShown ? selectedLayersRef.current : null; + + store.discreteLayersStore.showLayer(selectedLayer.id, isShown, order); + + const shouldUpdateTreeNode = activeTabView === TabViews.CATALOG; - const shouldUpdateTreeNode = activeTabView === TabViews.CATALOG; + if (shouldUpdateTreeNode) { + store.catalogTreeStore.updateNodeById(selectedLayer.id, { + ...selectedLayer, + layerImageShown: isShown, + }); + } + } + }, + [ + store.discreteLayersStore.showLayer, + store.catalogTreeStore.updateNodeById, + activeTabView, + ] + ); - if (shouldUpdateTreeNode) { + const basePolygonPartsShow = useCallback( + (isShown: boolean, selectedLayer: ILayerImage) => { + if (!isEmpty(selectedLayer) && activeTabView === TabViews.CATALOG) { + const activePPLayer = store.discreteLayersStore.layersImages?.find( + (layer) => + isPolygonPartsShown(layer as unknown as Record) + ) as LayerRasterRecordModelType; + store.discreteLayersStore.showPolygonParts(selectedLayer.id, isShown); + if (activePPLayer) { + store.catalogTreeStore.updateNodeById(activePPLayer.id, { + ...activePPLayer, + polygonPartsShown: false, + }); + } store.catalogTreeStore.updateNodeById(selectedLayer.id, { ...selectedLayer, - layerImageShown: isShown, - }); - } - } - }, - [ - store.discreteLayersStore.showLayer, - store.catalogTreeStore.updateNodeById, - activeTabView - ] - ); - - const basePolygonPartsShow = useCallback( - (isShown: boolean, selectedLayer: ILayerImage) => { - if (!isEmpty(selectedLayer) && activeTabView === TabViews.CATALOG) { - const activePPLayer = store.discreteLayersStore.layersImages?.find(layer => isPolygonPartsShown(layer as unknown as Record)) as LayerRasterRecordModelType; - store.discreteLayersStore.showPolygonParts(selectedLayer.id, isShown); - if (activePPLayer) { - store.catalogTreeStore.updateNodeById(activePPLayer.id, {...activePPLayer, polygonPartsShown: false}); - } - store.catalogTreeStore.updateNodeById(selectedLayer.id, {...selectedLayer}); - } - }, - [ - store.discreteLayersStore.showPolygonParts, - store.catalogTreeStore.updateNodeById, - activeTabView - ] - ); - - const basePPUpdateErrorShow = useCallback( - (ppResolutionsUpdateError: Record) => { - store.discreteLayersStore.setCustomValidationError(ppResolutionsUpdateError); - }, - [] - ); - - useEffect(() => { - if (store.actionDispatcherStore.action !== undefined) { - const { action, data } = store.actionDispatcherStore.action as IDispatchAction; - console.log(` ${action} EVENT`, data); - - switch (action) { - case UserAction.ENTITY_ACTION_LAYERRASTERRECORD_CREATE: - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.NEW); - handleOpenEntityDialog(RecordType.RECORD_RASTER, true); - break; - case UserAction.ENTITY_ACTION_LAYER3DRECORD_CREATE: - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.NEW); - handleOpenEntityDialog(RecordType.RECORD_3D, true); - break; - case UserAction.ENTITY_ACTION_LAYERDEMRECORD_CREATE: - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.NEW); - handleOpenEntityDialog(RecordType.RECORD_DEM, true); - break; - case 'LayerRasterRecord.edit': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, LayerRasterRecordModelKeys) as LayerMetadataMixedUnion); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); - handleOpenEntityDialog(RecordType.RECORD_RASTER, true); - break; - case 'Layer3DRecord.edit': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, Layer3DRecordModelKeys) as LayerMetadataMixedUnion); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); - handleOpenEntityDialog(RecordType.RECORD_3D, true); - break; - case 'LayerDemRecord.edit': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, LayerDemRecordModelKeys) as LayerMetadataMixedUnion); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); - handleOpenEntityDialog(RecordType.RECORD_DEM, true); - break; - case 'VectorBestRecord.edit': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, VectorBestRecordModelKeys) as LayerMetadataMixedUnion); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); - handleOpenEntityDialog(RecordType.RECORD_VECTOR, true); - break; - case 'QuantizedMeshBestRecord.edit': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, QuantizedMeshBestRecordModelKeys) as LayerMetadataMixedUnion); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); - handleOpenEntityDialog(RecordType.RECORD_DEM, true); - break; - case UserAction.ENTITY_ACTION_SELECTED_ENTITY_EDIT: - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); - handleOpenEntityDialog(store.discreteLayersStore.selectedLayer?.type as RecordType, true); - break; - case UserAction.ENTITY_ACTION_SELECTED_ENTITY_VIEW: - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.VIEW); - handleOpenEntityDialog(store.discreteLayersStore.selectedLayer?.type as RecordType, true); - break; - case 'LayerRasterRecord.flyTo': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, LayerRasterRecordModelKeys) as LayerMetadataMixedUnion); - handleFlyTo(); - break; - case 'Layer3DRecord.flyTo': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, Layer3DRecordModelKeys) as LayerMetadataMixedUnion); - handleFlyTo(); - break; - case 'LayerDemRecord.flyTo': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, LayerDemRecordModelKeys) as LayerMetadataMixedUnion); - handleFlyTo(); - break; - case 'VectorBestRecord.flyTo': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, VectorBestRecordModelKeys) as LayerMetadataMixedUnion); - handleFlyTo(); - break; - case 'QuantizedMeshBestRecord.flyTo': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, QuantizedMeshBestRecordModelKeys) as LayerMetadataMixedUnion); - handleFlyTo(); - break; - case 'LayerRasterRecord.update': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, LayerRasterRecordModelKeys) as LayerMetadataMixedUnion, true); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.UPDATE); - handleOpenEntityDialog(RecordType.RECORD_RASTER, true); - break; - case 'Layer3DRecord.viewer': - window.open(`${CONFIG.WEB_TOOLS_URL}/${CONFIG.MODEL_VIEWER_ROUTE}?model_ids=${data.productId}&token=${CONFIG.MODEL_VIEWER_TOKEN_VALUE}`); - break; - case 'Layer3DRecord.delete': - // @ts-ignore - store.discreteLayersStore.selectLayer(cleanUpEntity(data, Layer3DRecordModelKeys) as LayerMetadataMixedUnion, false, true); - store.discreteLayersStore.setSelectedLayerOperationMode(Mode.DELETE); - handleOpenEntityDialog(RecordType.RECORD_3D, true); - break; - case 'LayerRasterRecord.viewer': - case 'LayerDemRecord.viewer': - case 'VectorBestRecord.viewer': - case 'QuantizedMeshBestRecord.viewer': - break; - case 'Job.retry': - // Is handled in jobs.dialog.tsx - break; - case 'LayerRasterRecord.saveMetadata': - case 'Layer3DRecord.saveMetadata': - case 'LayerDemRecord.saveMetadata': - case 'VectorBestRecord.saveMetadata': - case 'QuantizedMeshBestRecord.saveMetadata': - downloadJSONToClient(data, 'metadata.json'); - break; - case 'LayerRasterRecord.export': { - // @ts-ignore - const selectedLayerToExport = cleanUpEntity(data, LayerRasterRecordModelKeys) as LayerMetadataMixedUnion; - store.exportStore.reset(); - store.exportStore.setLayerToExport(selectedLayerToExport); - break; - } - case 'Layer3DRecord.export': { - // @ts-ignore - const selectedLayerToExport = cleanUpEntity(data, Layer3DRecordModelKeys) as LayerMetadataMixedUnion; - store.exportStore.reset(); - store.exportStore.setLayerToExport(selectedLayerToExport); - break; - } - case 'LayerDemRecord.export': { - // @ts-ignore - const selectedLayerToExport = cleanUpEntity(data, LayerDemRecordModelKeys) as LayerMetadataMixedUnion; - store.exportStore.reset(); - store.exportStore.setLayerToExport(selectedLayerToExport); - break; - } - case 'VectorBestRecord.export': - break; - case 'QuantizedMeshBestRecord.export': - break; - case ContextActions.QUERY_WFS_FEATURE: { - const coordinates = data.coordinates as { longitude: number, latitude: number }; - const typeName = data.feature as string; - const closeMenu = (data.handleClose as (() => void | undefined)); - - setGetFeatureOptions({ - pointCoordinates: [ - coordinates.longitude.toString(), - coordinates.latitude.toString(), - ], - typeName, - count: 1, - onDataResolved: closeMenu, }); - - break; } - case ContextActions.QUERY_POLYGON_PARTS: { - const coordinates = data.coordinates as { longitude: number, latitude: number }; - const closeMenu = (data.handleClose as (() => void | undefined)); - - setGetPolygonPartsFeatureOptions({ - feature: { - type: 'Feature', - properties: {}, - geometry: { - coordinates: [ - coordinates.longitude.toString(), - coordinates.latitude.toString() - ], - type: 'Point' - } - }, - typeName: getWFSFeatureTypeName(data?.layerRecord as LayerRasterRecordModelType, ENUMS), - shouldFlyToFeatures: true, - onDataResolved: closeMenu, - dWithin: 0 - }); - - break; - } - case ContextActions.QUERY_DEM_HEIGHT: { - const coordinates = data.coordinates as { longitude: number, latitude: number }; - const closeMenu = (data.handleClose as (() => void | undefined)); + }, + [ + store.discreteLayersStore.showPolygonParts, + store.catalogTreeStore.updateNodeById, + activeTabView, + ] + ); - setDemHeightsOptions({ - positions: [coordinates], - onDataResolved: closeMenu, - }); - - break; - } - case ExportActions.DRAW_FOOTPRINT: { - const {layerToExport} = store.exportStore; - store.exportStore.setTempRawSelection(getLayerFootprint(layerToExport as LayerMetadataMixedUnion, false) as Feature); - break; - } - case ExportActions.TOGGLE_FULL_LAYER_EXPORT: { - const {layerToExport} = store.exportStore; + const basePPUpdateErrorShow = useCallback( + (ppResolutionsUpdateError: Record) => { + store.discreteLayersStore.setCustomValidationError( + ppResolutionsUpdateError + ); + }, + [] + ); - if (data.is3DInit as boolean) { - store.exportStore.resetFeatureSelections(); - store.exportStore.setTempRawSelection(getLayerFootprint(layerToExport as LayerMetadataMixedUnion, false) as Feature); - store.exportStore.setIsFullyLayerExportEnabled(true); + useEffect(() => { + if (store.actionDispatcherStore.action !== undefined) { + const { action, data } = store.actionDispatcherStore + .action as IDispatchAction; + console.log(` ${action} EVENT`, data); + + switch (action) { + case UserAction.ENTITY_ACTION_LAYERRASTERRECORD_CREATE: + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.NEW); + handleOpenEntityDialog(RecordType.RECORD_RASTER, true); + break; + case UserAction.ENTITY_ACTION_LAYER3DRECORD_CREATE: + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.NEW); + handleOpenEntityDialog(RecordType.RECORD_3D, true); + break; + case UserAction.ENTITY_ACTION_LAYERDEMRECORD_CREATE: + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.NEW); + handleOpenEntityDialog(RecordType.RECORD_DEM, true); + break; + case 'LayerRasterRecord.edit': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + LayerRasterRecordModelKeys + ) as LayerMetadataMixedUnion + ); + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); + handleOpenEntityDialog(RecordType.RECORD_RASTER, true); + break; + case 'Layer3DRecord.edit': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + Layer3DRecordModelKeys + ) as LayerMetadataMixedUnion + ); + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); + handleOpenEntityDialog(RecordType.RECORD_3D, true); + break; + case 'LayerDemRecord.edit': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + LayerDemRecordModelKeys + ) as LayerMetadataMixedUnion + ); + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); + handleOpenEntityDialog(RecordType.RECORD_DEM, true); + break; + case 'VectorBestRecord.edit': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + VectorBestRecordModelKeys + ) as LayerMetadataMixedUnion + ); + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); + handleOpenEntityDialog(RecordType.RECORD_VECTOR, true); + break; + case 'QuantizedMeshBestRecord.edit': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + QuantizedMeshBestRecordModelKeys + ) as LayerMetadataMixedUnion + ); + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); + handleOpenEntityDialog(RecordType.RECORD_DEM, true); + break; + case UserAction.ENTITY_ACTION_SELECTED_ENTITY_EDIT: + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.EDIT); + handleOpenEntityDialog( + store.discreteLayersStore.selectedLayer?.type as RecordType, + true + ); + break; + case UserAction.ENTITY_ACTION_SELECTED_ENTITY_VIEW: + store.discreteLayersStore.setSelectedLayerOperationMode(Mode.VIEW); + handleOpenEntityDialog( + store.discreteLayersStore.selectedLayer?.type as RecordType, + true + ); + break; + case 'LayerRasterRecord.flyTo': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + LayerRasterRecordModelKeys + ) as LayerMetadataMixedUnion + ); + handleFlyTo(); + break; + case 'Layer3DRecord.flyTo': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + Layer3DRecordModelKeys + ) as LayerMetadataMixedUnion + ); + handleFlyTo(); + break; + case 'LayerDemRecord.flyTo': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + LayerDemRecordModelKeys + ) as LayerMetadataMixedUnion + ); + handleFlyTo(); + break; + case 'VectorBestRecord.flyTo': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + VectorBestRecordModelKeys + ) as LayerMetadataMixedUnion + ); + handleFlyTo(); + break; + case 'QuantizedMeshBestRecord.flyTo': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + QuantizedMeshBestRecordModelKeys + ) as LayerMetadataMixedUnion + ); + handleFlyTo(); + break; + case 'LayerRasterRecord.update': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + LayerRasterRecordModelKeys + ) as LayerMetadataMixedUnion, + true + ); + store.discreteLayersStore.setSelectedLayerOperationMode( + Mode.UPDATE + ); + handleOpenEntityDialog(RecordType.RECORD_RASTER, true); + break; + case 'Layer3DRecord.viewer': + window.open( + `${CONFIG.WEB_TOOLS_URL}/${CONFIG.MODEL_VIEWER_ROUTE}?model_ids=${data.productId}&token=${CONFIG.MODEL_VIEWER_TOKEN_VALUE}` + ); + break; + case 'Layer3DRecord.delete': + // @ts-ignore + store.discreteLayersStore.selectLayer( + cleanUpEntity( + data, + Layer3DRecordModelKeys + ) as LayerMetadataMixedUnion, + false, + true + ); + store.discreteLayersStore.setSelectedLayerOperationMode( + Mode.DELETE + ); + handleOpenEntityDialog(RecordType.RECORD_3D, true); + break; + case 'LayerRasterRecord.viewer': + case 'LayerDemRecord.viewer': + case 'VectorBestRecord.viewer': + case 'QuantizedMeshBestRecord.viewer': + break; + case 'Job.retry': + // Is handled in jobs.dialog.tsx + break; + case 'LayerRasterRecord.saveMetadata': + case 'Layer3DRecord.saveMetadata': + case 'LayerDemRecord.saveMetadata': + case 'VectorBestRecord.saveMetadata': + case 'QuantizedMeshBestRecord.saveMetadata': + downloadJSONToClient(data, 'metadata.json'); + break; + case 'LayerRasterRecord.export': { + // @ts-ignore + const selectedLayerToExport = cleanUpEntity( + data, + LayerRasterRecordModelKeys + ) as LayerMetadataMixedUnion; + store.exportStore.reset(); + store.exportStore.setLayerToExport(selectedLayerToExport); + break; + } + case 'Layer3DRecord.export': { + // @ts-ignore + const selectedLayerToExport = cleanUpEntity( + data, + Layer3DRecordModelKeys + ) as LayerMetadataMixedUnion; + store.exportStore.reset(); + store.exportStore.setLayerToExport(selectedLayerToExport); + break; + } + case 'LayerDemRecord.export': { + // @ts-ignore + const selectedLayerToExport = cleanUpEntity( + data, + LayerDemRecordModelKeys + ) as LayerMetadataMixedUnion; + store.exportStore.reset(); + store.exportStore.setLayerToExport(selectedLayerToExport); + break; + } + case 'VectorBestRecord.export': + break; + case 'QuantizedMeshBestRecord.export': + break; + case ContextActions.QUERY_WFS_FEATURE: { + const coordinates = data.coordinates as { + longitude: number; + latitude: number; + }; + const typeName = data.feature as string; + const closeMenu = data.handleClose as () => void | undefined; + + setGetFeatureOptions({ + pointCoordinates: [ + coordinates.longitude.toString(), + coordinates.latitude.toString(), + ], + typeName, + count: 1, + onDataResolved: closeMenu, + }); break; } + case ContextActions.QUERY_POLYGON_PARTS: { + const coordinates = data.coordinates as { + longitude: number; + latitude: number; + }; + const closeMenu = data.handleClose as () => void | undefined; - if (!store.exportStore.isFullLayerExportEnabled) { - // Clean any previous selections - store.exportStore.resetFeatureSelections(); - store.exportStore.setTempRawSelection(getLayerFootprint(layerToExport as LayerMetadataMixedUnion, false) as Feature); - } else { + setGetPolygonPartsFeatureOptions({ + feature: { + type: 'Feature', + properties: {}, + geometry: { + coordinates: [ + coordinates.longitude.toString(), + coordinates.latitude.toString(), + ], + type: 'Point', + }, + }, + typeName: getWFSFeatureTypeName( + data?.layerRecord as LayerRasterRecordModelType, + ENUMS + ), + shouldFlyToFeatures: true, + onDataResolved: closeMenu, + dWithin: 0, + }); + + break; + } + case ContextActions.QUERY_DEM_HEIGHT: { + const coordinates = data.coordinates as { + longitude: number; + latitude: number; + }; + const closeMenu = data.handleClose as () => void | undefined; + + setDemHeightsOptions({ + positions: [coordinates], + onDataResolved: closeMenu, + }); + + break; + } + case ExportActions.DRAW_FOOTPRINT: { + const { layerToExport } = store.exportStore; + store.exportStore.setTempRawSelection( + getLayerFootprint( + layerToExport as LayerMetadataMixedUnion, + false + ) as Feature + ); + break; + } + case ExportActions.TOGGLE_FULL_LAYER_EXPORT: { + const { layerToExport } = store.exportStore; + + if (data.is3DInit as boolean) { + store.exportStore.resetFeatureSelections(); + store.exportStore.setTempRawSelection( + getLayerFootprint( + layerToExport as LayerMetadataMixedUnion, + false + ) as Feature + ); + store.exportStore.setIsFullyLayerExportEnabled(true); + + break; + } + + if (!store.exportStore.isFullLayerExportEnabled) { + // Clean any previous selections + store.exportStore.resetFeatureSelections(); + store.exportStore.setTempRawSelection( + getLayerFootprint( + layerToExport as LayerMetadataMixedUnion, + false + ) as Feature + ); + } else { + store.exportStore.resetFeatureSelections(); + } + + store.exportStore.toggleIsFullLayerExportEnabled(); + break; + } + case ExportActions.DRAW_RECTANGLE: + store.exportStore.setDrawingState({ + drawing: true, + type: DrawType.BOX, + }); + break; + case ExportActions.DRAW_POLYGON: + store.exportStore.setDrawingState({ + drawing: true, + type: DrawType.POLYGON, + }); + break; + case ExportActions.DRAW_BY_COORDINATES: + store.exportStore.setIsBBoxDialogOpen(true); + break; + case ExportActions.CLEAR_DRAWINGS: store.exportStore.resetFeatureSelections(); + store.exportStore.resetFullLayerExport(); + store.exportStore.resetHasExportPreviewed(); + store.exportStore.resetDrawingState(); + break; + case ExportActions.IMPORT_FROM_SHAPE_FILE: + importShapeFileFromClient((evt, fileType) => { + void store.exportStore.handleUploadedFile( + evt, + fileType, + exportDomainInternalFields + ); + }, true); + break; + case ExportActions.EXPORT_HOT_AREA_SELECTION: + store.exportStore.setTempRawSelection(data as unknown as Feature); + break; + case ExportActions.END_EXPORT_SESSION: + handleTabViewChange(TabViews.CATALOG); + store.discreteLayersStore.resetTabView([TabViews.EXPORT_LAYER]); + store.exportStore.reset(); + break; + // System Callback operations + case UserAction.SYSTEM_CALLBACK_EDIT: { + const inputValues = data as unknown as ILayerImage; + baseUpdateEntity(inputValues); + break; } + case UserAction.SYSTEM_CALLBACK_PUBLISH: { + const inputValues = data as unknown as ILayerImage; - store.exportStore.toggleIsFullLayerExportEnabled(); - break; - } - case ExportActions.DRAW_RECTANGLE: - store.exportStore.setDrawingState({ - drawing: true, - type: DrawType.BOX - }) - break; - case ExportActions.DRAW_POLYGON: - store.exportStore.setDrawingState({ - drawing: true, - type: DrawType.POLYGON - }) - break; - case ExportActions.DRAW_BY_COORDINATES: - store.exportStore.setIsBBoxDialogOpen(true); - break; - case ExportActions.CLEAR_DRAWINGS: - store.exportStore.resetFeatureSelections(); - store.exportStore.resetFullLayerExport(); - store.exportStore.resetHasExportPreviewed(); - store.exportStore.resetDrawingState(); - break; - case ExportActions.IMPORT_FROM_SHAPE_FILE: - importShapeFileFromClient((evt, fileType) => { - void store.exportStore.handleUploadedFile(evt, fileType, exportDomainInternalFields); - }, true); - break; - case ExportActions.EXPORT_HOT_AREA_SELECTION: - store.exportStore.setTempRawSelection(data as unknown as Feature); - break; - case ExportActions.END_EXPORT_SESSION: - handleTabViewChange(TabViews.CATALOG); - store.discreteLayersStore.resetTabView([TabViews.EXPORT_LAYER]); - store.exportStore.reset(); - break; - // System Callback operations - case UserAction.SYSTEM_CALLBACK_EDIT: { - const inputValues = data as unknown as ILayerImage; - baseUpdateEntity(inputValues); - break; - } - case UserAction.SYSTEM_CALLBACK_PUBLISH: { - const inputValues = data as unknown as ILayerImage; - - baseUpdateEntityField(inputValues, 'productStatus' as keyof ILayerImage, get(inputValues, 'productStatus')); - - const node = store.catalogTreeStore.findNodeById(inputValues.id); - - if (node) { - if (existStatus(inputValues as unknown as Record) && isUnpublished(inputValues as unknown as Record)) { - store.catalogTreeStore.addNodeToParent(node.node, "tab-views.catalog.top-categories.unpublished", true); - } else { - const unpublishedNode = store.catalogTreeStore.findNodeByTitle("tab-views.catalog.top-categories.unpublished", true) as NodeData; - store.catalogTreeStore.removeChildFromParent(inputValues.id, unpublishedNode); + baseUpdateEntityField( + inputValues, + 'productStatus' as keyof ILayerImage, + get(inputValues, 'productStatus') + ); + + const node = store.catalogTreeStore.findNodeById(inputValues.id); + + if (node) { + if ( + existStatus( + inputValues as unknown as Record + ) && + isUnpublished(inputValues as unknown as Record) + ) { + store.catalogTreeStore.addNodeToParent( + node.node, + 'tab-views.catalog.top-categories.unpublished', + true + ); + } else { + const unpublishedNode = store.catalogTreeStore.findNodeByTitle( + 'tab-views.catalog.top-categories.unpublished', + true + ) as NodeData; + store.catalogTreeStore.removeChildFromParent( + inputValues.id, + unpublishedNode + ); + } } + break; } - break; - } - case UserAction.SYSTEM_CALLBACK_DELETE: { - const selectedLayer = data as unknown as ILayerImage; - baseUpdateEntityField(selectedLayer, 'productStatus' as keyof ILayerImage, get(selectedLayer, 'productStatus')); - break; - } - case UserAction.SYSTEM_CALLBACK_FLYTO: { - const selectedLayer = data.selectedLayer as ILayerImage; - baseFootprintShow(true, selectedLayer); - break; - } - case UserAction.SYSTEM_CALLBACK_SHOWFOOTPRINT: { - const selectedLayer = data.selectedLayer as ILayerImage; - baseFootprintShow(selectedLayer.footprintShown as boolean, selectedLayer); - break; - } - case UserAction.SYSTEM_CALLBACK_SHOWLAYERIMAGE: { - const selectedLayer = data.selectedLayer as ILayerImage; - baseLayerImageShow(selectedLayer.layerImageShown as boolean, selectedLayer); - break; - } - case UserAction.SYSTEM_CALLBACK_SHOWPOLYGONPARTS: { - const selectedLayer = data.selectedLayer as LayerRasterRecordModelType; - basePolygonPartsShow(selectedLayer.polygonPartsShown as boolean, selectedLayer); - if (selectedLayer.polygonPartsShown) { - store.discreteLayersStore.resetPolygonPartsInfo(); - store.discreteLayersStore.setPolygonPartsLayer(selectedLayer); - // PP query moved to polygonParts.tsx - } else { - store.discreteLayersStore.resetPolygonParts(); + case UserAction.SYSTEM_CALLBACK_DELETE: { + const selectedLayer = data as unknown as ILayerImage; + baseUpdateEntityField( + selectedLayer, + 'productStatus' as keyof ILayerImage, + get(selectedLayer, 'productStatus') + ); + break; } - break; - } - case UserAction.SYSTEM_CALLBACK_SHOW_PPERROR_ON_UPDATE: { - basePPUpdateErrorShow(data as Record); - break; - } - case UserAction.SYSTEM_CALLBACK_OPEN_JOB_MANAGER: { - handleOpenJobDialog(true, data.job as unknown as JobModelType); - break; + case UserAction.SYSTEM_CALLBACK_FLYTO: { + const selectedLayer = data.selectedLayer as ILayerImage; + baseFootprintShow(true, selectedLayer); + break; + } + case UserAction.SYSTEM_CALLBACK_SHOWFOOTPRINT: { + const selectedLayer = data.selectedLayer as ILayerImage; + baseFootprintShow( + selectedLayer.footprintShown as boolean, + selectedLayer + ); + break; + } + case UserAction.SYSTEM_CALLBACK_SHOWLAYERIMAGE: { + const selectedLayer = data.selectedLayer as ILayerImage; + baseLayerImageShow( + selectedLayer.layerImageShown as boolean, + selectedLayer + ); + break; + } + case UserAction.SYSTEM_CALLBACK_SHOWPOLYGONPARTS: { + const selectedLayer = + data.selectedLayer as LayerRasterRecordModelType; + basePolygonPartsShow( + selectedLayer.polygonPartsShown as boolean, + selectedLayer + ); + if (selectedLayer.polygonPartsShown) { + store.discreteLayersStore.resetPolygonPartsInfo(); + store.discreteLayersStore.setPolygonPartsLayer(selectedLayer); + // PP query moved to polygonParts.tsx + } else { + store.discreteLayersStore.resetPolygonParts(); + } + break; + } + case UserAction.SYSTEM_CALLBACK_SHOW_PPERROR_ON_UPDATE: { + basePPUpdateErrorShow(data as Record); + break; + } + case UserAction.SYSTEM_CALLBACK_OPEN_JOB_MANAGER: { + handleOpenJobDialog(true, data.job as unknown as JobModelType); + break; + } + default: + break; } - default: - break; } - } - }, [store.actionDispatcherStore.action, store.discreteLayersStore]); - - return ( - <> - ); + }, [store.actionDispatcherStore.action, store.discreteLayersStore]); -}); + return <>; + } +); diff --git a/src/discrete-layer/views/components/app-title/app-title.component.tsx b/src/discrete-layer/views/components/app-title/app-title.component.tsx index 5400e28de..683eecfda 100644 --- a/src/discrete-layer/views/components/app-title/app-title.component.tsx +++ b/src/discrete-layer/views/components/app-title/app-title.component.tsx @@ -14,15 +14,20 @@ const AppTitle = (): JSX.Element => { const site = useMemo(() => currentSite(), []); useEffect(() => { - document.title = `${intl.formatMessage({ id: 'general.logo.text' })} - ${projectVersion}`; + document.title = `${intl.formatMessage({ + id: 'general.logo.text', + })} - ${projectVersion}`; }, []); - const versionText = intl.formatMessage({id: "general.version.text"}, { projectVersion, appVersion }); + const versionText = intl.formatMessage( + { id: 'general.version.text' }, + { projectVersion, appVersion } + ); return ( <> - - + + {intl.formatMessage({ id: 'general.logo.text' })} diff --git a/src/discrete-layer/views/components/data-fetchers/base-maps-legends-fetcher-component.tsx b/src/discrete-layer/views/components/data-fetchers/base-maps-legends-fetcher-component.tsx index 4a53756ae..4bf51d1c9 100644 --- a/src/discrete-layer/views/components/data-fetchers/base-maps-legends-fetcher-component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/base-maps-legends-fetcher-component.tsx @@ -26,8 +26,7 @@ export const BaseMapsLegendsFetcher: React.FC = observer(() => { }, { protocol: LinkType.LEGEND_IMG, - url: - 'https://c8.alamy.com/comp/F5HF5D/map-icon-legend-symbol-sign-toolkit-element-F5HF5D.jpg', + url: 'https://c8.alamy.com/comp/F5HF5D/map-icon-legend-symbol-sign-toolkit-element-F5HF5D.jpg', }, ], ], @@ -40,8 +39,7 @@ export const BaseMapsLegendsFetcher: React.FC = observer(() => { }, { protocol: LinkType.LEGEND_IMG, - url: - 'https://i.pinimg.com/564x/55/cf/a1/55cfa147dfef99d231ec95ab8cd3652d--outdoor-code-cub-scouts-brownie-hiking-badge.jpg', + url: 'https://i.pinimg.com/564x/55/cf/a1/55cfa147dfef99d231ec95ab8cd3652d--outdoor-code-cub-scouts-brownie-hiking-badge.jpg', }, ], ], @@ -56,8 +54,7 @@ export const BaseMapsLegendsFetcher: React.FC = observer(() => { }, { protocol: LinkType.LEGEND_IMG, - url: - 'https://i.pinimg.com/564x/55/cf/a1/55cfa147dfef99d231ec95ab8cd3652d--outdoor-code-cub-scouts-brownie-hiking-badge.jpg', + url: 'https://i.pinimg.com/564x/55/cf/a1/55cfa147dfef99d231ec95ab8cd3652d--outdoor-code-cub-scouts-brownie-hiking-badge.jpg', }, ], ], @@ -71,8 +68,7 @@ export const BaseMapsLegendsFetcher: React.FC = observer(() => { }, { protocol: LinkType.LEGEND_IMG, - url: - 'https://c8.alamy.com/comp/F5HF5D/map-icon-legend-symbol-sign-toolkit-element-F5HF5D.jpg', + url: 'https://c8.alamy.com/comp/F5HF5D/map-icon-legend-symbol-sign-toolkit-element-F5HF5D.jpg', }, ], ], @@ -106,8 +102,12 @@ export const BaseMapsLegendsFetcher: React.FC = observer(() => { const layerFromCatalog = await GET_MOCK_LAYER_WITH_LINKS( rasterLayer.id ); - const legendsLinks = ((layerFromCatalog.links as unknown) as LinkModelType[]).filter( - (link) => [LEGEND_PDF_PROTOCOL, LEGEND_IMG_PROTOCOL].includes(link.protocol as LinkType) + const legendsLinks = ( + layerFromCatalog.links as unknown as LinkModelType[] + ).filter((link) => + [LEGEND_PDF_PROTOCOL, LEGEND_IMG_PROTOCOL].includes( + link.protocol as LinkType + ) ); return { diff --git a/src/discrete-layer/views/components/data-fetchers/entity-descriptors-fetcher.component.tsx b/src/discrete-layer/views/components/data-fetchers/entity-descriptors-fetcher.component.tsx index 88d137199..203ed049e 100644 --- a/src/discrete-layer/views/components/data-fetchers/entity-descriptors-fetcher.component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/entity-descriptors-fetcher.component.tsx @@ -5,8 +5,10 @@ import { EntityDescriptorModelType } from '../../../models'; export const EntityDescriptorsFetcher: React.FC = observer(() => { const store = useStore(); - const descriptorsQuery = useQuery((store) => store.queryEntityDescriptors({}, - ` type + const descriptorsQuery = useQuery((store) => + store.queryEntityDescriptors( + {}, + ` type categories { category categoryTitle @@ -107,16 +109,21 @@ export const EntityDescriptorsFetcher: React.FC = observer(() => { default } __typename - }`)); - + }` + ) + ); + useEffect(() => { if (!descriptorsQuery.loading && descriptorsQuery.data) { - const descriptors = descriptorsQuery.data?.entityDescriptors as EntityDescriptorModelType[]; + const descriptors = descriptorsQuery.data + ?.entityDescriptors as EntityDescriptorModelType[]; store.discreteLayersStore.setEntityDescriptors([...descriptors]); } - }, [descriptorsQuery.data, descriptorsQuery.loading, store.discreteLayersStore]); - - return ( - <> - ); + }, [ + descriptorsQuery.data, + descriptorsQuery.loading, + store.discreteLayersStore, + ]); + + return <>; }); diff --git a/src/discrete-layer/views/components/data-fetchers/lookup-tables-fetcher.component.tsx b/src/discrete-layer/views/components/data-fetchers/lookup-tables-fetcher.component.tsx index 706dfe2f1..84a93a16e 100644 --- a/src/discrete-layer/views/components/data-fetchers/lookup-tables-fetcher.component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/lookup-tables-fetcher.component.tsx @@ -1,7 +1,9 @@ /* eslint-disable */ import { observer } from 'mobx-react'; import React, { useContext, useEffect } from 'react'; -import lookupTablesContext, { ILookupTableData } from '../../../../common/contexts/lookupTables.context'; +import lookupTablesContext, { + ILookupTableData, +} from '../../../../common/contexts/lookupTables.context'; import { useStore, useQuery } from '../../../models/RootStore'; import { Error } from './../../../../common/components/tree/statuses/error'; import { queue } from '../../../../discrete-layer/components/snackbar/notification-queue'; @@ -10,7 +12,12 @@ export const HOT_AREAS_TABLES_KEY = 'hotAreas'; export const LookupTablesFetcher: React.FC = observer(() => { const store = useStore(); - const { data, loading, error } = useQuery((store) => store.queryGetLookupTablesData({data: {lookupFields: [{ lookupTable: HOT_AREAS_TABLES_KEY }]}}, `dictionary`)); + const { data, loading, error } = useQuery((store) => + store.queryGetLookupTablesData( + { data: { lookupFields: [{ lookupTable: HOT_AREAS_TABLES_KEY }] } }, + `dictionary` + ) + ); const { setLookupTablesData } = useContext(lookupTablesContext); useEffect(() => { @@ -26,12 +33,14 @@ export const LookupTablesFetcher: React.FC = observer(() => { - ) - }) + ), + }); } - }, [error]) + }, [error]); return null; -}); \ No newline at end of file +}); diff --git a/src/discrete-layer/views/components/data-fetchers/mc-enums-fetcher.component.tsx b/src/discrete-layer/views/components/data-fetchers/mc-enums-fetcher.component.tsx index 17b99a139..6e3617290 100644 --- a/src/discrete-layer/views/components/data-fetchers/mc-enums-fetcher.component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/mc-enums-fetcher.component.tsx @@ -1,7 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention */ import React, { useContext, useEffect } from 'react'; import { observer } from 'mobx-react'; -import EnumsMapContext, { IEnumsMapType } from '../../../../common/contexts/enumsMap.context'; +import EnumsMapContext, { + IEnumsMapType, +} from '../../../../common/contexts/enumsMap.context'; import { DemDataType, NoDataValue, @@ -9,7 +11,7 @@ import { RecordStatus, RecordType, UndulationModel, - Transparency + Transparency, } from '../../../models'; import { useQuery, useStore } from '../../../models/RootStore'; @@ -24,19 +26,26 @@ export const MCEnumsFetcher: React.FC = observer(() => { ProductType, RecordStatus, RecordType, - Transparency + Transparency, }; useEffect(() => { if (!mcEnumsQuery.loading && mcEnumsQuery.data) { - const enums = { ...(mcEnumsQuery.data.getMcEnums).enums as IEnumsMapType }; + const enums = { + ...(mcEnumsQuery.data.getMcEnums.enums as IEnumsMapType), + }; + + Object.values(enumUnion).forEach( + (enumValues: Record): void => { + Object.keys(enumValues).forEach((item) => { + enums[item] = { + ...enums[item], + translationKey: `${enums[item].enumName}.${item.toLowerCase()}`, + }; + }); + } + ); - Object.values(enumUnion).forEach((enumValues: Record): void => { - Object.keys(enumValues).forEach(item => { - enums[item] = { ...enums[item], translationKey: `${enums[item].enumName}.${item.toLowerCase()}` }; - }); - }); - const { ORTHOPHOTO, ORTHOPHOTO_HISTORY, @@ -57,27 +66,149 @@ export const MCEnumsFetcher: React.FC = observer(() => { POINT_CLOUD, } = ProductType; - enums['LayerRasterRecord'] = { enumName: '', realValue: '', icon: 'mc-icon-Map-Orthophoto', translationKey: 'record-type.record_raster.label', parent: '', internal: false, properties: {}, parentDomain: RecordType.RECORD_RASTER }; - enums['Layer3DRecord'] = { enumName: '', realValue: '', icon: 'mc-icon-Map-3D', translationKey: 'record-type.record_3d.label', parent: '', internal: false, properties: {}, parentDomain: RecordType.RECORD_3D }; - enums['LayerDemRecord'] = { enumName: '', realValue: '', icon: 'mc-icon-Map-DTM', translationKey: 'record-type.record_dem.label', parent: '', internal: false, properties: {}, parentDomain: RecordType.RECORD_DEM }; - enums['QuantizedMeshBestRecord'] = { enumName: '', realValue: '', icon: 'mc-icon-Map-Best-Qmash', translationKey: 'record-type.record_quantized_mesh.label', parent: '', internal: false, properties: {}, parentDomain: RecordType.RECORD_3D }; - enums[ORTHOPHOTO] = { ...enums[ORTHOPHOTO], icon: 'mc-icon-Map-Orthophoto', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[ORTHOPHOTO_HISTORY] = { ...enums[ORTHOPHOTO_HISTORY], icon: 'mc-icon-Map-Orthophoto', parent: 'LayerRasterRecord', internal: true, parentDomain: RecordType.RECORD_RASTER }; - enums[ORTHOPHOTO_BEST] = { ...enums[ORTHOPHOTO_BEST], icon: 'mc-icon-Map-Best-Orthophoto', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[RASTER_MAP] = { ...enums[RASTER_MAP], icon: 'mc-icon-Map-Raster', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[RASTER_MAP_BEST] = { ...enums[RASTER_MAP_BEST], icon: 'mc-icon-Map-Best-Raster', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[RASTER_AID] = { ...enums[RASTER_AID], icon: 'mc-icon-Map-RasterAid', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[RASTER_AID_BEST] = { ...enums[RASTER_AID_BEST], icon: 'mc-icon-Map-Best-RasterAid', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[RASTER_VECTOR] = { ...enums[RASTER_VECTOR], icon: 'mc-icon-Map-Vector', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[RASTER_VECTOR_BEST] = { ...enums[RASTER_VECTOR_BEST], icon: 'mc-icon-Map-Vector', parent: 'LayerRasterRecord', parentDomain: RecordType.RECORD_RASTER }; - enums[DTM] = { ...enums[DTM], icon: 'mc-icon-Map-DTM', parent: 'LayerDemRecord', parentDomain: RecordType.RECORD_DEM }; - enums[DSM] = { ...enums[DSM], icon: 'mc-icon-Map-DSM', parent: 'LayerDemRecord', parentDomain: RecordType.RECORD_DEM }; - enums[QUANTIZED_MESH_DTM] = { ...enums[QUANTIZED_MESH_DTM], icon: 'mc-icon-Map-QMesh-DTM', parent: 'LayerDemRecord', parentDomain: RecordType.RECORD_DEM }; - enums[QUANTIZED_MESH_DSM] = { ...enums[QUANTIZED_MESH_DSM], icon: 'mc-icon-Map-QMesh-DSM', parent: 'LayerDemRecord', parentDomain: RecordType.RECORD_DEM }; - enums[QUANTIZED_MESH_DTM_BEST] = { ...enums[QUANTIZED_MESH_DTM_BEST], icon: 'mc-icon-Map-QMesh-DTM', parent: 'QuantizedMeshBestRecord', parentDomain: RecordType.RECORD_DEM }; - enums[QUANTIZED_MESH_DSM_BEST] = { ...enums[QUANTIZED_MESH_DSM_BEST], icon: 'mc-icon-Map-QMesh-DSM', parent: 'QuantizedMeshBestRecord', parentDomain: RecordType.RECORD_DEM }; - enums[PHOTO_REALISTIC_3D] = { ...enums[PHOTO_REALISTIC_3D], icon: 'mc-icon-Map-3D', parent: 'Layer3DRecord', parentDomain: RecordType.RECORD_3D }; - enums[POINT_CLOUD] = { ...enums[POINT_CLOUD], icon: 'mc-icon-Map-3D', parent: 'Layer3DRecord', parentDomain: RecordType.RECORD_3D }; + enums['LayerRasterRecord'] = { + enumName: '', + realValue: '', + icon: 'mc-icon-Map-Orthophoto', + translationKey: 'record-type.record_raster.label', + parent: '', + internal: false, + properties: {}, + parentDomain: RecordType.RECORD_RASTER, + }; + enums['Layer3DRecord'] = { + enumName: '', + realValue: '', + icon: 'mc-icon-Map-3D', + translationKey: 'record-type.record_3d.label', + parent: '', + internal: false, + properties: {}, + parentDomain: RecordType.RECORD_3D, + }; + enums['LayerDemRecord'] = { + enumName: '', + realValue: '', + icon: 'mc-icon-Map-DTM', + translationKey: 'record-type.record_dem.label', + parent: '', + internal: false, + properties: {}, + parentDomain: RecordType.RECORD_DEM, + }; + enums['QuantizedMeshBestRecord'] = { + enumName: '', + realValue: '', + icon: 'mc-icon-Map-Best-Qmash', + translationKey: 'record-type.record_quantized_mesh.label', + parent: '', + internal: false, + properties: {}, + parentDomain: RecordType.RECORD_3D, + }; + enums[ORTHOPHOTO] = { + ...enums[ORTHOPHOTO], + icon: 'mc-icon-Map-Orthophoto', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[ORTHOPHOTO_HISTORY] = { + ...enums[ORTHOPHOTO_HISTORY], + icon: 'mc-icon-Map-Orthophoto', + parent: 'LayerRasterRecord', + internal: true, + parentDomain: RecordType.RECORD_RASTER, + }; + enums[ORTHOPHOTO_BEST] = { + ...enums[ORTHOPHOTO_BEST], + icon: 'mc-icon-Map-Best-Orthophoto', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[RASTER_MAP] = { + ...enums[RASTER_MAP], + icon: 'mc-icon-Map-Raster', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[RASTER_MAP_BEST] = { + ...enums[RASTER_MAP_BEST], + icon: 'mc-icon-Map-Best-Raster', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[RASTER_AID] = { + ...enums[RASTER_AID], + icon: 'mc-icon-Map-RasterAid', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[RASTER_AID_BEST] = { + ...enums[RASTER_AID_BEST], + icon: 'mc-icon-Map-Best-RasterAid', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[RASTER_VECTOR] = { + ...enums[RASTER_VECTOR], + icon: 'mc-icon-Map-Vector', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[RASTER_VECTOR_BEST] = { + ...enums[RASTER_VECTOR_BEST], + icon: 'mc-icon-Map-Vector', + parent: 'LayerRasterRecord', + parentDomain: RecordType.RECORD_RASTER, + }; + enums[DTM] = { + ...enums[DTM], + icon: 'mc-icon-Map-DTM', + parent: 'LayerDemRecord', + parentDomain: RecordType.RECORD_DEM, + }; + enums[DSM] = { + ...enums[DSM], + icon: 'mc-icon-Map-DSM', + parent: 'LayerDemRecord', + parentDomain: RecordType.RECORD_DEM, + }; + enums[QUANTIZED_MESH_DTM] = { + ...enums[QUANTIZED_MESH_DTM], + icon: 'mc-icon-Map-QMesh-DTM', + parent: 'LayerDemRecord', + parentDomain: RecordType.RECORD_DEM, + }; + enums[QUANTIZED_MESH_DSM] = { + ...enums[QUANTIZED_MESH_DSM], + icon: 'mc-icon-Map-QMesh-DSM', + parent: 'LayerDemRecord', + parentDomain: RecordType.RECORD_DEM, + }; + enums[QUANTIZED_MESH_DTM_BEST] = { + ...enums[QUANTIZED_MESH_DTM_BEST], + icon: 'mc-icon-Map-QMesh-DTM', + parent: 'QuantizedMeshBestRecord', + parentDomain: RecordType.RECORD_DEM, + }; + enums[QUANTIZED_MESH_DSM_BEST] = { + ...enums[QUANTIZED_MESH_DSM_BEST], + icon: 'mc-icon-Map-QMesh-DSM', + parent: 'QuantizedMeshBestRecord', + parentDomain: RecordType.RECORD_DEM, + }; + enums[PHOTO_REALISTIC_3D] = { + ...enums[PHOTO_REALISTIC_3D], + icon: 'mc-icon-Map-3D', + parent: 'Layer3DRecord', + parentDomain: RecordType.RECORD_3D, + }; + enums[POINT_CLOUD] = { + ...enums[POINT_CLOUD], + icon: 'mc-icon-Map-3D', + parent: 'Layer3DRecord', + parentDomain: RecordType.RECORD_3D, + }; const { UNPUBLISHED } = RecordStatus; @@ -86,6 +217,6 @@ export const MCEnumsFetcher: React.FC = observer(() => { setEnumsMap(enums); } }, [mcEnumsQuery.data, mcEnumsQuery.loading, store.discreteLayersStore]); - + return null; -}); \ No newline at end of file +}); diff --git a/src/discrete-layer/views/components/data-fetchers/services-availability-fetcher-component.tsx b/src/discrete-layer/views/components/data-fetchers/services-availability-fetcher-component.tsx index 19a16aff8..6bcefaee2 100644 --- a/src/discrete-layer/views/components/data-fetchers/services-availability-fetcher-component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/services-availability-fetcher-component.tsx @@ -5,13 +5,17 @@ import { useQuery, useStore } from '../../../models/RootStore'; export const ServicesAvailabilityFetcher: React.FC = observer(() => { const store = useStore(); - const servicesAvailabilityQuery = useQuery((store) => store.queryServicesAvailability()); - + const servicesAvailabilityQuery = useQuery((store) => + store.queryServicesAvailability() + ); + useEffect(() => { - if (!servicesAvailabilityQuery.loading && servicesAvailabilityQuery.data) { - store.servicesAvailabilityStore.setServicesAvailabilities(servicesAvailabilityQuery.data.servicesAvailability); + if (!servicesAvailabilityQuery.loading && servicesAvailabilityQuery.data) { + store.servicesAvailabilityStore.setServicesAvailabilities( + servicesAvailabilityQuery.data.servicesAvailability + ); } }, [servicesAvailabilityQuery.data, servicesAvailabilityQuery.loading]); - + return null; }); diff --git a/src/discrete-layer/views/components/data-fetchers/static-data-fetcher.component.tsx b/src/discrete-layer/views/components/data-fetchers/static-data-fetcher.component.tsx index c17d22842..0c9fba635 100644 --- a/src/discrete-layer/views/components/data-fetchers/static-data-fetcher.component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/static-data-fetcher.component.tsx @@ -7,24 +7,26 @@ import { WfsFeaturesFetcher } from './wfs-features-fetcher.component'; import { ServicesAvailabilityFetcher } from './services-availability-fetcher-component'; import { useStore } from '../../../models'; - export const StaticDataFetcher: React.FC = () => { const store = useStore(); - // Init stores after some dependencies are set - useEffect(() => { - if (store.servicesAvailabilityStore.servicesAvailability) { - // Here we have the services availabilities initialized. - store.mapMenusManagerStore.initStore(); - } - }, [store.mapMenusManagerStore.wfsFeatureTypes, store.servicesAvailabilityStore.servicesAvailability]) + // Init stores after some dependencies are set + useEffect(() => { + if (store.servicesAvailabilityStore.servicesAvailability) { + // Here we have the services availabilities initialized. + store.mapMenusManagerStore.initStore(); + } + }, [ + store.mapMenusManagerStore.wfsFeatureTypes, + store.servicesAvailabilityStore.servicesAvailability, + ]); return ( <> - + {/* */} diff --git a/src/discrete-layer/views/components/data-fetchers/wfs-features-fetcher.component.tsx b/src/discrete-layer/views/components/data-fetchers/wfs-features-fetcher.component.tsx index 5d8d8117b..0956c9ee5 100644 --- a/src/discrete-layer/views/components/data-fetchers/wfs-features-fetcher.component.tsx +++ b/src/discrete-layer/views/components/data-fetchers/wfs-features-fetcher.component.tsx @@ -4,35 +4,43 @@ import { observer } from 'mobx-react'; import { useQuery, useStore } from '../../../models/RootStore'; export interface IFeatureConfig { - isVisualized?: boolean, - color?: string, - outlineColor?: string, - dWithin?: number, - translationId?: string, - icon?: string, + isVisualized?: boolean; + color?: string; + outlineColor?: string; + dWithin?: number; + translationId?: string; + icon?: string; markerIcon?: string; - outlineWidth?: number, + outlineWidth?: number; } export interface IFeatureConfigs { - [featureType: string]: IFeatureConfig | undefined + [featureType: string]: IFeatureConfig | undefined; } export const WfsFeaturesFetcher: React.FC = observer(() => { const store = useStore(); - const wfsGetFeatureTypesQuery = useQuery((store) => store.queryGetFeatureTypes()); - + const wfsGetFeatureTypesQuery = useQuery((store) => + store.queryGetFeatureTypes() + ); + useEffect(() => { if (!wfsGetFeatureTypesQuery.loading && wfsGetFeatureTypesQuery.data) { - const featureConfigs = {...(wfsGetFeatureTypesQuery.data.getFeatureTypes).featureConfigs as IFeatureConfigs}; + const featureConfigs = { + ...(wfsGetFeatureTypesQuery.data.getFeatureTypes + .featureConfigs as IFeatureConfigs), + }; const features = Object.fromEntries( - Object.entries(featureConfigs) - .filter(([key, value]) => value?.translationId) + Object.entries(featureConfigs).filter( + ([key, value]) => value?.translationId + ) + ); + store.mapMenusManagerStore.setWfsTotal( + Object.keys(featureConfigs).length ); - store.mapMenusManagerStore.setWfsTotal(Object.keys(featureConfigs).length); store.mapMenusManagerStore.setWfsFeatureConfigs(features); } }, [wfsGetFeatureTypesQuery.data, wfsGetFeatureTypesQuery.loading]); - + return null; }); diff --git a/src/discrete-layer/views/components/details-panel.component.css b/src/discrete-layer/views/components/details-panel.component.css index 0ca9cb60f..03d5313f7 100644 --- a/src/discrete-layer/views/components/details-panel.component.css +++ b/src/discrete-layer/views/components/details-panel.component.css @@ -1,6 +1,6 @@ .detailsTitle { color: var(--mdc-theme-text-primary-on-dark); - white-Space: nowrap; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: auto; @@ -42,10 +42,10 @@ body[dir='rtl'] .detailsContent { padding: 0; } -.detailsPanelProductView .categoryFieldsTitle{ +.detailsPanelProductView .categoryFieldsTitle { font-size: 1.2em; } -.categoryFieldsParentContainer.detailsPanelProductView{ +.categoryFieldsParentContainer.detailsPanelProductView { margin-top: 4px; -} \ No newline at end of file +} diff --git a/src/discrete-layer/views/components/details-panel.component.tsx b/src/discrete-layer/views/components/details-panel.component.tsx index 387e65903..8df54cb6b 100644 --- a/src/discrete-layer/views/components/details-panel.component.tsx +++ b/src/discrete-layer/views/components/details-panel.component.tsx @@ -11,7 +11,10 @@ import { PublishButton } from '../../components/layer-details/publish-button'; import { SaveMetadataButton } from '../../components/layer-details/save-metadata-button'; import { IDispatchAction } from '../../models/actionDispatcherStore'; import { UserAction } from '../../models/userStore'; -import { EntityDescriptorModelType, LayerMetadataMixedUnion } from '../../models'; +import { + EntityDescriptorModelType, + LayerMetadataMixedUnion, +} from '../../models'; import { useStore } from '../../models/RootStore'; import { TabViews } from '../tab-views'; @@ -23,111 +26,134 @@ interface DetailsPanelComponentProps { activeTabView: TabViews; } -export const DetailsPanel: React.FC = observer((props) => { - const { - detailsPanelExpanded, - setDetailsPanelExpanded, - activeTabView - } = props; +export const DetailsPanel: React.FC = observer( + (props) => { + const { detailsPanelExpanded, setDetailsPanelExpanded, activeTabView } = + props; - const store = useStore(); - const intl = useIntl(); - const layerToPresent = store.discreteLayersStore.selectedLayer; - - const permissions = useMemo(() => { - return { - isEditAllowed: layerToPresent && store.userStore.isActionAllowed(`entity_action.${layerToPresent.__typename}.edit`), - isPublishAllowed: layerToPresent && store.userStore.isActionAllowed(`entity_action.${layerToPresent.__typename}.publish`), - isSaveMetadataAllowed: layerToPresent && store.userStore.isActionAllowed(`entity_action.${layerToPresent.__typename}.saveMetadata`), - } - }, [store.userStore.user, layerToPresent]); + const store = useStore(); + const intl = useIntl(); + const layerToPresent = store.discreteLayersStore.selectedLayer; - const dispatchAction = (action: Record): void => { - store.actionDispatcherStore.dispatchAction( - { + const permissions = useMemo(() => { + return { + isEditAllowed: + layerToPresent && + store.userStore.isActionAllowed( + `entity_action.${layerToPresent.__typename}.edit` + ), + isPublishAllowed: + layerToPresent && + store.userStore.isActionAllowed( + `entity_action.${layerToPresent.__typename}.publish` + ), + isSaveMetadataAllowed: + layerToPresent && + store.userStore.isActionAllowed( + `entity_action.${layerToPresent.__typename}.saveMetadata` + ), + }; + }, [store.userStore.user, layerToPresent]); + + const dispatchAction = (action: Record): void => { + store.actionDispatcherStore.dispatchAction({ action: action.action, data: action.data, - } as IDispatchAction - ); - }; + } as IDispatchAction); + }; - return ( - <> - - - {layerToPresent?.productName} - - { - permissions.isPublishAllowed === true && !isBeingDeleted(layerToPresent as LayerMetadataMixedUnion) && - layerToPresent && - existStatus(layerToPresent as any) && - - } - { - permissions.isEditAllowed === true && !isBeingDeleted(layerToPresent as LayerMetadataMixedUnion) && - - { - dispatchAction({ - action: UserAction.ENTITY_ACTION_SELECTED_ENTITY_EDIT - }); - }} + return ( + <> + + + {layerToPresent?.productName} + + {permissions.isPublishAllowed === true && + !isBeingDeleted(layerToPresent as LayerMetadataMixedUnion) && + layerToPresent && + existStatus(layerToPresent as any) && ( + + )} + {permissions.isEditAllowed === true && + !isBeingDeleted(layerToPresent as LayerMetadataMixedUnion) && ( + + { + dispatchAction({ + action: UserAction.ENTITY_ACTION_SELECTED_ENTITY_EDIT, + }); + }} + /> + + )} + {permissions.isEditAllowed === false && ( + + { + dispatchAction({ + action: UserAction.ENTITY_ACTION_SELECTED_ENTITY_VIEW, + }); + }} + /> + + )} + {permissions.isSaveMetadataAllowed === true && layerToPresent && ( + - - } - { - permissions.isEditAllowed === false && - + )} + { - dispatchAction({ - action: UserAction.ENTITY_ACTION_SELECTED_ENTITY_VIEW - }); + setDetailsPanelExpanded(!detailsPanelExpanded); }} /> - } - { - permissions.isSaveMetadataAllowed === true && layerToPresent && - - } - - { - setDetailsPanelExpanded(!detailsPanelExpanded); - }} + + + - - - - - - - ); -}) \ No newline at end of file + + + ); + } +); diff --git a/src/discrete-layer/views/components/map-action-resolver.component.tsx b/src/discrete-layer/views/components/map-action-resolver.component.tsx index 8fe1e4dd1..7264fa5d8 100644 --- a/src/discrete-layer/views/components/map-action-resolver.component.tsx +++ b/src/discrete-layer/views/components/map-action-resolver.component.tsx @@ -1,6 +1,9 @@ import { useEffect, useRef, useState } from 'react'; import { observer } from 'mobx-react-lite'; -import { ICesiumImageryLayer, useCesiumMap } from '@map-colonies/react-components'; +import { + ICesiumImageryLayer, + useCesiumMap, +} from '@map-colonies/react-components'; import { ContextActions } from '../../../common/actions/context.actions'; import { useStore } from '../../models'; import { IDispatchAction } from '../../models/actionDispatcherStore'; @@ -11,10 +14,10 @@ export const MapActionResolver: React.FC = observer(() => { const store = useStore(); const mapViewer = useCesiumMap(); - const [highlightedLayer, setHighlightedLayer] = useState(); + const [highlightedLayer, setHighlightedLayer] = + useState(); const prevHighlightedLayer = useRef(); - // Preserve last highlighted layer to reset it when new highlighted layer is set. useEffect(() => { if (highlightedLayer) { @@ -42,28 +45,28 @@ export const MapActionResolver: React.FC = observer(() => { switch (action) { case ContextActions.MOVE_LAYER_UP: { mapViewer.layersManager?.raise(data?.id as string, 1); - + setHighlightedLayer(undefined); closeContextMenu(); break; } case ContextActions.MOVE_LAYER_DOWN: { mapViewer.layersManager?.lower(data?.id as string, 1); - + setHighlightedLayer(undefined); closeContextMenu(); break; } case ContextActions.MOVE_LAYER_TO_TOP: { mapViewer.layersManager?.raiseToTop(data?.id as string); - + setHighlightedLayer(undefined); closeContextMenu(); break; } case ContextActions.MOVE_LAYER_TO_BOTTOM: { mapViewer.layersManager?.lowerToBottom(data?.id as string); - + setHighlightedLayer(undefined); closeContextMenu(); break; @@ -72,17 +75,17 @@ export const MapActionResolver: React.FC = observer(() => { const foundLayer = mapViewer.layersManager?.get(data?.id as string); if (foundLayer) { - if (data?.hue as number > DEFAULT_LAYER_HUE_FACTOR) { + if ((data?.hue as number) > DEFAULT_LAYER_HUE_FACTOR) { if (highlightedLayer) { highlightedLayer.hue = DEFAULT_LAYER_HUE_FACTOR; } setHighlightedLayer(foundLayer); - } else if (data?.hue as number === DEFAULT_LAYER_HUE_FACTOR) { + } else if ((data?.hue as number) === DEFAULT_LAYER_HUE_FACTOR) { setHighlightedLayer(undefined); } foundLayer.hue = data?.hue as number; } - + break; } case ContextActions.QUERY_POLYGON_PARTS: { @@ -92,11 +95,7 @@ export const MapActionResolver: React.FC = observer(() => { default: break; } - - }, [ - store.actionDispatcherStore.action, - store.discreteLayersStore, - ]); + }, [store.actionDispatcherStore.action, store.discreteLayersStore]); return <>; }); diff --git a/src/discrete-layer/views/components/notifications/web-socket-notifications.tsx b/src/discrete-layer/views/components/notifications/web-socket-notifications.tsx index 797d31256..b162282b3 100644 --- a/src/discrete-layer/views/components/notifications/web-socket-notifications.tsx +++ b/src/discrete-layer/views/components/notifications/web-socket-notifications.tsx @@ -5,23 +5,21 @@ import { localStore } from '../../../../common/helpers/storage'; import { CallBack } from '../../../../common/models/job-errors-summary.raster'; const WebSocketNotifications: React.FC = () => { - useEffect(() => { const initWebSocket = () => { const wsClient = createClient({ url: `${CONFIG.WS_PROTOCOL}${CONFIG.SERVICE_NAME}/graphql-ws`, keepAlive: 300000, - connectionParams: { - }, + connectionParams: {}, on: { connected: () => { - console.log("WebSocket connected"); + console.log('WebSocket connected'); }, error: (error) => { - console.error("WebSocket error:", error); + console.error('WebSocket error:', error); }, closed: () => { - console.log("WebSocket disconnected"); + console.log('WebSocket disconnected'); }, }, }); @@ -29,7 +27,7 @@ const WebSocketNotifications: React.FC = () => { }; const wsClient = initWebSocket(); - + const subscribeToTask = () => { return wsClient.subscribe( { @@ -51,9 +49,16 @@ const WebSocketNotifications: React.FC = () => { }`, }, { - next: (res: { data: { taskUpdateDetails: CallBack}, errors: Record[]}) => { - console.log('WebSocket notification received for', `job:${res.data.taskUpdateDetails.jobId} task:${res.data.taskUpdateDetails.taskId}`); - const newCount = parseInt(localStore.get('taskNotificationCount') || '0', 10) + 1; + next: (res: { + data: { taskUpdateDetails: CallBack }; + errors: Record[]; + }) => { + console.log( + 'WebSocket notification received for', + `job:${res.data.taskUpdateDetails.jobId} task:${res.data.taskUpdateDetails.taskId}` + ); + const newCount = + parseInt(localStore.get('taskNotificationCount') || '0', 10) + 1; localStore.set('taskNotificationCount', newCount.toString()); localStore.setObject('lastTask', res.data.taskUpdateDetails); }, @@ -66,7 +71,7 @@ const WebSocketNotifications: React.FC = () => { } ); }; - + subscribeToTask(); return () => { diff --git a/src/discrete-layer/views/components/password-autofill-disabler.component.tsx b/src/discrete-layer/views/components/password-autofill-disabler.component.tsx index 529a2fd79..2084be338 100644 --- a/src/discrete-layer/views/components/password-autofill-disabler.component.tsx +++ b/src/discrete-layer/views/components/password-autofill-disabler.component.tsx @@ -1,8 +1,3 @@ export const PasswordAutofillDisabler: React.FC = () => { - return ( - - ); + return ; }; diff --git a/src/discrete-layer/views/components/tabs-views-switcher.component.css b/src/discrete-layer/views/components/tabs-views-switcher.component.css index ec63ca3ad..435d71e65 100644 --- a/src/discrete-layer/views/components/tabs-views-switcher.component.css +++ b/src/discrete-layer/views/components/tabs-views-switcher.component.css @@ -11,7 +11,7 @@ border-radius: 50%; } -.dirty-best-indicator{ +.dirty-best-indicator { background-color: var(--mdc-theme-gc-warning-high); width: 16px; height: 16px; diff --git a/src/discrete-layer/views/components/tabs-views-switcher.component.tsx b/src/discrete-layer/views/components/tabs-views-switcher.component.tsx index d5506458a..f4e675df6 100644 --- a/src/discrete-layer/views/components/tabs-views-switcher.component.tsx +++ b/src/discrete-layer/views/components/tabs-views-switcher.component.tsx @@ -1,4 +1,3 @@ - import React, { useEffect, useMemo, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { useIntl } from 'react-intl'; @@ -24,78 +23,103 @@ export interface ITabView { dependentValue?: unknown; } -export const TabViewsSwitcher: React.FC = observer((props) => { - const store = useStore(); - const intl = useIntl(); - const theme = useTheme(); - const { handleTabViewChange, activeTabView } = props; +export const TabViewsSwitcher: React.FC = + observer((props) => { + const store = useStore(); + const intl = useIntl(); + const theme = useTheme(); + const { handleTabViewChange, activeTabView } = props; - const layerToExport = store.exportStore.layerToExport; + const layerToExport = store.exportStore.layerToExport; - const tabViews: ITabView[] = useMemo(() => [ - { - idx: TabViews.CATALOG, - title: 'tab-views.catalog', - iconClassName: 'mc-icon-Catalog', - }, - { - idx: TabViews.SEARCH_RESULTS, - title: 'tab-views.search-results', - iconClassName: 'mc-icon-Search-History', - }, - { - idx: TabViews.EXPORT_LAYER, - title: 'tab-views.export-layer', - iconClassName: intl.locale === 'en' ? 'mc-icon-Export' : 'mc-icon-Export-Left', - dependentValue: store.exportStore.layerToExport, - } - ], [layerToExport]); + const tabViews: ITabView[] = useMemo( + () => [ + { + idx: TabViews.CATALOG, + title: 'tab-views.catalog', + iconClassName: 'mc-icon-Catalog', + }, + { + idx: TabViews.SEARCH_RESULTS, + title: 'tab-views.search-results', + iconClassName: 'mc-icon-Search-History', + }, + { + idx: TabViews.EXPORT_LAYER, + title: 'tab-views.export-layer', + iconClassName: + intl.locale === 'en' ? 'mc-icon-Export' : 'mc-icon-Export-Left', + dependentValue: store.exportStore.layerToExport, + }, + ], + [layerToExport] + ); - const [availableTabs, setAvailableTabs] = useState(tabViews); + const [availableTabs, setAvailableTabs] = useState(tabViews); - useEffect(() => { - const dependentTabs = tabViews.filter(tab => { - if ('dependentValue' in tab) { - return !isEmpty(tab.dependentValue); - } + useEffect(() => { + const dependentTabs = tabViews.filter((tab) => { + if ('dependentValue' in tab) { + return !isEmpty(tab.dependentValue); + } - return tab; - }); + return tab; + }); - setAvailableTabs(dependentTabs); - }, [tabViews]) - - useEffect(() => { - if (layerToExport !== undefined) { - handleTabViewChange(TabViews.EXPORT_LAYER); - } else { - handleTabViewChange(TabViews.CATALOG); - } - }, [layerToExport]); - - return ( - <> - - { - availableTabs.map((tab) => { - return - - ): void => handleTabViewChange(tab.idx)} - style={{ - backgroundColor: (activeTabView === tab.idx ? theme.custom?.GC_SELECTION_BACKGROUND : theme.custom?.GC_ALTERNATIVE_SURFACE) as string, - color: (activeTabView === tab.idx ? 'var(--mdc-theme-text-icon-on-dark)' : 'var(--mdc-theme-on-primary)') - }} - theme={[activeTabView === tab.idx ? 'onPrimary' : 'onSurface']} - /> - - ; - }) - } - - - ); + setAvailableTabs(dependentTabs); + }, [tabViews]); + + useEffect(() => { + if (layerToExport !== undefined) { + handleTabViewChange(TabViews.EXPORT_LAYER); + } else { + handleTabViewChange(TabViews.CATALOG); + } + }, [layerToExport]); -}); \ No newline at end of file + return ( + <> + + {availableTabs.map((tab) => { + return ( + + + + ): void => handleTabViewChange(tab.idx)} + style={{ + backgroundColor: (activeTabView === tab.idx + ? theme.custom?.GC_SELECTION_BACKGROUND + : theme.custom?.GC_ALTERNATIVE_SURFACE) as string, + color: + activeTabView === tab.idx + ? 'var(--mdc-theme-text-icon-on-dark)' + : 'var(--mdc-theme-on-primary)', + }} + theme={[ + activeTabView === tab.idx ? 'onPrimary' : 'onSurface', + ]} + /> + + + ); + })} + + + ); + }); diff --git a/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.css b/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.css index cd3d62e0f..f9e2d0d64 100644 --- a/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.css +++ b/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.css @@ -86,4 +86,4 @@ body[dir='rtl'] .userModeSwitchDialog .closeIcon { display: flex; justify-content: space-between; width: 100%; -} \ No newline at end of file +} diff --git a/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.tsx b/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.tsx index 038ebc14a..3e7a7a467 100644 --- a/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.tsx +++ b/src/discrete-layer/views/components/user-mode-switch/user-mode-switch.component.tsx @@ -24,136 +24,142 @@ interface UserModeSwitchProps { setUserRole: (role: UserRole) => void; } -const UserModeSwitch: React.FC = observer(({ userRole, setUserRole }) => { - const intl = useIntl(); - const [isDialogOpen, setIsDialogOpen] = useState(false); - const [password, setPassword] = useState(''); - const [isPasswordValid, setIsPasswordValid] = useState(true); - const store = useStore(); - const { data, loading, setQuery } = useQuery<{login: UserLoginModelType}>(); - - const resetDialogState = useCallback((): void => { - setPassword(''); - setIsPasswordValid(true); - }, []); - - const getIsChecked = (): boolean => { - return userRole === UserRole.ADMIN; - }; - - const handleSwitchClick = (): void => { - if (userRole === UserRole.USER) { - setIsDialogOpen(!isDialogOpen); - } else { - setUserRole(UserRole.USER); - } - }; - - const closeDialog = useCallback((): void => { - resetDialogState(); - setIsDialogOpen(false); - }, []); - - const validatePassword = useCallback((): void => { - setQuery(store.queryLogin({ - data:{ - userName:'NOT_USED', - userPassword: password +const UserModeSwitch: React.FC = observer( + ({ userRole, setUserRole }) => { + const intl = useIntl(); + const [isDialogOpen, setIsDialogOpen] = useState(false); + const [password, setPassword] = useState(''); + const [isPasswordValid, setIsPasswordValid] = useState(true); + const store = useStore(); + const { data, loading, setQuery } = useQuery<{ + login: UserLoginModelType; + }>(); + + const resetDialogState = useCallback((): void => { + setPassword(''); + setIsPasswordValid(true); + }, []); + + const getIsChecked = (): boolean => { + return userRole === UserRole.ADMIN; + }; + + const handleSwitchClick = (): void => { + if (userRole === UserRole.USER) { + setIsDialogOpen(!isDialogOpen); + } else { + setUserRole(UserRole.USER); } - })); - }, [password]); - - useEffect(() => { - if (!loading && data) { - setIsPasswordValid(data.login.isValid as boolean); - if (data.login.isValid) { - setUserRole(UserRole.ADMIN); - closeDialog(); + }; + + const closeDialog = useCallback((): void => { + resetDialogState(); + setIsDialogOpen(false); + }, []); + + const validatePassword = useCallback((): void => { + setQuery( + store.queryLogin({ + data: { + userName: 'NOT_USED', + userPassword: password, + }, + }) + ); + }, [password]); + + useEffect(() => { + if (!loading && data) { + setIsPasswordValid(data.login.isValid as boolean); + if (data.login.isValid) { + setUserRole(UserRole.ADMIN); + closeDialog(); + } } - } - }, [data, loading]); + }, [data, loading]); + + const renderInputErrorMsg = useCallback((): JSX.Element => { + return ( + + {!isPasswordValid && ( + + + + )} + + ); + }, [isPasswordValid]); + + const renderDialogContent = (): JSX.Element => { + return ( + + + ): void => { + setPassword(e.currentTarget.value.trim()); + }} + onKeyDown={(e: React.KeyboardEvent): void => { + const SUBMIT_KEY = 'Enter'; + if (password && e.key === SUBMIT_KEY) { + validatePassword(); + } + }} + value={password} + /> + + {renderInputErrorMsg()} + + ); + }; - const renderInputErrorMsg = useCallback((): JSX.Element => { return ( - - {!isPasswordValid && ( - - - - )} - - ); - }, [isPasswordValid]); + + + + - const renderDialogContent = (): JSX.Element => { - return ( - - - ): void => { - setPassword(e.currentTarget.value.trim()); - }} - onKeyDown={(e: React.KeyboardEvent): void => { - const SUBMIT_KEY = 'Enter' - if (password && e.key === SUBMIT_KEY) { - validatePassword(); - } - }} - value={password} - /> - - {renderInputErrorMsg()} + + + + + + + + + + + + + + + {renderDialogContent()} + + + ); - }; - - return ( - - - - - - - - - - - - - - - - - - - - {renderDialogContent()} - - - - - ); -}); + } +); export default UserModeSwitch; diff --git a/src/discrete-layer/views/discrete-layer-view.css b/src/discrete-layer/views/discrete-layer-view.css index cbc051578..f4663a15f 100644 --- a/src/discrete-layer/views/discrete-layer-view.css +++ b/src/discrete-layer/views/discrete-layer-view.css @@ -36,8 +36,8 @@ body[dir='rtl'] .sidePanelContainer { height: calc(100% - 8px); padding-bottom: 8px; transition: left ease-in-out var(--collapse-expand-duration), - right ease-in-out var(--collapse-expand-duration), - width ease-in-out var(--collapse-expand-duration); + right ease-in-out var(--collapse-expand-duration), + width ease-in-out var(--collapse-expand-duration); } body[dir='rtl'] .mapAppContainer { @@ -75,7 +75,7 @@ body[dir='rtl'] .mapAppContainer { padding-right: 16px; } -body[dir='rtl'] .headerSystemAreaContainer{ +body[dir='rtl'] .headerSystemAreaContainer { padding-right: unset; padding-left: 16px; } @@ -263,7 +263,7 @@ body[dir='rtl'] .tabHeaderContainer .filterByCatalogEntitySelect { } .cesium-viewer .bottomToolsContainer > div { - height: 28px;; + height: 28px; } .interactionsDisabled { @@ -271,7 +271,7 @@ body[dir='rtl'] .tabHeaderContainer .filterByCatalogEntitySelect { overflow: hidden; } -.interactionsDisabled::after{ +.interactionsDisabled::after { content: ''; display: block; position: absolute; diff --git a/src/discrete-layer/views/discrete-layer-view.tsx b/src/discrete-layer/views/discrete-layer-view.tsx index c4eac371b..88b9d2fee 100644 --- a/src/discrete-layer/views/discrete-layer-view.tsx +++ b/src/discrete-layer/views/discrete-layer-view.tsx @@ -8,7 +8,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import bbox from '@turf/bbox'; import bboxPolygon from '@turf/bbox-polygon'; import { lineString } from '@turf/helpers'; -import { +import { Avatar, Icon, IconButton, @@ -17,7 +17,7 @@ import { Select, Tooltip, Typography, - useTheme + useTheme, } from '@map-colonies/react-core'; import { BboxCorner, @@ -31,7 +31,7 @@ import { DrawType, IContextMenuData, IDrawing, - IDrawingEvent + IDrawingEvent, } from '@map-colonies/react-components'; import { GeocoderOptions } from '@map-colonies/react-components/dist/cesium-map/geocoder/geocoder-panel'; import { IMapLegend } from '@map-colonies/react-components/dist/cesium-map/legend'; @@ -76,7 +76,7 @@ import { JobModelType, LayerMetadataMixedUnion, LinkModelType, - RecordType + RecordType, } from '../models'; import { IDispatchAction } from '../models/actionDispatcherStore'; import { ILayerImage } from '../models/layerImage'; @@ -106,7 +106,9 @@ const START_IDX = 0; const DELTA = 0.00001; const DRAWING_MATERIAL_OPACITY = 0.5; const DRAWING_FINAL_MATERIAL_OPACITY = 0.8; -const DRAWING_MATERIAL_COLOR = CesiumColor.YELLOW.withAlpha(DRAWING_MATERIAL_OPACITY); +const DRAWING_MATERIAL_COLOR = CesiumColor.YELLOW.withAlpha( + DRAWING_MATERIAL_OPACITY +); const mapMode2D = MapMode2D[CONFIG.MAP.MAPMODE2D as keyof typeof MapMode2D]; const DRAWING_FINAL_MATERIAL = new CesiumPolylineDashMaterialProperty({ @@ -129,46 +131,73 @@ const getTimeStamp = (): string => new Date().getTime().toString(); const DiscreteLayerView: React.FC = observer(() => { // eslint-disable-next-line - const { loading: searchLoading, error: searchError, data, query, setQuery } = useQuery(); + const { + loading: searchLoading, + error: searchError, + data, + query, + setQuery, + } = useQuery(); const store = useStore(); const theme = useTheme(); const intl = useIntl(); const [isDrawing, setIsDrawing] = useState(false); - const [jobToOpenRasterEntity, setJobToOpenRasterEntity] = useState(undefined); - const [jobToOpenJobManager, setJobToOpenJobManager] = useState> | undefined>(undefined); + const [jobToOpenRasterEntity, setJobToOpenRasterEntity] = useState< + JobModelType | undefined + >(undefined); + const [jobToOpenJobManager, setJobToOpenJobManager] = useState< + Partial> | undefined + >(undefined); const [isRasterDialogOpen, setIsRasterDialogOpen] = useState(false); - const [is3DIngestDialogOpen, setIs3DIngestDialogOpen] = useState(false); - const [isDemIngestDialogOpen, setIsDemIngestDialogOpen] = useState(false); + const [is3DIngestDialogOpen, setIs3DIngestDialogOpen] = + useState(false); + const [isDemIngestDialogOpen, setIsDemIngestDialogOpen] = + useState(false); const [isEntityDialogOpen, setIsEntityDialogOpen] = useState(false); - const [isEntityDeleteDialogOpen, setIsEntityDeleteDialogOpen] = useState(false); - const [isSystemsJobsDialogOpen, setIsSystemsJobsDialogOpen] = useState(false); - const [isSystemCoreInfoDialogOpen, setIsSystemCoreInfoDialogOpen] = useState(false); - const [isCreateEntityMenuOpen, setIsCreateEntityMenuOpen] = useState(false); + const [isEntityDeleteDialogOpen, setIsEntityDeleteDialogOpen] = + useState(false); + const [isSystemsJobsDialogOpen, setIsSystemsJobsDialogOpen] = + useState(false); + const [isSystemCoreInfoDialogOpen, setIsSystemCoreInfoDialogOpen] = + useState(false); + const [isCreateEntityMenuOpen, setIsCreateEntityMenuOpen] = + useState(false); const [tabsPanelExpanded, setTabsPanelExpanded] = useState(true); - const [detailsPanelExpanded, setDetailsPanelExpanded] = useState(false); + const [detailsPanelExpanded, setDetailsPanelExpanded] = + useState(false); const [activeTabView, setActiveTabView] = useState(TabViews.CATALOG); const [drawPrimitive, setDrawPrimitive] = useState(noDrawing); const [catalogRefresh, setCatalogRefresh] = useState(START_IDX); - const [isActiveLayersFilterEnabled, setIsActiveLayersFilterEnabled] = useState(false); + const [isActiveLayersFilterEnabled, setIsActiveLayersFilterEnabled] = + useState(false); const [catalogFilter, setCatalogFilter] = useState(false); const [rect, setRect] = useState(undefined); const [poi, setPoi] = useState(undefined); const [isPoiSearchActive, setIsPoiSearchActive] = useState(false); const [corners, setCorners] = useState(undefined); - const [userRole, setUserRole] = useState(store.userStore.user?.role ?? CONFIG.DEFAULT_USER.ROLE); - const [drawEntities, setDrawEntities] = useState([{ - coordinates: [], - name: '', - id: '', - type: DrawType.UNKNOWN, - }]); + const [userRole, setUserRole] = useState( + store.userStore.user?.role ?? CONFIG.DEFAULT_USER.ROLE + ); + const [drawEntities, setDrawEntities] = useState([ + { + coordinates: [], + name: '', + id: '', + type: DrawType.UNKNOWN, + }, + ]); const [searchResultsError, setSearchResultsError] = useState(); - const [actionsMenuDimensions, setActionsMenuDimensions] = useState(); - const [whatsNewVisitedCount, setWhatsNewVisitedCount] = useState(ZERO); - const [taskNotificationCount, setTaskNotificationCount] = useState(ZERO); + const [actionsMenuDimensions, setActionsMenuDimensions] = + useState(); + const [whatsNewVisitedCount, setWhatsNewVisitedCount] = + useState(ZERO); + const [taskNotificationCount, setTaskNotificationCount] = + useState(ZERO); const isDrawingState = isDrawing || store.exportStore.drawingState?.drawing; - const disableOnDrawingClassName = isDrawingState ? 'interactionsDisabled' : ''; + const disableOnDrawingClassName = isDrawingState + ? 'interactionsDisabled' + : ''; useEffect(() => { const visitedCount = localStore.get('whatsNewVisitedCount'); @@ -207,57 +236,68 @@ const DiscreteLayerView: React.FC = observer(() => { store.discreteLayersStore.setTabviewData(TabViews.SEARCH_RESULTS, layers); } }, [data]); - + useEffect(() => { // When search query changes, we need to refetch catalog capabilities as well let fullCatalogLayers: LayerMetadataMixedUnion[] | undefined; - + // Tab data is set only when switching tabs if (activeTabView === TabViews.CATALOG) { fullCatalogLayers = store.discreteLayersStore.layersImages; } else { - fullCatalogLayers = store.discreteLayersStore.tabViews?.[TabViews.CATALOG].layersImages; + fullCatalogLayers = + store.discreteLayersStore.tabViews?.[TabViews.CATALOG].layersImages; } if (!isEmpty(data) && !isEmpty(fullCatalogLayers)) { const searchLayers = get(data, 'search', []) as ILayerImage[]; - + /** * There could be a case where the catalog includes outdated data (New layers has bee added). * Search results will always be updated each time new filter is applied. * As a workaround we add the delta layers to the capabilities search to update the capabilities state with the added layers. */ - searchLayers.forEach(layer => { - const isNewLayer = !fullCatalogLayers?.some(catalogLayer => catalogLayer.id === layer.id); + searchLayers.forEach((layer) => { + const isNewLayer = !fullCatalogLayers?.some( + (catalogLayer) => catalogLayer.id === layer.id + ); if (isNewLayer) { fullCatalogLayers?.push(layer); } - }) + }); } - + void store.catalogTreeStore.capabilitiesFetch(fullCatalogLayers); }, [data]); useEffect(() => { setSearchResultsError(searchError); }, [searchError]); - + useEffect(() => { /** * Instead of just set the width of the panel according to the state, we need to assign variable on the app container * because the map container will need to resize accordingly to fill up the space. - * */ - const appContainer = document.querySelector('.app-container') as HTMLDivElement; + * */ + const appContainer = document.querySelector( + '.app-container' + ) as HTMLDivElement; if (!tabsPanelExpanded) { - appContainer?.style.setProperty(SIDE_PANEL_WIDTH_VARIABLE, COLLAPSED_PANEL_WIDTH); + appContainer?.style.setProperty( + SIDE_PANEL_WIDTH_VARIABLE, + COLLAPSED_PANEL_WIDTH + ); } else { - appContainer?.style.setProperty(SIDE_PANEL_WIDTH_VARIABLE, EXPANDED_PANEL_WIDTH); + appContainer?.style.setProperty( + SIDE_PANEL_WIDTH_VARIABLE, + EXPANDED_PANEL_WIDTH + ); } }, [tabsPanelExpanded]); useEffect(() => { store.discreteLayersStore.resetTabView([TabViews.SEARCH_RESULTS]); - + if (activeTabView === TabViews.SEARCH_RESULTS) { store.discreteLayersStore.clearLayersImages(); store.discreteLayersStore.resetSelectedLayer(); @@ -269,42 +309,49 @@ const DiscreteLayerView: React.FC = observer(() => { } }, [store.discreteLayersStore.searchParams.geojson]); - const dispatchAction = (action: Record): void => { - store.actionDispatcherStore.dispatchAction( - { - action: action.action, - data: action.data, - } as IDispatchAction - ); + const dispatchAction = (action: Record): void => { + store.actionDispatcherStore.dispatchAction({ + action: action.action, + data: action.data, + } as IDispatchAction); }; - + /* eslint-disable */ - const mapSettingsLocale = useMemo(() => ({ - DIRECTION: intl.locale === 'he' ? 'rtl' : 'ltr', - METERS_UNIT: intl.formatMessage({ id: 'map.scale.units.meters' }), - KILOMETERS_UNIT: intl.formatMessage({ id: 'map.scale.units.kilometers' }), - ZOOM_LABEL: intl.formatMessage({ id: 'map.zoom.label' }), - DEBUG_PANEL_TITLE: intl.formatMessage({ id: 'debug-panel.title' }), - WFS_TITLE: intl.formatMessage({ id: 'debug-panel.wfs.title' }), - WFS_CACHE: intl.formatMessage({ id: 'debug-panel.wfs.cache' }), - WFS_EXTENT: intl.formatMessage({ id: 'debug-panel.wfs.extent' }), - NO_DATA_LAYERS: intl.formatMessage({ id: 'debug-panel.empty' }), - ACTIVE_LAYERS_TITLE: intl.formatMessage({ id: 'active-layers.title' }), - IMAGERY: intl.formatMessage({ id: 'active-layers.imagery' }), - DATA: intl.formatMessage({ id: 'active-layers.data' }), - FLY_TO: intl.formatMessage({ id: 'action.flyTo.tooltip' }), - REMOVE: intl.formatMessage({ id: 'active-layers.remove' }), - BASE_MAP_TITLE: intl.formatMessage({ id: 'map-settings.base-map.title' }), - TERRAIN_TITLE: intl.formatMessage({ id: 'record-type.record_quantized_mesh.label' }), - SHOW_FEATURE_ON_MAP: intl.formatMessage({ id: 'geocoder-panel.show-feature-on-map' }), - IN_MAP_EXTENT: intl.formatMessage({ id: 'geocoder-panel.in-map-extent' }), - SEARCH_PLACEHOLDER: intl.formatMessage({ id: 'general.search.placeholder' }), - NO_RESULTS: intl.formatMessage({ id: 'results.nodata' }), - }), [intl]); + const mapSettingsLocale = useMemo( + () => ({ + DIRECTION: intl.locale === 'he' ? 'rtl' : 'ltr', + METERS_UNIT: intl.formatMessage({ id: 'map.scale.units.meters' }), + KILOMETERS_UNIT: intl.formatMessage({ id: 'map.scale.units.kilometers' }), + ZOOM_LABEL: intl.formatMessage({ id: 'map.zoom.label' }), + DEBUG_PANEL_TITLE: intl.formatMessage({ id: 'debug-panel.title' }), + WFS_TITLE: intl.formatMessage({ id: 'debug-panel.wfs.title' }), + WFS_CACHE: intl.formatMessage({ id: 'debug-panel.wfs.cache' }), + WFS_EXTENT: intl.formatMessage({ id: 'debug-panel.wfs.extent' }), + NO_DATA_LAYERS: intl.formatMessage({ id: 'debug-panel.empty' }), + ACTIVE_LAYERS_TITLE: intl.formatMessage({ id: 'active-layers.title' }), + IMAGERY: intl.formatMessage({ id: 'active-layers.imagery' }), + DATA: intl.formatMessage({ id: 'active-layers.data' }), + FLY_TO: intl.formatMessage({ id: 'action.flyTo.tooltip' }), + REMOVE: intl.formatMessage({ id: 'active-layers.remove' }), + BASE_MAP_TITLE: intl.formatMessage({ id: 'map-settings.base-map.title' }), + TERRAIN_TITLE: intl.formatMessage({ + id: 'record-type.record_quantized_mesh.label', + }), + SHOW_FEATURE_ON_MAP: intl.formatMessage({ + id: 'geocoder-panel.show-feature-on-map', + }), + IN_MAP_EXTENT: intl.formatMessage({ id: 'geocoder-panel.in-map-extent' }), + SEARCH_PLACEHOLDER: intl.formatMessage({ + id: 'general.search.placeholder', + }), + NO_RESULTS: intl.formatMessage({ id: 'results.nodata' }), + }), + [intl] + ); /* eslint-enable */ const memoizedLayers = useMemo(() => { - return( + return ( <> @@ -318,8 +365,8 @@ const DiscreteLayerView: React.FC = observer(() => { const LayersResultsStyle = useMemo(() => { return { height: 'calc(100% - 50px)', - width: 'calc(100% - 8px)' - } + width: 'calc(100% - 8px)', + }; }, []); const handleTabViewChange = (targetViewIdx: TabViews): void => { @@ -334,17 +381,23 @@ const DiscreteLayerView: React.FC = observer(() => { }; const buildFilters = (): FilterField[] => { - const coordinates = (store.discreteLayersStore.searchParams.geojson as Polygon)?.coordinates[0]; - - const boundingBoxFilter = coordinates ? [{ - field: 'mc:boundingBox', - bbox: { - llon: coordinates[0][0], - llat: coordinates[0][1], - ulon: coordinates[2][0], - ulat: coordinates[2][1], - }, - }] : []; + const coordinates = ( + store.discreteLayersStore.searchParams.geojson as Polygon + )?.coordinates[0]; + + const boundingBoxFilter = coordinates + ? [ + { + field: 'mc:boundingBox', + bbox: { + llon: coordinates[0][0], + llat: coordinates[0][1], + ulon: coordinates[2][0], + ulat: coordinates[2][1], + }, + }, + ] + : []; return [ ...boundingBoxFilter, @@ -352,7 +405,7 @@ const DiscreteLayerView: React.FC = observer(() => { field: 'mc:type', eq: store.discreteLayersStore.searchParams.recordType, }, - ...store.discreteLayersStore.searchParams.catalogFilters + ...store.discreteLayersStore.searchParams.catalogFilters, ]; }; @@ -364,30 +417,39 @@ const DiscreteLayerView: React.FC = observer(() => { useEffect(() => { if (activeTabView === TabViews.SEARCH_RESULTS) { void store.discreteLayersStore.clearLayersImages(); - + // TODO: build query params: FILTERS and SORTS const filters = buildFilters(); - setQuery(store.querySearch({ - opts: { - filter: filters - }, - end: CONFIG.RUNNING_MODE.END_RECORD, - start: CONFIG.RUNNING_MODE.START_RECORD, - })); + setQuery( + store.querySearch({ + opts: { + filter: filters, + }, + end: CONFIG.RUNNING_MODE.END_RECORD, + start: CONFIG.RUNNING_MODE.START_RECORD, + }) + ); } - }, [store.discreteLayersStore.searchParams.geojson, store.discreteLayersStore.searchParams.catalogFilters]); + }, [ + store.discreteLayersStore.searchParams.geojson, + store.discreteLayersStore.searchParams.catalogFilters, + ]); useEffect(() => { - const hasFiltersEnabled = store.discreteLayersStore.searchParams.catalogFilters.length > START_IDX || store.discreteLayersStore.searchParams.geojson; + const hasFiltersEnabled = + store.discreteLayersStore.searchParams.catalogFilters.length > + START_IDX || store.discreteLayersStore.searchParams.geojson; if (hasFiltersEnabled) { const filters = buildFilters(); - setQuery(store.querySearch({ - opts: { - filter: filters - }, - end: CONFIG.RUNNING_MODE.END_RECORD, - start: CONFIG.RUNNING_MODE.START_RECORD, - })); + setQuery( + store.querySearch({ + opts: { + filter: filters, + }, + end: CONFIG.RUNNING_MODE.END_RECORD, + start: CONFIG.RUNNING_MODE.START_RECORD, + }) + ); } }, [store.discreteLayersStore.searchParams.recordType]); @@ -405,7 +467,11 @@ const DiscreteLayerView: React.FC = observer(() => { }; const handleCatalogFiltersReset = (): void => { - if (store.discreteLayersStore.searchParams.catalogFilters.length === START_IDX) { return; } + if ( + store.discreteLayersStore.searchParams.catalogFilters.length === START_IDX + ) { + return; + } store.discreteLayersStore.searchParams.resetCatalogFilters(); @@ -416,10 +482,10 @@ const DiscreteLayerView: React.FC = observer(() => { store.discreteLayersStore.resetSelectedLayer(); store.discreteLayersStore.resetPolygonParts(); } - + // Geographic filters are being cleaned via the "Trashcan" (handlePolygonReset function). // If any of the geographical filters is enabled, then we want to stay at the search results tab. - + if (typeof store.discreteLayersStore.searchParams.geojson === 'undefined') { handleTabViewChange(TabViews.CATALOG); setSearchResultsError(undefined); @@ -427,20 +493,23 @@ const DiscreteLayerView: React.FC = observer(() => { }; const handlePolygonReset = (): void => { - store.discreteLayersStore.searchParams.resetLocation(); - setDrawEntities([]); - setPoi(undefined); - setCorners(undefined); - setSearchResultsError(undefined); + store.discreteLayersStore.searchParams.resetLocation(); + setDrawEntities([]); + setPoi(undefined); + setCorners(undefined); + setSearchResultsError(undefined); if (activeTabView !== TabViews.CATALOG) { // Catalog filters are being cleaned from inside the catalog filters panel. // If there's any filter enabled, then we want to stay at the search results tab. - if (store.discreteLayersStore.searchParams.catalogFilters?.length === START_IDX) { + if ( + store.discreteLayersStore.searchParams.catalogFilters?.length === + START_IDX + ) { handleTabViewChange(TabViews.CATALOG); } } - + store.mapMenusManagerStore.resetMapMenusFeatures(); }; @@ -469,11 +538,11 @@ const DiscreteLayerView: React.FC = observer(() => { [RecordType.RECORD_DEM]: { [Mode.NEW]: setIsDemIngestDialogOpen, [Mode.VIEW]: setIsEntityDialogOpen, - } + }, }; const handleEntityDialogOpen = (recordType: RecordType, open: boolean) => { - const mode = store.discreteLayersStore.selectedLayerOperationMode; + const mode = store.discreteLayersStore.selectedLayerOperationMode; const setDialogOpen = get(dialogMap, `${recordType}.${mode}`); if (setDialogOpen) { @@ -489,7 +558,7 @@ const DiscreteLayerView: React.FC = observer(() => { handleTabViewChange(TabViews.SEARCH_RESULTS); handlePolygonSelected((drawing.geojson as Feature).geometry as Polygon); setIsDrawing(false); - + setDrawEntities([ { coordinates: drawing.primitive, @@ -504,53 +573,62 @@ const DiscreteLayerView: React.FC = observer(() => { }, }; }; - + const setDrawType = (drawType: DrawType): void => { setIsDrawing(true); setDrawPrimitive(createDrawPrimitive(drawType)); }; const onPoiSelection = (lon: number, lat: number): void => { - onPolygonSelection({ - primitive: undefined, - type: DrawType.BOX, - geojson: { - type : 'FeatureCollection', - features: [ - { - type : 'Feature', - properties : { - type : BboxCorner.TOP_RIGHT, - }, - geometry : { - type : 'Point', - coordinates : [ lon + DELTA, lat + DELTA ] - } - }, - { - type : 'Feature', - properties : { - type : BboxCorner.BOTTOM_LEFT - }, - geometry : { - type : 'Point', - coordinates : [ lon - DELTA, lat - DELTA ] - } - } - ] - } - }, true); - setPoi({lon, lat}); + onPolygonSelection( + { + primitive: undefined, + type: DrawType.BOX, + geojson: { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + type: BboxCorner.TOP_RIGHT, + }, + geometry: { + type: 'Point', + coordinates: [lon + DELTA, lat + DELTA], + }, + }, + { + type: 'Feature', + properties: { + type: BboxCorner.BOTTOM_LEFT, + }, + geometry: { + type: 'Point', + coordinates: [lon - DELTA, lat - DELTA], + }, + }, + ], + }, + }, + true + ); + setPoi({ lon, lat }); }; const onPolygonSelection = (polygon: IDrawingEvent, isPoi = false): void => { const timeStamp = getTimeStamp(); - const bottomLeftPoint = find((polygon.geojson as FeatureCollection).features, (feat: Feature)=>{ - return feat.properties?.type === BboxCorner.BOTTOM_LEFT; - }) as Feature; - const rightTopPoint = find((polygon.geojson as FeatureCollection).features, (feat: Feature)=>{ - return feat.properties?.type === BboxCorner.TOP_RIGHT; - }) as Feature; + const bottomLeftPoint = find( + (polygon.geojson as FeatureCollection).features, + (feat: Feature) => { + return feat.properties?.type === BboxCorner.BOTTOM_LEFT; + } + ) as Feature; + const rightTopPoint = find( + (polygon.geojson as FeatureCollection).features, + (feat: Feature) => { + return feat.properties?.type === BboxCorner.TOP_RIGHT; + } + ) as Feature; setCorners({ topRightLat: rightTopPoint.geometry.coordinates[1], topRightLon: rightTopPoint.geometry.coordinates[0], @@ -560,7 +638,7 @@ const DiscreteLayerView: React.FC = observer(() => { const line = lineString([ [ bottomLeftPoint.geometry.coordinates[0], - bottomLeftPoint.geometry.coordinates[1] + bottomLeftPoint.geometry.coordinates[1], ], [ rightTopPoint.geometry.coordinates[0], @@ -568,10 +646,10 @@ const DiscreteLayerView: React.FC = observer(() => { ], ]); const boxPolygon = bboxPolygon(bbox(line)); - + handleTabViewChange(TabViews.SEARCH_RESULTS); - handlePolygonSelected((boxPolygon as Feature).geometry as Polygon); + handlePolygonSelected((boxPolygon as Feature).geometry as Polygon); setDrawEntities([ { @@ -590,7 +668,7 @@ const DiscreteLayerView: React.FC = observer(() => { setRect(new CesiumRectangle()); dispatchAction({ action: UserAction.SYSTEM_CALLBACK_FLYTO, - data: { selectedLayer: store.discreteLayersStore.selectedLayer } + data: { selectedLayer: store.discreteLayersStore.selectedLayer }, }); }, []); @@ -612,59 +690,97 @@ const DiscreteLayerView: React.FC = observer(() => { { idx: TabViews.EXPORT_LAYER, title: 'tab-views.export-layer', - iconClassName: intl.locale === 'en' ? 'mc-icon-Export' : 'mc-icon-Export-Left', - } + iconClassName: + intl.locale === 'en' ? 'mc-icon-Export' : 'mc-icon-Export-Left', + }, ]; const permissions = useMemo(() => { return { - isSystemJobsAllowed: store.userStore.isActionAllowed(UserAction.SYSTEM_ACTION_JOBS), - isSystemCoreInfoAllowed: store.userStore.isActionAllowed(UserAction.SYSTEM_ACTION_COREINFO), - isWebToolsAllowed: store.userStore.isActionAllowed(UserAction.SYSTEM_ACTION_TOOLS), - isSystemFilterEnabled: store.userStore.isActionAllowed(UserAction.SYSTEM_ACTION_FILTER), - isSystemSidebarCollapseEnabled: store.userStore.isActionAllowed(UserAction.SYSTEM_ACTION_SIDEBARCOLLAPSEEXPAND), - isLayerRasterRecordIngestAllowed: store.userStore.isActionAllowed(UserAction.ENTITY_ACTION_LAYERRASTERRECORD_CREATE), - isLayer3DRecordIngestAllowed: store.userStore.isActionAllowed(UserAction.ENTITY_ACTION_LAYER3DRECORD_CREATE), - isLayerDemRecordIngestAllowed: store.userStore.isActionAllowed(UserAction.ENTITY_ACTION_LAYERDEMRECORD_CREATE), - isSwitchUserRoleAllowed: store.userStore.isActionAllowed(UserAction.FEATURE_SWITCH_USER_ROLE), - isDeleteAllowed: store.userStore.isActionAllowed(`entity_action.${store.discreteLayersStore.selectedLayer?.__typename}.delete`), - } + isSystemJobsAllowed: store.userStore.isActionAllowed( + UserAction.SYSTEM_ACTION_JOBS + ), + isSystemCoreInfoAllowed: store.userStore.isActionAllowed( + UserAction.SYSTEM_ACTION_COREINFO + ), + isWebToolsAllowed: store.userStore.isActionAllowed( + UserAction.SYSTEM_ACTION_TOOLS + ), + isSystemFilterEnabled: store.userStore.isActionAllowed( + UserAction.SYSTEM_ACTION_FILTER + ), + isSystemSidebarCollapseEnabled: store.userStore.isActionAllowed( + UserAction.SYSTEM_ACTION_SIDEBARCOLLAPSEEXPAND + ), + isLayerRasterRecordIngestAllowed: store.userStore.isActionAllowed( + UserAction.ENTITY_ACTION_LAYERRASTERRECORD_CREATE + ), + isLayer3DRecordIngestAllowed: store.userStore.isActionAllowed( + UserAction.ENTITY_ACTION_LAYER3DRECORD_CREATE + ), + isLayerDemRecordIngestAllowed: store.userStore.isActionAllowed( + UserAction.ENTITY_ACTION_LAYERDEMRECORD_CREATE + ), + isSwitchUserRoleAllowed: store.userStore.isActionAllowed( + UserAction.FEATURE_SWITCH_USER_ROLE + ), + isDeleteAllowed: store.userStore.isActionAllowed( + `entity_action.${store.discreteLayersStore.selectedLayer?.__typename}.delete` + ), + }; }, [store.userStore.user, store.discreteLayersStore.selectedLayer]); const recordTypeOptions = useMemo(() => { return CONFIG.SERVED_ENTITY_TYPES.map((entity) => { const value = entity as keyof typeof RecordType; return { - label: intl.formatMessage({id: `record-type.${RecordType[value].toLowerCase()}.label`}), - value: RecordType[value] + label: intl.formatMessage({ + id: `record-type.${RecordType[value].toLowerCase()}.label`, + }), + value: RecordType[value], }; }); }, []); const PanelExpanderButton: React.FC = () => { const isRtl = intl.locale === 'he'; - const iconClassExpand = isRtl ? 'mc-icon-Arrows-Left' : 'mc-icon-Arrows-Right'; - const iconClassCollapse = isRtl ? 'mc-icon-Arrows-Right' : 'mc-icon-Arrows-Left'; - const className = `${tabsPanelExpanded ? iconClassCollapse : iconClassExpand}`; + const iconClassExpand = isRtl + ? 'mc-icon-Arrows-Left' + : 'mc-icon-Arrows-Right'; + const iconClassCollapse = isRtl + ? 'mc-icon-Arrows-Right' + : 'mc-icon-Arrows-Left'; + const className = `${ + tabsPanelExpanded ? iconClassCollapse : iconClassExpand + }`; return ( - - + {setTabsPanelExpanded(!tabsPanelExpanded);}} + onClick={(): void => { + setTabsPanelExpanded(!tabsPanelExpanded); + }} /> ); }; const getActiveTabHeader = (tabIdx: number, site: string): JSX.Element => { - if (!tabsPanelExpanded) { return (
- +
); } @@ -673,63 +789,90 @@ const DiscreteLayerView: React.FC = observer(() => { return tab.idx === tabIdx; }); - return (
-
-
- +
+ -
+
- - {site!=='generic' && intl.formatMessage({ id: `tab-views.catalog.site.${site}` })} + + {site !== 'generic' && + intl.formatMessage({ id: `tab-views.catalog.site.${site}` })}
-
-
- { - tabIdx === TabViews.CATALOG && +
+
+ {tabIdx === TabViews.CATALOG && (