33 lines
4.2 KiB
Vue
33 lines
4.2 KiB
Vue
<script setup lang="ts">
|
|
import type { KbxAsyncState, KbxScreenDefinition, KbxSummaryItem, KbxTemplateContext } from '@kbx/contracts'
|
|
import KbxScreenFrame from './KbxScreenFrame.vue'
|
|
import KbxSectionHeader from './KbxSectionHeader.vue'
|
|
import KbxTemplateContextBar from './KbxTemplateContextBar.vue'
|
|
import KbxTemplateStateBoundary from './KbxTemplateStateBoundary.vue'
|
|
import KbxSummaryBar from './KbxSummaryBar.vue'
|
|
|
|
withDefaults(defineProps<{ screen:KbxScreenDefinition; can?:(permission:string)=>boolean; selectionCount?:number; breadcrumb?:string; masterSize?:'sm'|'md'|'lg'; masterTitle?:string; detailTitle?:string; bottomTitle?:string; contextText?:string; context?:KbxTemplateContext|null; contentState?:KbxAsyncState; refreshing?:boolean; summaryItems?:KbxSummaryItem[] }>(), { masterSize:'md', masterTitle:'목록', detailTitle:'상세', bottomTitle:'이력', contextText:'', context:null, contentState:'ready', refreshing:false, summaryItems:()=>[] })
|
|
const emit = defineEmits<{ command:[string] }>()
|
|
</script>
|
|
|
|
<template>
|
|
<KbxScreenFrame expected-type="master-detail" template-code="T05" :screen="screen" :can="can" :selection-count="selectionCount" :breadcrumb="breadcrumb" :suppress-default-utility="Boolean($slots.utility)" @command="emit('command',$event)">
|
|
<template #utility><slot name="utility" /></template><template #notice><slot name="notice" /></template>
|
|
<div v-if="$slots.search" class="kbx-master-detail__search" data-kbx-surface="search"><slot name="search" /></div>
|
|
<div v-if="$slots.context || context || contextText" data-kbx-surface="context"><slot name="context"><KbxTemplateContextBar :context="context ?? (contextText ? {label:contextText} : null)" /></slot></div>
|
|
<KbxTemplateStateBoundary :state="contentState" :refreshing="refreshing" idle-action-label="조회 F3" @idle-action="emit('command','search')" @retry="emit('command','search')">
|
|
<div class="kbx-master-detail__workspace" :data-master-size="masterSize">
|
|
<section class="kbx-master-detail__pane kbx-master-detail__master" :aria-label="masterTitle" data-kbx-surface="master"><slot name="master-header"><KbxSectionHeader :title="masterTitle" /></slot><div class="kbx-master-detail__pane-body"><slot name="master" /></div></section>
|
|
<section class="kbx-master-detail__pane kbx-master-detail__detail" :aria-label="detailTitle" data-kbx-surface="detail"><slot name="detail-header"><KbxSectionHeader :title="detailTitle" /></slot><div class="kbx-master-detail__pane-body"><slot name="detail" /></div></section>
|
|
</div>
|
|
</KbxTemplateStateBoundary>
|
|
<section v-if="$slots.bottom" class="kbx-master-detail__pane kbx-master-detail__bottom" :aria-label="bottomTitle" data-kbx-surface="bottom/history"><slot name="bottom-header"><KbxSectionHeader :title="bottomTitle" /></slot><div class="kbx-master-detail__pane-body"><slot name="bottom" /></div></section>
|
|
<footer v-if="$slots.summary || summaryItems.length" class="kbx-master-detail__footer" data-kbx-surface="summary"><slot name="summary"><KbxSummaryBar :items="summaryItems" /></slot></footer>
|
|
<div v-if="$slots.drawer" data-kbx-surface="drawer"><slot name="drawer" /></div>
|
|
</KbxScreenFrame>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.kbx-master-detail__workspace{min-height:var(--kbx-master-detail-min-height);flex:1;display:grid;gap:var(--kbx-space-2)}.kbx-master-detail__workspace[data-master-size="sm"]{grid-template-columns:minmax(var(--kbx-master-detail-master-min-sm),34%) minmax(0,1fr)}.kbx-master-detail__workspace[data-master-size="md"]{grid-template-columns:minmax(var(--kbx-master-detail-master-min-md),42%) minmax(0,1fr)}.kbx-master-detail__workspace[data-master-size="lg"]{grid-template-columns:minmax(var(--kbx-master-detail-master-min-lg),50%) minmax(0,1fr)}.kbx-master-detail__pane{min-height:0;border:var(--kbx-border-width) solid var(--kbx-color-border);background:var(--kbx-color-surface);overflow:hidden;display:flex;flex-direction:column;padding:0 var(--kbx-space-2)}.kbx-master-detail__pane-body{min-height:0;flex:1;padding:var(--kbx-space-2) 0}.kbx-master-detail__bottom{min-height:var(--kbx-master-detail-bottom-min-height)}.kbx-master-detail__footer{min-height:var(--kbx-control-sm);border-top:var(--kbx-border-width) solid var(--kbx-color-border)}.kbx-master-detail__footer :deep(.kbx-summary-bar){border-top:0}
|
|
</style>
|