Replace demo data with 2026 R&D planning, fix zoom and dimension-aware creation

Seeder: Replace 12 demo projects with 6 real 2026 projects from Planning PPTX:
- BRIDGE (Pilot Klundert), CRISP (Compressor Aanbesteding), WISE (Monsternamekast),
  Gemaal 3.0, Afvlakkingsregeling, Structuur & Borging
- 4 strategic themes: Architectuur, Productiewaardig, Lab, Governance
- Real team members, commitments, documents, and dependencies

MetroCanvas: Fix zoom-out scaling
- Wider transition range (0.6→0.25 instead of 0.5→0.1) for smoother feel
- Animated zoom reset on dimension commit (400ms ease) instead of jarring snap
- Guard against re-entry during transitions with isCommitting flag
- Expose dimension metadata (parentEntityType/Id/Name) for parent components

FloatingActions: Dimension-aware creation
- Shows "Nieuw commitment/document" when inside a project dimension
- Shows "Nieuw project/thema" at root level
- Receives depth and parentEntityType props from MetroMap

MetroMap: Wire dimension tracking
- Tracks canvasDepth/canvasDimension from MetroCanvas dimension-change events
- Updates breadcrumb for both page-level and canvas-level navigation
- Passes dimension context to FloatingActions and CommitmentForm

MapDataService: Add parent metadata to buildProjectChildren output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
znetsixe
2026-04-08 08:50:51 +02:00
parent 926872a082
commit 6711cd01a3
6 changed files with 531 additions and 415 deletions

View File

@@ -1,7 +1,18 @@
<script setup>
import { ref } from 'vue'
import { ref, computed } from 'vue'
const emit = defineEmits(['create-project', 'create-theme'])
const props = defineProps({
depth: { type: Number, default: 1 },
parentEntityType: { type: String, default: null },
parentProjectId: { type: Number, default: null },
})
const emit = defineEmits([
'create-project',
'create-theme',
'create-commitment',
'create-document',
])
const menuOpen = ref(false)
@@ -9,14 +20,25 @@ const toggle = () => {
menuOpen.value = !menuOpen.value
}
const handleCreateProject = () => {
menuOpen.value = false
emit('create-project')
}
/** Options change based on which dimension we're in */
const menuItems = computed(() => {
if (props.depth > 1 && props.parentEntityType === 'project') {
// Inside a project dimension: create project-level items
return [
{ label: 'Nieuw commitment', event: 'create-commitment' },
{ label: 'Nieuw document', event: 'create-document' },
]
}
// Root dimension: create top-level items
return [
{ label: 'Nieuw project', event: 'create-project' },
{ label: 'Nieuw thema', event: 'create-theme' },
]
})
const handleCreateTheme = () => {
const handleItemClick = (item) => {
menuOpen.value = false
emit('create-theme')
emit(item.event)
}
</script>
@@ -25,13 +47,14 @@ const handleCreateTheme = () => {
<!-- Expanded menu -->
<Transition name="fab-menu">
<div v-if="menuOpen" class="fab-menu">
<button class="fab-menu-item" @click="handleCreateProject">
<button
v-for="item in menuItems"
:key="item.event"
class="fab-menu-item"
@click="handleItemClick(item)"
>
<span class="fab-menu-icon">+</span>
<span class="fab-menu-label">Nieuw project</span>
</button>
<button class="fab-menu-item" @click="handleCreateTheme">
<span class="fab-menu-icon">+</span>
<span class="fab-menu-label">Nieuw thema</span>
<span class="fab-menu-label">{{ item.label }}</span>
</button>
</div>
</Transition>
@@ -51,7 +74,7 @@ const handleCreateTheme = () => {
<style scoped>
.fab-container {
position: fixed;
bottom: 64px; /* above the CLI bar */
bottom: 64px;
right: 20px;
z-index: 150;
display: flex;