Feat: Add Copy URL button and reusable toast notification system
Detail page now has a "Copy URL" button that copies the image's direct file URL to the clipboard. A toast service (BehaviorSubject-backed, auto-dismissing after 3s) confirms success or failure. ToastComponent is registered at the app root and available to all future features. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
74
specs/016-copy-url-toast/plan.md
Normal file
74
specs/016-copy-url-toast/plan.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Implementation Plan: Copy URL & Toast Notifications
|
||||
|
||||
**Branch**: `016-copy-url-toast` | **Date**: 2026-05-09 | **Spec**: [spec.md](spec.md)
|
||||
**Input**: Feature specification from `specs/016-copy-url-toast/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Add a "Copy URL" button to the image detail page that copies the image's direct file URL to the clipboard, with a reusable toast notification service wired to confirm success or failure. All changes are UI-only; no API changes are required.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: TypeScript (strict mode), Angular latest stable
|
||||
**Primary Dependencies**: Angular (`@angular/core`, `@angular/common`), RxJS (`BehaviorSubject`), browser Clipboard API (`navigator.clipboard.writeText`)
|
||||
**Storage**: N/A
|
||||
**Testing**: Karma/Jasmine (`ng test`)
|
||||
**Target Platform**: Browser (modern; Clipboard API requires HTTPS — already in place)
|
||||
**Project Type**: Angular standalone SPA
|
||||
**Performance Goals**: Copy action completes in < 100ms perceived latency; toast appears within 300ms of action
|
||||
**Constraints**: TypeScript strict mode, `ChangeDetectionStrategy.OnPush` on all components, no new npm dependencies
|
||||
**Scale/Scope**: Two new files (service + component), two modified files (detail + app component)
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
| Principle | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| §2.1 Strict separation of concerns | ✓ PASS | Pure UI change; no API knowledge in UI beyond what's already in `ImageRecord.file_url` |
|
||||
| §2.6 No speculative abstraction | ✓ PASS | Toast service is justified: used immediately by this feature and explicitly planned for reuse (upload confirmation, delete confirmation, filter feedback). Two concrete use cases exist. |
|
||||
| §5.1 Tests alongside implementation | ✓ PASS | Tests required for `ToastService` and the copy button on `DetailComponent` |
|
||||
| §5.2 Test pyramid | ✓ PASS | Unit tests only (no API/DB involved); Karma/Jasmine |
|
||||
| §6 Tech stack | ✓ PASS | Angular, TypeScript strict — no new dependencies |
|
||||
| §7.3 Linting | ✓ PASS | `ng lint` must pass before task is done |
|
||||
| §8 Scope boundaries | ✓ PASS | No multi-user, no embeds, no public sharing infrastructure — just a clipboard copy |
|
||||
|
||||
**Post-design re-check**: No violations. Feature is entirely additive.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/016-copy-url-toast/
|
||||
├── plan.md ← this file
|
||||
├── research.md ← Phase 0 output
|
||||
├── quickstart.md ← Phase 1 output
|
||||
├── contracts/
|
||||
│ └── toast-service.md ← Phase 1 output
|
||||
└── tasks.md ← /speckit-tasks output
|
||||
```
|
||||
|
||||
### Source Code
|
||||
|
||||
```text
|
||||
ui/src/app/
|
||||
├── app.component.ts ← modified: add <app-toast> to template
|
||||
├── services/
|
||||
│ └── toast.service.ts ← new: singleton toast service
|
||||
├── toast/
|
||||
│ └── toast.component.ts ← new: toast display component
|
||||
└── detail/
|
||||
└── detail.component.ts ← modified: add Copy URL button + inject ToastService
|
||||
|
||||
ui/src/app/services/
|
||||
toast.service.spec.ts ← new: unit tests for ToastService
|
||||
|
||||
ui/src/app/toast/
|
||||
toast.component.spec.ts ← new: unit tests for ToastComponent
|
||||
|
||||
ui/src/app/detail/
|
||||
detail.component.spec.ts ← modified: tests for copy button behaviour
|
||||
```
|
||||
|
||||
**Structure Decision**: Single-project Angular SPA. Toast service lives in `services/` alongside `ImageService` and `TagService`. Toast component gets its own `toast/` directory following the existing component-per-directory convention.
|
||||
Reference in New Issue
Block a user