43 lines
1.9 KiB
Vue
43 lines
1.9 KiB
Vue
<script setup lang="ts">
|
|
import type { KbxConflictSnapshot } from '@kbx/contracts'
|
|
import KbxButton from './KbxButton.vue'
|
|
|
|
defineProps<{ conflict: KbxConflictSnapshot }>()
|
|
const emit = defineEmits<{ reload: []; cancel: [] }>()
|
|
</script>
|
|
|
|
<template>
|
|
<section class="kbx-conflict" role="alert">
|
|
<header>
|
|
<strong>{{ conflict.title }}</strong>
|
|
<span v-if="conflict.detail">{{ conflict.detail }}</span>
|
|
</header>
|
|
|
|
<div v-if="conflict.changes?.length" class="changes">
|
|
<div class="head"><span>항목</span><span>내 화면</span><span>최신 값</span></div>
|
|
<div v-for="change in conflict.changes" :key="change.field" class="row">
|
|
<strong>{{ change.label }}</strong>
|
|
<span>{{ change.mine ?? '-' }}</span>
|
|
<span>{{ change.latest ?? '-' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<p v-if="conflict.correlationId" class="reference">참조번호 {{ conflict.correlationId }}</p>
|
|
<footer>
|
|
<KbxButton label="계속 편집" variant="secondary" @click="emit('cancel')" />
|
|
<KbxButton label="최신 내용 보기" variant="primary" @click="emit('reload')" />
|
|
</footer>
|
|
</section>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.kbx-conflict { display:grid; gap:12px; padding:16px; border:1px solid var(--kbx-color-warning); border-radius:var(--kbx-radius-md); background:var(--kbx-color-surface); }
|
|
header { display:grid; gap:4px; } header span,.reference { color:var(--kbx-color-text-muted); }
|
|
.changes { border:1px solid var(--kbx-color-border); border-radius:var(--kbx-radius-sm); overflow:hidden; }
|
|
.head,.row { display:grid; grid-template-columns:minmax(120px,1fr) minmax(120px,1fr) minmax(120px,1fr); gap:8px; padding:8px 10px; }
|
|
.head { background:var(--kbx-color-surface-muted); font-size:var(--kbx-font-sm); color:var(--kbx-color-text-muted); }
|
|
.row + .row { border-top:1px solid var(--kbx-color-border); }
|
|
footer { display:flex; justify-content:flex-end; gap:8px; }
|
|
.reference { margin:0; font-size:var(--kbx-font-sm); }
|
|
</style>
|