Compare commits

..

3 Commits

Author SHA1 Message Date
Otto
42b7b6ee37 fix: Use strokeOpacity and stroke color for SVG hit detection
The invisible path needs an actual stroke color (just made invisible via
strokeOpacity=0) for SVG to register pointer events on the stroke area.
Also added react-flow__edge-interaction class for consistency with the
legacy builder pattern.
2026-02-12 09:43:16 +00:00
Krzysztof Czerwinski
a7f9bf3cb8 Merge branch 'dev' into fix/edge-hover-x-button-SECRT-1943 2026-02-12 18:07:43 +09:00
Otto
764070f6a7 fix(builder): Show X button on edge line hover, not just button hover
Add invisible interaction path along edge that triggers hover state,
making the remove button appear when hovering anywhere on the connection
line rather than requiring users to find the small button directly.

Fixes SECRT-1943
2026-02-12 08:25:56 +00:00
3 changed files with 37 additions and 116 deletions

View File

@@ -142,6 +142,9 @@ jobs:
e2e_test:
runs-on: big-boi
needs: setup
strategy:
fail-fast: false
steps:
- name: Checkout repository
@@ -171,29 +174,29 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v5
with:
driver-opts: network=host
- name: Build Docker images with cache
working-directory: autogpt_platform
run: |
pip install pyyaml
python ../.github/workflows/scripts/generate-docker-ci-compose.py \
--source docker-compose.platform.yml \
--output docker-compose.ci.yml \
--cache-from "type=gha" \
--cache-to "type=gha,mode=max" \
--backend-scope "platform-backend-${{ hashFiles('autogpt_platform/backend/Dockerfile', 'autogpt_platform/backend/poetry.lock', 'autogpt_platform/backend/backend') }}" \
--frontend-scope "platform-frontend-${{ hashFiles('autogpt_platform/frontend/Dockerfile', 'autogpt_platform/frontend/pnpm-lock.yaml', 'autogpt_platform/frontend/src') }}"
docker buildx bake --allow=fs.read=.. -f docker-compose.yml -f docker-compose.ci.yml --load
env:
NEXT_PUBLIC_PW_TEST: true
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-frontend-test-${{ hashFiles('autogpt_platform/docker-compose.yml', 'autogpt_platform/backend/Dockerfile', 'autogpt_platform/backend/pyproject.toml', 'autogpt_platform/backend/poetry.lock') }}
restore-keys: |
${{ runner.os }}-buildx-frontend-test-
- name: Run docker compose
run: docker compose -f ../docker-compose.yml up -d --no-build
run: |
NEXT_PUBLIC_PW_TEST=true docker compose -f ../docker-compose.yml up -d
env:
NEXT_PUBLIC_PW_TEST: true
DOCKER_BUILDKIT: 1
BUILDX_CACHE_FROM: type=local,src=/tmp/.buildx-cache
BUILDX_CACHE_TO: type=local,dest=/tmp/.buildx-cache-new,mode=max
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
if [ -d "/tmp/.buildx-cache-new" ]; then
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
fi
- name: Wait for services to be ready
run: |
@@ -227,14 +230,14 @@ jobs:
}
fi
- name: Cache pnpm store
- name: Restore dependencies cache
uses: actions/cache@v5
with:
path: ~/.pnpm-store
# Use separate cache key for big-boi runner since it doesn't share cache with ubuntu-latest
key: big-boi-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
key: ${{ needs.setup.outputs.cache-key }}
restore-keys: |
big-boi-pnpm-
${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
${{ runner.os }}-pnpm-
- name: Install dependencies
run: pnpm install --frozen-lockfile

View File

@@ -1,93 +0,0 @@
#!/usr/bin/env python3
"""
Generate a docker-compose.ci.yml with cache configuration for all services
that have a build key in the source compose file.
"""
import argparse
import yaml
def main():
parser = argparse.ArgumentParser(
description="Generate docker-compose cache override file"
)
parser.add_argument(
"--source",
default="docker-compose.platform.yml",
help="Source compose file to read (default: docker-compose.platform.yml)",
)
parser.add_argument(
"--output",
default="docker-compose.ci.yml",
help="Output compose file to write (default: docker-compose.ci.yml)",
)
parser.add_argument(
"--cache-from",
default="type=local,src=/tmp/.buildx-cache",
help="Cache source configuration",
)
parser.add_argument(
"--cache-to",
default="type=local,dest=/tmp/.buildx-cache-new,mode=max",
help="Cache destination configuration",
)
parser.add_argument(
"--backend-scope",
default="",
help="GHA cache scope for backend services (e.g., platform-backend-{hash})",
)
parser.add_argument(
"--frontend-scope",
default="",
help="GHA cache scope for frontend service (e.g., platform-frontend-{hash})",
)
args = parser.parse_args()
with open(args.source, "r") as f:
compose = yaml.safe_load(f)
ci_compose = {"services": {}}
for service_name, service_config in compose.get("services", {}).items():
if "build" not in service_config:
continue
cache_from = args.cache_from
cache_to = args.cache_to
# Determine scope based on Dockerfile path
if "type=gha" in args.cache_from or "type=gha" in args.cache_to:
dockerfile = service_config["build"].get("dockerfile", "Dockerfile")
if "frontend" in dockerfile:
scope = args.frontend_scope
elif "backend" in dockerfile:
scope = args.backend_scope
else:
# Skip services that don't clearly match frontend/backend
continue
if scope:
if "type=gha" in args.cache_from:
cache_from = f"{args.cache_from},scope={scope}"
if "type=gha" in args.cache_to:
cache_to = f"{args.cache_to},scope={scope}"
ci_compose["services"][service_name] = {
"build": {
"cache_from": [cache_from],
"cache_to": [cache_to],
}
}
with open(args.output, "w") as f:
yaml.dump(ci_compose, f, default_flow_style=False)
services = list(ci_compose["services"].keys())
print(f"Generated {args.output} with cache config for {len(services)} services:")
for svc in services:
print(f" - {svc}")
if __name__ == "__main__":
main()

View File

@@ -63,6 +63,17 @@ const CustomEdge = ({
return (
<>
{/* Invisible interaction path - wider hit area for hover detection */}
<path
d={edgePath}
fill="none"
stroke="black"
strokeOpacity={0}
strokeWidth={20}
className="react-flow__edge-interaction cursor-pointer"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
/>
<BaseEdge
path={edgePath}
markerEnd={markerEnd}