fix: [planning-design] 블록 툴바를 단위업무 상단으로 이동

This commit is contained in:
김보곤
2026-03-08 00:17:05 +09:00
parent 35d092f065
commit e5e5b69ad8

View File

@@ -632,7 +632,7 @@
/* Block Editor (Wireframe) */
.sb-block-toolbar {
display: flex; align-items: center; gap: 4px; padding: 6px 12px;
border-bottom: 1px solid #e2e8f0; background: #fafbfc; flex-wrap: wrap;
border-bottom: 1px solid #e2e8f0; background: #fafbfc; flex-wrap: wrap; flex-shrink: 0;
}
.sb-block-toolbar-btn {
padding: 3px 8px; border: 1px solid #e2e8f0; border-radius: 5px;
@@ -1333,6 +1333,83 @@
{{-- Storyboard View --}}
<div class="sb-wrap" x-show="viewMode === 'storyboard'">
{{-- Block Toolbar (상단) --}}
<div class="sb-block-toolbar">
<button class="sb-block-toolbar-btn" @click="sbAddBlock('heading')">H1</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('heading2')">H2</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('text')">T 텍스트</button>
<div class="sb-block-toolbar-sep"></div>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('table')"> 테이블</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('callout')">💡 콜아웃</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('todo')"> 체크리스트</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('code')">{ } 코드</button>
<div class="sb-block-toolbar-sep"></div>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('button')">🔘 버튼</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('input')"> 입력필드</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('select')"> 셀렉트</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('card')"> 카드</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('badges')"> 뱃지</button>
<div class="sb-block-toolbar-sep"></div>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('image')">🖼 이미지</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('divider')"> 구분선</button>
<div class="sb-block-toolbar-sep"></div>
{{-- Template Dropdown --}}
<div class="sb-tpl-dropdown" @click.outside="sbTplOpen = false">
<button class="sb-tpl-trigger" x-ref="sbTplBtn" @click="sbToggleTplPanel()">📋 템플릿 <span style="font-size:8px;"></span></button>
<div class="sb-tpl-panel" x-ref="sbTplPanel" x-show="sbTplOpen" x-cloak x-transition>
<div class="sb-tpl-tabs">
<div class="sb-tpl-tab" :class="{ active: sbTplTab === 'preset' }" @click="sbTplTab = 'preset'">기본 템플릿</div>
<div class="sb-tpl-tab" :class="{ active: sbTplTab === 'custom' }" @click="sbTplTab = 'custom'"> 템플릿</div>
</div>
<input class="sb-tpl-search" type="text" placeholder="템플릿 검색..." x-model="sbTplSearch">
<div class="sb-tpl-list">
{{-- Preset Templates --}}
<template x-if="sbTplTab === 'preset'">
<div>
<template x-for="tpl in sbFilteredPresets" :key="tpl.name">
<div class="sb-tpl-item" @click="sbInsertTemplate(tpl); sbTplOpen = false;">
<div class="sb-tpl-item-icon" x-text="tpl.icon"></div>
<div class="sb-tpl-item-info">
<div class="sb-tpl-item-name" x-text="tpl.name"></div>
<div class="sb-tpl-item-desc" x-text="tpl.desc"></div>
</div>
</div>
</template>
<div class="sb-tpl-empty" x-show="sbFilteredPresets.length === 0">검색 결과가 없습니다</div>
</div>
</template>
{{-- Custom Templates --}}
<template x-if="sbTplTab === 'custom'">
<div>
<template x-for="(tpl, ti) in sbFilteredCustoms" :key="tpl.name">
<div class="sb-tpl-item">
<div class="sb-tpl-item-icon">📄</div>
<div class="sb-tpl-item-info" @click="sbInsertTemplate(tpl); sbTplOpen = false;">
<div class="sb-tpl-item-name" x-text="tpl.name"></div>
<div class="sb-tpl-item-desc" x-text="tpl.blocks.length + '개 블록'"></div>
</div>
<div class="sb-tpl-item-actions">
<button class="sb-tpl-item-btn" @click.stop="sbDeleteCustomTemplate(ti)" title="삭제">×</button>
</div>
</div>
</template>
<div class="sb-tpl-empty" x-show="sbFilteredCustoms.length === 0 && !sbTplSearch">
저장된 템플릿이 없습니다<br>
<span style="font-size:10px;">현재 페이지 블록을 아래에서 저장하세요</span>
</div>
<div class="sb-tpl-empty" x-show="sbFilteredCustoms.length === 0 && sbTplSearch">검색 결과가 없습니다</div>
</div>
</template>
</div>
{{-- Save current blocks as template --}}
<div class="sb-tpl-save-bar">
<input class="sb-tpl-save-input" type="text" placeholder="현재 블록을 템플릿으로 저장..." x-model="sbTplSaveName" @keydown.enter="sbSaveAsTemplate()">
<button class="sb-tpl-save-btn" @click="sbSaveAsTemplate()" :disabled="!sbTplSaveName.trim()">저장</button>
</div>
</div>
</div>
</div>
{{-- Storyboard Top Bar --}}
<div class="sb-topbar">
<label>프로젝트</label>
@@ -1426,83 +1503,8 @@
{{-- Content + Description --}}
<div class="sb-content-area">
{{-- Block Toolbar --}}
<div class="sb-block-toolbar">
<button class="sb-block-toolbar-btn" @click="sbAddBlock('heading')">H1</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('heading2')">H2</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('text')">T 텍스트</button>
<div class="sb-block-toolbar-sep"></div>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('table')"> 테이블</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('callout')">💡 콜아웃</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('todo')"> 체크리스트</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('code')">{ } 코드</button>
<div class="sb-block-toolbar-sep"></div>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('button')">🔘 버튼</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('input')"> 입력필드</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('select')"> 셀렉트</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('card')"> 카드</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('badges')"> 뱃지</button>
<div class="sb-block-toolbar-sep"></div>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('image')">🖼 이미지</button>
<button class="sb-block-toolbar-btn" @click="sbAddBlock('divider')"> 구분선</button>
<input type="file" accept="image/*" x-ref="sbBlockImageInput" style="display:none;" @change="sbBlockUploadImage($event)">
<div class="sb-block-toolbar-sep"></div>
{{-- Template Dropdown --}}
<div class="sb-tpl-dropdown" @click.outside="sbTplOpen = false">
<button class="sb-tpl-trigger" x-ref="sbTplBtn" @click="sbToggleTplPanel()">📋 템플릿 <span style="font-size:8px;"></span></button>
<div class="sb-tpl-panel" x-ref="sbTplPanel" x-show="sbTplOpen" x-cloak x-transition>
<div class="sb-tpl-tabs">
<div class="sb-tpl-tab" :class="{ active: sbTplTab === 'preset' }" @click="sbTplTab = 'preset'">기본 템플릿</div>
<div class="sb-tpl-tab" :class="{ active: sbTplTab === 'custom' }" @click="sbTplTab = 'custom'"> 템플릿</div>
</div>
<input class="sb-tpl-search" type="text" placeholder="템플릿 검색..." x-model="sbTplSearch">
<div class="sb-tpl-list">
{{-- Preset Templates --}}
<template x-if="sbTplTab === 'preset'">
<div>
<template x-for="tpl in sbFilteredPresets" :key="tpl.name">
<div class="sb-tpl-item" @click="sbInsertTemplate(tpl); sbTplOpen = false;">
<div class="sb-tpl-item-icon" x-text="tpl.icon"></div>
<div class="sb-tpl-item-info">
<div class="sb-tpl-item-name" x-text="tpl.name"></div>
<div class="sb-tpl-item-desc" x-text="tpl.desc"></div>
</div>
</div>
</template>
<div class="sb-tpl-empty" x-show="sbFilteredPresets.length === 0">검색 결과가 없습니다</div>
</div>
</template>
{{-- Custom Templates --}}
<template x-if="sbTplTab === 'custom'">
<div>
<template x-for="(tpl, ti) in sbFilteredCustoms" :key="tpl.name">
<div class="sb-tpl-item">
<div class="sb-tpl-item-icon">📄</div>
<div class="sb-tpl-item-info" @click="sbInsertTemplate(tpl); sbTplOpen = false;">
<div class="sb-tpl-item-name" x-text="tpl.name"></div>
<div class="sb-tpl-item-desc" x-text="tpl.blocks.length + '개 블록'"></div>
</div>
<div class="sb-tpl-item-actions">
<button class="sb-tpl-item-btn" @click.stop="sbDeleteCustomTemplate(ti)" title="삭제">×</button>
</div>
</div>
</template>
<div class="sb-tpl-empty" x-show="sbFilteredCustoms.length === 0 && !sbTplSearch">
저장된 템플릿이 없습니다<br>
<span style="font-size:10px;">현재 페이지 블록을 아래에서 저장하세요</span>
</div>
<div class="sb-tpl-empty" x-show="sbFilteredCustoms.length === 0 && sbTplSearch">검색 결과가 없습니다</div>
</div>
</template>
</div>
{{-- Save current blocks as template --}}
<div class="sb-tpl-save-bar">
<input class="sb-tpl-save-input" type="text" placeholder="현재 블록을 템플릿으로 저장..." x-model="sbTplSaveName" @keydown.enter="sbSaveAsTemplate()">
<button class="sb-tpl-save-btn" @click="sbSaveAsTemplate()" :disabled="!sbTplSaveName.trim()">저장</button>
</div>
</div>
</div>
</div>
{{-- Block Editor Area (moved toolbar to sb-topbar above) --}}
<input type="file" accept="image/*" x-ref="sbBlockImageInput" style="display:none;" @change="sbBlockUploadImage($event)">
{{-- Block Editor Area (Free Canvas) --}}
<div class="sb-blocks-area" x-ref="sbCanvas"