diff --git a/.github/actions/ci-optimization/action.yml b/.github/actions/ci-optimization/action.yml index ff901b5de04b6..0d43596338267 100644 --- a/.github/actions/ci-optimization/action.yml +++ b/.github/actions/ci-optimization/action.yml @@ -57,7 +57,8 @@ runs: - "metadata-ingestion-modules/**" - "metadata-ingestion/**" - "metadata-models/**" - - "docker/datahub-ingestion**" + - "docker/datahub-ingestion-base/**" + - "docker/datahub-ingestion/**" ingestion-base: - "docker/datahub-ingestion-base/**" docker: diff --git a/.github/actions/docker-custom-build-and-push/action.yml b/.github/actions/docker-custom-build-and-push/action.yml index 3805b3501ccec..ccaff510c120a 100644 --- a/.github/actions/docker-custom-build-and-push/action.yml +++ b/.github/actions/docker-custom-build-and-push/action.yml @@ -31,16 +31,21 @@ inputs: description: "Main tag to use for the Docker image" required: true flavor: - description: 'Image flavor (e.g., slim, full)' + description: "Image flavor (e.g., slim, full)" required: false target: description: "Sets the target stage to build" required: false + depot-project: + # Setting this will use native arm64 docker builds instead of QEMU emulation. + # This speeds up builds by 2-3x. + description: "Depot project id" + required: false + outputs: image_tag: description: "Docker image tags" value: ${{ steps.docker_meta.outputs.tags }} - # image_name: ${{ env.DATAHUB_GMS_IMAGE }} runs: using: "composite" @@ -53,15 +58,27 @@ runs: images: ${{ inputs.images }} flavor: | latest=false - suffix=${{ inputs.flavor && format('-{0}', inputs.flavor) || '' }} tags: | type=raw,value=${{ inputs.image_tag }} - type=raw,value=head,enable={{is_default_branch}} - type=sha,prefix=,format=short + type=raw,value=head,suffix=${{ inputs.flavor && format('-{0}', inputs.flavor) || '' }},enable={{is_default_branch}} + type=sha,prefix=,format=short,suffix=${{ inputs.flavor && format('-{0}', inputs.flavor) || '' }} + + - name: Single Tag + id: single_tag + shell: bash + run: | + IMAGES=""" + ${{ inputs.images }} + """ + TAGS=""" + ${{ inputs.image_tag }} + """ + echo "SINGLE_IMAGE=$(echo $IMAGES | tr '\n' ' ' | awk -F' |,' '{ print $1 }')" >> "$GITHUB_OUTPUT" + echo "SINGLE_TAG=$(echo $IMAGES | tr '\n' ' ' | awk -F' |,' '{ print $1 }'):$(echo $TAGS | tr '\n' ' ' | awk -F' |,' '{ print $1 }')" >> "$GITHUB_OUTPUT" # Code for testing the build when not pushing to Docker Hub. - name: Build and Load image for testing (if not publishing) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 if: ${{ inputs.publish != 'true' }} with: context: ${{ inputs.context }} @@ -74,20 +91,11 @@ runs: target: ${{ inputs.target }} load: true push: false - cache-from: type=registry,ref=${{ steps.docker_meta.outputs.tags }} - cache-to: type=inline - - name: Single Tag - if: ${{ inputs.publish != 'true' }} - shell: bash - run: | - IMAGES=""" - ${{ inputs.images }} - """ - TAGS=""" - ${{ inputs.image_tag }} - """ - echo "SINGLE_TAG=$(echo $IMAGES | tr '\n' ' ' | awk -F' |,' '{ print $1 }'):$(echo $TAGS | tr '\n' ' ' | awk -F' |,' '{ print $1 }')" >> $GITHUB_OUTPUT - id: single_tag + cache-from: | + type=registry,ref=${{ steps.single_tag.outputs.SINGLE_IMAGE }}:head${{ inputs.flavor && format('-{0}', inputs.flavor) || '' }} + type=registry,ref=${{ steps.docker_meta.outputs.tags }} + cache-to: | + type=inline - name: Upload image locally for testing (if not publishing) uses: ishworkh/docker-image-artifact-upload@v1 if: ${{ inputs.publish != 'true' }} @@ -97,19 +105,42 @@ runs: # Code for building multi-platform images and pushing to Docker Hub. - name: Set up QEMU uses: docker/setup-qemu-action@v3 - if: ${{ inputs.publish == 'true' }} + if: ${{ inputs.publish == 'true' && inputs.depot-project == '' }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - if: ${{ inputs.publish == 'true' }} + if: ${{ inputs.publish == 'true' && inputs.depot-project == '' }} + - name: Setup Depot CLI + uses: depot/setup-action@v1 + if: ${{ inputs.publish == 'true' && inputs.depot-project != '' }} - name: Login to DockerHub uses: docker/login-action@v3 if: ${{ inputs.publish == 'true' }} with: username: ${{ inputs.username }} password: ${{ inputs.password }} + + # Depot variant. - name: Build and Push Multi-Platform image - uses: docker/build-push-action@v5 - if: ${{ inputs.publish == 'true' }} + uses: depot/build-push-action@v1 + if: ${{ inputs.publish == 'true' && inputs.depot-project != '' }} + with: + project: ${{ inputs.depot-project }} + context: ${{ inputs.context }} + file: ${{ inputs.file }} + platforms: ${{ inputs.platforms }} + build-args: ${{ inputs.build-args }} + tags: ${{ steps.docker_meta.outputs.tags }} + target: ${{ inputs.target }} + push: true + cache-from: | + type=registry,ref=${{ steps.single_tag.outputs.SINGLE_IMAGE }}:head${{ inputs.flavor && format('-{0}', inputs.flavor) || '' }} + type=registry,ref=${{ steps.docker_meta.outputs.tags }} + cache-to: | + type=inline + + - name: Build and Push Multi-Platform image + uses: docker/build-push-action@v6 + if: ${{ inputs.publish == 'true' && inputs.depot-project == '' }} with: context: ${{ inputs.context }} file: ${{ inputs.file }} @@ -118,7 +149,10 @@ runs: tags: ${{ steps.docker_meta.outputs.tags }} target: ${{ inputs.target }} push: true - cache-from: type=registry,ref=${{ steps.docker_meta.outputs.tags }} - cache-to: type=inline + cache-from: | + type=registry,ref=${{ steps.single_tag.outputs.SINGLE_IMAGE }}:head${{ inputs.flavor && format('-{0}', inputs.flavor) || '' }} + type=registry,ref=${{ steps.docker_meta.outputs.tags }} + cache-to: | + type=inline # TODO add code for vuln scanning? diff --git a/.github/workflows/airflow-plugin.yml b/.github/workflows/airflow-plugin.yml index d4f0a1369da25..912dd985f66c0 100644 --- a/.github/workflows/airflow-plugin.yml +++ b/.github/workflows/airflow-plugin.yml @@ -57,13 +57,13 @@ jobs: fail-fast: false steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - uses: acryldata/sane-checkout-action@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 3eb34eca85a46..52148ef1b91f9 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -68,12 +68,12 @@ jobs: - name: Check out the repo uses: acryldata/sane-checkout-action@v3 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 if: ${{ needs.setup.outputs.ingestion_change == 'true' }} with: python-version: "3.10" @@ -91,6 +91,8 @@ jobs: -x :metadata-ingestion-modules:airflow-plugin:check \ -x :metadata-ingestion-modules:dagster-plugin:build \ -x :metadata-ingestion-modules:dagster-plugin:check \ + -x :metadata-ingestion-modules:prefect-plugin:build \ + -x :metadata-ingestion-modules:prefect-plugin:check \ -x :metadata-ingestion-modules:gx-plugin:build \ -x :metadata-ingestion-modules:gx-plugin:check \ -x :datahub-frontend:build \ @@ -125,7 +127,7 @@ jobs: steps: - name: Check out the repo uses: acryldata/sane-checkout-action@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - name: Quickstart Compose Validation @@ -138,4 +140,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: Event File - path: ${{ github.event_path }} + path: ${{ github.event_path }} \ No newline at end of file diff --git a/.github/workflows/check-datahub-jars.yml b/.github/workflows/check-datahub-jars.yml index b45d130e0494d..becf8126dc45b 100644 --- a/.github/workflows/check-datahub-jars.yml +++ b/.github/workflows/check-datahub-jars.yml @@ -29,12 +29,12 @@ jobs: steps: - uses: acryldata/sane-checkout-action@v3 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - name: check ${{ matrix.command }} jar diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index b3b94cc40a2fd..0583f9ab3c426 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Check out the repo uses: acryldata/sane-checkout-action@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - name: run check ${{ matrix.command }} diff --git a/.github/workflows/dagster-plugin.yml b/.github/workflows/dagster-plugin.yml index 48f1b24196c9e..f0b9038b610d2 100644 --- a/.github/workflows/dagster-plugin.yml +++ b/.github/workflows/dagster-plugin.yml @@ -40,12 +40,12 @@ jobs: fail-fast: false steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" diff --git a/.github/workflows/docker-unified.yml b/.github/workflows/docker-unified.yml index 4b2f5f3b5f4dd..b5b825638aced 100644 --- a/.github/workflows/docker-unified.yml +++ b/.github/workflows/docker-unified.yml @@ -32,6 +32,10 @@ env: #### END CHANGES #### #### IMPORTANT #### +permissions: + contents: read + id-token: write + jobs: setup: runs-on: ubuntu-latest @@ -67,23 +71,23 @@ jobs: id: tag run: | source .github/scripts/docker_helpers.sh - echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT - echo "tag=$(get_tag)" >> $GITHUB_OUTPUT - echo "slim_tag=$(get_tag_slim)" >> $GITHUB_OUTPUT - echo "full_tag=$(get_tag_full)" >> $GITHUB_OUTPUT - echo "unique_tag=$(get_unique_tag)" >> $GITHUB_OUTPUT - echo "unique_slim_tag=$(get_unique_tag_slim)" >> $GITHUB_OUTPUT - echo "unique_full_tag=$(get_unique_tag_full)" >> $GITHUB_OUTPUT - echo "python_release_version=$(get_python_docker_release_v)" >> $GITHUB_OUTPUT - echo "branch_name=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT - echo "repository_name=${GITHUB_REPOSITORY#*/}" >> $GITHUB_OUTPUT + echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT" + echo "tag=$(get_tag)" >> "$GITHUB_OUTPUT" + echo "slim_tag=$(get_tag_slim)" >> "$GITHUB_OUTPUT" + echo "full_tag=$(get_tag_full)" >> "$GITHUB_OUTPUT" + echo "unique_tag=$(get_unique_tag)" >> "$GITHUB_OUTPUT" + echo "unique_slim_tag=$(get_unique_tag_slim)" >> "$GITHUB_OUTPUT" + echo "unique_full_tag=$(get_unique_tag_full)" >> "$GITHUB_OUTPUT" + echo "python_release_version=$(get_python_docker_release_v)" >> "$GITHUB_OUTPUT" + echo "branch_name=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT" + echo "repository_name=${GITHUB_REPOSITORY#*/}" >> "$GITHUB_OUTPUT" - name: Check whether docker login is possible id: docker-login env: ENABLE_DOCKER_LOGIN: ${{ secrets.ACRYL_DOCKER_PASSWORD != '' }} run: | echo "Enable Docker Login: ${{ env.ENABLE_DOCKER_LOGIN }}" - echo "docker-login=${{ env.ENABLE_DOCKER_LOGIN }}" >> $GITHUB_OUTPUT + echo "docker-login=${{ env.ENABLE_DOCKER_LOGIN }}" >> "$GITHUB_OUTPUT" - name: Check whether publishing enabled id: publish env: @@ -94,7 +98,7 @@ jobs: }} run: | echo "Enable publish: ${{ env.ENABLE_PUBLISH }}" - echo "publish=${{ env.ENABLE_PUBLISH }}" >> $GITHUB_OUTPUT + echo "publish=${{ env.ENABLE_PUBLISH }}" >> "$GITHUB_OUTPUT" - name: Check whether PR publishing enabled id: pr-publish env: @@ -105,10 +109,10 @@ jobs: }} run: | echo "Enable PR publish: ${{ env.ENABLE_PUBLISH }}" - echo "publish=${{ env.ENABLE_PUBLISH }}" >> $GITHUB_OUTPUT + echo "publish=${{ env.ENABLE_PUBLISH }}" >> "$GITHUB_OUTPUT" - uses: ./.github/actions/ci-optimization id: ci-optimize - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 if: ${{ steps.ci-optimize.outputs.smoke-test-change == 'true' }} with: python-version: "3.10" @@ -120,7 +124,7 @@ jobs: ~/.cache/uv key: ${{ runner.os }}-uv-${{ hashFiles('**/requirements.txt') }} - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 if: ${{ steps.ci-optimize.outputs.smoke-test-change == 'true' }} with: distribution: "zulu" @@ -140,7 +144,7 @@ jobs: if: ${{ needs.setup.outputs.backend_change == 'true' || needs.setup.outputs.publish == 'true' }} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -204,7 +208,7 @@ jobs: if: ${{ needs.setup.outputs.backend_change == 'true' || needs.setup.outputs.publish == 'true' }} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -268,7 +272,7 @@ jobs: if: ${{ needs.setup.outputs.backend_change == 'true' || needs.setup.outputs.publish == 'true' }} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -332,7 +336,7 @@ jobs: if: ${{ needs.setup.outputs.backend_change == 'true' || needs.setup.outputs.publish == 'true' }} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -396,7 +400,7 @@ jobs: if: ${{ needs.setup.outputs.frontend_change == 'true' || needs.setup.outputs.publish == 'true' || needs.setup.outputs.pr-publish == 'true'}} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -432,7 +436,7 @@ jobs: actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status steps: - name: Checkout # adding checkout step just to make trivy upload happy - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Download image uses: ishworkh/docker-image-artifact-download@v1 if: ${{ needs.setup.outputs.publish != 'true' && needs.setup.outputs.pr-publish != 'true' }} @@ -542,9 +546,10 @@ jobs: context: . file: ./docker/datahub-ingestion-base/Dockerfile platforms: linux/amd64,linux/arm64/v8 + depot-project: ${{ vars.DEPOT_PROJECT_ID }} - name: Compute DataHub Ingestion (Base) Tag id: tag - run: echo "tag=${{ needs.setup.outputs.ingestion_base_change == 'true' && needs.setup.outputs.unique_tag || 'head' }}" >> $GITHUB_OUTPUT + run: echo "tag=${{ needs.setup.outputs.ingestion_base_change == 'true' && needs.setup.outputs.unique_tag || 'head' }}" >> "$GITHUB_OUTPUT" datahub_ingestion_base_slim_build: name: Build and Push DataHub Ingestion (Base-Slim) Docker Image runs-on: ubuntu-latest @@ -574,6 +579,7 @@ jobs: images: | ${{ env.DATAHUB_INGESTION_BASE_IMAGE }} image_tag: ${{ needs.setup.outputs.slim_tag }} + flavor: slim username: ${{ secrets.ACRYL_DOCKER_USERNAME }} password: ${{ secrets.ACRYL_DOCKER_PASSWORD }} build-args: | @@ -583,9 +589,10 @@ jobs: context: . file: ./docker/datahub-ingestion-base/Dockerfile platforms: linux/amd64,linux/arm64/v8 + depot-project: ${{ vars.DEPOT_PROJECT_ID }} - name: Compute DataHub Ingestion (Base-Slim) Tag id: tag - run: echo "tag=${{ needs.setup.outputs.ingestion_base_change == 'true' && needs.setup.outputs.unique_slim_tag || 'head-slim' }}" >> $GITHUB_OUTPUT + run: echo "tag=${{ needs.setup.outputs.ingestion_base_change == 'true' && needs.setup.outputs.unique_slim_tag || 'head-slim' }}" >> "$GITHUB_OUTPUT" datahub_ingestion_base_full_build: name: Build and Push DataHub Ingestion (Base-Full) Docker Image runs-on: ubuntu-latest @@ -614,7 +621,7 @@ jobs: target: full-install images: | ${{ env.DATAHUB_INGESTION_BASE_IMAGE }} - tags: ${{ needs.setup.outputs.full_tag }} + image_tag: ${{ needs.setup.outputs.full_tag }} username: ${{ secrets.ACRYL_DOCKER_USERNAME }} password: ${{ secrets.ACRYL_DOCKER_PASSWORD }} build-args: | @@ -626,7 +633,7 @@ jobs: platforms: linux/amd64,linux/arm64/v8 - name: Compute DataHub Ingestion (Base-Full) Tag id: tag - run: echo "tag=${{ needs.setup.outputs.ingestion_base_change == 'true' && needs.setup.outputs.unique_full_tag || 'head' }}" >> $GITHUB_OUTPUT + run: echo "tag=${{ needs.setup.outputs.ingestion_base_change == 'true' && needs.setup.outputs.unique_full_tag || 'head' }}" >> "$GITHUB_OUTPUT" datahub_ingestion_slim_build: name: Build and Push DataHub Ingestion Docker Images @@ -638,7 +645,7 @@ jobs: if: ${{ needs.setup.outputs.ingestion_change == 'true' || needs.setup.outputs.publish == 'true' || needs.setup.outputs.pr-publish == 'true' }} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -672,15 +679,17 @@ jobs: RELEASE_VERSION=${{ needs.setup.outputs.python_release_version }} APP_ENV=slim image_tag: ${{ needs.setup.outputs.slim_tag }} + flavor: slim username: ${{ secrets.ACRYL_DOCKER_USERNAME }} password: ${{ secrets.ACRYL_DOCKER_PASSWORD }} publish: ${{ needs.setup.outputs.publish == 'true' || needs.setup.outputs.pr-publish == 'true' }} context: . file: ./docker/datahub-ingestion/Dockerfile platforms: linux/amd64,linux/arm64/v8 + depot-project: ${{ vars.DEPOT_PROJECT_ID }} - name: Compute Tag id: tag - run: echo "tag=${{ needs.setup.outputs.ingestion_change == 'true' && needs.setup.outputs.unique_slim_tag || 'head-slim' }}" >> $GITHUB_OUTPUT + run: echo "tag=${{ needs.setup.outputs.ingestion_change == 'true' && needs.setup.outputs.unique_slim_tag || 'head-slim' }}" >> "$GITHUB_OUTPUT" datahub_ingestion_slim_scan: permissions: contents: read # for actions/checkout to fetch code @@ -710,6 +719,7 @@ jobs: severity: "CRITICAL,HIGH" ignore-unfixed: true vuln-type: "os,library" + timeout: 15m - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v2 with: @@ -725,7 +735,7 @@ jobs: if: ${{ needs.setup.outputs.ingestion_change == 'true' || needs.setup.outputs.publish == 'true' || needs.setup.outputs.pr-publish == 'true' }} steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 @@ -764,9 +774,10 @@ jobs: context: . file: ./docker/datahub-ingestion/Dockerfile platforms: linux/amd64,linux/arm64/v8 + depot-project: ${{ vars.DEPOT_PROJECT_ID }} - name: Compute Tag (Full) id: tag - run: echo "tag=${{ needs.setup.outputs.ingestion_change == 'true' && needs.setup.outputs.unique_tag || 'head' }}" >> $GITHUB_OUTPUT + run: echo "tag=${{ needs.setup.outputs.ingestion_change == 'true' && needs.setup.outputs.unique_tag || 'head' }}" >> "$GITHUB_OUTPUT" datahub_ingestion_full_scan: permissions: contents: read # for actions/checkout to fetch code @@ -796,6 +807,7 @@ jobs: severity: "CRITICAL,HIGH" ignore-unfixed: true vuln-type: "os,library" + timeout: 15m - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v2 with: @@ -810,13 +822,13 @@ jobs: - id: set-matrix run: | if [ '${{ needs.setup.outputs.frontend_only }}' == 'true' ]; then - echo 'matrix=["cypress_suite1","cypress_rest"]' >> $GITHUB_OUTPUT + echo 'matrix=["cypress_suite1","cypress_rest"]' >> "$GITHUB_OUTPUT" elif [ '${{ needs.setup.outputs.ingestion_only }}' == 'true' ]; then - echo 'matrix=["no_cypress_suite0","no_cypress_suite1"]' >> $GITHUB_OUTPUT + echo 'matrix=["no_cypress_suite0","no_cypress_suite1"]' >> "$GITHUB_OUTPUT" elif [[ '${{ needs.setup.outputs.backend_change }}' == 'true' || '${{ needs.setup.outputs.smoke_test_change }}' == 'true' ]]; then - echo 'matrix=["no_cypress_suite0","no_cypress_suite1","cypress_suite1","cypress_rest"]' >> $GITHUB_OUTPUT + echo 'matrix=["no_cypress_suite0","no_cypress_suite1","cypress_suite1","cypress_rest"]' >> "$GITHUB_OUTPUT" else - echo 'matrix=[]' >> $GITHUB_OUTPUT + echo 'matrix=[]' >> "$GITHUB_OUTPUT" fi smoke_test: @@ -852,12 +864,12 @@ jobs: - name: Check out the repo uses: acryldata/sane-checkout-action@v3 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" cache: "pip" diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index cdd2c1bc64feb..3552c0d61803b 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -36,12 +36,12 @@ jobs: with: fetch-depth: 0 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" cache: pip diff --git a/.github/workflows/gx-plugin.yml b/.github/workflows/gx-plugin.yml index 84ba2e0559be1..06a10883e70f5 100644 --- a/.github/workflows/gx-plugin.yml +++ b/.github/workflows/gx-plugin.yml @@ -42,12 +42,12 @@ jobs: fail-fast: false steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" diff --git a/.github/workflows/metadata-ingestion.yml b/.github/workflows/metadata-ingestion.yml index a27013c4bf488..cfb3693d89381 100644 --- a/.github/workflows/metadata-ingestion.yml +++ b/.github/workflows/metadata-ingestion.yml @@ -52,13 +52,13 @@ jobs: sudo rm -rf /usr/local/lib/android/ || true sudo docker image prune -a -f || true - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - uses: acryldata/sane-checkout-action@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" @@ -67,7 +67,7 @@ jobs: path: | ~/.cache/uv key: ${{ runner.os }}-uv-${{ hashFiles('**/requirements.txt') }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" diff --git a/.github/workflows/metadata-io.yml b/.github/workflows/metadata-io.yml index 332330b4ed898..e5e5f1dae5447 100644 --- a/.github/workflows/metadata-io.yml +++ b/.github/workflows/metadata-io.yml @@ -54,12 +54,12 @@ jobs: sudo docker image prune -a -f || true - uses: acryldata/sane-checkout-action@v3 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 if: ${{ needs.setup.outputs.ingestion_change == 'true' }} with: python-version: "3.10" diff --git a/.github/workflows/metadata-model.yml b/.github/workflows/metadata-model.yml index d62c03057db3f..632e6ac35d673 100644 --- a/.github/workflows/metadata-model.yml +++ b/.github/workflows/metadata-model.yml @@ -30,13 +30,13 @@ jobs: needs: setup steps: - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - uses: acryldata/sane-checkout-action@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" cache: "pip" diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 52f83b3be5283..a3d1b85df0818 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -36,6 +36,7 @@ jobs: "maggiehays", "pedro93", "RyanHolstien", + "sakethvarma397", "Kunal-kankriya", "purnimagarg1", "dushayntAW", diff --git a/.github/workflows/prefect-plugin.yml b/.github/workflows/prefect-plugin.yml new file mode 100644 index 0000000000000..09af0ad3f354a --- /dev/null +++ b/.github/workflows/prefect-plugin.yml @@ -0,0 +1,86 @@ +name: Prefect Plugin +on: + push: + branches: + - master + paths: + - ".github/workflows/prefect-plugin.yml" + - "metadata-ingestion-modules/prefect-plugin/**" + - "metadata-ingestion/**" + - "metadata-models/**" + pull_request: + branches: + - "**" + paths: + - ".github/workflows/prefect-plugin.yml" + - "metadata-ingestion-modules/prefect-plugin/**" + - "metadata-ingestion/**" + - "metadata-models/**" + release: + types: [published] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + prefect-plugin: + runs-on: ubuntu-latest + env: + SPARK_VERSION: 3.0.3 + DATAHUB_TELEMETRY_ENABLED: false + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + include: + - python-version: "3.8" + - python-version: "3.9" + - python-version: "3.10" + fail-fast: false + steps: + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: 17 + - uses: gradle/gradle-build-action@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - name: Install dependencies + run: ./metadata-ingestion/scripts/install_deps.sh + - name: Install prefect package + run: ./gradlew :metadata-ingestion-modules:prefect-plugin:lint :metadata-ingestion-modules:prefect-plugin:testQuick + - name: pip freeze show list installed + if: always() + run: source metadata-ingestion-modules/prefect-plugin/venv/bin/activate && pip freeze + - uses: actions/upload-artifact@v3 + if: ${{ always() && matrix.python-version == '3.10'}} + with: + name: Test Results (Prefect Plugin ${{ matrix.python-version}}) + path: | + **/build/reports/tests/test/** + **/build/test-results/test/** + **/junit.*.xml + !**/binary/** + - name: Upload coverage to Codecov + if: always() + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + directory: . + fail_ci_if_error: false + flags: prefect,prefect-${{ matrix.extra_pip_extras }} + name: pytest-prefect-${{ matrix.python-version }} + verbose: true + + event-file: + runs-on: ubuntu-latest + steps: + - name: Upload + uses: actions/upload-artifact@v3 + with: + name: Event File + path: ${{ github.event_path }} diff --git a/.github/workflows/publish-datahub-jars.yml b/.github/workflows/publish-datahub-jars.yml index aceee756339ad..eb57c29e151ae 100644 --- a/.github/workflows/publish-datahub-jars.yml +++ b/.github/workflows/publish-datahub-jars.yml @@ -53,12 +53,12 @@ jobs: steps: - uses: acryldata/sane-checkout-action@v3 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" cache: "pip" diff --git a/.github/workflows/spark-smoke-test.yml b/.github/workflows/spark-smoke-test.yml index d1618c6528577..23413336404f2 100644 --- a/.github/workflows/spark-smoke-test.yml +++ b/.github/workflows/spark-smoke-test.yml @@ -31,12 +31,12 @@ jobs: steps: - uses: acryldata/sane-checkout-action@v3 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: 17 - uses: gradle/actions/setup-gradle@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" cache: "pip" diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml index 947fc35f169a0..23a80aab8082a 100644 --- a/.github/workflows/test-results.yml +++ b/.github/workflows/test-results.yml @@ -2,7 +2,7 @@ name: Test Results on: workflow_run: - workflows: ["build & test", "metadata ingestion", "Airflow Plugin", "Dagster Plugin", "GX Plugin"] + workflows: ["build & test", "metadata ingestion", "Airflow Plugin", "Dagster Plugin", "Prefect Plugin", "GX Plugin"] types: - completed diff --git a/datahub-web-react/src/app/businessAttribute/BusinessAttributeItemMenu.tsx b/datahub-web-react/src/app/businessAttribute/BusinessAttributeItemMenu.tsx index 4e56d81203b6f..422de728f7090 100644 --- a/datahub-web-react/src/app/businessAttribute/BusinessAttributeItemMenu.tsx +++ b/datahub-web-react/src/app/businessAttribute/BusinessAttributeItemMenu.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { DeleteOutlined } from '@ant-design/icons'; -import { Dropdown, Menu, message, Modal } from 'antd'; +import { Dropdown, message, Modal } from 'antd'; import { MenuIcon } from '../entity/shared/EntityDropdown/EntityDropdown'; import { useDeleteBusinessAttributeMutation } from '../../graphql/businessAttribute.generated'; +import { MenuItemStyle } from '../entity/view/menu/item/styledComponent'; type Props = { urn: string; @@ -48,17 +49,19 @@ export default function BusinessAttributeItemMenu({ title, urn, onDelete }: Prop }); }; + const items = [ + { + key: 'delete', + label: ( + +  Delete + + ), + }, + ]; + return ( - - -  Delete - - - } - > + ); diff --git a/datahub-web-react/src/app/businessAttribute/BusinessAttributes.tsx b/datahub-web-react/src/app/businessAttribute/BusinessAttributes.tsx index b16593f5497f6..e2794de5e5691 100644 --- a/datahub-web-react/src/app/businessAttribute/BusinessAttributes.tsx +++ b/datahub-web-react/src/app/businessAttribute/BusinessAttributes.tsx @@ -246,7 +246,7 @@ export const BusinessAttributes = () => { /> setIsCreatingBusinessAttribute(false)} onCreateBusinessAttribute={() => { businessAttributeRefetch?.(); diff --git a/datahub-web-react/src/app/businessAttribute/CreateBusinessAttributeModal.tsx b/datahub-web-react/src/app/businessAttribute/CreateBusinessAttributeModal.tsx index 1ee0ca030748e..979f8377c7fdd 100644 --- a/datahub-web-react/src/app/businessAttribute/CreateBusinessAttributeModal.tsx +++ b/datahub-web-react/src/app/businessAttribute/CreateBusinessAttributeModal.tsx @@ -13,7 +13,7 @@ import { SchemaFieldDataType } from './businessAttributeUtils'; import { validateCustomUrnId } from '../shared/textUtil'; type Props = { - visible: boolean; + open: boolean; onClose: () => void; onCreateBusinessAttribute: () => void; }; @@ -51,7 +51,7 @@ const StyledButton = styled(Button)` // Ensures that any newly added datatype is automatically included in the user dropdown. const DATA_TYPES = Object.values(SchemaFieldDataType); -export default function CreateBusinessAttributeModal({ visible, onClose, onCreateBusinessAttribute }: Props) { +export default function CreateBusinessAttributeModal({ open, onClose, onCreateBusinessAttribute }: Props) { const [createButtonEnabled, setCreateButtonEnabled] = useState(true); const [createBusinessAttribute] = useCreateBusinessAttributeMutation(); @@ -120,7 +120,7 @@ export default function CreateBusinessAttributeModal({ visible, onClose, onCreat <> diff --git a/datahub-web-react/src/app/domain/CreateDomainModal.tsx b/datahub-web-react/src/app/domain/CreateDomainModal.tsx index 606444d34bdc9..a50065e25fea1 100644 --- a/datahub-web-react/src/app/domain/CreateDomainModal.tsx +++ b/datahub-web-react/src/app/domain/CreateDomainModal.tsx @@ -115,7 +115,7 @@ export default function CreateDomainModal({ onClose, onCreate }: Props) { return ( diff --git a/datahub-web-react/src/app/domain/DomainItemMenu.tsx b/datahub-web-react/src/app/domain/DomainItemMenu.tsx index a0007b90435d7..3e04864b379db 100644 --- a/datahub-web-react/src/app/domain/DomainItemMenu.tsx +++ b/datahub-web-react/src/app/domain/DomainItemMenu.tsx @@ -48,17 +48,19 @@ export default function DomainItemMenu({ name, urn, onDelete }: Props) { }); }; + const items = [ + { + key: 0, + label: ( + +  Delete + + ), + }, + ]; + return ( - - -  Delete - - - } - > + ); diff --git a/datahub-web-react/src/app/entity/dataset/profile/schema/components/CustomPagination.tsx b/datahub-web-react/src/app/entity/dataset/profile/schema/components/CustomPagination.tsx index 8d270898a4456..d97582cace7b1 100644 --- a/datahub-web-react/src/app/entity/dataset/profile/schema/components/CustomPagination.tsx +++ b/datahub-web-react/src/app/entity/dataset/profile/schema/components/CustomPagination.tsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; -import { Button, Menu, Dropdown, Typography } from 'antd'; +import { Button, Dropdown, Typography } from 'antd'; import { LeftOutlined, RightOutlined } from '@ant-design/icons'; import styled from 'styled-components'; +import { MenuItemStyle } from '../../../../view/menu/item/styledComponent'; const CustomPaginationContainer = styled.div` display: flex; @@ -60,27 +61,29 @@ export default function CustomPagination({ onChange, maxVersion }: Props) { onChange(version1, parseInt(key, 10)); }; - const menu1 = ( - - {[...Array(maxVersion)].map((_, i) => ( - // eslint-disable-next-line react/no-array-index-key - + const items1 = [...Array(maxVersion)].map((_, i) => { + // eslint-disable-next-line react/no-array-index-key + return { + key: maxVersion - i, + label: ( + onVersion1Click({ key: maxVersion - i })}> {i === 0 ? 'latest' : `version ${maxVersion + 1 - i}`} - - ))} - - ); + + ), + }; + }); - const menu2 = ( - - {[...Array(version1)].map((_, i) => ( - // eslint-disable-next-line react/no-array-index-key - + const items2 = [...Array(version1)].map((_, i) => { + // eslint-disable-next-line react/no-array-index-key + return { + key: version1 - i - 1, + label: ( + onVersion2Click({ key: version1 - i - 1 })}> {`version ${version1 - i}`} - - ))} - - ); + + ), + }; + }); return ( @@ -92,13 +95,13 @@ export default function CustomPagination({ onChange, maxVersion }: Props) { disabled={version1 >= maxVersion} /> Comparing - + {version1 === maxVersion ? 'latest' : `version ${version1 + 1}`} to - + {`version ${version2 + 1}`} {selectedProfile && ( - + )} diff --git a/datahub-web-react/src/app/entity/glossaryTerm/profile/AddRelatedTermsModal.tsx b/datahub-web-react/src/app/entity/glossaryTerm/profile/AddRelatedTermsModal.tsx index f97f3c327676b..a609dc4cca599 100644 --- a/datahub-web-react/src/app/entity/glossaryTerm/profile/AddRelatedTermsModal.tsx +++ b/datahub-web-react/src/app/entity/glossaryTerm/profile/AddRelatedTermsModal.tsx @@ -167,7 +167,7 @@ function AddRelatedTermsModal(props: Props) { return ( diff --git a/datahub-web-react/src/app/entity/glossaryTerm/profile/RelatedTerm.tsx b/datahub-web-react/src/app/entity/glossaryTerm/profile/RelatedTerm.tsx index bb252c8459e22..4db28768c66a0 100644 --- a/datahub-web-react/src/app/entity/glossaryTerm/profile/RelatedTerm.tsx +++ b/datahub-web-react/src/app/entity/glossaryTerm/profile/RelatedTerm.tsx @@ -1,5 +1,5 @@ import { DeleteOutlined, MoreOutlined } from '@ant-design/icons'; -import { Divider, Dropdown, Menu } from 'antd'; +import { Divider, Dropdown } from 'antd'; import React from 'react'; import styled from 'styled-components/macro'; import { useGetGlossaryTermQuery } from '../../../../graphql/glossaryTerm.generated'; @@ -51,23 +51,23 @@ function RelatedTerm(props: Props) { if (loading) return null; + const items = [ + { + key: '0', + label: ( + +   Remove Term + + ), + }, + ]; + return ( {entityRegistry.renderPreview(EntityType.GlossaryTerm, PreviewType.PREVIEW, data?.glossaryTerm)} {isEditable && ( - - - -   Remove Term - - - - } - trigger={['click']} - > + )} diff --git a/datahub-web-react/src/app/entity/group/AddGroupMembersModal.tsx b/datahub-web-react/src/app/entity/group/AddGroupMembersModal.tsx index 95c288052e978..2485fb1e48fbe 100644 --- a/datahub-web-react/src/app/entity/group/AddGroupMembersModal.tsx +++ b/datahub-web-react/src/app/entity/group/AddGroupMembersModal.tsx @@ -10,7 +10,7 @@ import { OwnerLabel } from '../../shared/OwnerLabel'; type Props = { urn: string; - visible: boolean; + open: boolean; onCloseModal: () => void; onSubmit: () => void; }; @@ -29,7 +29,7 @@ const StyleTag = styled(Tag)` align-items: center; `; -export const AddGroupMembersModal = ({ urn, visible, onCloseModal, onSubmit }: Props) => { +export const AddGroupMembersModal = ({ urn, open, onCloseModal, onSubmit }: Props) => { const entityRegistry = useEntityRegistry(); const [selectedMembers, setSelectedMembers] = useState([]); const [inputValue, setInputValue] = useState(''); @@ -134,7 +134,7 @@ export const AddGroupMembersModal = ({ urn, visible, onCloseModal, onSubmit }: P return ( diff --git a/datahub-web-react/src/app/entity/group/EditGroupDescriptionModal.tsx b/datahub-web-react/src/app/entity/group/EditGroupDescriptionModal.tsx index 356daf584d9f7..5c672745053b5 100644 --- a/datahub-web-react/src/app/entity/group/EditGroupDescriptionModal.tsx +++ b/datahub-web-react/src/app/entity/group/EditGroupDescriptionModal.tsx @@ -38,7 +38,7 @@ export default function EditGroupDescriptionModal({ diff --git a/datahub-web-react/src/app/entity/group/GroupEditModal.tsx b/datahub-web-react/src/app/entity/group/GroupEditModal.tsx index be1289ad3202b..6a3354eb358bb 100644 --- a/datahub-web-react/src/app/entity/group/GroupEditModal.tsx +++ b/datahub-web-react/src/app/entity/group/GroupEditModal.tsx @@ -11,7 +11,7 @@ type PropsData = { }; type Props = { - visible: boolean; + open: boolean; onClose: () => void; onSave: () => void; editModalData: PropsData; @@ -19,7 +19,7 @@ type Props = { /** Regex Validations */ export const USER_NAME_REGEX = new RegExp('^[a-zA-Z ]*$'); -export default function GroupEditModal({ visible, onClose, onSave, editModalData }: Props) { +export default function GroupEditModal({ open, onClose, onSave, editModalData }: Props) { const [updateCorpGroupPropertiesMutation] = useUpdateCorpGroupPropertiesMutation(); const [form] = Form.useForm(); @@ -76,7 +76,7 @@ export default function GroupEditModal({ visible, onClose, onSave, editModalData return ( diff --git a/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx b/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx index 4cba8499877f1..af3f89f7c21ba 100644 --- a/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx +++ b/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx @@ -368,7 +368,7 @@ export default function GroupInfoSidebar({ sideBarData, refetch }: Props) { {/* Modal */} showEditGroupModal(false)} onSave={() => { refetch(); diff --git a/datahub-web-react/src/app/entity/group/GroupMembers.tsx b/datahub-web-react/src/app/entity/group/GroupMembers.tsx index 45697cb50b309..147c3f8030d0e 100644 --- a/datahub-web-react/src/app/entity/group/GroupMembers.tsx +++ b/datahub-web-react/src/app/entity/group/GroupMembers.tsx @@ -232,7 +232,7 @@ export default function GroupMembers({ urn, pageSize, isExternalGroup, onChangeM {isEditingMembers && ( setIsEditingMembers(false)} /> diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx index d60e86b0af8ca..c92e6015c6cca 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx @@ -131,7 +131,7 @@ function CreateGlossaryEntityModal(props: Props) { return ( diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/EntityDropdown.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/EntityDropdown.tsx index 2856a219c435d..b7dbd9a43c872 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/EntityDropdown.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/EntityDropdown.tsx @@ -57,6 +57,9 @@ const MenuItem = styled.div` `; const StyledMenuItem = styled(Menu.Item)<{ disabled: boolean }>` + &&&& { + background-color: transparent; + } ${(props) => props.disabled ? ` @@ -157,114 +160,145 @@ function EntityDropdown(props: Props) { */ const deleteRedirectPath = getEntityProfileDeleteRedirectPath(entityType, entityData); + const items = [ + menuItems.has(EntityMenuItems.COPY_URL) && navigator.clipboard + ? { + key: 0, + label: ( + { + navigator.clipboard.writeText(pageUrl); + message.info('Copied URL!', 1.2); + }} + > +   Copy Url + + ), + } + : null, + menuItems.has(EntityMenuItems.UPDATE_DEPRECATION) + ? { + key: 1, + label: !entityData?.deprecation?.deprecated ? ( + setIsDeprecationModalVisible(true)}> +   Mark as deprecated + + ) : ( + handleUpdateDeprecation(false)}> +   Mark as un-deprecated + + ), + } + : null, + menuItems.has(EntityMenuItems.ADD_TERM) + ? { + key: 2, + label: ( + setIsCreateTermModalVisible(true)} + > + +  Add Term + + + ), + } + : null, + menuItems.has(EntityMenuItems.ADD_TERM_GROUP) + ? { + key: 3, + label: ( + setIsCreateNodeModalVisible(true)} + > + +  Add Term Group + + + ), + } + : null, + !isDomainMoveHidden && menuItems.has(EntityMenuItems.MOVE) + ? { + key: 4, + label: ( + setIsMoveModalVisible(true)} + > + +  Move + + + ), + } + : null, + menuItems.has(EntityMenuItems.DELETE) + ? { + key: 5, + label: ( + + + +  Delete + + + + ), + } + : null, + menuItems.has(EntityMenuItems.CLONE) + ? { + key: 6, + label: ( + setIsCloneEntityModalVisible(true)} + > + +  Clone + + + ), + } + : null, + menuItems.has(EntityMenuItems.RAISE_INCIDENT) + ? { + key: 6, + label: ( + + setIsRaiseIncidentModalVisible(true)}> +  Raise Incident + + + ), + } + : null, + ]; + return ( <> - - {menuItems.has(EntityMenuItems.COPY_URL) && navigator.clipboard && ( - - { - navigator.clipboard.writeText(pageUrl); - message.info('Copied URL!', 1.2); - }} - > -   Copy Url - - - )} - {menuItems.has(EntityMenuItems.UPDATE_DEPRECATION) && ( - - {!entityData?.deprecation?.deprecated ? ( - setIsDeprecationModalVisible(true)}> -   Mark as deprecated - - ) : ( - handleUpdateDeprecation(false)}> -   Mark as un-deprecated - - )} - - )} - {menuItems.has(EntityMenuItems.ADD_TERM) && ( - setIsCreateTermModalVisible(true)} - > - -  Add Term - - - )} - {menuItems.has(EntityMenuItems.ADD_TERM_GROUP) && ( - setIsCreateNodeModalVisible(true)} - > - -  Add Term Group - - - )} - {!isDomainMoveHidden && menuItems.has(EntityMenuItems.MOVE) && ( - setIsMoveModalVisible(true)} - > - -  Move - - - )} - {menuItems.has(EntityMenuItems.DELETE) && ( - - - -  Delete - - - - )} - {menuItems.has(EntityMenuItems.CLONE) && ( - setIsCloneEntityModalVisible(true)} - > - -  Clone - - - )} - {menuItems.has(EntityMenuItems.RAISE_INCIDENT) && ( - - setIsRaiseIncidentModalVisible(true)}> -  Raise Incident - - - )} - - } - trigger={['click']} - > + {isCreateTermModalVisible && ( @@ -303,7 +337,7 @@ function EntityDropdown(props: Props) { {hasBeenDeleted && !onDelete && deleteRedirectPath && } {isRaiseIncidentModalVisible && ( setIsRaiseIncidentModalVisible(false)} refetch={ (() => { diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveDomainModal.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveDomainModal.tsx index 3826f934c1c25..dbf14b069f521 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveDomainModal.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveDomainModal.tsx @@ -68,7 +68,7 @@ function MoveDomainModal(props: Props) { diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx index 51b39be4e20ea..de32f48f687a0 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx @@ -67,7 +67,7 @@ function MoveGlossaryEntityModal(props: Props) { diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/UpdateDeprecationModal.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/UpdateDeprecationModal.tsx index 01287c2b367bf..0c36c3a953cb7 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/UpdateDeprecationModal.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/UpdateDeprecationModal.tsx @@ -58,7 +58,7 @@ export const UpdateDeprecationModal = ({ urns, onClose, refetch }: Props) => { return ( { void; editERModelRelation?: ErModelRelationship; @@ -42,7 +42,7 @@ export const CreateERModelRelationModal = ({ table1Schema, table2, table2Schema, - visible, + open, setModalVisible, onCancel, editERModelRelation, @@ -349,7 +349,7 @@ export const CreateERModelRelationModal = ({ } - visible={visible} + open={open} closable={false} className="CreateERModelRelationModal" okButtonProps={{ hidden: true }} diff --git a/datahub-web-react/src/app/entity/shared/components/styled/ERModelRelationship/ERModelRelationPreview.tsx b/datahub-web-react/src/app/entity/shared/components/styled/ERModelRelationship/ERModelRelationPreview.tsx index b360f03bb5b28..ef65aed02decf 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/ERModelRelationship/ERModelRelationPreview.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/ERModelRelationship/ERModelRelationPreview.tsx @@ -132,7 +132,7 @@ export const ERModelRelationPreview = ({ ermodelrelationData, baseEntityUrn, pre
{ermodelrelationData?.properties?.relationshipFieldMappings !== undefined && ( { setModalVisible(false); diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/DownloadAsCsvModal.tsx b/datahub-web-react/src/app/entity/shared/components/styled/search/DownloadAsCsvModal.tsx index c4b5f8fa02b2b..f5bdd205045e8 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/DownloadAsCsvModal.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/DownloadAsCsvModal.tsx @@ -123,7 +123,7 @@ export default function DownloadAsCsvModal({ centered onCancel={() => setShowDownloadAsCsvModal(false)} title="Download as..." - visible={showDownloadAsCsvModal} + open={showDownloadAsCsvModal} footer={ <> } > diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/SearchExtendedMenu.tsx b/datahub-web-react/src/app/entity/shared/components/styled/search/SearchExtendedMenu.tsx index a26749d8a37a1..b9ab2a4bd4fbe 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/SearchExtendedMenu.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/SearchExtendedMenu.tsx @@ -1,11 +1,12 @@ import React, { useState } from 'react'; -import { Button, Dropdown, Menu } from 'antd'; +import { Button, Dropdown } from 'antd'; import { FormOutlined, MoreOutlined } from '@ant-design/icons'; import styled from 'styled-components/macro'; import { AndFilterInput } from '../../../../../../types.generated'; import DownloadAsCsvButton from './DownloadAsCsvButton'; import DownloadAsCsvModal from './DownloadAsCsvModal'; import { DownloadSearchResultsInput, DownloadSearchResults } from '../../../../../search/utils/types'; +import { MenuItemStyle } from '../../../../view/menu/item/styledComponent'; const MenuIcon = styled(MoreOutlined)` font-size: 20px; @@ -18,10 +19,6 @@ const SelectButton = styled(Button)` padding-right: 12px; `; -const MenuItem = styled(Menu.Item)` - padding: 0px; -`; - type Props = { filters: AndFilterInput[]; query: string; @@ -43,24 +40,32 @@ export default function SearchExtendedMenu({ const [isDownloadingCsv, setIsDownloadingCsv] = useState(false); const [showDownloadAsCsvModal, setShowDownloadAsCsvModal] = useState(false); - const menu = ( - - - - - {setShowSelectMode && ( - - setShowSelectMode(true)}> - - Edit... - - - )} - - ); + const items = [ + { + key: 0, + label: ( + + + + ), + }, + setShowSelectMode + ? { + key: 1, + label: ( + + setShowSelectMode(true)}> + + Edit... + + + ), + } + : null, + ]; return ( <> @@ -74,7 +79,7 @@ export default function SearchExtendedMenu({ setShowDownloadAsCsvModal={setShowDownloadAsCsvModal} totalResults={totalResults} /> - + diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/SearchSelectModal.tsx b/datahub-web-react/src/app/entity/shared/components/styled/search/SearchSelectModal.tsx index 985be5b3f37c7..3a9b38b461f4c 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/SearchSelectModal.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/SearchSelectModal.tsx @@ -68,7 +68,7 @@ export const SearchSelectModal = ({ bodyStyle={MODAL_BODY_STYLE} title={titleText || 'Select entities'} width={MODAL_WIDTH_PX} - visible + open onCancel={onCancelSelect} footer={ <> diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/action/ActionDropdown.tsx b/datahub-web-react/src/app/entity/shared/components/styled/search/action/ActionDropdown.tsx index 8158f052a6eb1..c958d3b82a430 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/action/ActionDropdown.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/action/ActionDropdown.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { Button, Dropdown, Menu, Tooltip } from 'antd'; +import { Button, Dropdown, Tooltip } from 'antd'; import { CaretDownOutlined } from '@ant-design/icons'; import styled from 'styled-components'; -import MenuItem from 'antd/lib/menu/MenuItem'; import { ANTD_GRAY } from '../../../../constants'; +import { MenuItemStyle } from '../../../../../view/menu/item/styledComponent'; const DownArrow = styled(CaretDownOutlined)` && { @@ -15,12 +15,6 @@ const DownArrow = styled(CaretDownOutlined)` } `; -const StyledMenuItem = styled(MenuItem)` - && { - padding: 0px; - } -`; - const ActionButton = styled(Button)` font-weight: normal; `; @@ -47,23 +41,20 @@ type Props = { }; export default function ActionDropdown({ name, actions, disabled }: Props) { + const items = actions.map((action, i) => ({ + key: i, + label: ( + + + {action.title} + + + ), + })); + return ( - - {actions.map((action) => ( - - - {action.title} - - - ))} - - } - > + {name} diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/action/GlossaryTermsDropdown.tsx b/datahub-web-react/src/app/entity/shared/components/styled/search/action/GlossaryTermsDropdown.tsx index 7206abed305c4..9083567d0fd70 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/action/GlossaryTermsDropdown.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/action/GlossaryTermsDropdown.tsx @@ -39,7 +39,7 @@ export default function GlossaryTermsDropdown({ urns, disabled = false, refetch {isEditModalVisible && ( { setIsEditModalVisible(false); refetch?.(); diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/action/TagsDropdown.tsx b/datahub-web-react/src/app/entity/shared/components/styled/search/action/TagsDropdown.tsx index 411ee62f64cca..94dcd4d24540f 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/action/TagsDropdown.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/action/TagsDropdown.tsx @@ -39,7 +39,7 @@ export default function TagsDropdown({ urns, disabled = false, refetch }: Props) {isEditModalVisible && ( { setIsEditModalVisible(false); refetch?.(); diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Container/ContainerSelectModal.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Container/ContainerSelectModal.tsx index 17e03ff1ddaf6..681f89831b92c 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Container/ContainerSelectModal.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Container/ContainerSelectModal.tsx @@ -140,7 +140,7 @@ export const ContainerSelectModal = ({ onCloseModal, defaultValues, onOkOverride return ( diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Domain/SetDomainModal.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Domain/SetDomainModal.tsx index ab63553c6376b..f0c315332a053 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Domain/SetDomainModal.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Domain/SetDomainModal.tsx @@ -195,7 +195,7 @@ export const SetDomainModal = ({ urns, onCloseModal, refetch, defaultValue, onOk return ( diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Ownership/EditOwnersModal.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Ownership/EditOwnersModal.tsx index ff26b5d8aa4c5..62b967e8f7b30 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Ownership/EditOwnersModal.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Ownership/EditOwnersModal.tsx @@ -336,7 +336,7 @@ export const EditOwnersModal = ({ return ( diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryBuilderModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryBuilderModal.tsx index 33f9652bb3fd3..063408fbf55a6 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryBuilderModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryBuilderModal.tsx @@ -147,7 +147,7 @@ export default function QueryBuilderModal({ initialState, datasetUrn, onClose, o bodyStyle={MODAL_BODY_STYLE} title={{isUpdating ? 'Edit' : 'New'} Query} className="query-builder-modal" - visible + open onCancel={confirmClose} footer={ <> diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryCardDetailsMenu.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryCardDetailsMenu.tsx index a663dfffaaabf..cff45f153c948 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryCardDetailsMenu.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryCardDetailsMenu.tsx @@ -1,9 +1,10 @@ import React from 'react'; import styled from 'styled-components'; import { DeleteOutlined, MoreOutlined } from '@ant-design/icons'; -import { Dropdown, Menu, message, Modal } from 'antd'; +import { Dropdown, message, Modal } from 'antd'; import { useDeleteQueryMutation } from '../../../../../../graphql/query.generated'; import handleGraphQLError from '../../../../../shared/handleGraphQLError'; +import { MenuItemStyle } from '../../../../view/menu/item/styledComponent'; const StyledMoreOutlined = styled(MoreOutlined)` font-size: 14px; @@ -52,17 +53,19 @@ export default function QueryCardDetailsMenu({ urn, onDeleted, index }: Props) { }); }; + const items = [ + { + key: 0, + label: ( + +   Delete + + ), + }, + ]; + return ( - - -   Delete - - - } - trigger={['click']} - > + ); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryModal.tsx index 985f2094b0fb1..32ac91071a3ec 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Queries/QueryModal.tsx @@ -72,7 +72,7 @@ type Props = { export default function QueryModal({ query, title, description, showDetails = true, onClose }: Props) { return ( { table1Schema={entityWithSchema} table2={table2LazyDataset} table2Schema={table2LazySchema} - visible={modalVisible} + open={modalVisible} setModalVisible={setModalVisible} onCancel={() => { setModalVisible(false); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/components/MenuColumn.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/components/MenuColumn.tsx index b5cd7add41c84..8c97bfbf598bd 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/components/MenuColumn.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/components/MenuColumn.tsx @@ -2,11 +2,12 @@ import React from 'react'; import { VscGraphLeft } from 'react-icons/vsc'; import { CopyOutlined } from '@ant-design/icons'; import styled from 'styled-components/macro'; -import { Dropdown, Menu } from 'antd'; +import { Dropdown } from 'antd'; import { MenuIcon } from '../../../../EntityDropdown/EntityDropdown'; import { useEntityData, useRouteToTab } from '../../../../EntityContext'; import { SchemaField } from '../../../../../../../types.generated'; import { generateSchemaFieldUrn } from '../../../Lineage/utils'; +import { MenuItemStyle } from '../../../../../view/menu/item/styledComponent'; export const ImpactAnalysisIcon = styled(VscGraphLeft)` transform: scaleX(-1); @@ -18,14 +19,6 @@ export const CopyOutlinedIcon = styled(CopyOutlined)` font-size: 16px; `; -const MenuItem = styled.div` - align-items: center; - display: flex; - font-size: 12px; - padding: 0 4px; - color: #262626; -`; - interface Props { field: SchemaField; } @@ -35,43 +28,49 @@ export default function MenuColumn({ field }: Props) { const { urn } = useEntityData(); const selectedColumnUrn = generateSchemaFieldUrn(field.fieldPath, urn); + const items = [ + { + key: 0, + label: ( + routeToTab({ tabName: 'Lineage', tabParams: { column: field.fieldPath } })} + > +   See Column Lineage + + ), + }, + navigator.clipboard + ? { + key: 1, + label: ( + { + navigator.clipboard.writeText(field.fieldPath); + }} + > +   Copy Column Field Path + + ), + } + : null, + navigator.clipboard + ? { + key: 2, + label: ( + { + navigator.clipboard.writeText(selectedColumnUrn || ''); + }} + > +   Copy Column Urn + + ), + } + : null, + ]; + return ( - - - routeToTab({ tabName: 'Lineage', tabParams: { column: field.fieldPath } })} - > -   See Column Lineage - - - {navigator.clipboard && ( - - { - navigator.clipboard.writeText(field.fieldPath); - }} - > -   Copy Column Field Path - - - )} - {navigator.clipboard && ( - - { - navigator.clipboard.writeText(selectedColumnUrn || ''); - }} - > -   Copy Column Urn - - - )} - - } - trigger={['click']} - > + ); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Stats/historical/charts/ProfilingRunsChart.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Stats/historical/charts/ProfilingRunsChart.tsx index 11ec85d65da42..0b2eb6db1c6f0 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Stats/historical/charts/ProfilingRunsChart.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Stats/historical/charts/ProfilingRunsChart.tsx @@ -84,7 +84,7 @@ export default function ProfilingRunsChart({ profiles }: Props) { return ( <> {selectedProfile && ( - + - - - ); -} diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionDescription.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionDescription.tsx index daebfd5597588..3318baf6d0c60 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionDescription.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionDescription.tsx @@ -362,7 +362,7 @@ export const DatasetAssertionDescription = ({ description, assertionInfo }: Prop )} setIsLogicVisible(false)} /> diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionLogicModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionLogicModal.tsx index 549a10ecd24cd..627deb163c2a0 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionLogicModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionLogicModal.tsx @@ -11,13 +11,13 @@ export type AssertionsSummary = { type Props = { logic: string; - visible: boolean; + open: boolean; onClose: () => void; }; -export const DatasetAssertionLogicModal = ({ logic, visible, onClose }: Props) => { +export const DatasetAssertionLogicModal = ({ logic, open, onClose }: Props) => { return ( - Close}> + Close}> ); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionsList.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionsList.tsx index bfcb30b6c5e7a..af8f943455849 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionsList.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/DatasetAssertionsList.tsx @@ -17,11 +17,11 @@ import { Assertion, AssertionRunStatus, DataContract, EntityType } from '../../. import { getResultColor, getResultIcon, getResultText } from './assertionUtils'; import { useDeleteAssertionMutation } from '../../../../../../graphql/assertion.generated'; import { capitalizeFirstLetterOnly } from '../../../../../shared/textUtil'; -import AssertionMenu from './AssertionMenu'; import { REDESIGN_COLORS } from '../../../constants'; import { useEntityRegistry } from '../../../../../useEntityRegistry'; import { isAssertionPartOfContract } from './contract/utils'; import { useEntityData } from '../../../EntityContext'; +import CopyUrnMenuItem from '../../../../../shared/share/items/CopyUrnMenuItem'; const ResultContainer = styled.div` display: flex; @@ -136,6 +136,15 @@ export const DatasetAssertionsList = ({ assertion.runEvents.runEvents[0].result?.type, })); + const assertionMenuItems = (urn: string) => { + return [ + { + key: 1, + label: , + }, + ]; + }; + const assertionsTableCols = [ { title: '', @@ -215,9 +224,9 @@ export const DatasetAssertionsList = ({ title: '', dataIndex: '', key: '', - render: (_, record: any) => ( - <> - {showMenu && ( + render: (_, record: any) => { + return ( + showMenu && ( onDeleteAssertion(record.urn)} type="text" shape="circle" danger> - } trigger={['click']}> + - )} - - ), + ) + ); + }, }, ]; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/contract/builder/DataContractBuilderModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/contract/builder/DataContractBuilderModal.tsx index 75a8fe0410918..e678ce5c334ea 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/contract/builder/DataContractBuilderModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Validations/contract/builder/DataContractBuilderModal.tsx @@ -52,7 +52,7 @@ export const DataContractBuilderModal = ({ entityUrn, initialState, onSubmit, on title={{titleText}} style={modalStyle} bodyStyle={modalBodyStyle} - visible + open onCancel={onCancel} > { <> { commandName="insertImage" onClick={handleButtonClick} /> - +
{ commandName="insertLink" onClick={handleButtonClick} /> - + ); }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/FloatingToolbar.tsx b/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/FloatingToolbar.tsx index 24e87853b58c7..bcd8e44b36761 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/FloatingToolbar.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/FloatingToolbar.tsx @@ -112,7 +112,7 @@ export const FloatingToolbar = () => { )} - + ); }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/LinkModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/LinkModal.tsx index 14698291575c4..81fce2635f12e 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/LinkModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Documentation/components/editor/toolbar/LinkModal.tsx @@ -5,12 +5,12 @@ import { useAttrs, useCommands, useEditorState, useHelpers } from '@remirror/rea import { getMarkRange } from '@remirror/core-utils'; type LinkModalProps = { - visible: boolean; + open: boolean; handleClose: () => void; }; export const LinkModal = (props: LinkModalProps) => { - const { visible, handleClose } = props; + const { open, handleClose } = props; const [trPos, setTrPos] = useState({ from: 0, to: 0 }); const [form] = Form.useForm(); @@ -22,7 +22,7 @@ export const LinkModal = (props: LinkModalProps) => { const href = (useAttrs().link()?.href as string) ?? ''; useEffect(() => { - if (visible) { + if (open) { const { from, to } = editorState.selection; const pos = getMarkRange(editorState.doc.resolve(from), 'link') || { from, to }; @@ -34,7 +34,7 @@ export const LinkModal = (props: LinkModalProps) => { setTrPos(pos); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [visible]); + }, [open]); const handleOk = async () => { try { @@ -58,7 +58,7 @@ export const LinkModal = (props: LinkModalProps) => { }; return ( - + { const active = useActive(); const commands = useCommands(); - const menu = ( - - } - disabled={active.tableHeaderCell()} - onClick={() => commands.addTableRowBefore()} - > - Insert row above - - } onClick={() => commands.addTableRowAfter()}> - Insert row below - - } onClick={() => commands.addTableColumnBefore()}> - Insert column left - - } onClick={() => commands.addTableColumnAfter()}> - Insert column right - - - } - disabled={active.tableHeaderCell()} - onClick={() => commands.deleteTableRow()} - > - Delete row - - } onClick={() => commands.deleteTableColumn()}> - Delete column - - } onClick={() => commands.deleteTable()}> - Delete table - - - ); + const divider = { + key: 'divider', + type: 'divider', + }; + + const items = [ + { + key: 0, + label: ( + } + disabled={active.tableHeaderCell()} + onClick={() => commands.addTableRowBefore()} + > + Insert row above + + ), + }, + { + key: 1, + label: ( + } onClick={() => commands.addTableRowAfter()}> + Insert row below + + ), + }, + { + key: 2, + label: ( + } onClick={() => commands.addTableColumnBefore()}> + Insert column left + + ), + }, + { + key: 3, + label: ( + } onClick={() => commands.addTableColumnAfter()}> + Insert column right + + ), + }, + divider, + { + key: 4, + label: ( + } + disabled={active.tableHeaderCell()} + onClick={() => commands.deleteTableRow()} + > + Delete row + + ), + }, + { + key: 5, + label: ( + } onClick={() => commands.deleteTableColumn()}> + Delete column + + ), + }, + { + key: 6, + label: ( + } onClick={() => commands.deleteTable()}> + Delete table + + ), + }, + ]; return ( } placement="bottomLeft" - overlay={menu} + menu={{ items }} type="primary" /> ); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Incident/IncidentTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Incident/IncidentTab.tsx index 47627068ad4ce..f2b03a11ffb55 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Incident/IncidentTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Incident/IncidentTab.tsx @@ -87,7 +87,7 @@ export const IncidentTab = () => { setIsRaiseIncidentModalVisible(false)} /> diff --git a/datahub-web-react/src/app/entity/shared/tabs/Incident/components/AddIncidentModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Incident/components/AddIncidentModal.tsx index bb83f0f9ddaf7..fda8c9cda2d0d 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Incident/components/AddIncidentModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Incident/components/AddIncidentModal.tsx @@ -11,12 +11,12 @@ import handleGraphQLError from '../../../../../shared/handleGraphQLError'; import { useUserContext } from '../../../../../context/useUserContext'; type AddIncidentProps = { - visible: boolean; + open: boolean; onClose?: () => void; refetch?: () => Promise; }; -export const AddIncidentModal = ({ visible, onClose, refetch }: AddIncidentProps) => { +export const AddIncidentModal = ({ open, onClose, refetch }: AddIncidentProps) => { const { urn, entityType } = useEntityData(); const { user } = useUserContext(); const incidentTypes = INCIDENT_DISPLAY_TYPES; @@ -109,7 +109,7 @@ export const AddIncidentModal = ({ visible, onClose, refetch }: AddIncidentProps <> - - updateIncidentStatus(IncidentState.Active, '')} data-testid="reopen-incident"> + const items = [ + { + key: 0, + label: ( + updateIncidentStatus(IncidentState.Active, '')} + data-testid="reopen-incident" + > Reopen incident - - - - ); + + ), + }, + ]; return ( <> @@ -296,7 +294,7 @@ export default function IncidentListItem({ incident, refetch }: Props) { - + diff --git a/datahub-web-react/src/app/entity/shared/tabs/Incident/components/ResolveIncidentModal.tsx b/datahub-web-react/src/app/entity/shared/tabs/Incident/components/ResolveIncidentModal.tsx index b915ef0a76a3f..cdc82420a73b2 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Incident/components/ResolveIncidentModal.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Incident/components/ResolveIncidentModal.tsx @@ -31,7 +31,7 @@ export const ResolveIncidentModal = ({ <> void; onSave: () => void; editModalData: PropsData; @@ -24,7 +24,7 @@ type Props = { /** Regex Validations */ export const USER_NAME_REGEX = new RegExp('^[a-zA-Z ]*$'); -export default function UserEditProfileModal({ visible, onClose, onSave, editModalData }: Props) { +export default function UserEditProfileModal({ open, onClose, onSave, editModalData }: Props) { const { config } = useAppConfig(); const { readOnlyModeEnabled } = config.featureFlags; const [updateCorpUserPropertiesMutation] = useUpdateCorpUserPropertiesMutation(); @@ -95,7 +95,7 @@ export default function UserEditProfileModal({ visible, onClose, onSave, editMod return ( diff --git a/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx b/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx index 4e3dc45489b55..8d3b1b43bad56 100644 --- a/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx +++ b/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx @@ -174,7 +174,7 @@ export default function UserInfoSideBar({ sideBarData, refetch }: Props) { {/* Modal */} showEditProfileModal(false)} onSave={() => { refetch(); diff --git a/datahub-web-react/src/app/entity/view/builder/ViewBuilderModal.tsx b/datahub-web-react/src/app/entity/view/builder/ViewBuilderModal.tsx index a69e7e156ba9a..ff49a9d06d1ea 100644 --- a/datahub-web-react/src/app/entity/view/builder/ViewBuilderModal.tsx +++ b/datahub-web-react/src/app/entity/view/builder/ViewBuilderModal.tsx @@ -77,7 +77,7 @@ export const ViewBuilderModal = ({ mode, urn, initialState, onSubmit, onCancel } } style={modalStyle} bodyStyle={modalBodyStyle} - visible + open width={modalWidth} onCancel={onCancel} data-testid="view-modal" diff --git a/datahub-web-react/src/app/entity/view/menu/ViewDropdownMenu.tsx b/datahub-web-react/src/app/entity/view/menu/ViewDropdownMenu.tsx index 38deb4052b7a9..f75240aba2f0d 100644 --- a/datahub-web-react/src/app/entity/view/menu/ViewDropdownMenu.tsx +++ b/datahub-web-react/src/app/entity/view/menu/ViewDropdownMenu.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import styled from 'styled-components'; import { useApolloClient } from '@apollo/client'; import { MoreOutlined } from '@ant-design/icons'; -import { Dropdown, Menu, message, Modal } from 'antd'; +import { Dropdown, message, Modal } from 'antd'; import { DataHubView, DataHubViewType } from '../../../../types.generated'; import { useUserContext } from '../../../context/useUserContext'; import { useUpdateCorpUserViewsSettingsMutation } from '../../../../graphql/user.generated'; @@ -33,17 +33,6 @@ const MenuButton = styled(MoreOutlined)` } `; -const MenuStyled = styled(Menu)` - &&& { - .ant-dropdown-menu-item:not(:hover) { - background: none; - } - .ant-dropdown-menu-item:hover { - background: #f5f5f5; - } - } -`; - const DEFAULT_VIEW_BUILDER_STATE = { mode: ViewBuilderMode.EDITOR, visible: false, @@ -240,28 +229,42 @@ export const ViewDropdownMenu = ({ const showRemoveGlobalDefaultView = canManageGlobalViews && isGlobalView && isGlobalDefault; const showSetGlobalDefaultView = canManageGlobalViews && isGlobalView && !isGlobalDefault; + const items = [ + { + key: 0, + label: (canManageView && ) || ( + + ), + }, + { + key: 1, + label: (isUserDefault && setUserDefault(null)} />) || ( + setUserDefault(view.urn)} /> + ), + }, + showRemoveGlobalDefaultView + ? { + key: 2, + label: setGlobalDefault(null)} />, + } + : null, + showSetGlobalDefaultView + ? { + key: 2, + label: setGlobalDefault(view.urn)} />, + } + : null, + canManageView + ? { + key: 3, + label: , + } + : null, + ]; + return ( <> - - {(canManageView && ) || ( - - )} - {(isUserDefault && setUserDefault(null)} />) || ( - setUserDefault(view.urn)} /> - )} - {showRemoveGlobalDefaultView && ( - setGlobalDefault(null)} /> - )} - {showSetGlobalDefaultView && ( - setGlobalDefault(view.urn)} /> - )} - {canManageView && } - - } - trigger={[trigger]} - > + {viewBuilderState.visible && ( diff --git a/datahub-web-react/src/app/entity/view/menu/item/DeleteViewItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/DeleteViewItem.tsx index b8513c23ebe4f..c6dce2c01e23c 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/DeleteViewItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/DeleteViewItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { DeleteOutlined } from '@ant-design/icons'; -import { Menu } from 'antd'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,8 +13,8 @@ type Props = { */ export const DeleteViewItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/EditViewItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/EditViewItem.tsx index 650bc239957ab..5301f9977126d 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/EditViewItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/EditViewItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { FormOutlined } from '@ant-design/icons'; -import { Menu } from 'antd'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,8 +13,8 @@ type Props = { */ export const EditViewItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/PreviewViewItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/PreviewViewItem.tsx index 24b122feeb235..eb64ec8101a5b 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/PreviewViewItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/PreviewViewItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Menu } from 'antd'; import { EyeOutlined } from '@ant-design/icons'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,8 +13,8 @@ type Props = { */ export const PreviewViewItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/RemoveGlobalDefaultItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/RemoveGlobalDefaultItem.tsx index 10977fcc4470e..0b6657892169b 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/RemoveGlobalDefaultItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/RemoveGlobalDefaultItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StopOutlined } from '@ant-design/icons'; -import { Menu } from 'antd'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,12 +13,12 @@ type Props = { */ export const RemoveGlobalDefaultItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/RemoveUserDefaultItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/RemoveUserDefaultItem.tsx index d07d54f6b929b..612bcd0a0a431 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/RemoveUserDefaultItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/RemoveUserDefaultItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StopOutlined } from '@ant-design/icons'; -import { Menu } from 'antd'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,12 +13,12 @@ type Props = { */ export const RemoveUserDefaultItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/SetGlobalDefaultItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/SetGlobalDefaultItem.tsx index 7461565c22ec5..94e1adb280c2f 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/SetGlobalDefaultItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/SetGlobalDefaultItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Menu } from 'antd'; import { GlobalDefaultViewIcon } from '../../shared/GlobalDefaultViewIcon'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,12 +13,12 @@ type Props = { */ export const SetGlobalDefaultItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/SetUserDefaultItem.tsx b/datahub-web-react/src/app/entity/view/menu/item/SetUserDefaultItem.tsx index 3149f06294c00..4eea8e5c2c65c 100644 --- a/datahub-web-react/src/app/entity/view/menu/item/SetUserDefaultItem.tsx +++ b/datahub-web-react/src/app/entity/view/menu/item/SetUserDefaultItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Menu } from 'antd'; import { UserDefaultViewIcon } from '../../shared/UserDefaultViewIcon'; import { IconItemTitle } from './IconItemTitle'; +import { MenuItemStyle } from './styledComponent'; type Props = { key: string; @@ -13,12 +13,12 @@ type Props = { */ export const SetUserDefaultItem = ({ key, onClick }: Props) => { return ( - + } /> - + ); }; diff --git a/datahub-web-react/src/app/entity/view/menu/item/styledComponent.ts b/datahub-web-react/src/app/entity/view/menu/item/styledComponent.ts new file mode 100644 index 0000000000000..7534dd391c472 --- /dev/null +++ b/datahub-web-react/src/app/entity/view/menu/item/styledComponent.ts @@ -0,0 +1,11 @@ +import MenuItem from 'antd/lib/menu/MenuItem'; +import styled from 'styled-components'; + +export const MenuItemStyle = styled(MenuItem)` + &&&& { + background-color: transparent; + a { + color: inherit; + } + } +`; diff --git a/datahub-web-react/src/app/identity/group/AssignRoletoGroupConfirmation.tsx b/datahub-web-react/src/app/identity/group/AssignRoletoGroupConfirmation.tsx index f08b607222de6..513a85c97ffc1 100644 --- a/datahub-web-react/src/app/identity/group/AssignRoletoGroupConfirmation.tsx +++ b/datahub-web-react/src/app/identity/group/AssignRoletoGroupConfirmation.tsx @@ -5,7 +5,7 @@ import { DataHubRole } from '../../../types.generated'; import analytics, { EventType } from '../../analytics'; type Props = { - visible: boolean; + open: boolean; roleToAssign: DataHubRole | undefined; groupName: string; groupUrn: string; @@ -14,7 +14,7 @@ type Props = { }; export default function AssignRoletoGroupConfirmation({ - visible, + open, roleToAssign, groupName, groupUrn, @@ -63,5 +63,5 @@ export default function AssignRoletoGroupConfirmation({ ? `Would you like to assign the role ${roleToAssign?.name} to group ${groupName}?` : `Would you like to remove group ${groupName}'s existing role?`; - return ; + return ; } diff --git a/datahub-web-react/src/app/identity/group/CreateGroupModal.tsx b/datahub-web-react/src/app/identity/group/CreateGroupModal.tsx index 4ba714ca23ae0..b24fc8f17b49f 100644 --- a/datahub-web-react/src/app/identity/group/CreateGroupModal.tsx +++ b/datahub-web-react/src/app/identity/group/CreateGroupModal.tsx @@ -89,7 +89,7 @@ export default function CreateGroupModal({ onClose, onCreate }: Props) { diff --git a/datahub-web-react/src/app/identity/group/SelectRoleGroup.tsx b/datahub-web-react/src/app/identity/group/SelectRoleGroup.tsx index 22c7a4bfb0364..0e68c4e25af90 100644 --- a/datahub-web-react/src/app/identity/group/SelectRoleGroup.tsx +++ b/datahub-web-react/src/app/identity/group/SelectRoleGroup.tsx @@ -90,7 +90,7 @@ export default function SelectRoleGroup({ group, groupRoleUrn, selectRoleOptions {selectOptions} void; }; -export default function AssignRoleConfirmation({ - visible, - roleToAssign, - userUrn, - username, - onClose, - onConfirm, -}: Props) { +export default function AssignRoleConfirmation({ open, roleToAssign, userUrn, username, onClose, onConfirm }: Props) { const [batchAssignRoleMutation] = useBatchAssignRoleMutation(); // eslint-disable-next-line const batchAssignRole = () => { @@ -63,5 +56,5 @@ export default function AssignRoleConfirmation({ ? `Would you like to assign the role ${roleToAssign?.name} to ${username}?` : `Would you like to remove ${username}'s existing role?`; - return ; + return ; } diff --git a/datahub-web-react/src/app/identity/user/SelectRole.tsx b/datahub-web-react/src/app/identity/user/SelectRole.tsx index deaa85f14b088..7e9acb08ed0bc 100644 --- a/datahub-web-react/src/app/identity/user/SelectRole.tsx +++ b/datahub-web-react/src/app/identity/user/SelectRole.tsx @@ -90,7 +90,7 @@ export default function SelectRole({ user, userRoleUrn, selectRoleOptions, refet {selectOptions} { /> {canManagePolicies && ( - setIsViewingInviteToken(false)} - /> + setIsViewingInviteToken(false)} /> )} diff --git a/datahub-web-react/src/app/identity/user/UserListItem.tsx b/datahub-web-react/src/app/identity/user/UserListItem.tsx index ff349664d7628..486646c05bd6b 100644 --- a/datahub-web-react/src/app/identity/user/UserListItem.tsx +++ b/datahub-web-react/src/app/identity/user/UserListItem.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import styled from 'styled-components/macro'; -import { Dropdown, List, Menu, Tag, Tooltip, Typography } from 'antd'; +import { Dropdown, List, Tag, Tooltip, Typography } from 'antd'; import { Link } from 'react-router-dom'; import { DeleteOutlined, MoreOutlined, UnlockOutlined } from '@ant-design/icons'; import { CorpUser, CorpUserStatus, EntityType, DataHubRole } from '../../../types.generated'; @@ -11,6 +11,7 @@ import ViewResetTokenModal from './ViewResetTokenModal'; import useDeleteEntity from '../../entity/shared/EntityDropdown/useDeleteEntity'; import SelectRole from './SelectRole'; import { USERS_ASSIGN_ROLE_ID } from '../../onboarding/config/UsersOnboardingConfig'; +import { MenuItemStyle } from '../../entity/view/menu/item/styledComponent'; type Props = { user: CorpUser; @@ -84,6 +85,29 @@ export default function UserListItem({ user, canManageUserCredentials, selectRol const userStatusToolTip = userStatus && getUserStatusToolTip(userStatus); const userStatusColor = userStatus && getUserStatusColor(userStatus); + const items = [ + { + key: 'reset', + label: ( + setIsViewingResetToken(true)} + data-testid="reset-menu-item" + > +   Reset user password + + ), + }, + { + key: 'delete', + label: ( + +  Delete + + ), + }, + ]; + return ( @@ -117,23 +141,7 @@ export default function UserListItem({ user, canManageUserCredentials, selectRol selectRoleOptions={selectRoleOptions} refetch={refetch} /> - - setIsViewingResetToken(true)} - data-testid="reset-menu-item" - > -   Reset user password - - -  Delete - - - } - > + setIsViewingResetToken(false)} diff --git a/datahub-web-react/src/app/identity/user/ViewInviteTokenModal.tsx b/datahub-web-react/src/app/identity/user/ViewInviteTokenModal.tsx index b823d7bace549..4f4d2d5b8c69e 100644 --- a/datahub-web-react/src/app/identity/user/ViewInviteTokenModal.tsx +++ b/datahub-web-react/src/app/identity/user/ViewInviteTokenModal.tsx @@ -65,11 +65,11 @@ const RoleIcon = styled.span` `; type Props = { - visible: boolean; + open: boolean; onClose: () => void; }; -export default function ViewInviteTokenModal({ visible, onClose }: Props) { +export default function ViewInviteTokenModal({ open, onClose }: Props) { const baseUrl = window.location.origin; const location = useLocation(); const params = QueryString.parse(location.search, { arrayFormat: 'comma' }); @@ -110,7 +110,7 @@ export default function ViewInviteTokenModal({ visible, onClose }: Props) { // Code related to getting or creating an invite token const { data: getInviteTokenData } = useGetInviteTokenQuery({ - skip: !visible, + skip: !open, variables: { input: { roleUrn: selectedRole?.urn } }, }); @@ -167,7 +167,7 @@ export default function ViewInviteTokenModal({ visible, onClose }: Props) { Share Invite Link } - visible={visible} + open={open} onCancel={onClose} > diff --git a/datahub-web-react/src/app/identity/user/ViewResetTokenModal.tsx b/datahub-web-react/src/app/identity/user/ViewResetTokenModal.tsx index 42754c4c4d362..4711040bf8f5e 100644 --- a/datahub-web-react/src/app/identity/user/ViewResetTokenModal.tsx +++ b/datahub-web-react/src/app/identity/user/ViewResetTokenModal.tsx @@ -34,13 +34,13 @@ const CreateResetTokenButton = styled(Button)` `; type Props = { - visible: boolean; + open: boolean; userUrn: string; username: string; onClose: () => void; }; -export default function ViewResetTokenModal({ visible, userUrn, username, onClose }: Props) { +export default function ViewResetTokenModal({ open, userUrn, username, onClose }: Props) { const baseUrl = window.location.origin; const [hasGeneratedResetToken, setHasGeneratedResetToken] = useState(false); @@ -87,7 +87,7 @@ export default function ViewResetTokenModal({ visible, userUrn, username, onClos Reset User Password } - visible={visible} + open={open} onCancel={onClose} > {hasGeneratedResetToken ? ( diff --git a/datahub-web-react/src/app/ingest/secret/SecretBuilderModal.tsx b/datahub-web-react/src/app/ingest/secret/SecretBuilderModal.tsx index 2d20ac77891ea..8f42505e5e07a 100644 --- a/datahub-web-react/src/app/ingest/secret/SecretBuilderModal.tsx +++ b/datahub-web-react/src/app/ingest/secret/SecretBuilderModal.tsx @@ -10,13 +10,13 @@ const VALUE_FIELD_NAME = 'value'; type Props = { initialState?: SecretBuilderState; editSecret?: SecretBuilderState; - visible: boolean; + open: boolean; onSubmit?: (source: SecretBuilderState, resetState: () => void) => void; onUpdate?: (source: SecretBuilderState, resetState: () => void) => void; onCancel?: () => void; }; -export const SecretBuilderModal = ({ initialState, editSecret, visible, onSubmit, onUpdate, onCancel }: Props) => { +export const SecretBuilderModal = ({ initialState, editSecret, open, onSubmit, onUpdate, onCancel }: Props) => { const [createButtonEnabled, setCreateButtonEnabled] = useState(false); const [form] = Form.useForm(); @@ -52,7 +52,7 @@ export const SecretBuilderModal = ({ initialState, editSecret, visible, onSubmit {titleText}} - visible={visible} + open={open} onCancel={onCloseModal} zIndex={1051} // one higher than other modals - needed for managed ingestion forms footer={ diff --git a/datahub-web-react/src/app/ingest/secret/SecretsList.tsx b/datahub-web-react/src/app/ingest/secret/SecretsList.tsx index 472dbf7f849de..145bf3dd029fb 100644 --- a/datahub-web-react/src/app/ingest/secret/SecretsList.tsx +++ b/datahub-web-react/src/app/ingest/secret/SecretsList.tsx @@ -294,7 +294,7 @@ export const SecretsList = () => {
{ {isViewingRecipe && } {focusExecutionUrn && ( - setFocusExecutionUrn(undefined)} - /> + setFocusExecutionUrn(undefined)} /> )} ); diff --git a/datahub-web-react/src/app/ingest/source/RecipeViewerModal.tsx b/datahub-web-react/src/app/ingest/source/RecipeViewerModal.tsx index 99c93d2a174fc..f08747e757e58 100644 --- a/datahub-web-react/src/app/ingest/source/RecipeViewerModal.tsx +++ b/datahub-web-react/src/app/ingest/source/RecipeViewerModal.tsx @@ -18,7 +18,7 @@ function RecipeViewerModal({ recipe, onCancel }: Props) { return ( void, shouldRun?: boolean) => void; onCancel?: () => void; }; -export const IngestionSourceBuilderModal = ({ initialState, visible, onSubmit, onCancel }: Props) => { +export const IngestionSourceBuilderModal = ({ initialState, open, onSubmit, onCancel }: Props) => { const isEditing = initialState !== undefined; const titleText = isEditing ? 'Edit Data Source' : 'Connect Data Source'; const initialStep = isEditing @@ -139,7 +139,7 @@ export const IngestionSourceBuilderModal = ({ initialState, visible, onSubmit, o } style={{ top: 40 }} bodyStyle={modalBodyStyle} - visible={visible} + open={open} onCancel={onCancel} > {currentStepIndex > 0 ? ( diff --git a/datahub-web-react/src/app/ingest/source/builder/RecipeForm/SecretField/CreateSecretButton.tsx b/datahub-web-react/src/app/ingest/source/builder/RecipeForm/SecretField/CreateSecretButton.tsx index 8561805e6270c..b5788c3ecb116 100644 --- a/datahub-web-react/src/app/ingest/source/builder/RecipeForm/SecretField/CreateSecretButton.tsx +++ b/datahub-web-react/src/app/ingest/source/builder/RecipeForm/SecretField/CreateSecretButton.tsx @@ -64,7 +64,7 @@ function CreateSecretButton({ initialState, onSubmit, refetchSecrets }: Props) { {isCreateModalVisible && ( setIsCreateModalVisible(false)} onSubmit={createSecret} /> diff --git a/datahub-web-react/src/app/ingest/source/builder/RecipeForm/TestConnection/TestConnectionModal.tsx b/datahub-web-react/src/app/ingest/source/builder/RecipeForm/TestConnection/TestConnectionModal.tsx index 3528c5d7fa50c..3a0bc47fa7d26 100644 --- a/datahub-web-react/src/app/ingest/source/builder/RecipeForm/TestConnection/TestConnectionModal.tsx +++ b/datahub-web-react/src/app/ingest/source/builder/RecipeForm/TestConnection/TestConnectionModal.tsx @@ -101,7 +101,7 @@ function TestConnectionModal({ return ( Done} title={ diff --git a/datahub-web-react/src/app/ingest/source/executions/ExecutionRequestDetailsModal.tsx b/datahub-web-react/src/app/ingest/source/executions/ExecutionRequestDetailsModal.tsx index 6711f0ad12b03..c8d4188886750 100644 --- a/datahub-web-react/src/app/ingest/source/executions/ExecutionRequestDetailsModal.tsx +++ b/datahub-web-react/src/app/ingest/source/executions/ExecutionRequestDetailsModal.tsx @@ -113,11 +113,11 @@ type DetailsContainerProps = { type Props = { urn: string; - visible: boolean; + open: boolean; onClose: () => void; }; -export const ExecutionDetailsModal = ({ urn, visible, onClose }: Props) => { +export const ExecutionDetailsModal = ({ urn, open, onClose }: Props) => { const [showExpandedLogs, setShowExpandedLogs] = useState(false); const [showExpandedRecipe, setShowExpandedRecipe] = useState(false); @@ -178,7 +178,7 @@ export const ExecutionDetailsModal = ({ urn, visible, onClose }: Props) => { Sync Details } - visible={visible} + open={open} onCancel={onClose} > {!data && loading && } diff --git a/datahub-web-react/src/app/ingest/source/executions/IngestionSourceExecutionList.tsx b/datahub-web-react/src/app/ingest/source/executions/IngestionSourceExecutionList.tsx index 6a75ddb3200c8..9c40a3334df17 100644 --- a/datahub-web-react/src/app/ingest/source/executions/IngestionSourceExecutionList.tsx +++ b/datahub-web-react/src/app/ingest/source/executions/IngestionSourceExecutionList.tsx @@ -172,7 +172,7 @@ export const IngestionSourceExecutionList = ({ urn, isExpanded, lastRefresh, onR {focusExecutionUrn && ( setFocusExecutionUrn(undefined)} /> )} diff --git a/datahub-web-react/src/app/lineage/LineageExplorer.tsx b/datahub-web-react/src/app/lineage/LineageExplorer.tsx index ce0c4bb8f122d..6d5815afe7d30 100644 --- a/datahub-web-react/src/app/lineage/LineageExplorer.tsx +++ b/datahub-web-react/src/app/lineage/LineageExplorer.tsx @@ -210,7 +210,7 @@ export default function LineageExplorer({ urn, type }: Props) { placement="left" closable={false} onClose={handleClose} - visible={isDrawerVisible} + open={isDrawerVisible} width={490} bodyStyle={{ overflowX: 'hidden' }} mask={false} diff --git a/datahub-web-react/src/app/lineage/manage/ManageLineageMenu.tsx b/datahub-web-react/src/app/lineage/manage/ManageLineageMenu.tsx index 3c329b1784fc4..b321075fdef81 100644 --- a/datahub-web-react/src/app/lineage/manage/ManageLineageMenu.tsx +++ b/datahub-web-react/src/app/lineage/manage/ManageLineageMenu.tsx @@ -1,5 +1,5 @@ import { ArrowDownOutlined, ArrowUpOutlined, MoreOutlined } from '@ant-design/icons'; -import { Dropdown, Menu, Popover, Tooltip } from 'antd'; +import { Dropdown, Popover, Tooltip } from 'antd'; import React, { useState } from 'react'; import styled from 'styled-components'; import FocusIcon from '../../../images/focus.svg'; @@ -7,6 +7,7 @@ import { Direction, UpdatedLineages } from '../types'; import { EntityType } from '../../../types.generated'; import ManageLineageModal from './ManageLineageModal'; import { ENTITY_TYPES_WITH_MANUAL_LINEAGE } from '../../entity/shared/constants'; +import { MenuItemStyle } from '../../entity/view/menu/item/styledComponent'; const DROPDOWN_Z_INDEX = 1; const POPOVER_Z_INDEX = 2; @@ -21,13 +22,7 @@ const UnderlineWrapper = styled.span` cursor: pointer; `; -const StyledMenuItem = styled(Menu.Item)` - padding: 0; -`; - -const MenuItemContent = styled.div` - padding: 5px 12px; -`; +const MenuItemContent = styled.div``; function PopoverContent({ centerEntity, direction }: { centerEntity?: () => void; direction: string }) { return ( @@ -93,6 +88,65 @@ export default function ManageLineageMenu({ // if we don't show manual lineage options or the center node option, this menu has no options if (!isManualLineageSupported && isCenterNode) return null; + const items = [ + isManualLineageSupported + ? { + key: 0, + label: ( + manageLineage(Direction.Upstream)} disabled={isUpstreamDisabled}> + + ) + } + overlayStyle={isUpstreamDisabled ? { zIndex: POPOVER_Z_INDEX } : { display: 'none' }} + > + + +   Edit Upstream + + + + ), + } + : null, + isManualLineageSupported + ? { + key: 1, + label: ( + manageLineage(Direction.Downstream)} + disabled={isDownstreamDisabled} + > + + + +   Edit Downstream + + + + ), + } + : null, + !isCenterNode && centerEntity + ? { + key: 2, + label: ( + + +   Focus on Entity + + ), + } + : null, + ]; + return ( <> @@ -100,71 +154,7 @@ export default function ManageLineageMenu({ - {isManualLineageSupported && ( - <> - manageLineage(Direction.Upstream)} - disabled={isUpstreamDisabled} - > - - ) - } - overlayStyle={ - isUpstreamDisabled - ? { zIndex: POPOVER_Z_INDEX } - : { display: 'none' } - } - > - - -   Edit Upstream - - - - manageLineage(Direction.Downstream)} - disabled={isDownstreamDisabled} - > - - - -   Edit Downstream - - - - - )} - {!isCenterNode && centerEntity && ( - - -   Focus on Entity - - )} - - } + menu={{ items }} trigger={['click']} > {menuIcon || } diff --git a/datahub-web-react/src/app/lineage/manage/ManageLineageModal.tsx b/datahub-web-react/src/app/lineage/manage/ManageLineageModal.tsx index 6f459034579d3..ed792724ebedf 100644 --- a/datahub-web-react/src/app/lineage/manage/ManageLineageModal.tsx +++ b/datahub-web-react/src/app/lineage/manage/ManageLineageModal.tsx @@ -117,7 +117,7 @@ export default function ManageLineageModal({ return ( Manage {lineageDirection} Lineage} - visible + open onCancel={closeModal} keyboard footer={ diff --git a/datahub-web-react/src/app/permissions/policy/ManagePolicies.tsx b/datahub-web-react/src/app/permissions/policy/ManagePolicies.tsx index 5838271b3de5b..51fbc83d32063 100644 --- a/datahub-web-react/src/app/permissions/policy/ManagePolicies.tsx +++ b/datahub-web-react/src/app/permissions/policy/ManagePolicies.tsx @@ -426,7 +426,7 @@ export const ManagePolicies = () => { focusPolicyUrn={focusPolicyUrn} policy={focusPolicy || EMPTY_POLICY} setPolicy={setFocusPolicy} - visible={showPolicyBuilderModal} + open={showPolicyBuilderModal} onClose={onClosePolicyBuilder} onSave={onSavePolicy} /> @@ -434,7 +434,7 @@ export const ManagePolicies = () => { {showViewPolicyModal && ( diff --git a/datahub-web-react/src/app/permissions/policy/PolicyBuilderModal.tsx b/datahub-web-react/src/app/permissions/policy/PolicyBuilderModal.tsx index 131a586329ff5..7471aa476dc23 100644 --- a/datahub-web-react/src/app/permissions/policy/PolicyBuilderModal.tsx +++ b/datahub-web-react/src/app/permissions/policy/PolicyBuilderModal.tsx @@ -12,7 +12,7 @@ import ClickOutside from '../../shared/ClickOutside'; type Props = { policy: Omit; setPolicy: (policy: Omit) => void; - visible: boolean; + open: boolean; focusPolicyUrn: string | undefined; onClose: () => void; onSave: (savePolicy: Omit) => void; @@ -40,7 +40,7 @@ const NextButtonContainer = styled.div` * Component used for constructing new policies. The purpose of this flow is to populate or edit a Policy * object through a sequence of steps. */ -export default function PolicyBuilderModal({ policy, setPolicy, visible, onClose, onSave, focusPolicyUrn }: Props) { +export default function PolicyBuilderModal({ policy, setPolicy, open, onClose, onSave, focusPolicyUrn }: Props) { // Step control-flow. const [activeStepIndex, setActiveStepIndex] = useState(0); const [selectedTags, setSelectedTags] = useState([]); @@ -168,7 +168,7 @@ export default function PolicyBuilderModal({ policy, setPolicy, visible, onClose ; - visible: boolean; + open: boolean; onClose: () => void; privileges: PrivilegeOptionType[] | undefined; }; @@ -60,7 +60,7 @@ const Privileges = styled.div` /** * Component used for displaying the details about an existing Policy. */ -export default function PolicyDetailsModal({ policy, visible, onClose, privileges }: Props) { +export default function PolicyDetailsModal({ policy, open, onClose, privileges }: Props) { const entityRegistry = useEntityRegistry(); const isActive = policy?.state === PolicyState.Active; @@ -121,7 +121,7 @@ export default function PolicyDetailsModal({ policy, visible, onClose, privilege }; return ( - +
Type diff --git a/datahub-web-react/src/app/permissions/roles/ManageRoles.tsx b/datahub-web-react/src/app/permissions/roles/ManageRoles.tsx index 4982be27fa421..7c2cec63071ad 100644 --- a/datahub-web-react/src/app/permissions/roles/ManageRoles.tsx +++ b/datahub-web-react/src/app/permissions/roles/ManageRoles.tsx @@ -284,7 +284,7 @@ export const ManageRoles = () => { showSizeChanger={false} /> - + ); }; diff --git a/datahub-web-react/src/app/permissions/roles/RoleDetailsModal.tsx b/datahub-web-react/src/app/permissions/roles/RoleDetailsModal.tsx index c32e9c07823da..7bca62c040c2d 100644 --- a/datahub-web-react/src/app/permissions/roles/RoleDetailsModal.tsx +++ b/datahub-web-react/src/app/permissions/roles/RoleDetailsModal.tsx @@ -7,7 +7,7 @@ import AvatarsGroup from '../AvatarsGroup'; type Props = { role: DataHubRole; - visible: boolean; + open: boolean; onClose: () => void; }; @@ -34,7 +34,7 @@ const ThinDivider = styled(Divider)` /** * Component used for displaying the details about an existing Role. */ -export default function RoleDetailsModal({ role, visible, onClose }: Props) { +export default function RoleDetailsModal({ role, open, onClose }: Props) { const entityRegistry = useEntityRegistry(); const actionButtons = ( @@ -49,7 +49,7 @@ export default function RoleDetailsModal({ role, visible, onClose }: Props) { const policies = castedRole?.policies?.relationships.map((relationship) => relationship.entity as DataHubPolicy); return ( - +
Description diff --git a/datahub-web-react/src/app/preview/EntityPaths/EntityPathsModal.tsx b/datahub-web-react/src/app/preview/EntityPaths/EntityPathsModal.tsx index 2bb76714d6119..68c754b6b21d3 100644 --- a/datahub-web-react/src/app/preview/EntityPaths/EntityPathsModal.tsx +++ b/datahub-web-react/src/app/preview/EntityPaths/EntityPathsModal.tsx @@ -47,7 +47,7 @@ export default function EntityPathsModal({ paths, resultEntityUrn, hideModal }: } width="75vw" - visible + open onCancel={hideModal} onOk={hideModal} footer={null} diff --git a/datahub-web-react/src/app/search/AdvancedFilterSelectValueModal.tsx b/datahub-web-react/src/app/search/AdvancedFilterSelectValueModal.tsx index c562fc6e8349a..056aca56c1313 100644 --- a/datahub-web-react/src/app/search/AdvancedFilterSelectValueModal.tsx +++ b/datahub-web-react/src/app/search/AdvancedFilterSelectValueModal.tsx @@ -187,7 +187,7 @@ export const AdvancedFilterSelectValueModal = ({ { onSelect(urns); @@ -211,7 +211,7 @@ export const AdvancedFilterSelectValueModal = ({ { onSelect(urns); diff --git a/datahub-web-react/src/app/search/ChooseEntityTypeModal.tsx b/datahub-web-react/src/app/search/ChooseEntityTypeModal.tsx index 1e31bd74ee06f..dd611bba346c1 100644 --- a/datahub-web-react/src/app/search/ChooseEntityTypeModal.tsx +++ b/datahub-web-react/src/app/search/ChooseEntityTypeModal.tsx @@ -29,7 +29,7 @@ export const ChooseEntityTypeModal = ({ defaultValues, onCloseModal, onOk, title return ( void; accessToken: string; expiresInText: string; }; -export const AccessTokenModal = ({ visible, onClose, accessToken, expiresInText }: Props) => { +export const AccessTokenModal = ({ open, onClose, accessToken, expiresInText }: Props) => { const baseUrl = window.location.origin; const accessTokenCurl = `curl -X POST '${baseUrl}/api/graphql' \\ --header 'Authorization: Bearer ${accessToken}' \\ @@ -56,7 +56,7 @@ export const AccessTokenModal = ({ visible, onClose, accessToken, expiresInText New Personal Access Token } - visible={visible} + open={open} onCancel={onClose} footer={ <> diff --git a/datahub-web-react/src/app/settings/AccessTokens.tsx b/datahub-web-react/src/app/settings/AccessTokens.tsx index ef58a1b84c140..6ccca8dd360d7 100644 --- a/datahub-web-react/src/app/settings/AccessTokens.tsx +++ b/datahub-web-react/src/app/settings/AccessTokens.tsx @@ -419,7 +419,7 @@ export const AccessTokens = () => { setIsCreatingToken(false)} onCreateToken={() => { // Hack to deal with eventual consistency. diff --git a/datahub-web-react/src/app/settings/CreateTokenModal.tsx b/datahub-web-react/src/app/settings/CreateTokenModal.tsx index 3cc446651efcb..e53de77b54e15 100644 --- a/datahub-web-react/src/app/settings/CreateTokenModal.tsx +++ b/datahub-web-react/src/app/settings/CreateTokenModal.tsx @@ -12,7 +12,7 @@ import analytics, { EventType } from '../analytics'; type Props = { currentUserUrn: string; - visible: boolean; + open: boolean; onClose: () => void; onCreateToken: () => void; }; @@ -39,7 +39,7 @@ const OptionText = styled.span<{ isRed: boolean }>` ${(props) => props.isRed && `color: ${red[5]};`} `; -export default function CreateTokenModal({ currentUserUrn, visible, onClose, onCreateToken }: Props) { +export default function CreateTokenModal({ currentUserUrn, open, onClose, onCreateToken }: Props) { const [selectedTokenDuration, setSelectedTokenDuration] = useState(null); const [showModal, setShowModal] = useState(false); @@ -113,7 +113,7 @@ export default function CreateTokenModal({ currentUserUrn, visible, onClose, onC <> @@ -192,7 +192,7 @@ export default function CreateTokenModal({ currentUserUrn, visible, onClose, onC +  Delete + + ), + }, + { + key: 'edit', + label: ( + +  Edit + + ), + }, + ]; + return ( - - -  Delete - - -  Edit - - - } - > + ); diff --git a/datahub-web-react/src/app/shared/ManageAccount.tsx b/datahub-web-react/src/app/shared/ManageAccount.tsx index 6d496b40362e5..359a7d77dd02c 100644 --- a/datahub-web-react/src/app/shared/ManageAccount.tsx +++ b/datahub-web-react/src/app/shared/ManageAccount.tsx @@ -1,6 +1,6 @@ import React from 'react'; import Cookies from 'js-cookie'; -import { Menu, Dropdown } from 'antd'; +import { Dropdown } from 'antd'; import { CaretDownOutlined } from '@ant-design/icons'; import styled, { useTheme } from 'styled-components'; import { EntityType } from '../../types.generated'; @@ -12,22 +12,7 @@ import analytics, { EventType } from '../analytics'; import { ANTD_GRAY } from '../entity/shared/constants'; import { useAppConfig } from '../useAppConfig'; import { useUserContext } from '../context/useUserContext'; - -const MenuItem = styled(Menu.Item)` - display: flex; - justify-content: start; - align-items: center; - && { - margin-top: 2px; - } - & > a:visited, - & > a:active, - & > a:focus { - clear: both; - border: none; - outline: 0; - } -`; +import { MenuItemStyle } from '../entity/view/menu/item/styledComponent'; const DownArrow = styled(CaretDownOutlined)` vertical-align: -1px; @@ -63,55 +48,88 @@ export const ManageAccount = ({ urn: _urn, pictureLink: _pictureLink, name }: Pr userContext.updateLocalState({ selectedViewUrn: undefined }); }; const version = config?.appVersion; - const menu = ( - - {version && ( - - {version} - - )} - - - - Your Profile - - - - {themeConfig.content.menu.items.map((value) => { - return ( - - - {value.label} - - - ); - })} - - GraphiQL - - - OpenAPI - - - - - Sign Out - - - - ); + + const themeConfigItems = themeConfig.content.menu.items.map((value) => { + return { + key: value.label, + label: ( + + + {value.label} + + + ), + }; + }); + + const divider = { + key: 'divider', + type: 'divider', + }; + + const items = [ + version + ? { + key: 'version', + label: ( + + {version} + + ), + } + : null, + divider, + { + key: 'profile', + label: ( + + + Your Profile + + + ), + }, + ...themeConfigItems, + { + key: 'graphiQLLink', + label: ( + + GraphiQL + + ), + }, + { + key: 'openapiLink', + label: ( + + OpenAPI + + ), + }, + divider, + { + key: 'logout', + label: ( + + + Sign Out + + + ), + }, + ]; return ( - + diff --git a/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx b/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx index cce2a2336515d..8936a935735c5 100644 --- a/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx +++ b/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx @@ -10,7 +10,7 @@ import { GlobalOutlined, } from '@ant-design/icons'; import { Link } from 'react-router-dom'; -import { Button, Dropdown, Menu, Tooltip } from 'antd'; +import { Button, Dropdown, Tooltip } from 'antd'; import { useAppConfig, useBusinessAttributesFlag } from '../../useAppConfig'; import { ANTD_GRAY } from '../../entity/shared/constants'; import { HOME_PAGE_INGESTION_ID } from '../../onboarding/config/HomePageOnboardingConfig'; @@ -35,12 +35,6 @@ const LinksWrapper = styled.div<{ areLinksHidden?: boolean }>` `} `; -const MenuItem = styled(Menu.Item)` - font-size: 12px; - font-weight: bold; - max-width: 240px; -`; - const NavTitleContainer = styled.span` display: flex; align-items: center; @@ -50,6 +44,7 @@ const NavTitleContainer = styled.span` const NavTitleText = styled.span` margin-left: 6px; + font-weight: bold; `; const NavTitleDescription = styled.div` @@ -79,6 +74,59 @@ export function HeaderLinks(props: Props) { useToggleEducationStepIdsAllowList(!!showIngestion, HOME_PAGE_INGESTION_ID); + const items = [ + { + key: 0, + label: ( + + + + Glossary + + View and modify your data dictionary + + ), + }, + { + key: 1, + label: ( + + + + Domains + + Manage related groups of data assets + + ), + }, + ...(businessAttributesFlag + ? [ + { + key: 2, + label: ( + + + + Business Attribute + + Universal field for data consistency + + ), + }, + ] + : []), + ]; + return ( {showAnalytics && ( @@ -95,52 +143,7 @@ export function HeaderLinks(props: Props) { )} - - - - - - Glossary - - View and modify your data dictionary - - - - - - - Domains - - Manage related groups of data assets - - - {businessAttributesFlag && ( - - - - - Business Attribute - - Universal field for data consistency - - - )} - - } - > +