hunk.code_window:         }, [setOpenWorkspacesModal])}
           onMoveWorkspace={useCallback(
             (activeId, overId) => {
               const oldIndex = workspaces.findIndex(w => w.id === activeId);
               const newIndex = workspaces.findIndex(w => w.id === overId);
               setWorkspaces(workspaces =>
                 arrayMove(workspaces, oldIndex, newIndex)
               );
             },
             [setWorkspaces, workspaces]
           )}
  
hunk.labels: keep keep keep keep keep replace replace keep keep keep keep
hunk.after_edit:             transition(() =>
                 setWorkspaces(workspaces =>
                   arrayMove(workspaces, oldIndex, newIndex)
                 )
  
hunk.file_path: apps/web/src/providers/ModalProvider.tsx
hunk.type: replace
file: name: Build & Test
  
  on:
    pull_request:
      branches:
        - master
  
  jobs:
    lint:
      name: Lint
      runs-on: ubuntu-latest
      environment: development
  
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
        - run: yarn lint --max-warnings=0
  
    install-all:
      name: Install All Dependencies
      runs-on: ubuntu-latest
      environment: development
  
      steps:
        - uses: actions/checkout@v3
        - name: Install All Dependencies
          uses: ./.github/actions/setup-node
          with:
            electron-workspace-install: true
  
    build-storybook:
      name: Build Storybook
      runs-on: ubuntu-latest
      environment: development
  
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
        - run: yarn build:storybook
        - name: Upload storybook artifact
          uses: actions/upload-artifact@v3
          with:
            name: storybook
            path: ./packages/component/storybook-static
            if-no-files-found: error
  
    build:
      name: Build @affine/web
      runs-on: ubuntu-latest
      environment: development
  
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
        - name: Cache Next.js
          uses: actions/cache@v3
          with:
            path: |
              ${{ github.workspace }}/apps/web/.next/cache
            key: ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
            restore-keys: |
              ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-
        - name: Build
          run: yarn build
          env:
            NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }}
            NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }}
            NEXT_PUBLIC_FIREBASE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_PROJECT_ID }}
            NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: ${{ secrets.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET }}
            NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID }}
            NEXT_PUBLIC_FIREBASE_APP_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_APP_ID }}
            NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }}
  
        - name: Upload artifact
          uses: actions/upload-artifact@v3
          with:
            name: next-js
            path: ./apps/web/.next
            if-no-files-found: error
  
    storybook-test:
      name: Storybook Test
      runs-on: ubuntu-latest
      environment: development
      needs: [build-storybook]
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
          with:
            playwright-install: true
        - name: Download storybook artifact
          uses: actions/download-artifact@v3
          with:
            name: storybook
            path: ./packages/component/storybook-static
        - name: Run storybook tests
          working-directory: ./packages/component
          run: |
            yarn exec concurrently -k -s first -n "SB,TEST" -c "magenta,blue" "yarn exec serve ./storybook-static -l 6006" "yarn exec wait-on tcp:6006 && yarn test-storybook --coverage"
        - name: Upload storybook test coverage results
          uses: codecov/codecov-action@v3
          with:
            token: ${{ secrets.CODECOV_TOKEN }}
            files: ./packages/component/coverage/storybook/coverage-storybook.json
            flags: storybook-test
            name: affine
            fail_ci_if_error: true
  
    e2e-test:
      name: E2E Test
      runs-on: ubuntu-latest
      strategy:
        fail-fast: false
        matrix:
          shard: [1, 2, 3, 4]
      environment: development
      needs: [build, build-storybook]
      services:
        octobase:
          image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest
          ports:
            - 3000:3000
          env:
            SIGN_KEY: 'test123'
            RUST_LOG: 'debug'
            JWST_DEV: '1'
  
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
          with:
            playwright-install: true
        - name: Download artifact
          uses: actions/download-artifact@v3
          with:
            name: next-js
            path: ./apps/web/.next
  
        - name: Download storybook artifact
          uses: actions/download-artifact@v3
          with:
            name: storybook
            path: ./packages/component/storybook-static
  
        - name: Run playwright tests
          run: yarn test --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
          env:
            COVERAGE: true
  
        - name: Collect code coverage report
          run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
  
        - name: Upload e2e test coverage results
          uses: codecov/codecov-action@v3
          with:
            token: ${{ secrets.CODECOV_TOKEN }}
            files: ./.coverage/lcov.info
            flags: e2etest
            name: affine
            fail_ci_if_error: true
  
        - name: Upload test results
          if: ${{ failure() }}
          uses: actions/upload-artifact@v2
          with:
            name: test-results-e2e
            path: ./test-results
            if-no-files-found: ignore
  
    unit-test:
      name: Unit Test
      runs-on: ubuntu-latest
      environment: development
      services:
        octobase:
          image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest
          ports:
            - 3000:3000
          env:
            SIGN_KEY: 'test123'
            RUST_LOG: 'debug'
            JWST_DEV: '1'
  
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
  
        - name: Unit Test
          run: yarn run test:unit:coverage
  
        - name: Upload unit test coverage results
          uses: codecov/codecov-action@v3
          with:
            token: ${{ secrets.CODECOV_TOKEN }}
            files: ./.coverage/store/lcov.info
            flags: unittest
            name: affine
            fail_ci_if_error: true
  