diff --git a/.eslintignore b/.eslintignore index c5f275b63..d4bcc0de1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,4 +7,3 @@ legacy/js/dist legacy/css web/public/legacy/legacy.minified.js legacy -sanityv3 diff --git a/.github/workflows/PREPROD-studios-v3.yaml b/.github/workflows/PREPROD-studios-v3.yaml index 40001f4fc..88608c9f1 100644 --- a/.github/workflows/PREPROD-studios-v3.yaml +++ b/.github/workflows/PREPROD-studios-v3.yaml @@ -35,7 +35,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Modify radixconfig tag for preprod on main branch 🗒️ if: github.ref == 'refs/heads/main' @@ -46,8 +46,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py studio ${{ env.IMAGE_TAG_SHA }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy studios to preprod for tag ${{ env.IMAGE_TAG_SHA }}" diff --git a/.github/workflows/PREPROD-studios.yaml b/.github/workflows/PREPROD-studios.yaml index e72b83f2e..24d6d3210 100644 --- a/.github/workflows/PREPROD-studios.yaml +++ b/.github/workflows/PREPROD-studios.yaml @@ -35,7 +35,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Modify radixconfig tag for preprod on main branch 🗒️ if: github.ref == 'refs/heads/main' @@ -46,8 +46,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py studio ${{ env.IMAGE_TAG_SHA }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy studios to preprod for tag ${{ env.IMAGE_TAG_SHA }}" diff --git a/.github/workflows/PREPROD-webs.yaml b/.github/workflows/PREPROD-webs.yaml index 27319e8a8..76217479d 100644 --- a/.github/workflows/PREPROD-webs.yaml +++ b/.github/workflows/PREPROD-webs.yaml @@ -39,7 +39,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Modify radixconfig tag for preprod on main branch 🗒️ if: github.ref == 'refs/heads/main' @@ -50,8 +50,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py web ${{ env.IMAGE_TAG_SHA }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy webs to preprod with tag ${{ env.IMAGE_TAG_SHA }}" --allow-empty diff --git a/.github/workflows/PROD-all-studios-v3.yaml b/.github/workflows/PROD-all-studios-v3.yaml index 08384d778..716f83b5f 100644 --- a/.github/workflows/PROD-all-studios-v3.yaml +++ b/.github/workflows/PROD-all-studios-v3.yaml @@ -31,7 +31,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Get preprod sha 🏷️ id: get-preprod-sha shell: bash @@ -113,7 +113,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Get preprod sha 🏷️ id: get-preprod-sha shell: bash @@ -179,7 +179,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Promote preprod tag to prod 🗒️ if: github.ref == 'refs/heads/main' shell: bash @@ -189,8 +189,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/promoteAllToProduction.py studio git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy all studios to production" @@ -248,11 +248,11 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Setup Node.js uses: actions/setup-node@v2 with: - node-version: '14' # Or any version you prefer + node-version: '14' # Or any version you prefer - name: Install dependencies run: | @@ -264,8 +264,8 @@ jobs: - name: Commit and push changes run: | git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal git add latest-prod-tags.json git commit -m "Update latest-prod-tags.json with new tags" || echo "No changes to commit" git push diff --git a/.github/workflows/PROD-all-studios.yaml b/.github/workflows/PROD-all-studios.yaml index 34bf0a219..f41c9aa51 100644 --- a/.github/workflows/PROD-all-studios.yaml +++ b/.github/workflows/PROD-all-studios.yaml @@ -31,7 +31,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Get preprod sha 🏷️ id: get-preprod-sha shell: bash @@ -113,7 +113,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Get preprod sha 🏷️ id: get-preprod-sha shell: bash @@ -179,7 +179,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Promote preprod tag to prod 🗒️ if: github.ref == 'refs/heads/main' shell: bash @@ -189,8 +189,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/promoteAllToProduction.py studio git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy all studios to production" diff --git a/.github/workflows/PROD-all-webs.yaml b/.github/workflows/PROD-all-webs.yaml index 1da88c2f7..601e19902 100644 --- a/.github/workflows/PROD-all-webs.yaml +++ b/.github/workflows/PROD-all-webs.yaml @@ -15,7 +15,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Promote preprod tag to prod 🗒️ if: github.ref == 'refs/heads/main' shell: bash @@ -25,8 +25,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/promoteAllToProduction.py web git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy all web sites to production" @@ -85,11 +85,11 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Setup Node.js uses: actions/setup-node@v2 with: - node-version: '14' # Or any version you prefer + node-version: '14' # Or any version you prefer - name: Install dependencies run: | @@ -101,8 +101,8 @@ jobs: - name: Commit and push changes run: | git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal git add latest-prod-tags.json git commit -m "Update latest-prod-tags.json with new tags" || echo "No changes to commit" git push diff --git a/.github/workflows/PROD-studios-rollback.yaml b/.github/workflows/PROD-studios-rollback.yaml index 40051505f..2a138ce85 100644 --- a/.github/workflows/PROD-studios-rollback.yaml +++ b/.github/workflows/PROD-studios-rollback.yaml @@ -40,7 +40,7 @@ jobs: set -u set -o pipefail set -x - TOKEN=$(curl -u nilsml:${{ secrets.GHCR_PAT }} https://ghcr.io/token\?scope\="repository:equinor/energyvision>:pull" | jq -r .token) + TOKEN=$(curl -u padms:${{ secrets.PADMS_PAT }} https://ghcr.io/token\?scope\="repository:equinor/energyvision>:pull" | jq -r .token) statusCode=$(curl --head --write-out '%{http_code}' --silent --output /dev/null -H "Authorization: Bearer $TOKEN" https://ghcr.io/v2/equinor/energyvision/studio-global/manifests/${{ github.event.inputs.image-sha }}) if [[ $statusCode -eq 200 ]] then @@ -206,7 +206,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Write to console 🗒️ shell: bash run: | @@ -214,8 +214,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py studio ${{ github.event.inputs.image-sha }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🔙 Rolling back satellite studios in production to version ${{ github.event.inputs.image-sha }}" diff --git a/.github/workflows/PROD-studios.yaml b/.github/workflows/PROD-studios.yaml index 664b97ab7..6e69a9c77 100644 --- a/.github/workflows/PROD-studios.yaml +++ b/.github/workflows/PROD-studios.yaml @@ -48,7 +48,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Get preprod sha 🏷️ id: get-preprod-sha shell: bash @@ -131,7 +131,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} - name: Get preprod sha 🏷️ id: get-preprod-sha shell: bash @@ -198,7 +198,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Promote preprod tag to prod 🗒️ if: github.ref == 'refs/heads/main' shell: bash @@ -208,8 +208,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/promoteToProduction.py studio ${{ github.event.inputs.site }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy studio for ${{ github.event.inputs.site }} to production" diff --git a/.github/workflows/PROD-webs-rollback.yaml b/.github/workflows/PROD-webs-rollback.yaml index bbce31845..902f71919 100644 --- a/.github/workflows/PROD-webs-rollback.yaml +++ b/.github/workflows/PROD-webs-rollback.yaml @@ -43,7 +43,7 @@ jobs: set -u set -o pipefail set -x - TOKEN=$(curl -u nilsml:${{ secrets.GHCR_PAT }} https://ghcr.io/token\?scope\="repository:equinor/energyvision>:pull" | jq -r .token) + TOKEN=$(curl -u padms:${{ secrets.PADMS_PAT }} https://ghcr.io/token\?scope\="repository:equinor/energyvision>:pull" | jq -r .token) statusCode=$(curl --head --write-out '%{http_code}' --silent --output /dev/null -H "Authorization: Bearer $TOKEN" https://ghcr.io/v2/equinor/energyvision/web-global/manifests/${{ github.event.inputs.image-sha }}) if [[ $statusCode -eq 200 ]] then @@ -72,7 +72,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Write to console 🗒️ shell: bash run: | @@ -80,8 +80,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py web ${{ github.event.inputs.image-sha }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🔙 Rolling back all websites in production to version ${{ github.event.inputs.image-sha }}" diff --git a/.github/workflows/PROD-webs.yaml b/.github/workflows/PROD-webs.yaml index 4f96187e0..1337515a5 100644 --- a/.github/workflows/PROD-webs.yaml +++ b/.github/workflows/PROD-webs.yaml @@ -32,7 +32,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Promote preprod tag to prod 🗒️ if: github.ref == 'refs/heads/main' shell: bash @@ -42,8 +42,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/promoteToProduction.py web ${{ github.event.inputs.site }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy web for ${{ github.event.inputs.site }} to production" diff --git a/.github/workflows/TEST-studio.yaml b/.github/workflows/TEST-studio.yaml index b690627e6..8cea27f2c 100644 --- a/.github/workflows/TEST-studio.yaml +++ b/.github/workflows/TEST-studio.yaml @@ -71,7 +71,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Modify radixconfig tag for TEST on staging branch 🗒️ if: github.ref == 'refs/heads/staging' shell: bash @@ -81,8 +81,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py studio ${{ env.IMAGE_TAG_SHA }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy studio to test for tag ${{ env.IMAGE_TAG_SHA }}" diff --git a/.github/workflows/TEST-web.yaml b/.github/workflows/TEST-web.yaml index a43655d31..487b8b94b 100644 --- a/.github/workflows/TEST-web.yaml +++ b/.github/workflows/TEST-web.yaml @@ -80,7 +80,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue + token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue - name: Modify radixconfig tag for TEST on staging branch 🗒️ if: github.ref == 'refs/heads/staging' shell: bash @@ -90,8 +90,8 @@ jobs: python -m pip install --user ruamel.yaml python ci/upgradeEnvironment.py web ${{ env.IMAGE_TAG_SHA }} ${{ secrets.ENV }} git config --global user.name 'github' - git config --global user.email 'nilsml@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/equinor/energyvision-internal + git config --global user.email 'padms@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal if [[ `git status --porcelain` ]] then git commit -am "🚀 Deploy web to test with tag ${{ env.IMAGE_TAG_SHA }}" --allow-empty diff --git a/.github/workflows/ghcr-cleanup.yaml b/.github/workflows/ghcr-cleanup.yaml index fe42ac7b8..89b3eb361 100644 --- a/.github/workflows/ghcr-cleanup.yaml +++ b/.github/workflows/ghcr-cleanup.yaml @@ -23,7 +23,7 @@ jobs: org-name: Equinor keep-at-least: 5 untagged-only: false - token: ${{ secrets.NLUN_GITHUB_PAT }} + token: ${{ secrets.PADMS_PAT }} - name: log-errors-to-slack 📄 uses: act10ns/slack@v2 with: diff --git a/.github/workflows/ghcr-cleanup_v2.yaml b/.github/workflows/ghcr-cleanup_v2.yaml index 11623432c..15aa5c035 100644 --- a/.github/workflows/ghcr-cleanup_v2.yaml +++ b/.github/workflows/ghcr-cleanup_v2.yaml @@ -12,37 +12,37 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} steps: - - name: Checkout internal 🛎️ - id: checkout-internal - uses: actions/checkout@v3 - with: - repository: 'equinor/energyvision-internal' - ref: main - token: ${{ secrets.PAT }} + - name: Checkout internal 🛎️ + id: checkout-internal + uses: actions/checkout@v3 + with: + repository: 'equinor/energyvision-internal' + ref: main + token: ${{ secrets.PADMS_PAT }} - - name: Get tags to keep from output.json - id: get-tags - run: | - TAGS=$(jq -r '[.web + .studio | unique[]] | join(", ")' latest-prod-tags.json) - echo "TAGS_TO_KEEP=$TAGS" >> $GITHUB_ENV - echo "TAGS TO KEEP: $TAGS" + - name: Get tags to keep from output.json + id: get-tags + run: | + TAGS=$(jq -r '[.web + .studio | unique[]] | join(", ")' latest-prod-tags.json) + echo "TAGS_TO_KEEP=$TAGS" >> $GITHUB_ENV + echo "TAGS TO KEEP: $TAGS" - - name: Clean up Docker images - id: delete-containers - uses: snok/container-retention-policy@v2 - with: - token: ${{ secrets.NLUN_GITHUB_PAT }} - account-type: org - org-name: Equinor - image-names: energyvision/equinor/web-global - cut-off: one day ago UTC+2 - keep-at-least: 5 - # skip-tags: ${{ env.TAGS_TO_KEEP }} - dry-run: true + - name: Clean up Docker images + id: delete-containers + uses: snok/container-retention-policy@v2 + with: + token: ${{ secrets.PADMS_PAT }} + account-type: org + org-name: Equinor + image-names: energyvision/equinor/web-global + cut-off: one day ago UTC+2 + keep-at-least: 5 + # skip-tags: ${{ env.TAGS_TO_KEEP }} + dry-run: true - - name: log-errors-to-slack 📄 - uses: act10ns/slack@v2 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - if: failure() + - name: log-errors-to-slack 📄 + uses: act10ns/slack@v2 + with: + status: ${{ job.status }} + steps: ${{ toJson(steps) }} + if: failure() diff --git a/.github/workflows/setup-azure.yaml b/.github/workflows/setup-azure.yaml index 3dab56b1f..6a5613cbc 100644 --- a/.github/workflows/setup-azure.yaml +++ b/.github/workflows/setup-azure.yaml @@ -29,7 +29,7 @@ jobs: with: repository: 'equinor/energyvision-internal' ref: main - token: ${{ secrets.PAT }} + token: ${{ secrets.PADMS_PAT }} # Do the actual deployment - name: deploy id: deploy diff --git a/package.json b/package.json index 948e30b7f..c9a75f2d7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "lint:web": "eslint ./web/ --ext .js,.jsx,.ts,.tsx", "lint:studio": "eslint ./studio/ --ext .js,.jsx,.ts,.tsx", "lint:search": "eslint ./search/ --ext .ts", - "lint": "pnpm lint:web && pnpm lint:studio && pnpm lint:search", + "lint:sanityv3": "eslint ./sanityv3/ --ext .js,.jsx,.ts,.tsx", + "lint": "pnpm lint:web && pnpm lint:studio && pnpm lint:search && pnpm lint:sanityv3", "studio": "yarn --cwd ./studio", "web": "pnpm --filter ./web", "sanityv3": "pnpm --filter ./sanityv3", diff --git a/sanityv3/.eslintrc b/sanityv3/.eslintrc index da5d50048..df6a38327 100644 --- a/sanityv3/.eslintrc +++ b/sanityv3/.eslintrc @@ -1,3 +1,6 @@ -// { -// "extends": "@sanity/eslint-config-studio" -// } +{ + "rules": { + "import/default": "off", + "@typescript-eslint/no-explicit-any": "off" + } +} diff --git a/sanityv3/components/CustomArrayFunctions.tsx b/sanityv3/components/CustomArrayFunctions.tsx index 91e9b01f9..de88fd181 100644 --- a/sanityv3/components/CustomArrayFunctions.tsx +++ b/sanityv3/components/CustomArrayFunctions.tsx @@ -2,7 +2,7 @@ // custom implementation of @sanity/form-builder/src/inputs/arrays/common/ArrayFunctions.tsx import { ArraySchemaType, isReferenceSchemaType } from 'sanity' import { AddIcon } from '@sanity/icons' -import React, { ReactNode, useMemo, useCallback } from 'react' +import { ReactNode, useMemo, useCallback } from 'react' import { Button, Grid, Menu, MenuButton, MenuItem } from '@sanity/ui' import { useId } from '@reach/auto-id' diff --git a/sanityv3/icons/SvgIcon.tsx b/sanityv3/icons/SvgIcon.tsx index 674eeb47f..2f04a608d 100644 --- a/sanityv3/icons/SvgIcon.tsx +++ b/sanityv3/icons/SvgIcon.tsx @@ -1,4 +1,3 @@ -import React from 'react' import type { IconData } from '@equinor/eds-icons' type IconProps = { diff --git a/sanityv3/icons/countries/Argentina.tsx b/sanityv3/icons/countries/Argentina.tsx index 11315bc68..e52d96e58 100644 --- a/sanityv3/icons/countries/Argentina.tsx +++ b/sanityv3/icons/countries/Argentina.tsx @@ -1,5 +1,3 @@ -import React from 'react' - const Argentina = ({ width = 30, height = 30 }: { width: number; height: number }) => { return ( diff --git a/sanityv3/icons/countries/Brazil.tsx b/sanityv3/icons/countries/Brazil.tsx index e55901895..1ce932ab0 100644 --- a/sanityv3/icons/countries/Brazil.tsx +++ b/sanityv3/icons/countries/Brazil.tsx @@ -1,5 +1,3 @@ -import React from 'react' - const Brazil = ({ width = 30, height = 30 }: { width: number; height: number }) => { return ( { return ( diff --git a/sanityv3/icons/countries/Norway.tsx b/sanityv3/icons/countries/Norway.tsx index 77de9fcc0..f681551bd 100644 --- a/sanityv3/icons/countries/Norway.tsx +++ b/sanityv3/icons/countries/Norway.tsx @@ -1,6 +1,3 @@ -/* eslint max-len: off */ -import React from 'react' - const Norway = ({ width = 30, height = 30 }: { width: number; height: number }) => { return ( { return ( diff --git a/sanityv3/icons/edsIcons.tsx b/sanityv3/icons/edsIcons.tsx index 740d7867b..6610809d1 100644 --- a/sanityv3/icons/edsIcons.tsx +++ b/sanityv3/icons/edsIcons.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { list, IconData } from '@equinor/eds-icons' import { SvgIcon, BlockEditorSvgIcon } from './SvgIcon' diff --git a/sanityv3/initialValueTemplates.ts b/sanityv3/initialValueTemplates.ts index 2d833b10e..6e9303728 100644 --- a/sanityv3/initialValueTemplates.ts +++ b/sanityv3/initialValueTemplates.ts @@ -85,15 +85,6 @@ const localNewsWithTagTemplate: Template = { }), } -const promotedMagazineTagTemplate: Template = { - id: `promoted-magazine-tags`, - title: `Promoted magazine tags`, - schemaType: `promotedMagazineTags`, - value: () => { - return { tags: [] } - }, -} - export const initialValueTemplates = [ //promotedMagazineTagTemplate, localNewsWithTagTemplate, diff --git a/sanityv3/plugins/asset-source-brandmaster/src/BrandmasterAssetSource.tsx b/sanityv3/plugins/asset-source-brandmaster/src/BrandmasterAssetSource.tsx index cf4861bcd..b1f36868c 100644 --- a/sanityv3/plugins/asset-source-brandmaster/src/BrandmasterAssetSource.tsx +++ b/sanityv3/plugins/asset-source-brandmaster/src/BrandmasterAssetSource.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useCallback, forwardRef, useState, useRef } from 'react' +import { useEffect, useCallback, forwardRef, useState, useRef } from 'react' import { createPortal } from 'react-dom' import { Dialog } from '@sanity/ui' import styled from 'styled-components' diff --git a/sanityv3/plugins/asset-source-brandmaster/src/Icon.tsx b/sanityv3/plugins/asset-source-brandmaster/src/Icon.tsx index e285d9847..9428666f0 100644 --- a/sanityv3/plugins/asset-source-brandmaster/src/Icon.tsx +++ b/sanityv3/plugins/asset-source-brandmaster/src/Icon.tsx @@ -1,5 +1,3 @@ -import React from 'react' - export default function BrandmasterIcon() { return ( diff --git a/sanityv3/plugins/asset-source-fotoware/src/FotowareAssetSource.tsx b/sanityv3/plugins/asset-source-fotoware/src/FotowareAssetSource.tsx index 943836b2e..514da58bb 100644 --- a/sanityv3/plugins/asset-source-fotoware/src/FotowareAssetSource.tsx +++ b/sanityv3/plugins/asset-source-fotoware/src/FotowareAssetSource.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -import React, { useEffect, useCallback, forwardRef, useState, useRef } from 'react' +import { useEffect, useCallback, forwardRef, useState, useRef } from 'react' // @ts-ignore import { createPortal } from 'react-dom' import { Dialog, Spinner } from '@sanity/ui' @@ -128,20 +128,25 @@ const FotowareAssetSource = forwardRef((props: any, ref) => { const assetTitle = asset && asset?.builtinFields.find((item: FWAttributeField) => item.field === 'title') const assetDescription = asset && asset?.builtinFields.find((item: FWAttributeField) => item.field === 'description') + const assetId = asset?.metadata?.[187]?.value + const personShownInTheImage = asset?.metadata?.[368]?.value?.join(', ') + const description = assetDescription?.value + ? [assetDescription?.value, personShownInTheImage].join('\n') + : personShownInTheImage onSelect([ { kind: 'base64', value: data.image, assetDocumentProps: { - originalFileName: asset?.filename || '', + originalFilename: asset?.filename || '', source: { - id: asset?.uniqueid || uri, name: 'fotoware', + id: assetId || asset?.uniqueid || uri, url: source, }, - ...(assetTitle?.value && { title: assetTitle.value }), - ...(assetDescription?.value && { description: assetDescription.value }), + title: assetTitle?.value, + description: description, }, }, ]) diff --git a/sanityv3/plugins/asset-source-fotoware/src/Icon.tsx b/sanityv3/plugins/asset-source-fotoware/src/Icon.tsx index daa1ed1c8..21d237907 100644 --- a/sanityv3/plugins/asset-source-fotoware/src/Icon.tsx +++ b/sanityv3/plugins/asset-source-fotoware/src/Icon.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { useColorSchemeValue } from 'sanity' export default function FotowareIcon() { diff --git a/sanityv3/plugins/asset-source-fotoware/src/Placeholder.tsx b/sanityv3/plugins/asset-source-fotoware/src/Placeholder.tsx index 0f982be60..db8c56903 100644 --- a/sanityv3/plugins/asset-source-fotoware/src/Placeholder.tsx +++ b/sanityv3/plugins/asset-source-fotoware/src/Placeholder.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef } from 'react' +import { forwardRef } from 'react' import { ErrorMessage } from './components' const PlacholderAssetSource = forwardRef((props: any, ref) => { diff --git a/sanityv3/plugins/asset-source-fotoware/src/components.tsx b/sanityv3/plugins/asset-source-fotoware/src/components.tsx index 0bc5d9b6d..f95a536be 100644 --- a/sanityv3/plugins/asset-source-fotoware/src/components.tsx +++ b/sanityv3/plugins/asset-source-fotoware/src/components.tsx @@ -1,5 +1,5 @@ -import React, { forwardRef } from 'react' -import { Box, Dialog } from '@sanity/ui' +import { ReactNode, forwardRef } from 'react' +import { Dialog, Box } from '@sanity/ui' import styled from 'styled-components' export const Content = styled.div` @@ -49,7 +49,7 @@ export const FullScreenDialog = styled(Dialog)` type ErrorMessageProps = { onClose: any ref: any - children?: React.ReactNode + children?: ReactNode } export const ErrorMessage = forwardRef((props, ref) => { diff --git a/sanityv3/plugins/asset-source-fotoware/src/types.ts b/sanityv3/plugins/asset-source-fotoware/src/types.ts index fa5cf9e6d..97eda3ca2 100644 --- a/sanityv3/plugins/asset-source-fotoware/src/types.ts +++ b/sanityv3/plugins/asset-source-fotoware/src/types.ts @@ -22,7 +22,17 @@ export type FWAsset = { photoAttributes: any } builtinFields: FWAttributeField[] - metadata: any + metadata: { + // https://learn.fotoware.com/On-Premises/Getting_started/Metadata_in_the_FotoWare_system/04_Operators_to_search_in_specific_fields/XMP_Field_code_reference + // Unique Document ID + 187?: { + value: string + } + // Person shown in the Image + 368?: { + value: string[] + } + } ancestors: any[] props: any } diff --git a/sanityv3/sanity.config.tsx b/sanityv3/sanity.config.tsx index 921687870..38c55825e 100644 --- a/sanityv3/sanity.config.tsx +++ b/sanityv3/sanity.config.tsx @@ -2,7 +2,6 @@ import { visionTool } from '@sanity/vision' import { media } from 'sanity-plugin-media' import { - Config, ConfigContext, createAuthStore, defineConfig, @@ -60,7 +59,7 @@ const getStudioTitle = (dataset: string) => { } } -const getConfig = (datasetParam: string, projectIdParam: string, isSecret: boolean = false) => ({ +const getConfig = (datasetParam: string, projectIdParam: string, isSecret = false) => ({ name: 'equinor-' + datasetParam, title: 'Studio [' + getStudioTitle(datasetParam) + ']', icon: DatabaseIcon, diff --git a/sanityv3/schemas/components/CharCounterEditor.tsx b/sanityv3/schemas/components/CharCounterEditor.tsx index abf4aac92..63992e904 100644 --- a/sanityv3/schemas/components/CharCounterEditor.tsx +++ b/sanityv3/schemas/components/CharCounterEditor.tsx @@ -3,10 +3,11 @@ import { Stack, Text } from '@sanity/ui' import { ArrayOfObjectsInputProps, PortableTextBlock } from 'sanity' export function CharCounterEditor(props: ArrayOfObjectsInputProps) { - const content = props.value ? blocksToText(props.value as PortableTextBlock[]) : [] + const { value, renderDefault } = props + const content = value ? blocksToText(value as PortableTextBlock[]) : [] return ( - {props.renderDefault(props)} + {renderDefault(props)} Characters: {content?.length || 0} diff --git a/sanityv3/schemas/components/EventPromotion/EventPromotionInput.tsx b/sanityv3/schemas/components/EventPromotion/EventPromotionInput.tsx index 10de69d2a..1cdbc3e4c 100644 --- a/sanityv3/schemas/components/EventPromotion/EventPromotionInput.tsx +++ b/sanityv3/schemas/components/EventPromotion/EventPromotionInput.tsx @@ -27,7 +27,7 @@ const InlinePreview = ({ value }: { value: EventPromotion | undefined }) => { } export const EventPromotionInput = (props: EventPromotionInputProps) => { - const { value, members, renderField, renderInput, renderItem, renderPreview, onChange } = props + const { value, members, renderField, renderInput, renderItem, renderPreview, onChange, renderDefault } = props const useTags = getObjectMemberField(members, 'useTags') const promotePastEvents = getObjectMemberField(members, 'promotePastEvents') @@ -36,7 +36,7 @@ export const EventPromotionInput = (props: EventPromotionInputProps) => { const promotedEvents = getObjectMemberField(members, 'promotedEvents') if (!promotePastEvents || !pastEventsCount || !useTags || !selectedTags || !promotedEvents) - return props.renderDefault(props) + return renderDefault(props) return ( diff --git a/sanityv3/schemas/components/EventPromotion/EventPromotionPreview.tsx b/sanityv3/schemas/components/EventPromotion/EventPromotionPreview.tsx index 225b96e21..628a303cb 100644 --- a/sanityv3/schemas/components/EventPromotion/EventPromotionPreview.tsx +++ b/sanityv3/schemas/components/EventPromotion/EventPromotionPreview.tsx @@ -14,7 +14,8 @@ type EventPromotionPreviewProps = { } & PreviewProps export const EventPromotionPreview = (props: EventPromotionPreviewProps) => { - const { manuallySelectEvents, promotedEvents, promotePastEvents, pastEventsCount, useTags, tags } = props + const { manuallySelectEvents, promotedEvents, promotePastEvents, pastEventsCount, useTags, tags, renderDefault } = + props const [title, setTitle] = useState('Event promotion') useEffect(() => { @@ -32,7 +33,7 @@ export const EventPromotionPreview = (props: EventPromotionPreviewProps) => { return ( - {props.renderDefault({ ...props, title: title, subtitle: 'Event promotion', media: EdsIcon(calendar_event) })} + {renderDefault({ ...props, title: title, subtitle: 'Event promotion', media: EdsIcon(calendar_event) })} {manuallySelectEvents ? ( diff --git a/sanityv3/schemas/components/HLSPlayer.tsx b/sanityv3/schemas/components/HLSPlayer.tsx index 142c8ce4b..da77511ce 100644 --- a/sanityv3/schemas/components/HLSPlayer.tsx +++ b/sanityv3/schemas/components/HLSPlayer.tsx @@ -1,13 +1,13 @@ /* eslint-disable import/no-named-as-default-member */ /* eslint-disable jsx-a11y/media-has-caption */ -import React, { useRef, HTMLProps, useEffect } from 'react' +import { FC, useRef, HTMLProps, useEffect } from 'react' import Hls from 'hls.js' type Props = Omit, 'src'> & { src: string } -const HLSPlayer: React.FC = ({ src, ...props }) => { +const HLSPlayer: FC = ({ src, ...props }) => { const videoRef = useRef(null) const hlsRef = useRef(null) diff --git a/sanityv3/schemas/components/RadioIconSelector.tsx b/sanityv3/schemas/components/RadioIconSelector.tsx index a8d3228d4..dd70ec83f 100644 --- a/sanityv3/schemas/components/RadioIconSelector.tsx +++ b/sanityv3/schemas/components/RadioIconSelector.tsx @@ -1,10 +1,10 @@ import { Box, Inline } from '@sanity/ui' -import React, { useCallback, useState } from 'react' +import { ReactNode, useCallback, useState } from 'react' import { PatchEvent, set } from 'sanity' import styled from 'styled-components' type StyledBoxProps = { - children: React.ReactNode + children: ReactNode } const StyledBox = ({ children }: StyledBoxProps) => ( diff --git a/sanityv3/schemas/components/SlugInput/index.tsx b/sanityv3/schemas/components/SlugInput/index.tsx index d41c69805..0c54bec61 100644 --- a/sanityv3/schemas/components/SlugInput/index.tsx +++ b/sanityv3/schemas/components/SlugInput/index.tsx @@ -1,5 +1,5 @@ import { Box, Button, Card, Flex, Stack, TextInput } from '@sanity/ui' -import React, { useCallback, useMemo } from 'react' +import { useCallback, useMemo } from 'react' import { getValueAtPath, ObjectInputProps, @@ -77,7 +77,7 @@ export function SlugInput(props: SlugInputProps) { const isUpdating = generateState?.status === 'pending' - const handleChange = React.useCallback((event: any) => updateSlug(event.currentTarget.value), [updateSlug]) + const handleChange = useCallback((event: any) => updateSlug(event.currentTarget.value), [updateSlug]) return ( diff --git a/sanityv3/schemas/components/SlugInput/utils/useAsync.ts b/sanityv3/schemas/components/SlugInput/utils/useAsync.ts index ef439ee60..0399b407f 100644 --- a/sanityv3/schemas/components/SlugInput/utils/useAsync.ts +++ b/sanityv3/schemas/components/SlugInput/utils/useAsync.ts @@ -1,4 +1,4 @@ -import React from 'react' +import { DependencyList, useState, useRef, useCallback } from 'react' export type AsyncCompleteState = { status: 'complete' @@ -12,10 +12,7 @@ export type AsyncErrorState = { error: Error } -export type AsyncState = - | AsyncPendingState - | AsyncCompleteState - | AsyncErrorState +export type AsyncState = AsyncPendingState | AsyncCompleteState | AsyncErrorState /** * Takes an async function and returns a [AsyncState, callback] pair. @@ -26,13 +23,13 @@ export type AsyncState = */ export function useAsync( fn: (arg: U) => Promise, - dependencies: React.DependencyList, + dependencies: DependencyList, ): [null | AsyncState, (arg: U) => void] { - const [state, setState] = React.useState | null>(null) + const [state, setState] = useState | null>(null) - const lastId = React.useRef(0) + const lastId = useRef(0) - const wrappedCallback = React.useCallback( + const wrappedCallback = useCallback( (arg: U) => { const asyncId = ++lastId.current setState({ status: 'pending' }) diff --git a/sanityv3/schemas/components/TimeInput.tsx b/sanityv3/schemas/components/TimeInput.tsx index 5756fdaa6..d6bc8c898 100644 --- a/sanityv3/schemas/components/TimeInput.tsx +++ b/sanityv3/schemas/components/TimeInput.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from 'react' +import { FormEvent, useCallback, useState } from 'react' import { useId } from '@reach/auto-id' import { ResetIcon } from '@sanity/icons' import { Box, Button, Flex, Select, Text } from '@sanity/ui' @@ -46,7 +46,7 @@ type TimeType = { } const TimeInput = (props: ObjectInputProps) => { - const { value, onChange, elementProps, validation } = props + const { value, onChange, elementProps } = props const [time, setTime] = useState(formatTime(value)) const updateValue = useCallback( @@ -65,14 +65,14 @@ const TimeInput = (props: ObjectInputProps) => { ) const handleHoursChange = useCallback( - (event: React.FormEvent) => { + (event: FormEvent) => { updateValue({ ...time, hours: event.currentTarget.value }) }, [time, updateValue], ) const handleMinutesChange = useCallback( - (event: React.FormEvent) => { + (event: FormEvent) => { updateValue({ ...time, minutes: event.currentTarget.value }) }, [time, updateValue], diff --git a/sanityv3/schemas/components/TimezoneInput.tsx b/sanityv3/schemas/components/TimezoneInput.tsx index ab179ad11..e5eb018ca 100644 --- a/sanityv3/schemas/components/TimezoneInput.tsx +++ b/sanityv3/schemas/components/TimezoneInput.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import { FormEvent } from 'react' import { useId } from '@reach/auto-id' import { Select } from '@sanity/ui' @@ -8,7 +8,7 @@ import { set, unset, StringInputProps } from 'sanity' const TimezoneInput = (props: StringInputProps) => { const { value = '', onChange, elementProps } = props const id = useId() - const handleChange = (event: React.FormEvent) => { + const handleChange = (event: FormEvent) => { onChange(event.currentTarget.value === '' ? unset() : set(event.currentTarget.value)) } diff --git a/sanityv3/schemas/components/VideoSelector.tsx b/sanityv3/schemas/components/VideoSelector.tsx index 53d94fed8..7daed95a8 100644 --- a/sanityv3/schemas/components/VideoSelector.tsx +++ b/sanityv3/schemas/components/VideoSelector.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useRef, forwardRef, useEffect } from 'react' +import { ReactNode, useState, useCallback, useRef, forwardRef, useEffect } from 'react' import { MemberField, set, unset } from 'sanity' import { createPortal } from 'react-dom' import type { ObjectInputProps } from 'sanity' @@ -17,7 +17,7 @@ type VideoSelector = { type VideoSelectorProps = { value?: VideoSelector - children?: React.ReactNode + children?: ReactNode } & ObjectInputProps const MEDIABANK_DOMAIN = 'https://communicationtoolbox.equinor.com' diff --git a/sanityv3/schemas/components/renderers.tsx b/sanityv3/schemas/components/renderers.tsx index 0b2d87898..94aa125a7 100644 --- a/sanityv3/schemas/components/renderers.tsx +++ b/sanityv3/schemas/components/renderers.tsx @@ -1,7 +1,7 @@ -import React from 'react' +import {ReactNode} from 'react' type Props = { - children: React.ReactNode + children: ReactNode } export const ExternalLinkRenderer = ({ children }: Props) => {children} diff --git a/sanityv3/schemas/documents/404.ts b/sanityv3/schemas/documents/404.ts index a9d734d32..1f153ee51 100644 --- a/sanityv3/schemas/documents/404.ts +++ b/sanityv3/schemas/documents/404.ts @@ -1,4 +1,4 @@ -import { flight_land } from '@equinor/eds-icons' +import { flight_land, collection_4 } from '@equinor/eds-icons' import type { PortableTextBlock, Rule } from 'sanity' import blocksToText from '../../helpers/blocksToText' import { EdsIcon } from '../../icons' @@ -6,7 +6,6 @@ import CompactBlockEditor from '../components/CompactBlockEditor' import { i18n } from '../documentTranslation' import { configureTitleBlockContent } from '../editors' import { configureBlockContent } from '../editors/blockContentType' -import { collection_4 } from '@equinor/eds-icons' const titleContentType = configureTitleBlockContent() const textContentType = configureBlockContent({ diff --git a/sanityv3/schemas/documents/assetFile.ts b/sanityv3/schemas/documents/assetFile.ts index 2ca673ef2..eb14cf8ab 100644 --- a/sanityv3/schemas/documents/assetFile.ts +++ b/sanityv3/schemas/documents/assetFile.ts @@ -5,7 +5,6 @@ import { microsoft_powerpoint, library_pdf, file, - library_books, calendar_event, attach_file, } from '@equinor/eds-icons' diff --git a/sanityv3/schemas/documents/header/sharedHeaderFields.ts b/sanityv3/schemas/documents/header/sharedHeaderFields.ts index c91fcfc0f..da9e87d18 100644 --- a/sanityv3/schemas/documents/header/sharedHeaderFields.ts +++ b/sanityv3/schemas/documents/header/sharedHeaderFields.ts @@ -125,6 +125,7 @@ const heroImage = { title: 'Hero image', name: 'heroFigure', type: 'imageWithAltAndCaption', + description: 'Caption and credit is not shown for 50-50 banner.', validation: (Rule: Rule) => Rule.custom((value: string, context: ValidationContext) => { const { parent } = context as DocumentType diff --git a/sanityv3/schemas/documents/localNews.ts b/sanityv3/schemas/documents/localNews.ts index cb1b16929..5c458872c 100644 --- a/sanityv3/schemas/documents/localNews.ts +++ b/sanityv3/schemas/documents/localNews.ts @@ -1,6 +1,5 @@ import { file_description } from '@equinor/eds-icons' import { - defineType, Rule, SanityDocument, SlugSchemaType, diff --git a/sanityv3/schemas/documents/localNewsTag.tsx b/sanityv3/schemas/documents/localNewsTag.tsx index 40ed59b3a..8609f8013 100644 --- a/sanityv3/schemas/documents/localNewsTag.tsx +++ b/sanityv3/schemas/documents/localNewsTag.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { languages } from '../../languages' import type { CurrentUser } from 'sanity' import styled from 'styled-components' diff --git a/sanityv3/schemas/documents/magazineTag.tsx b/sanityv3/schemas/documents/magazineTag.tsx index 254d4bfdd..14a36ee3f 100644 --- a/sanityv3/schemas/documents/magazineTag.tsx +++ b/sanityv3/schemas/documents/magazineTag.tsx @@ -1,5 +1,5 @@ import { defaultLanguage, languages } from '../../languages' -import { TagIcon, EdsIcon } from '../../icons' +import { EdsIcon } from '../../icons' import type { Rule } from 'sanity' import { tag_main_equipment } from '@equinor/eds-icons' diff --git a/sanityv3/schemas/documents/route.tsx b/sanityv3/schemas/documents/route.tsx index 83ea99a72..48594c9a9 100644 --- a/sanityv3/schemas/documents/route.tsx +++ b/sanityv3/schemas/documents/route.tsx @@ -1,13 +1,12 @@ import slugify from 'slugify' import { Reference, Rule, SlugParent, SlugSchemaType, SlugSourceContext } from 'sanity' import blocksToText from '../../helpers/blocksToText' -import { calendar_event } from '@equinor/eds-icons' +import { calendar_event, library_books } from '@equinor/eds-icons' import { EdsIcon, TopicDocuments } from '../../icons' import { Flags } from '../../src/lib/datasetHelpers' import { withSlugValidation } from '../validations/validateSlug' import SlugInput from '../components/SlugInput' import { SanityClient, SanityDocument } from '@sanity/client' -import { library_books } from '@equinor/eds-icons' export default (isoCode: string, title: string) => { return { @@ -96,15 +95,17 @@ export default (isoCode: string, title: string) => { _schemaType: SlugSchemaType, context: SlugSourceContext & { client: SanityClient }, ) => { - const slug = slugify(input) const { client, parent } = context const document = parent as SlugParent & { parent: Reference } - const refId = document.parent._ref - return client - .fetch(/* groq */ `*[_id == $refId][0].slug.current`, { refId: refId }) - .then((parentSlug: string) => { - return `${parentSlug}/${slug}` - }) + const refId = document.parent?._ref + + if (refId) { + return client + .fetch(/* groq */ `*[_id == $refId][0].slug.current`, { refId: refId }) + .then((parentSlug: string) => `${parentSlug}/${slugify(input)}`) + } else { + return `/${slugify(input)}` + } }, }), validation: (Rule: Rule) => Rule.required(), diff --git a/sanityv3/schemas/documents/simpleMenu.tsx b/sanityv3/schemas/documents/simpleMenu.tsx index ea4dde170..16f4c2908 100644 --- a/sanityv3/schemas/documents/simpleMenu.tsx +++ b/sanityv3/schemas/documents/simpleMenu.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { MenuIcon } from '../../icons' export default { diff --git a/sanityv3/schemas/documents/siteMenu.tsx b/sanityv3/schemas/documents/siteMenu.tsx index bffbeb9fd..b91d32ce4 100644 --- a/sanityv3/schemas/documents/siteMenu.tsx +++ b/sanityv3/schemas/documents/siteMenu.tsx @@ -1,4 +1,3 @@ -import React from 'react' import type { Rule } from 'sanity' import { filterByLang } from '../../helpers/referenceFilters' import { EdsIcon, MenuIcon } from '../../icons' diff --git a/sanityv3/schemas/editors/titleEditorContentType.tsx b/sanityv3/schemas/editors/titleEditorContentType.tsx index f52c6bf04..c3989715b 100644 --- a/sanityv3/schemas/editors/titleEditorContentType.tsx +++ b/sanityv3/schemas/editors/titleEditorContentType.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { SuperScriptRenderer, SubScriptRenderer, StrikeThroughRenderer } from '../components' import { IconSuperScript, IconSubScript } from '../../icons' import { StrikethroughIcon } from '@sanity/icons' diff --git a/sanityv3/schemas/objects/anchorLink.tsx b/sanityv3/schemas/objects/anchorLink.tsx index 4bce2a4b8..a3ab61cce 100644 --- a/sanityv3/schemas/objects/anchorLink.tsx +++ b/sanityv3/schemas/objects/anchorLink.tsx @@ -5,7 +5,6 @@ import { validateComponentAnchor } from '../validations/validateAnchorReference' import { EdsIcon } from '../../icons' import { Heading, Text, Box } from '@sanity/ui' import styled from 'styled-components' -import React from 'react' export type AnchorLink = { _type: 'anchorLink' diff --git a/sanityv3/schemas/objects/anchorReferenceField.tsx b/sanityv3/schemas/objects/anchorReferenceField.tsx index 3f6726f21..dffee3928 100644 --- a/sanityv3/schemas/objects/anchorReferenceField.tsx +++ b/sanityv3/schemas/objects/anchorReferenceField.tsx @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -import React from 'react' import { validateAnchorReference } from '../validations/validateAnchorReference' import styled from 'styled-components' import { Rule } from 'sanity' diff --git a/sanityv3/schemas/objects/cookieDeclaration.tsx b/sanityv3/schemas/objects/cookieDeclaration.tsx index 6aa97ef82..8cf60fbd8 100644 --- a/sanityv3/schemas/objects/cookieDeclaration.tsx +++ b/sanityv3/schemas/objects/cookieDeclaration.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { table_chart } from '@equinor/eds-icons' import { EdsIcon } from '../../icons' import { Heading, Text, Box } from '@sanity/ui' diff --git a/sanityv3/schemas/objects/downloadableImage.tsx b/sanityv3/schemas/objects/downloadableImage.tsx index 29b3a314e..f3e9a7018 100644 --- a/sanityv3/schemas/objects/downloadableImage.tsx +++ b/sanityv3/schemas/objects/downloadableImage.tsx @@ -1,4 +1,3 @@ -import React from 'react' import type { Rule, Reference } from 'sanity' export type DownloadableImage = { diff --git a/sanityv3/schemas/objects/eventDate.tsx b/sanityv3/schemas/objects/eventDate.tsx index c216281b1..f30666a09 100644 --- a/sanityv3/schemas/objects/eventDate.tsx +++ b/sanityv3/schemas/objects/eventDate.tsx @@ -1,4 +1,3 @@ -import React from 'react' import type { Rule, ValidationContext } from 'sanity' import TimeInput, { EMPTY, INVALID_TIME_FORMAT } from '../components/TimeInput' import TimezoneInput from '../components/TimezoneInput' diff --git a/sanityv3/schemas/objects/files.tsx b/sanityv3/schemas/objects/files.tsx index 216dbe525..aa010c72e 100644 --- a/sanityv3/schemas/objects/files.tsx +++ b/sanityv3/schemas/objects/files.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { library_pdf, microsoft_excel, file } from '@equinor/eds-icons' import { EdsIcon } from '../../icons' import type { Rule, File } from 'sanity' diff --git a/sanityv3/schemas/objects/fullWidthVideo.tsx b/sanityv3/schemas/objects/fullWidthVideo.tsx index 14fee733e..bc06d2783 100644 --- a/sanityv3/schemas/objects/fullWidthVideo.tsx +++ b/sanityv3/schemas/objects/fullWidthVideo.tsx @@ -1,14 +1,9 @@ import { play_circle } from '@equinor/eds-icons' import { EdsIcon } from '../../icons' - -import { configureTitleBlockContent } from '../editors' -import CompactBlockEditor from '../components/CompactBlockEditor' import blocksToText from '../../helpers/blocksToText' import type { PortableTextBlock, Rule } from 'sanity' import { ImageWithAlt } from './imageWithAlt' -const titleContentType = configureTitleBlockContent() - export default { name: 'fullWidthVideo', title: 'Full Width Video Player', diff --git a/sanityv3/schemas/objects/iframe.tsx b/sanityv3/schemas/objects/iframe.tsx index 187d1b029..dfd1d9cf6 100644 --- a/sanityv3/schemas/objects/iframe.tsx +++ b/sanityv3/schemas/objects/iframe.tsx @@ -7,7 +7,16 @@ import type { ColorSelectorValue } from '../components/ColorSelector' import blocksToText from '../../helpers/blocksToText' import { EdsIcon } from '../../icons' import { configureBlockContent, configureTitleBlockContent } from '../editors' -import { title, frameTitle, description, cookiePolicy, aspectRatio, url, height } from './iframe/sharedIframeFields' +import { + title, + frameTitle, + description, + cookiePolicy, + aspectRatio, + url, + height, + action, +} from './iframe/sharedIframeFields' const ingressContentType = configureBlockContent({ h1: false, @@ -65,14 +74,7 @@ export default { aspectRatio, height, description, - { - name: 'action', - title: 'Link/action', - description: 'You can add one separate link if you need. The link will show up at the bottom of the component.', - type: 'array', - of: [{ type: 'linkSelector', title: 'Link' }], - validation: (Rule: Rule) => Rule.max(1), - }, + action, { title: 'Background', description: 'Pick a colour for the background. Default is white.', diff --git a/sanityv3/schemas/objects/iframe/sharedIframeFields.tsx b/sanityv3/schemas/objects/iframe/sharedIframeFields.tsx index 4533527ad..07c08b85e 100644 --- a/sanityv3/schemas/objects/iframe/sharedIframeFields.tsx +++ b/sanityv3/schemas/objects/iframe/sharedIframeFields.tsx @@ -104,3 +104,12 @@ export const description = { type: 'array', of: [descriptionContentType], } + +export const action = { + name: 'action', + title: 'Link/action', + description: 'You can add one separate link if you need. The link will show up at the bottom of the component.', + type: 'array', + of: [{ type: 'linkSelector', title: 'Link' }], + validation: (Rule: Rule) => Rule.max(1), +} diff --git a/sanityv3/schemas/objects/iframeCarousel.tsx b/sanityv3/schemas/objects/iframeCarousel.tsx index 876302a6f..f738d1846 100644 --- a/sanityv3/schemas/objects/iframeCarousel.tsx +++ b/sanityv3/schemas/objects/iframeCarousel.tsx @@ -2,9 +2,18 @@ import { EdsIcon } from '../../icons' import { library_image } from '@equinor/eds-icons' import blocksToText from '../../helpers/blocksToText' import type { Rule } from 'sanity' -import { title, frameTitle, description, cookiePolicy, aspectRatio, url, height } from './iframe/sharedIframeFields' +import { + title, + frameTitle, + description, + cookiePolicy, + aspectRatio, + url, + height, + action, +} from './iframe/sharedIframeFields' -const carouselItemFields = [title, frameTitle, description, cookiePolicy, aspectRatio, url, height] +const carouselItemFields = [title, frameTitle, description, cookiePolicy, aspectRatio, url, height, action] export default { name: 'iframeCarousel', title: 'Horizontal scroll iframe', diff --git a/sanityv3/schemas/objects/imageWithAltAndCaption.tsx b/sanityv3/schemas/objects/imageWithAltAndCaption.tsx index bfe08365f..856f94487 100644 --- a/sanityv3/schemas/objects/imageWithAltAndCaption.tsx +++ b/sanityv3/schemas/objects/imageWithAltAndCaption.tsx @@ -1,6 +1,4 @@ -import React from 'react' import type { ImageWithAlt } from './imageWithAlt' -import { HeroTypes } from '../HeroTypes' export type ImageWithAltAndCaption = { _type: 'imageWithAltAndCaption' @@ -26,13 +24,11 @@ export default { name: 'caption', title: 'Image caption', type: 'string', - hidden: ({ document }: any) => document?.heroType === HeroTypes.FIFTY_FIFTY, }, { name: 'attribution', title: 'Credit', type: 'string', - hidden: ({ document }: any) => document?.heroType === HeroTypes.FIFTY_FIFTY, }, ], preview: { diff --git a/sanityv3/schemas/objects/newsList.tsx b/sanityv3/schemas/objects/newsList.tsx index 1e6919cd0..895ca4179 100644 --- a/sanityv3/schemas/objects/newsList.tsx +++ b/sanityv3/schemas/objects/newsList.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { defaultLanguage } from '../../languages' import { EdsIcon } from '../../icons' import { list } from '@equinor/eds-icons' diff --git a/sanityv3/schemas/objects/positionedInlineImage.tsx b/sanityv3/schemas/objects/positionedInlineImage.tsx index b7a556a67..fa7aff63e 100644 --- a/sanityv3/schemas/objects/positionedInlineImage.tsx +++ b/sanityv3/schemas/objects/positionedInlineImage.tsx @@ -1,5 +1,4 @@ /* eslint-disable import/no-unresolved */ -import React from 'react' import { InlineImageFullWidth, InlineImageLeftAlign, InlineImageRightAlign } from '../../icons' import { RadioIconSelector } from '../components' import type { ImageWithAlt } from './imageWithAlt' diff --git a/sanityv3/schemas/objects/promoTileArray.tsx b/sanityv3/schemas/objects/promoTileArray.tsx index ce6129d02..c8e91e054 100644 --- a/sanityv3/schemas/objects/promoTileArray.tsx +++ b/sanityv3/schemas/objects/promoTileArray.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { collection_2 } from '@equinor/eds-icons' import { EdsIcon } from '../../icons' import type { PortableTextBlock, Rule } from 'sanity' diff --git a/sanityv3/schemas/objects/promotion/promoteMagazine.tsx b/sanityv3/schemas/objects/promotion/promoteMagazine.tsx index d2260d3fd..c7bfc86f9 100644 --- a/sanityv3/schemas/objects/promotion/promoteMagazine.tsx +++ b/sanityv3/schemas/objects/promotion/promoteMagazine.tsx @@ -1,8 +1,7 @@ import { library_books } from '@equinor/eds-icons' -import type { Rule, Reference, ValidationContext } from 'sanity' +import type { Rule, Reference } from 'sanity' import { filterMagazineByLang } from '../../../helpers/referenceFilters' import { EdsIcon } from '../../../icons' -import { Flags } from '../../../src/lib/datasetHelpers' export type MagazinePromotion = { manuallySelectArticles: boolean diff --git a/sanityv3/schemas/objects/promotion/promoteNews.tsx b/sanityv3/schemas/objects/promotion/promoteNews.tsx index efdc607d6..e6f5e605b 100644 --- a/sanityv3/schemas/objects/promotion/promoteNews.tsx +++ b/sanityv3/schemas/objects/promotion/promoteNews.tsx @@ -1,4 +1,3 @@ -import React from 'react' import type { Rule } from 'sanity' import { defaultLanguage } from '../../../languages' import { Flags } from '../../../src/lib/datasetHelpers' diff --git a/sanityv3/schemas/objects/promotion/promotion.tsx b/sanityv3/schemas/objects/promotion/promotion.tsx index 9f348b551..68db697d8 100644 --- a/sanityv3/schemas/objects/promotion/promotion.tsx +++ b/sanityv3/schemas/objects/promotion/promotion.tsx @@ -14,8 +14,7 @@ import { Flags } from '../../../src/lib/datasetHelpers' const horizontalScrollValidation = (context: Promotion): true | ValidationError => { const { promotion, useHorizontalScroll } = context const promo = promotion[0] - const numberOfItems = promo._type === 'promoteTopics' ? promo.references.length : promo.promotedArticles.length - + const numberOfItems = promo._type === 'promoteTopics' ? promo.references?.length : promo.promotedArticles?.length const MIN = 3 const MAX = useHorizontalScroll ? 6 : 3 diff --git a/sanityv3/schemas/objects/titleAndMeta.tsx b/sanityv3/schemas/objects/titleAndMeta.tsx index a563934e0..1ddcca70f 100644 --- a/sanityv3/schemas/objects/titleAndMeta.tsx +++ b/sanityv3/schemas/objects/titleAndMeta.tsx @@ -1,8 +1,7 @@ import { useCallback } from 'react' import { Stack, TextArea, Label } from '@sanity/ui' -import { set, unset } from 'sanity' +import { set, unset, Rule } from 'sanity' import { SchemaType } from '../../types' -import { Rule } from 'sanity' export const TextAreaWithChars = (props: any) => { const { elementProps, onChange, value = '' } = props diff --git a/sanityv3/schemas/objects/videoPlayer.tsx b/sanityv3/schemas/objects/videoPlayer.tsx index 219770ea5..4cd28f0ba 100644 --- a/sanityv3/schemas/objects/videoPlayer.tsx +++ b/sanityv3/schemas/objects/videoPlayer.tsx @@ -1,5 +1,3 @@ -import React from 'react' - import { play_circle } from '@equinor/eds-icons' import { EdsIcon } from '../../icons' diff --git a/sanityv3/server.js b/sanityv3/server.js index 70025dd72..b567f50c9 100644 --- a/sanityv3/server.js +++ b/sanityv3/server.js @@ -1,4 +1,5 @@ 'use strict' +/* eslint-disable @typescript-eslint/no-var-requires */ const path = require('path') const express = require('express') diff --git a/sanityv3/src/lib/structure/index.js b/sanityv3/src/lib/structure/index.js index 15605e7e1..47232dd01 100644 --- a/sanityv3/src/lib/structure/index.js +++ b/sanityv3/src/lib/structure/index.js @@ -20,10 +20,10 @@ const LocalNews = (S, context) => Flags.HAS_LOCAL_NEWS && LocalNewsStructure(S, const LandingPage = (S) => Flags.HAS_LANDING_PAGE && LandingPageStructure(S) const Event = (S) => Flags.HAS_EVENT && EventStructure(S) -const ADMIN_ITEMS = (S) => +const ADMIN_ITEMS = (S, context) => [ News(S), - LocalNews(S), + LocalNews(S, context), TopicContent(S), LandingPage(S), Event(S), @@ -31,7 +31,7 @@ const ADMIN_ITEMS = (S) => Misc(S), S.divider(), Homepage(S), - Routes(S), + Routes(S, context), S.divider(), Menu(S), Footer(S), @@ -41,10 +41,10 @@ const ADMIN_ITEMS = (S) => Settings(S), ].filter((e) => e) -const SUB_EDITOR_ITEMS = (S) => +const SUB_EDITOR_ITEMS = (S, context) => [ News(S), - LocalNews(S), + LocalNews(S, context), TopicContent(S), LandingPage(S), Magazine(S), @@ -53,49 +53,32 @@ const SUB_EDITOR_ITEMS = (S) => AssetLibrary(S, context), ].filter((e) => e) -const LOCAL_NEWS_EDITOR_ITEMS = (S) => [LocalNews(S)].filter((e) => e) +const LOCAL_NEWS_EDITOR_ITEMS = (S, context) => [LocalNews(S, context)].filter((e) => e) + +/** + * Datasets are not taken into consideration in order to simplify logic. + * This is used only to hide/show items in the UI. + * + * Drawback scenario: + * An user with "Editor" access to the "brazil" dataset, and "Sub Editor" to the "argentina" dataset + * will get ADMIN_ITEMS menu structure for both studios. This is acceptable because it is just + * the UI menu items, the content is properly hidden and handled at sanity.io -> Access tab. + */ const getItems = (S, context) => { - /** - * Datasets are not taken into consideration in order to simplify logic. - * This is used only to hide/show items in the UI. - * - * Drawback scenario: - * An user with "Editor" access to the "brazil" dataset, and "Sub Editor" to the "argentina" dataset - * will get ADMIN_ITEMS menu structure for both studios. This is acceptable because it is just - * the UI menu items, the content is properly hidden and handled at sanity.io -> Access tab. - */ const userRoles = getCurrentUserRoles(context) const isAdmin = userRoles.some( (role) => role.startsWith('editor') || role === 'administrator' || role === 'developer', ) const isSubEditor = userRoles.some((role) => role.startsWith('sub-editor')) const isLocalNewsEditor = userRoles.some((role) => role.startsWith('local-news-editor')) - return [ - News(S), - LocalNews(S, context), - TopicContent(S), - LandingPage(S), - Event(S), - Magazine(S), - Misc(S), - S.divider(), - Homepage(S), - Routes(S, context), - S.divider(), - Menu(S), - Footer(S), - S.divider(), - AssetLibrary(S, context), - S.divider(), - Settings(S), - ].filter((e) => e) + if (isAdmin) { - return ADMIN_ITEMS(S) + return ADMIN_ITEMS(S, context) } else if (isSubEditor) { - return SUB_EDITOR_ITEMS(S) + return SUB_EDITOR_ITEMS(S, context) } else if (isLocalNewsEditor) { - return LOCAL_NEWS_EDITOR_ITEMS(S) + return LOCAL_NEWS_EDITOR_ITEMS(S, context) } else { return [] } diff --git a/sanityv3/src/lib/structure/items/ErrorPages.js b/sanityv3/src/lib/structure/items/ErrorPages.js index 79b3034d4..60fd928e4 100644 --- a/sanityv3/src/lib/structure/items/ErrorPages.js +++ b/sanityv3/src/lib/structure/items/ErrorPages.js @@ -1,6 +1,6 @@ import { FileIcon } from '../../../../icons' -export const ErrorPages = [ +export const ErrorPages = (S) => [ S.listItem() .title('404 - Page not found') .icon(FileIcon) diff --git a/sanityv3/src/previews/Preview.tsx b/sanityv3/src/previews/Preview.tsx index 04cbb30e8..1f25ac394 100644 --- a/sanityv3/src/previews/Preview.tsx +++ b/sanityv3/src/previews/Preview.tsx @@ -1,4 +1,3 @@ -import React from 'react' import resolveProductionUrl from '../../resolveProductionUrl' import styled from 'styled-components' import { dataset } from '../lib/datasetHelpers' diff --git a/sanityv3/src/previews/PreviewWrapper.tsx b/sanityv3/src/previews/PreviewWrapper.tsx index 1b4c5881f..fa6e91928 100644 --- a/sanityv3/src/previews/PreviewWrapper.tsx +++ b/sanityv3/src/previews/PreviewWrapper.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components' -import React from 'react' +import { ReactNode } from 'react' import { useToast, Button, Tooltip, Box, Text } from '@sanity/ui' import { CopyIcon } from '@sanity/icons' @@ -19,7 +19,7 @@ const StyledButton = styled(Button)` type Props = { src: string - children: React.ReactNode + children: ReactNode shareable?: boolean } diff --git a/sanityv3/structure/BlogStructure.ts b/sanityv3/structure/BlogStructure.ts deleted file mode 100644 index f0faa91c8..000000000 --- a/sanityv3/structure/BlogStructure.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { useFlag } from '@studio/helpers/useFlag' -import { Outlined } from '@ui/Icons' -import { StructureBuilder } from 'sanity/desk' -import { Flags } from 'settings' - -const ArticleStructure = (S: StructureBuilder) => - S.listItem() - .icon(Outlined.DocumentTextIcon) - .title('Articles') - .schemaType('article') - .child(S.documentTypeList('article').title('Articles')) - -const AuthorStructure = (S: StructureBuilder) => - useFlag( - Flags.HAS_AUTHOR, - Flags.HAS_AUTHOR && - S.listItem() - .icon(Outlined.IdentificationIcon) - .title('Authors') - .schemaType('author') - .child(S.documentTypeList('author').title('Authors')), - ) - -const CategoryStructure = (S: StructureBuilder) => - S.listItem() - .icon(Outlined.TagIcon) - .title('Categories') - .schemaType('category') - .child(S.documentTypeList('category').title('Categories')) - -const HomeStructure = (S: StructureBuilder) => - S.listItem() - .icon(Outlined.HomeModernIcon) - .title('Home') - .schemaType('blogHome') - .child(S.document().schemaType('blogHome').documentId('blogHome')) - -const BlogStructure = (S: StructureBuilder) => - S.listItem() - .title('Blog') - .icon(Outlined.NewspaperIcon) - .child( - S.list() - .id('blog') - .title('Blog') - .items([ - ArticleStructure(S), - ...AuthorStructure(S), - CategoryStructure(S), - HomeStructure(S), - ]), - ) - -export default BlogStructure diff --git a/sanityv3/structure/PageStructure.ts b/sanityv3/structure/PageStructure.ts deleted file mode 100644 index 3174e6c55..000000000 --- a/sanityv3/structure/PageStructure.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Outlined } from '@ui/Icons' -import { StructureBuilder } from 'sanity/desk' - -const PageStructure = (S: StructureBuilder) => - S.listItem() - .title('Pages') - .icon(Outlined.RectangleGroupIcon) - .child(S.documentTypeList('article').title('Pages')) - -export default PageStructure diff --git a/sanityv3/structure/SettingsStructure.ts b/sanityv3/structure/SettingsStructure.ts deleted file mode 100644 index 9f821048a..000000000 --- a/sanityv3/structure/SettingsStructure.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Outlined } from '@ui/Icons' -import { StructureBuilder } from 'sanity/desk' - -const SettingsStructure = (S: StructureBuilder) => - S.listItem() - .title('Settings') - .icon(Outlined.WrenchIcon) - .child(S.document().schemaType('siteSettings').documentId('siteSettings')) - -export default SettingsStructure diff --git a/sanityv3/structure/index.ts b/sanityv3/structure/index.ts deleted file mode 100644 index 0b1687496..000000000 --- a/sanityv3/structure/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { StructureBuilder } from 'sanity/desk' -import BlogStructure from './BlogStructure' -import PageStructure from './PageStructure' -import SettingsStructure from './SettingsStructure' - -export default (S: StructureBuilder) => - S.list() - .title('Content') - .items([ - BlogStructure(S), - PageStructure(S), - S.divider(), - SettingsStructure(S), - ]) diff --git a/studio/schemas/objects/iframe.tsx b/studio/schemas/objects/iframe.tsx index 74ab5913d..3ccccd824 100644 --- a/studio/schemas/objects/iframe.tsx +++ b/studio/schemas/objects/iframe.tsx @@ -10,7 +10,16 @@ import CharCounterEditor from '../components/CharCounterEditor' import blocksToText from '../../helpers/blocksToText' import type { Rule, Block } from '@sanity/types' import type { ColorListValue } from 'sanity-plugin-color-list' -import { title, frameTitle, description, cookiePolicy, aspectRatio, url, height } from './iframe/sharedIframeFields' +import { + title, + frameTitle, + description, + cookiePolicy, + aspectRatio, + url, + height, + action, +} from './iframe/sharedIframeFields' const ingressContentType = configureBlockContent({ h1: false, @@ -69,14 +78,7 @@ export default { aspectRatio, height, description, - { - name: 'action', - title: 'Link/action', - description: 'You can add one separate link if you need. The link will show up at the bottom of the component.', - type: 'array', - of: [{ type: 'linkSelector', title: 'Link' }], - validation: (Rule: Rule) => Rule.max(1), - }, + action, { title: 'Background', description: 'Pick a colour for the background. Default is white.', diff --git a/studio/schemas/objects/iframe/sharedIframeFields.tsx b/studio/schemas/objects/iframe/sharedIframeFields.tsx index 18dd8899b..b7b19d7f7 100644 --- a/studio/schemas/objects/iframe/sharedIframeFields.tsx +++ b/studio/schemas/objects/iframe/sharedIframeFields.tsx @@ -106,3 +106,12 @@ export const description = { inputComponent: CharCounterEditor, of: [descriptionContentType], } + +export const action = { + name: 'action', + title: 'Link/action', + description: 'You can add one separate link if you need. The link will show up at the bottom of the component.', + type: 'array', + of: [{ type: 'linkSelector', title: 'Link' }], + validation: (Rule: Rule) => Rule.max(1), +} diff --git a/studio/schemas/objects/iframeCarousel.tsx b/studio/schemas/objects/iframeCarousel.tsx index 42f2435b3..70a550306 100644 --- a/studio/schemas/objects/iframeCarousel.tsx +++ b/studio/schemas/objects/iframeCarousel.tsx @@ -3,9 +3,18 @@ import { EdsIcon } from '../../icons' import { library_image } from '@equinor/eds-icons' import blocksToText from '../../helpers/blocksToText' import type { Rule } from '@sanity/types' -import { title, frameTitle, description, cookiePolicy, aspectRatio, url, height } from './iframe/sharedIframeFields' +import { + title, + frameTitle, + description, + cookiePolicy, + aspectRatio, + url, + height, + action, +} from './iframe/sharedIframeFields' -const carouselItemFields = [title, frameTitle, description, cookiePolicy, aspectRatio, url, height] +const carouselItemFields = [title, frameTitle, description, cookiePolicy, aspectRatio, url, height, action] export default { name: 'iframeCarousel', title: 'Horizontal scroll iframe', diff --git a/studio/src/lib/structure/items/ErrorPages.js b/studio/src/lib/structure/items/ErrorPages.js index 528ec3d1f..60fd928e4 100644 --- a/studio/src/lib/structure/items/ErrorPages.js +++ b/studio/src/lib/structure/items/ErrorPages.js @@ -1,7 +1,6 @@ -import S from '@sanity/desk-tool/structure-builder' import { FileIcon } from '../../../../icons' -export const ErrorPages = [ +export const ErrorPages = (S) => [ S.listItem() .title('404 - Page not found') .icon(FileIcon) diff --git a/web/components/src/Backgrounds/BackgroundContainer.tsx b/web/components/src/Backgrounds/BackgroundContainer.tsx index d0d281e7b..3d42bf8e7 100644 --- a/web/components/src/Backgrounds/BackgroundContainer.tsx +++ b/web/components/src/Backgrounds/BackgroundContainer.tsx @@ -42,6 +42,39 @@ export const getBackgroundByColorName = (name: BackgroundColours) => { return backgrounds[styleVariant] } +export const getHexFromColorName = (color?: BackgroundColours) => { + switch (color) { + case 'Moss Green': + return '#a8cfd1' + case 'Moss Green Light': + return '#f2f7f8' + case 'Spruce Wood': + return '#ffede0' + case 'Mist Blue': + return '#d7ebf4' + case 'Slate Blue': + return '#182530' + case 'White': + default: + return '#ffffff' + } +} + +export function getFontColorForBg(bgColor?: BackgroundColours): string { + const hex = getHexFromColorName(bgColor) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const [r, g, b] = hex + .replace(/^#/, '') + .match(/.{2}/g)! + .map((h) => parseInt(h, 16) / 255) + const luminance = [0.2126, 0.7152, 0.0722].reduce( + (acc, v, i) => + acc + v * ([r, g, b][i] <= 0.03928 ? [r, g, b][i] / 12.92 : Math.pow(([r, g, b][i] + 0.055) / 1.055, 2.4)), + 0, + ) + return luminance > 0.5 ? 'var(--default-text)' : 'var(--inverted-text)' +} + export const BackgroundContainer = forwardRef(function BackgroundContainer( { background = 'White', disableContainerWrapper = false, style, children, ...rest }, ref, diff --git a/web/components/src/Card/Card.stories.tsx b/web/components/src/Card/Card.stories.tsx index 81fe55c3d..e7af0fdee 100644 --- a/web/components/src/Card/Card.stories.tsx +++ b/web/components/src/Card/Card.stories.tsx @@ -55,7 +55,7 @@ Default.storyName = 'Default' export const NewsCard: StoryFn = () => ( - + @@ -78,7 +78,7 @@ export const NewsCard: StoryFn = () => ( - + diff --git a/web/components/src/Card/Card.tsx b/web/components/src/Card/Card.tsx index 9dcf37589..7549254f9 100644 --- a/web/components/src/Card/Card.tsx +++ b/web/components/src/Card/Card.tsx @@ -3,6 +3,7 @@ import styled from 'styled-components' import { outlineTemplate, Tokens } from '@utils' import { LandscapeCard } from './LandscapeCard' import { PortraitCard } from './PortraitCard' +import { default as NextLink } from 'next/link' const { outline } = Tokens @@ -13,7 +14,7 @@ export type CardProps = { orientation?: 'landscape' | 'portrait' } & HTMLAttributes -export const CardLink = styled.a` +export const CardLink = styled(NextLink)` text-decoration: none; color: inherit; &:hover { diff --git a/web/components/src/Link/ButtonLink.tsx b/web/components/src/Link/ButtonLink.tsx index a0bf87e29..e59fac164 100644 --- a/web/components/src/Link/ButtonLink.tsx +++ b/web/components/src/Link/ButtonLink.tsx @@ -1,6 +1,7 @@ import { forwardRef } from 'react' import { Button, ButtonProps } from '@equinor/eds-core-react' import styled from 'styled-components' +import { default as NextLink } from 'next/link' const StyledButtonLink = styled(Button)` --eds_button__height: auto; @@ -26,15 +27,17 @@ const StyledButtonLink = styled(Button)` } ` -export type ButtonLinkProps = ButtonProps +export type ButtonLinkProps = { locale?: string } & ButtonProps export const ButtonLink = forwardRef(function ButtonLink( - { children, ...rest }, + { children, href = '', locale, ...rest }, ref, ) { return ( - - {children} - + + + {children} + + ) }) diff --git a/web/components/src/Link/Link.tsx b/web/components/src/Link/Link.tsx index 3b3716040..292c6bec9 100644 --- a/web/components/src/Link/Link.tsx +++ b/web/components/src/Link/Link.tsx @@ -6,14 +6,15 @@ import { arrow_forward, external_link, arrow_down } from '@equinor/eds-icons' import styled from 'styled-components' import { outlineTemplate, Tokens } from '@utils' import type { LinkType } from '../../../types/types' +import { default as NextLink } from 'next/link' const { outline } = Tokens -export const BaseLink = styled.a` +export const BaseLink = styled(NextLink)` display: inline-flex; align-items: center; color: var(--slate-blue-95); - text-decoration: var(--textDecoration); + text-decoration: none; &[data-focus-visible-added]:focus { ${outlineTemplate(outline)} } @@ -114,21 +115,23 @@ export type LinkProps = { type?: LinkType /** Some links don't have an underline, like the menu links */ underline?: boolean + /** The locale for the link, required for internal URLs */ + locale?: string } & AnchorHTMLAttributes export const Link = forwardRef(function Link( - { children, variant = 'regular', type = 'internalUrl', underline = true, style, ...rest }, + { children, variant = 'regular', type = 'internalUrl', underline = true, style, href = '', ...rest }, ref, ) { if (variant === 'contentLink') { return ( - + {children} ) } else if (variant === 'readMore') { return ( - + {children} ) @@ -138,6 +141,7 @@ export const Link = forwardRef(function Link( return ( - - {/* @TODO: Language string for Details */} - {details} - + {/* @TODO: Language string for Details */} + + {details} + ) } diff --git a/web/pageComponents/cards/FeaturedEventCard.tsx b/web/pageComponents/cards/FeaturedEventCard.tsx index 64e9a9317..18217894a 100644 --- a/web/pageComponents/cards/FeaturedEventCard.tsx +++ b/web/pageComponents/cards/FeaturedEventCard.tsx @@ -1,5 +1,4 @@ import { Card, FormattedDate, FormattedTime } from '@components' -import { default as NextLink } from 'next/link' import { FormattedMessage } from 'react-intl' import styled from 'styled-components' import { toPlainText } from '@portabletext/react' @@ -59,54 +58,51 @@ const FeaturedEventCard = ({ data, fitToContent = false, ...rest }: FeaturedEven const plainTitle = title ? toPlainText(title as PortableTextBlock[]) : '' return ( - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - - -
- {plainTitle} -
- - {start && ( - - - - )} - {location && ( - -
- {location} -
-
- )} - {start && end ? ( - - - - - - - ) : ( - - - - - - - )} -
- - - -
-
-
+ + + +
+ {plainTitle} +
+ + {start && ( + + + + )} + {location && ( + +
+ {location} +
+
+ )} + {start && end ? ( + + + - + + + ) : ( + + + + + + + )} +
+ + + +
+
) } diff --git a/web/pageComponents/cards/MagazineCard.tsx b/web/pageComponents/cards/MagazineCard.tsx index 495c9ce04..1c8b4224e 100644 --- a/web/pageComponents/cards/MagazineCard.tsx +++ b/web/pageComponents/cards/MagazineCard.tsx @@ -1,5 +1,4 @@ import { Card } from '@components' -import { default as NextLink } from 'next/link' import { CSSProperties } from 'react' import styled from 'styled-components' import { Flags } from '../../common/helpers/datasetHelpers' @@ -72,35 +71,32 @@ const MagazineCard = ({ data, fitToContent = false, ...rest }: MagazineCardProp) if (!thumbnail) return null return ( - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - - {thumbnail} -
- - <>{title}</> - -
- - - - {tags && tags.length > 0 && ( - - {tags.map((tag: string) => ( - {tag} - ))} - - )} -
-
-
+ + + {thumbnail} +
+ + <>{title}</> + +
+ + + + {tags && tags.length > 0 && ( + + {tags.map((tag: string) => ( + {tag} + ))} + + )} +
+
) } diff --git a/web/pageComponents/cards/NewsCard.tsx b/web/pageComponents/cards/NewsCard.tsx index 915a7f4d5..0b2901348 100644 --- a/web/pageComponents/cards/NewsCard.tsx +++ b/web/pageComponents/cards/NewsCard.tsx @@ -1,5 +1,4 @@ import { Card, FormattedDate } from '@components' -import { default as NextLink } from 'next/link' import { CSSProperties } from 'react' import styled from 'styled-components' import type { CardData } from '../../types/types' @@ -53,62 +52,59 @@ const NewsCard = ({ data, fitToContent = false, ...rest }: NewsCardProp) => { if (!heroImage) return null return ( - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - - - {heroImage && ( - + + + {heroImage && ( + + )} + +
+ {publishDateTime && ( + + - )} - -
- {publishDateTime && ( - - - - )} - - <>{title} - -
- {ingress && ( - - { - return {children} - }, - smallText: ({ children }) => { - return {children} - }, - }, - }} - > - +
)} - - - - - - + + <>{title} + +
+ {ingress && ( + + { + return {children} + }, + smallText: ({ children }) => { + return {children} + }, + }, + }} + > + + )} + + + +
+
) } diff --git a/web/pageComponents/cards/PeopleCard/CV.tsx b/web/pageComponents/cards/PeopleCard/CV.tsx index 80c4cee49..d8449f649 100644 --- a/web/pageComponents/cards/PeopleCard/CV.tsx +++ b/web/pageComponents/cards/PeopleCard/CV.tsx @@ -1,4 +1,3 @@ -import { default as NextLink } from 'next/link' import { ButtonLink } from '@components' import type { LinkData } from '../../../types/types' import { getUrlFromAction } from '../../../common/helpers/getUrlFromAction' @@ -14,17 +13,9 @@ const CV = ({ data }: CVProps) => { const url = getUrlFromAction(data) || '' return ( - <> - {type === 'internalUrl' ? ( - - {label} - - ) : ( - - {label} - - )} - + + {label} + ) } diff --git a/web/pageComponents/cards/SimpleCard.tsx b/web/pageComponents/cards/SimpleCard.tsx index 854c5ba0c..45bbb53ce 100644 --- a/web/pageComponents/cards/SimpleCard.tsx +++ b/web/pageComponents/cards/SimpleCard.tsx @@ -1,4 +1,3 @@ -import { default as NextLink } from 'next/link' import { CSSProperties } from 'react' import styled from 'styled-components' import Image, { Ratios } from '../shared/SanityImage' @@ -51,40 +50,38 @@ function getLink(linkData: MenuLinkData, label: string) { const SimpleCard = ({ data }: SimpleCardData) => { const { id, label, image } = data return ( - - - - - {/* If this i static content, we don't have an image so we will just add an empty placeholder instead */} - {image ? ( - - ) : ( - - - - )} - -
- {label} -
- - - -
-
-
+ + + + {/* If this i static content, we don't have an image so we will just add an empty placeholder instead */} + {image ? ( + + ) : ( + + + + )} + +
+ {label} +
+ + + +
+
) } diff --git a/web/pageComponents/cards/TopicPageCard.tsx b/web/pageComponents/cards/TopicPageCard.tsx index 88243f125..141e9a63b 100644 --- a/web/pageComponents/cards/TopicPageCard.tsx +++ b/web/pageComponents/cards/TopicPageCard.tsx @@ -1,6 +1,5 @@ import { Card } from '@components' import { toPlainText } from '@portabletext/react' -import { default as NextLink } from 'next/link' import { CSSProperties } from 'react' import styled from 'styled-components' import Image, { Ratios } from '../shared/SanityImage' @@ -35,40 +34,37 @@ const TopicPageCard = ({ data, fitToContent = false, ...rest }: TopicPageCardPro const pageTitle = title ? toPlainText(title as PortableTextBlock[]) : '' return ( - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - - - {thumbnail && ( - - )} - -
- {pageTitle} -
- {ingress && ( - - - + + + + {thumbnail && ( + )} - - - - - -
+ +
+ {pageTitle} +
+ {ingress && ( + + + + )} + + + + + ) } diff --git a/web/pageComponents/icons/index.ts b/web/pageComponents/icons/index.ts new file mode 100644 index 000000000..b6a524254 --- /dev/null +++ b/web/pageComponents/icons/index.ts @@ -0,0 +1,5 @@ +export { default as Facebook } from './Facebook' +export { default as Instagram } from './Instagram' +export { default as Linkedin } from './Linkedin' +export { default as Twitter } from './Twitter' +export { default as Youtube } from './Youtube' diff --git a/web/pageComponents/pageTemplates/newsroom/Hit.tsx b/web/pageComponents/pageTemplates/newsroom/Hit.tsx index 5274e39be..1029a2583 100644 --- a/web/pageComponents/pageTemplates/newsroom/Hit.tsx +++ b/web/pageComponents/pageTemplates/newsroom/Hit.tsx @@ -7,7 +7,7 @@ import { PortableTextBlock } from '@portabletext/types' const { outline } = Tokens -const StyledHitLink = styled.a` +const StyledHitLink = styled(NextLink)` padding: var(--space-small) 0; display: block; color: var(--default-text); @@ -47,17 +47,15 @@ const Hit = ({ hit }: { hit: any }) => { const pageTitle = Array.isArray(hit.pageTitle) ? toPlainText(hit.pageTitle as PortableTextBlock[]) : hit.pageTitle return ( - - -
- {hit.publishDateTime && } - - {pageTitle} - - {/* {hit.text} */} -
-
-
+ +
+ {hit.publishDateTime && } + + {pageTitle} + + {/* {hit.text} */} +
+
) } diff --git a/web/pageComponents/pageTemplates/shared/SharedTitle.tsx b/web/pageComponents/pageTemplates/shared/SharedTitle.tsx index af273a11c..64c1dd855 100644 --- a/web/pageComponents/pageTemplates/shared/SharedTitle.tsx +++ b/web/pageComponents/pageTemplates/shared/SharedTitle.tsx @@ -2,7 +2,8 @@ import styled from 'styled-components' import TitleText from '../../shared/portableText/TitleText' import type { PortableTextBlock } from '@portabletext/types' import type { TitleStyles } from '../../../lib/hooks/useSharedTitleStyles' -import { getBackgroundByColorName } from '@components' +import type { BackgroundColours } from 'types' +import { getBackgroundByColorName, getFontColorForBg } from '@components' type SharedTitleProps = { title: PortableTextBlock[] @@ -29,16 +30,17 @@ const TitleWrapper = styled.div<{ styles?: TitleStyles }>` }} ` -const StyledHeading = styled(TitleText)` +const StyledHeading = styled(TitleText)<{ $bgColor?: BackgroundColours }>` max-width: 1186px; /* 1920 - (2 * 367) */ margin-left: auto; margin-right: auto; + color: ${({ $bgColor }) => getFontColorForBg($bgColor)}; ` const SharedTitle = ({ title, styles }: SharedTitleProps) => { return ( - + ) } diff --git a/web/pageComponents/search/EventHit.tsx b/web/pageComponents/search/EventHit.tsx index 3f9a1727e..3b3f56ba1 100644 --- a/web/pageComponents/search/EventHit.tsx +++ b/web/pageComponents/search/EventHit.tsx @@ -1,5 +1,4 @@ import { Highlight } from './Highlight' -import { default as NextLink } from 'next/link' import getConfig from 'next/config' import styled from 'styled-components' import type { Hit as AlgoliaHit } from '@algolia/client-search' @@ -47,21 +46,19 @@ const EventHit = ({ hit }: HitProps) => { // @TODO: A more generic Hit component for more than events. Or multiple components??? return (
- - - {eventDate && } - - - - - - - - - - {fullUrl} - - + + {eventDate && } + + + + + + + + + + {fullUrl} +
) } diff --git a/web/pageComponents/search/MagazineHit.tsx b/web/pageComponents/search/MagazineHit.tsx index ea9726646..e146e265e 100644 --- a/web/pageComponents/search/MagazineHit.tsx +++ b/web/pageComponents/search/MagazineHit.tsx @@ -1,5 +1,4 @@ import { Highlight } from './Highlight' -import { default as NextLink } from 'next/link' import styled from 'styled-components' import type { Hit as AlgoliaHit } from '@algolia/client-search' import getConfig from 'next/config' @@ -53,29 +52,27 @@ const MagazineHit = ({ hit }: HitProps) => { return (
- - - - - - {hit.title && ( - - - - )} - {hit.ingress && ( - - - - )} - {hit.text && ( - - - - )} - {fullUrl} - - + + + + + {hit.title && ( + + + + )} + {hit.ingress && ( + + + + )} + {hit.text && ( + + + + )} + {fullUrl} +
) } diff --git a/web/pageComponents/search/NewsHit.tsx b/web/pageComponents/search/NewsHit.tsx index fdefab58d..707ebbafb 100644 --- a/web/pageComponents/search/NewsHit.tsx +++ b/web/pageComponents/search/NewsHit.tsx @@ -1,5 +1,4 @@ import { Highlight } from './Highlight' -import { default as NextLink } from 'next/link' import styled from 'styled-components' import type { Hit as AlgoliaHit } from '@algolia/client-search' import getConfig from 'next/config' @@ -60,25 +59,23 @@ const NewsHit = ({ hit }: HitProps) => { return (
- - - {hit.publishDateTime && } - - - - {hit.ingress && ( - - - - )} - {hit.text && ( - - - - )} - {fullUrl} - - + + {hit.publishDateTime && } + + + + {hit.ingress && ( + + + + )} + {hit.text && ( + + + + )} + {fullUrl} +
) } diff --git a/web/pageComponents/search/TopicHit.tsx b/web/pageComponents/search/TopicHit.tsx index 0073596bf..c1a574ea8 100644 --- a/web/pageComponents/search/TopicHit.tsx +++ b/web/pageComponents/search/TopicHit.tsx @@ -1,5 +1,4 @@ import { Highlight } from './Highlight' -import { default as NextLink } from 'next/link' import styled from 'styled-components' import type { Hit as AlgoliaHit } from '@algolia/client-search' import getConfig from 'next/config' @@ -38,29 +37,27 @@ const TopicHit = ({ hit }: HitProps) => { // @TODO: A more generic Hit component for more than events. Or multiple components??? return (
- - - - - - {hit.title && ( - - - - )} - {hit.ingress && ( - - - - )} - {hit.text && ( - - - - )} - {fullUrl} - - + + + + + {hit.title && ( + + + + )} + {hit.ingress && ( + + + + )} + {hit.text && ( + + + + )} + {fullUrl} +
) } diff --git a/web/pageComponents/search/hit/HitLink.tsx b/web/pageComponents/search/hit/HitLink.tsx index 44c4893e5..15fadaeb8 100644 --- a/web/pageComponents/search/hit/HitLink.tsx +++ b/web/pageComponents/search/hit/HitLink.tsx @@ -1,11 +1,12 @@ import styled from 'styled-components' +import { default as NextLink } from 'next/link' // This is just the shared styles and not the // component itself. This is because we had some issues with // Next.js and error message in the console. When we tried the // suggested workaround, next/link didn't work // properly with client side navigation using forwardRef. See issue #892 -export const StyledHitLink = styled.a` +export const StyledHitLink = styled(NextLink)` padding: var(--space-medium) 0; display: block; color: var(--inverted-text); diff --git a/web/pageComponents/shared/ButtonLink.tsx b/web/pageComponents/shared/ButtonLink.tsx index 436550207..7f4a88367 100644 --- a/web/pageComponents/shared/ButtonLink.tsx +++ b/web/pageComponents/shared/ButtonLink.tsx @@ -22,23 +22,18 @@ export const ButtonLink = ({ action, children, ...rest }: Props) => { if (type === 'internalUrl') { const locale = getLocaleFromName(action.link?.lang) return ( - + <> {children || ( - + {label} )} - + ) } return children ? ( - )} - > + )}> {children} ) : ( diff --git a/web/pageComponents/shared/Carousel.tsx b/web/pageComponents/shared/Carousel.tsx index ff1a8d36b..6dcf7077a 100644 --- a/web/pageComponents/shared/Carousel.tsx +++ b/web/pageComponents/shared/Carousel.tsx @@ -3,6 +3,9 @@ import styled from 'styled-components' import { Icon } from '@equinor/eds-core-react' import { chevron_left, chevron_right } from '@equinor/eds-icons' import { usePrefersReducedMotion } from '../../common/hooks/usePrefersReducedMotion' +import { outlineTemplate, Tokens } from '@utils' + +const { outline } = Tokens const StyledButton = styled.button` display: flex; @@ -32,6 +35,9 @@ const StyledButton = styled.button` background-color: var(--energy-red-100); outline: transparent; } + &[data-focus-visible-added]:focus { + ${outlineTemplate(outline)} + } @media (min-width: 520px) { min-height: 32px; @@ -66,8 +72,8 @@ const StyledRightButton = styled(StyledButton)` ` const Container = styled.div` - padding: var(--iframe-innerPadding, 0 var(--layout-paddingHorizontal-small)); - max-width: var(--iframe-maxWidth, var(--maxViewportWidth)); + padding: 0 var(--layout-paddingHorizontal-small); + max-width: var(--maxViewportWidth); margin: auto; ` diff --git a/web/pageComponents/shared/Footer.tsx b/web/pageComponents/shared/Footer.tsx index 5bcd02c17..3fae08049 100644 --- a/web/pageComponents/shared/Footer.tsx +++ b/web/pageComponents/shared/Footer.tsx @@ -1,15 +1,8 @@ import styled from 'styled-components' -import { Link } from '@components' import { forwardRef } from 'react' -import { Typography } from '@equinor/eds-core-react' -import NextLink from 'next/link' -import Facebook from '../icons/Facebook' -import Instagram from '../icons/Instagram' -import Linkedin from '../icons/Linkedin' -import Twitter from '../icons/Twitter' -import Youtube from '../icons/Youtube' - +import { Facebook, Instagram, Linkedin, Twitter, Youtube } from '../icons' import type { FooterLinkData, SomeType, FooterColumns } from '../../types/types' +import { default as NextLink } from 'next/link' const StyledFooter = styled.footer` min-height: var(--space-4xLarge); @@ -18,6 +11,7 @@ const StyledFooter = styled.footer` background-color: var(--slate-blue-95); padding: var(--space-medium) 0; ` + const FooterTop = styled.div` display: flex; flex-direction: row; @@ -30,6 +24,7 @@ const FooterTop = styled.div` flex-direction: column; } ` + const LinkHeader = styled.h3` font-size: var(--typeScale-2); color: var(--white-100); @@ -37,6 +32,7 @@ const LinkHeader = styled.h3` font-weight: var(--fontWeight-medium); line-height: var(--lineHeight-1); ` + const LinkWrapper = styled.section` display: flex; flex-direction: column; @@ -59,13 +55,14 @@ const LinksList = styled.div` } ` -const FooterLink = styled(Link)` +const FooterLink = styled(NextLink)` font-size: var(--typeScale-05); padding: var(--space-xSmall) 0; color: var(--white-100); text-decoration: none; display: flex; flex-direction: row; + align-items: center; height: var(--space-xLarge); @media (hover: hover) and (pointer: fine) { &:hover { @@ -112,30 +109,22 @@ const SomeIcon = styled.span` ` function getSomeSvg(someType: SomeType) { - switch (someType) { - case 'facebook': - return - case 'instagram': - return - case 'linkedin': - return - case 'twitter': - return - case 'youtube': - return - default: - console.warn('Unable to get social icon for footer: Unknown SoMe type passed') + const iconMap = { + facebook: , + instagram: , + linkedin: , + twitter: , + youtube: , } + + if (!(someType in iconMap)) console.warn('Unable to get social icon for footer: Unknown SoMe type passed') + + return iconMap[someType] || null } function getLink(linkData: FooterLinkData) { - // Fallback to home page, if this happens it is an error somewhere - // Sanity should take care of the validation here, and this is temp. until - // the static pages are migrated {link.image && } - if (!linkData) return 'something-wrong' - const { link } = linkData - - return (link && link.slug) || '/' + const { link } = linkData || {} + return link?.slug ?? '/' } type FooterProps = { @@ -143,44 +132,30 @@ type FooterProps = { } const Footer = forwardRef(function Footer({ footerData, ...rest }, ref) { - const dt = new Date() return ( - {footerData?.footerColumns?.map(({ header, linkList }) => { - return ( - - {header} - - {linkList?.map((link: FooterLinkData) => { - const { id, type, someType, label, url } = link - if (url) - return ( - - {type === 'someLink' && someType && ( - {getSomeSvg(someType)} - )} - {label} - - ) - return ( - - - {type === 'someLink' && someType && ( - {getSomeSvg(someType)} - )} - {label} - - - ) - })} - - - ) - })} + {footerData?.footerColumns?.map(({ header, linkList }) => ( + + {header} + + {linkList?.map((link: FooterLinkData) => { + const { id, type, someType, label, url } = link + const icon = type === 'someLink' && someType ? getSomeSvg(someType) : null + + return ( + + {icon && {icon}} + {label} + + ) + })} + + + ))} - Copyright {dt.getFullYear()} Equinor ASA + Copyright {new Date().getFullYear()} Equinor ASA ) diff --git a/web/pageComponents/shared/Header.tsx b/web/pageComponents/shared/Header.tsx index a17bdb3d1..dbe433de8 100644 --- a/web/pageComponents/shared/Header.tsx +++ b/web/pageComponents/shared/Header.tsx @@ -3,7 +3,7 @@ import styled, { createGlobalStyle } from 'styled-components' import { CSSProperties } from 'react' import { useRouter } from 'next/router' import { default as NextLink } from 'next/link' -import { Topbar, Link, Button } from '@components' +import { Topbar, Button } from '@components' import { AllSlugsType, LocalizationSwitch } from './LocalizationSwitch' import type { MenuData, SimpleMenuData } from '../../types/types' import SiteMenu from './siteMenu/SiteMenu' @@ -65,7 +65,7 @@ const ControlsContainer = styled.div` } ` -const StyledAllSites = styled(Link)` +const StyledAllSites = styled(NextLink)` cursor: pointer; font-size: var(--typeScale-1); text-decoration: none; @@ -130,11 +130,9 @@ const HeadTags = ({ slugs }: { slugs: AllSlugsType }) => { const AllSites = () => { const allSitesURL = getAllSitesLink('external') return ( - - - - - + + + ) } @@ -173,7 +171,7 @@ const Header = ({ slugs, menuData }: HeaderProps) => { > {hasSearch && ( - + diff --git a/web/pageComponents/shared/Hero/FiftyFiftyHero.tsx b/web/pageComponents/shared/Hero/FiftyFiftyHero.tsx index 5a7963262..878695907 100644 --- a/web/pageComponents/shared/Hero/FiftyFiftyHero.tsx +++ b/web/pageComponents/shared/Hero/FiftyFiftyHero.tsx @@ -1,5 +1,4 @@ import styled from 'styled-components' -import { default as NextLink } from 'next/link' import Image from '../SanityImage' import IngressText from '../portableText/IngressText' import TitleText from '../portableText/TitleText' @@ -70,11 +69,9 @@ const HeroActionLink = ({ action, ...rest }: { action: LinkData }) => { if (action.type === 'internalUrl') { const linkLocale = getLocaleFromName(action.link?.lang) return ( - - - {action.label} - - + + {action.label} + ) } return ( diff --git a/web/pageComponents/shared/HorizontalScroll/HorizontalScroll.tsx b/web/pageComponents/shared/HorizontalScroll/HorizontalScroll.tsx deleted file mode 100644 index b25873fb8..000000000 --- a/web/pageComponents/shared/HorizontalScroll/HorizontalScroll.tsx +++ /dev/null @@ -1,157 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable import/no-unresolved */ -import { Children, ReactNode } from 'react' -import { Swiper, SwiperSlide, type SwiperProps } from 'swiper/react' -import { FreeMode, Scrollbar } from 'swiper' -import styled, { css } from 'styled-components' -import { NavButton } from './Navigation' -import { EdsProvider } from '@equinor/eds-core-react' - -import 'swiper/css' -import 'swiper/css/scrollbar' -import 'swiper/css/free-mode' - -const CardCarouselStyles = css` - --card-maxWidth: 360px; - - padding: 0 var(--space-large); - - @media (max-width: 800px) { - --card-maxWidth: 300px; - } -` - -const IframeCarouselStyles = css` - --card-maxWidth: 480px; - - @media (max-width: 800px) { - --card-maxWidth: 300px; - padding: 0 var(--space-large); - } -` - -const PromoTileStyles = css` - --card-maxWidth: 400px; - padding: 0 var(--space-large); - - @media (max-width: 800px) { - --card-maxWidth: 300px; - padding: 0 var(--space-large); - } -` - -// more to be added -export type CarouselTypes = 'card' | 'iframe' | 'promoTile' - -export type StyledSwiperTypes = { - $carouselType?: CarouselTypes - $items?: number -} & SwiperProps - -const Wrapper = styled.div<{ $items?: number }>` - max-width: calc(var(--card-maxWidth) * ${({ items }: any) => items || '3'} + var(--space-large) * 4); - margin: auto; - - position: relative; - padding: 0 var(--space-xxLarge); - - @media (max-width: 600px) { - padding: 0; - } -` - -const StyledSwiper = styled(Swiper)` - ${({ $carouselType }: any) => { - switch ($carouselType) { - case 'card': - return CardCarouselStyles - case 'iframe': - return IframeCarouselStyles - case 'promoTile': - return PromoTileStyles - default: - return CardCarouselStyles - } - }} - - position: unset; - - .swiper-wrapper { - padding: var(--space-medium) 0 var(--space-xxLarge) 0; - @media (min-width: 800px) { - justify-content: ${({ $items, $carouselType }: any) => - $items ? ($items < 3 && $carouselType === 'iframe' ? 'center' : 'normal') : `normal`}; - } - } - - .swiper-scrollbar { - left: 0; - margin: 0 var(--space-3xLarge); - width: calc(100% - (var(--space-3xLarge) * 2)); - z-index: 1; - } -` - -const StyledSwiperSlide = styled(SwiperSlide)<{ $autoSlideWidth?: boolean }>` - display: flex; - width: ${({ $autoSlideWidth }) => ($autoSlideWidth ? 'auto' : 'var(--card-maxWidth)')}; - height: auto; - margin-right: var(--space-large); - - &:last-of-type { - margin: 0; - } -` - -export type HorizontalScrollProps = { - slidesPerView?: number | 'auto' - type?: CarouselTypes - children: any -} - -export const HorizontalScroll = ({ - slidesPerView = 'auto', - type = 'card', - children, - ...rest -}: HorizontalScrollProps) => { - const numberOfItems = Children.toArray(children).length - - return ( - - - {children} - - - - - - - ) -} - -export type HorizontalScrollItemProps = { - autoSlideWidth?: boolean - children: ReactNode -} - -export const HorizontalScrollItem = ({ autoSlideWidth, children, ...rest }: HorizontalScrollItemProps) => { - return ( - - {children} - - ) -} -// This is required in order for the Swiper library to correctly render -HorizontalScrollItem.displayName = 'SwiperSlide' diff --git a/web/pageComponents/shared/HorizontalScroll/Navigation.tsx b/web/pageComponents/shared/HorizontalScroll/Navigation.tsx deleted file mode 100644 index 035f404e8..000000000 --- a/web/pageComponents/shared/HorizontalScroll/Navigation.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import styled from 'styled-components' -import { Icon } from '@equinor/eds-core-react' -import { Button } from '@components' -import { chevron_right, chevron_left } from '@equinor/eds-icons' -import { useSwiper } from 'swiper/react' -import { useState, useEffect } from 'react' -import type { Swiper } from 'swiper' - -const SharedStyle = styled.div` - height: calc(100% - var(--space-xxLarge)); - position: absolute; - top: 0; - z-index: 1; - display: flex; - align-items: center; - padding: 0 var(--space-small); -` - -const Prev = styled(SharedStyle)` - left: 0; -` - -const Next = styled(SharedStyle)` - right: 0; -` - -const StyledButton = styled(Button)` - background: var(--white-100); - border: 1px solid var(--black-80); - color: var(--black-80); - - &:hover { - background: var(--black-80); - color: var(--white-100); - } - @media (max-width: 425px) { - display: none; - } -` - -type NavigationType = 'prev' | 'next' - -const checkShouldRender = (config: Swiper, type: NavigationType) => { - if (config.isLocked) return false - - if (config.isBeginning == null || config.isEnd == null) return false - - if ((type === 'prev' && config.isBeginning) || (type !== 'prev' && config.isEnd)) return false - - return true -} - -export const NavButton = ({ type }: { type: 'prev' | 'next' }) => { - const swiper = useSwiper() - const [shouldRender, setShouldRender] = useState(false) - - useEffect(() => { - setShouldRender(checkShouldRender(swiper, type)) - - swiper.on('reachBeginning', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.on('reachEnd', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.on('lock', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.on('unlock', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.on('slideChange', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - - return () => { - swiper.off('reachBeginning', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.off('reachEnd', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.off('lock', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.off('unlock', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - swiper.off('slideChange', (swipe) => setShouldRender(checkShouldRender(swipe, type))) - } - }, [swiper, setShouldRender, type]) - - if (!shouldRender) return null - - const isPrev = type === 'prev' - const Wrapper = isPrev ? Prev : Next - - return ( - - (isPrev ? swiper.slidePrev() : swiper.slideNext())}> - - - - ) -} diff --git a/web/pageComponents/shared/HorizontalScroll/index.ts b/web/pageComponents/shared/HorizontalScroll/index.ts deleted file mode 100644 index f50f8635e..000000000 --- a/web/pageComponents/shared/HorizontalScroll/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * This should ideally be in web/components/src/Carousel instead of in web/pageComponents/Carousel - * However, it would seem that the Swiper.js library and Jest do not get along nicely - * See: https://github.com/nolimits4web/swiper/discussions/4969 - * I have tried some of the suggestions in that discussion without much success. Due to the structure of our code, using - * the transformIgnorePatterns causes other issues, since we are exporting all components from web/components/src/index.ts - * and we can't selectively ignore just the export line for the Carousel there - */ - -export * from './HorizontalScroll' diff --git a/web/pageComponents/shared/IframeCarousel/IframeCarousel.tsx b/web/pageComponents/shared/IframeCarousel/IframeCarousel.tsx index a371efa25..08a34d49a 100644 --- a/web/pageComponents/shared/IframeCarousel/IframeCarousel.tsx +++ b/web/pageComponents/shared/IframeCarousel/IframeCarousel.tsx @@ -10,6 +10,7 @@ import 'swiper/css/pagination' import CoreIFrame from '../iframe/IFrame' import RichText from '../portableText/RichText' import { Carousel } from '../../shared/Carousel' +import { ButtonLink } from '../ButtonLink' const Container = styled.div` padding: var(--space-3xLarge) calc(var(--layout-paddingHorizontal-small) - var(--space-xxLarge)); @@ -23,19 +24,31 @@ const Container = styled.div` const Figure = styled.figure` margin: 0; width: 100%; + flex-grow: 1; ` const ItemContainer = styled.div` + min-width: 100%; width: 100%; - min-width: 90%; + display: flex; + flex-direction: column; + + @media (min-width: 1300px) { + min-width: 45%; + /* exactly two items */ + :first-child:nth-last-child(2), + :last-child:nth-child(2) { + min-width: calc(50% - var(--space-medium)); + } + } ` const StyledHeading = styled(TitleText)` - padding: var(--iframe-titlePadding, 0 0 var(--space-large) 0); - text-align: var(--iframe-titleAlign, center); + padding: 0 0 var(--space-large) 0; + text-align: center; ` const StyledItemHeading = styled(TitleText)` - margin: var(--iframe-titlePadding, 0 0 var(--space-large) 0); - text-align: var(--iframe-titleAlign, left); + margin: 0 0 var(--space-large) 0; + text-align: left; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; @@ -43,6 +56,12 @@ const StyledItemHeading = styled(TitleText)` display: -webkit-box; -webkit-box-orient: vertical; ` +const StyledButtonLink = styled(ButtonLink)` + margin-top: var(--space-xLarge); +` +const StyledCoreIframe = styled(CoreIFrame)` + flex-grow: 1; +` type IframeCarouselProps = { data: IframeCarouselData @@ -76,7 +95,7 @@ const IframeCarousel = ({ data, anchor, ...rest }: IframeCarouselProps) => { ) : ( - { hasSectionTitle={!!item.title} /> )} + {item.action && item.action.label && } ))} diff --git a/web/pageComponents/shared/ImageCarousel/ImageCarousel.tsx b/web/pageComponents/shared/ImageCarousel/ImageCarousel.tsx index ccc86620b..fa464462d 100644 --- a/web/pageComponents/shared/ImageCarousel/ImageCarousel.tsx +++ b/web/pageComponents/shared/ImageCarousel/ImageCarousel.tsx @@ -22,8 +22,8 @@ const Container = styled.div` ` const StyledHeading = styled(TitleText)` - padding: var(--iframe-titlePadding, 0 0 var(--space-large) 0); - text-align: var(--iframe-titleAlign, left); + padding: 0 0 var(--space-large) 0; + text-align: left; ` type ImageCarouselProps = { diff --git a/web/pageComponents/shared/LocalizationSwitch.tsx b/web/pageComponents/shared/LocalizationSwitch.tsx index c9d36362f..850d6338d 100644 --- a/web/pageComponents/shared/LocalizationSwitch.tsx +++ b/web/pageComponents/shared/LocalizationSwitch.tsx @@ -46,7 +46,7 @@ const ActiveLocale = styled.span` } ` -const StyledLink = styled.a` +const StyledLink = styled(NextLink)` ${SharedStyle} text-decoration: none; color: var(--grey-60); @@ -97,9 +97,9 @@ type LocaleLinkProps = { const LocaleLink: React.FC> = ({ href, title, locale, active, children }) => { if (!active) { return ( - - {children} - + + {children} + ) } diff --git a/web/pageComponents/shared/LogoLink.tsx b/web/pageComponents/shared/LogoLink.tsx index c011f1b9c..b21f13b2b 100644 --- a/web/pageComponents/shared/LogoLink.tsx +++ b/web/pageComponents/shared/LogoLink.tsx @@ -6,7 +6,7 @@ import NextLink from 'next/link' const { outline } = Tokens -const StyledLogoLink = styled.a` +const StyledLogoLink = styled(NextLink)` justify-self: left; display: flex; align-items: center; @@ -36,11 +36,8 @@ type LogoLinkProps = { export const LogoLink = ({ inverted = false, ...rest }: LogoLinkProps) => { return ( - - {/* Localize text */} - - - - + + + ) } diff --git a/web/pageComponents/shared/RelatedContent.tsx b/web/pageComponents/shared/RelatedContent.tsx index 1d0b313ee..acbde0fdc 100644 --- a/web/pageComponents/shared/RelatedContent.tsx +++ b/web/pageComponents/shared/RelatedContent.tsx @@ -1,7 +1,6 @@ import { Fragment } from 'react' import { Heading, Link, List } from '@components' import type { RelatedLinksData, LinkData } from '../../types/types' -import { default as NextLink } from 'next/link' import { getUrlFromAction } from '../../common/helpers/getUrlFromAction' import styled from 'styled-components' import { getLocaleFromName } from '../../lib/localization' @@ -39,11 +38,9 @@ const RelatedContent = ({ data, ...rest }: RelatedContentProps) => { {type === 'internalUrl' ? ( - - - {label} - - + + {label} + ) : ( diff --git a/web/pageComponents/shared/Teaser.tsx b/web/pageComponents/shared/Teaser.tsx index 42abed98b..6b59b094e 100644 --- a/web/pageComponents/shared/Teaser.tsx +++ b/web/pageComponents/shared/Teaser.tsx @@ -1,6 +1,5 @@ import { Teaser as EnvisTeaser, Link, Eyebrow, BackgroundContainer } from '@components' import styled from 'styled-components' -import { default as NextLink } from 'next/link' import IngressText from './portableText/IngressText' import TitleText from './portableText/TitleText' import { urlFor } from '../../common/helpers' @@ -56,11 +55,9 @@ const TeaserAction = ({ action }: { action: LinkData }) => { if (action.type === 'internalUrl') { const locale = getLocaleFromName(action.link?.lang) return ( - - + {action.label} - ) } diff --git a/web/pageComponents/shared/VideoPlayer.tsx b/web/pageComponents/shared/VideoPlayer.tsx index 08f6e87aa..7c082d2c9 100644 --- a/web/pageComponents/shared/VideoPlayer.tsx +++ b/web/pageComponents/shared/VideoPlayer.tsx @@ -14,13 +14,13 @@ import IngressText from './portableText/IngressText' import { ButtonLink } from './ButtonLink' const StyledHeading = styled(TitleText)` - padding: var(--iframe-titlePadding, 0 0 var(--space-large) 0); - text-align: var(--iframe-titleAlign, left); + padding: 0 0 var(--space-large) 0; + text-align: left; ` const Container = styled.div` - padding: var(--iframe-innerPadding, var(--space-3xLarge) var(--layout-paddingHorizontal-large)); - max-width: var(--iframe-maxWidth, var(--maxViewportWidth)); + padding: var(--space-3xLarge) var(--layout-paddingHorizontal-large); + max-width: var(--maxViewportWidth); margin: auto; ` @@ -87,6 +87,10 @@ const ButtonWrapper = styled.div` const StyledHLSPlayer = styled(HLSPlayer)` object-fit: cover; width: inherit; + + :fullscreen { + object-fit: contain; + } ` const getThumbnailRatio = (aspectRatio: string, height?: number) => { diff --git a/web/pageComponents/shared/VideoPlayerCarousel.tsx b/web/pageComponents/shared/VideoPlayerCarousel.tsx index 1be013840..e95af2f40 100644 --- a/web/pageComponents/shared/VideoPlayerCarousel.tsx +++ b/web/pageComponents/shared/VideoPlayerCarousel.tsx @@ -6,22 +6,19 @@ import { HLSVideoComponent } from './VideoPlayer' import { Carousel } from './Carousel' const StyledHeading = styled(TitleText)` - padding: var( - --iframe-innerPadding, - var(--space-xxLarge) var(--layout-paddingHorizontal-large) 0 var(--layout-paddingHorizontal-large) - ); + padding: var(--space-3xLarge) var(--layout-paddingHorizontal-large) 0 var(--layout-paddingHorizontal-large); margin-bottom: calc(-1 * var(--space-small)); - text-align: var(--iframe-titleAlign, left); + text-align: left; ` const Container = styled.div` - padding: var(--iframe-innerPadding, var(--space-xLarge) 0); - max-width: var(--iframe-maxWidth, var(--maxViewportWidth)); + padding: var(--space-xLarge) 0 var(--space-3xLarge) 0; + max-width: var(--maxViewportWidth); margin: auto; ` const HeadingWrapper = styled.div` - max-width: var(--iframe-maxWidth, var(--maxViewportWidth)); + max-width: var(--maxViewportWidth); margin: auto; ` @@ -42,7 +39,11 @@ const VideoPlayer = ({ anchor, data }: { data: VideoPlayerCarouselData; anchor?: return ( - {title && } + {title && ( + + + + )} {items.map((item) => ( diff --git a/web/pageComponents/shared/iframe/IFrame.tsx b/web/pageComponents/shared/iframe/IFrame.tsx index 8055375f5..243c56657 100644 --- a/web/pageComponents/shared/iframe/IFrame.tsx +++ b/web/pageComponents/shared/iframe/IFrame.tsx @@ -1,4 +1,4 @@ -import { useContext } from 'react' +import { HTMLAttributes, useContext } from 'react' import { PreviewContext } from '../../../lib/contexts/PreviewContext' import styled from 'styled-components' import RequestConsentContainer from './RequestConsentContainer' @@ -35,7 +35,7 @@ type IFrameProps = { height?: number aspectRatio: string hasSectionTitle: boolean -} +} & HTMLAttributes const IFrame = ({ hasSectionTitle = true, @@ -44,6 +44,7 @@ const IFrame = ({ cookiePolicy = 'none', aspectRatio, height, + className, }: IFrameProps) => { const { isPreview } = useContext(PreviewContext) @@ -61,7 +62,7 @@ const IFrame = ({ return ( <> -
+
` max-width: var(--maxViewportWidth); padding: 0 var(--layout-paddingHorizontal-small); margin-left: auto; margin-right: auto; + color: ${({ $bgColor }) => getFontColorForBg($bgColor)}; ` const CaptionWrapper = styled.div<{ background?: BackgroundColours }>` display: inline-block; @@ -26,7 +27,7 @@ const CaptionWrapper = styled.div<{ background?: BackgroundColours }>` export const StyledCaption = ({ attribution, caption, background }: CaptionProps) => { return caption || attribution ? ( - + ) : ( <> diff --git a/web/pageComponents/shared/portableText/components/InternalLink.tsx b/web/pageComponents/shared/portableText/components/InternalLink.tsx index 9f593f613..3b082e211 100644 --- a/web/pageComponents/shared/portableText/components/InternalLink.tsx +++ b/web/pageComponents/shared/portableText/components/InternalLink.tsx @@ -1,5 +1,4 @@ import { Link } from '@components' -import { default as NextLink } from 'next/link' import { getLocaleFromName } from '../../../../lib/localization' type InternalLinkProps = { @@ -31,9 +30,9 @@ export const InternalLink = ({ value, children }: { value?: InternalLinkProps; c } return ( - - {children} - + + {children} + ) } catch (e) { console.error('Could not render internal link', children, e) diff --git a/web/pageComponents/shared/siteMenu/MenuGroup.tsx b/web/pageComponents/shared/siteMenu/MenuGroup.tsx index dabeadb18..418219b62 100644 --- a/web/pageComponents/shared/siteMenu/MenuGroup.tsx +++ b/web/pageComponents/shared/siteMenu/MenuGroup.tsx @@ -1,6 +1,5 @@ import { Fragment } from 'react' import styled from 'styled-components' -import NextLink from 'next/link' import RichText from '../portableText/RichText' import { Link, List, Menu } from '@components' import type { MenuLinkData, SubMenuData, SubMenuGroupData } from '../../../types/types' @@ -94,10 +93,9 @@ export const MenuGroup = ({ topLevelItem, index }: MenuGroupType) => { )} - - - {topLevelLink?.label} - + + {topLevelLink?.label} + {groups && groups.length > 0 && ( @@ -112,9 +110,7 @@ export const MenuGroup = ({ topLevelItem, index }: MenuGroupType) => { {groupItem.links?.map((link: MenuLinkData) => ( - - {link.label} - + {link.label} ))} diff --git a/web/pageComponents/shared/siteMenu/SiteMenu.tsx b/web/pageComponents/shared/siteMenu/SiteMenu.tsx index 88aec17a8..1322419a0 100644 --- a/web/pageComponents/shared/siteMenu/SiteMenu.tsx +++ b/web/pageComponents/shared/siteMenu/SiteMenu.tsx @@ -3,7 +3,6 @@ import styled from 'styled-components' import { useRouter } from 'next/router' import { RemoveScroll } from 'react-remove-scroll' import FocusLock from 'react-focus-lock' -import NextLink from 'next/link' import { Menu, MenuButton, Link } from '@components' import { MenuGroup } from './MenuGroup' import { TopbarDropdown } from './TopbarDropdown' @@ -83,11 +82,9 @@ const SiteMenu = ({ data, ...rest }: MenuProps) => { return })} - - + - )} diff --git a/web/pageComponents/shared/siteMenu/simple/SimpleMenuItem.tsx b/web/pageComponents/shared/siteMenu/simple/SimpleMenuItem.tsx index a22cdb0ef..0f698e806 100644 --- a/web/pageComponents/shared/siteMenu/simple/SimpleMenuItem.tsx +++ b/web/pageComponents/shared/siteMenu/simple/SimpleMenuItem.tsx @@ -1,5 +1,4 @@ import styled from 'styled-components' -import NextLink from 'next/link' import { Link, List, Menu } from '@components' import { SimplePanel } from './SimplePanel' @@ -44,16 +43,16 @@ export const SimpleMenuItem = ({ item, index }: MenuGroupType) => { {!!readMoreLink?.link?.slug && ( - - {readMoreLink.label} - + + {readMoreLink.label} + )} {links?.map((link) => ( - - {link.label} - + + {link.label} + ))} diff --git a/web/pageComponents/shared/siteMenu/simple/SimpleSiteMenu.tsx b/web/pageComponents/shared/siteMenu/simple/SimpleSiteMenu.tsx index 3355c90ad..4becff7d1 100644 --- a/web/pageComponents/shared/siteMenu/simple/SimpleSiteMenu.tsx +++ b/web/pageComponents/shared/siteMenu/simple/SimpleSiteMenu.tsx @@ -9,7 +9,6 @@ import { FormattedMessage, useIntl } from 'react-intl' import { SimpleMenuWrapper } from './SimpleMenuWrapper' import { MenuButton, Link } from '@components' import { SimpleMenuItem } from './SimpleMenuItem' -import NextLink from 'next/link' import { getAllSitesLink } from '../../../../common/helpers/getAllSitesLink' import type { SimpleMenuData, SimpleGroupData } from '../../../../types/types' @@ -91,18 +90,14 @@ const SimpleSiteMenu = ({ data, ...rest }: MenuProps) => { } return (
  • - - {item.label} - + {item.label}
  • ) } })} - - - - - + + + diff --git a/web/pageComponents/topicPages/Breadcrumbs.tsx b/web/pageComponents/topicPages/Breadcrumbs.tsx index 0eacdbbcd..a7c9fd9c0 100644 --- a/web/pageComponents/topicPages/Breadcrumbs.tsx +++ b/web/pageComponents/topicPages/Breadcrumbs.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components' import { default as NextLink } from 'next/link' -import { BreadcrumbsList, getBackgroundByColorName, Link } from '@components' +import { BreadcrumbsList, getBackgroundByColorName, getFontColorForBg } from '@components' import { BreadcrumbJsonLd } from 'next-seo' import { useRouter } from 'next/router' import type { NextRouter } from 'next/router' @@ -32,6 +32,22 @@ const Container = styled.div<{ $containerStyles?: ContainerStyles }>` }} ` +const StyledBreadcrumbsList = styled(BreadcrumbsList)<{ $bgColor?: BackgroundColours }>` + color: ${({ $bgColor }) => getFontColorForBg($bgColor)}; +` + +const StyledBreadcrumbsListItem = styled(BreadcrumbsListItem)<{ $bgColor?: BackgroundColours }>` + &:last-child { + color: ${({ $bgColor }) => + getFontColorForBg($bgColor) === 'var(--inverted-text)' ? 'var(--grey-30)' : 'var(--slate-blue-90)'}; + } +` + +const StyledNextLink = styled(NextLink)<{ $bgColor?: BackgroundColours }>` + text-decoration: none; + color: ${({ $bgColor }) => getFontColorForBg($bgColor)}; +` + type BreadcrumbsProps = { slug: string useCustomBreadcrumbs: boolean @@ -84,23 +100,26 @@ export const Breadcrumbs = ({ return ( - + {crumbs.map((item: Breadcrumb) => { if (item.slug === slug) { - return {item.label} + return ( + + {item.label} + + ) } return ( - - - {item.label} - - + + {item.label} + + ) })} - + ) diff --git a/web/pageComponents/topicPages/CallToActions.tsx b/web/pageComponents/topicPages/CallToActions.tsx index fd70244d2..e55fdb28a 100644 --- a/web/pageComponents/topicPages/CallToActions.tsx +++ b/web/pageComponents/topicPages/CallToActions.tsx @@ -1,7 +1,6 @@ import { Fragment } from 'react' import { List, Link } from '@components' import type { LinkData } from '../../types/types' -import { default as NextLink } from 'next/link' import { ButtonLink } from '../shared/ButtonLink' import { getUrlFromAction } from '../../common/helpers/getUrlFromAction' import { getLocaleFromName } from '../../lib/localization' @@ -38,11 +37,9 @@ const CallToActions = ({ callToActions, overrideButtonStyle, splitList }: CallTo {/* If the URL is a static AEM page it should behave as an internal link in the web */} {type === 'internalUrl' ? ( - - - {label} - - + + {label} + ) : ( diff --git a/web/pageComponents/topicPages/IFrame.tsx b/web/pageComponents/topicPages/IFrame.tsx index 7d638eee3..347bc03ab 100644 --- a/web/pageComponents/topicPages/IFrame.tsx +++ b/web/pageComponents/topicPages/IFrame.tsx @@ -8,13 +8,13 @@ import TitleText from '../shared/portableText/TitleText' import RichText from '../shared/portableText/RichText' const StyledHeading = styled(TitleText)` - padding: var(--iframe-titlePadding, 0 0 var(--space-large) 0); - text-align: var(--iframe-titleAlign, left); + padding: 0 0 var(--space-large) 0; + text-align: left; ` const Container = styled.div` - padding: var(--iframe-innerPadding, var(--space-3xLarge) var(--layout-paddingHorizontal-large)); - max-width: var(--iframe-maxWidth, var(--maxViewportWidth)); + padding: var(--space-3xLarge) var(--layout-paddingHorizontal-large); + max-width: var(--maxViewportWidth); margin: auto; ` diff --git a/web/pageComponents/topicPages/PromoTileArray.tsx b/web/pageComponents/topicPages/PromoTileArray.tsx index 263b7c943..0df5dff34 100644 --- a/web/pageComponents/topicPages/PromoTileArray.tsx +++ b/web/pageComponents/topicPages/PromoTileArray.tsx @@ -28,9 +28,8 @@ const Container = styled.div` const HorizontalWrapper = styled.div` --card-maxWidth: 280px; - - margin-top: var(--space-3xLarge); - margin-bottom: var(--space-3xLarge); + padding-top: var(--space-3xLarge); + padding-bottom: var(--space-3xLarge); @media (min-width: 800px) { --card-maxWidth: 400px; diff --git a/web/pageComponents/topicPages/PromoTileButton.tsx b/web/pageComponents/topicPages/PromoTileButton.tsx index 54f4de9da..965901d8f 100644 --- a/web/pageComponents/topicPages/PromoTileButton.tsx +++ b/web/pageComponents/topicPages/PromoTileButton.tsx @@ -1,6 +1,6 @@ import { LinkData } from '../../types/types' import { ButtonLink } from '../shared/ButtonLink' -import { Card, Link } from '@components' +import { Card } from '@components' import { CSSProperties } from 'react' import styled from 'styled-components' @@ -10,13 +10,10 @@ type Props = { template?: 'default' | 'icon' } -const StyledLink = styled(Link)` - gap: var(--space-medium); - border-bottom: none; -` - const StyledButtonLink = styled(ButtonLink)` text-decoration: none; + gap: var(--space-medium); + border-bottom: none; ` const Wrapper = styled.div` padding: 0 var(--space-medium); @@ -25,19 +22,17 @@ const Wrapper = styled.div` const IconButtonLink = ({ action, hasImage }: { action: LinkData; hasImage: boolean }) => { return ( - - - - {action.label} - - + + + {action.label} + ) diff --git a/web/pageComponents/topicPages/StockValues.tsx b/web/pageComponents/topicPages/StockValues.tsx index 3c74e131a..ea3e5b4b7 100644 --- a/web/pageComponents/topicPages/StockValues.tsx +++ b/web/pageComponents/topicPages/StockValues.tsx @@ -39,8 +39,8 @@ const fetchData = async (url: string) => { } const Container = styled.div` - padding: var(--iframe-innerPadding, var(--space-3xLarge) var(--layout-paddingHorizontal-large)); - max-width: var(--iframe-maxWidth, var(--maxViewportWidth)); + padding: var(--space-3xLarge) var(--layout-paddingHorizontal-large); + max-width: var(--maxViewportWidth); margin: auto; display: grid; grid-template-columns: 1fr; diff --git a/web/pageComponents/topicPages/Table.tsx b/web/pageComponents/topicPages/Table.tsx index 93c891a2c..7189a1023 100644 --- a/web/pageComponents/topicPages/Table.tsx +++ b/web/pageComponents/topicPages/Table.tsx @@ -1,5 +1,4 @@ import { BackgroundContainer, FormattedDate, Link, Table as EnvisTable, Text } from '@components' -import { default as NextLink } from 'next/link' import styled from 'styled-components' import isEmpty from '../shared/portableText/helpers/isEmpty' import IngressText from '../shared/portableText/IngressText' @@ -74,17 +73,17 @@ const renderCellByType = (cellData: CellData) => { return ( <> {cellData.href ? ( - - {cellData.filename} - + + {cellData.filename} + ) : null} ) case 'linkSelector': return ( - - {cellData.label} - + + {cellData.label} + ) default: return <>default diff --git a/web/types/types.ts b/web/types/types.ts index 23ef801ee..663174645 100644 --- a/web/types/types.ts +++ b/web/types/types.ts @@ -701,7 +701,6 @@ export type VideoPlayerCarouselData = { title?: PortableTextBlock[] } - export type LoopingVideoRatio = '1:2' | 'narrow' export type LoopingVideoData = { @@ -736,6 +735,7 @@ export type IFrameCarouselItemData = { cookiePolicy: CookiePolicy aspectRatio: string height?: number + action?: LinkData } export type IframeCarouselData = {