4695de8783
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 14s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 23s
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 9s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 10s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 10s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
Frontend CI Pipeline / ci-frontend-8-steps (push) Failing after 3m3s
142 lines
6.7 KiB
Vue
142 lines
6.7 KiB
Vue
<!-- ComponentShowcaseView.vue -->
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import BaseInput from '../components/primitives/BaseInput.vue';
|
|
import BaseSelect from '../components/primitives/BaseSelect.vue';
|
|
import BaseCheckbox from '../components/primitives/BaseCheckbox.vue';
|
|
import BaseButton from '../components/primitives/BaseButton.vue';
|
|
import BaseStatusBadge from '../components/primitives/BaseStatusBadge.vue';
|
|
import BaseDialog from '../components/primitives/BaseDialog.vue';
|
|
import TextField from '../components/fields/TextField.vue';
|
|
import CodeField from '../components/fields/CodeField.vue';
|
|
import DecimalField from '../components/fields/DecimalField.vue';
|
|
import DateField from '../components/fields/DateField.vue';
|
|
import QuantityField from '../components/domain-fields/QuantityField.vue';
|
|
import MoneyField from '../components/domain-fields/MoneyField.vue';
|
|
import LotField from '../components/domain-fields/LotField.vue';
|
|
import ReferenceLookup from '../components/domain-fields/ReferenceLookup.vue';
|
|
import BarcodeInput from '../components/domain-fields/BarcodeInput.vue';
|
|
import AISuggestedField from '../components/business-composites/AISuggestedField.vue';
|
|
import AddressEditor from '../components/business-composites/AddressEditor.vue';
|
|
import InventoryAllocationEditor from '../components/business-composites/InventoryAllocationEditor.vue';
|
|
|
|
// Primitive State
|
|
const sampleInput = ref('표준 입력 텍스트');
|
|
const sampleSelect = ref('OPT2');
|
|
const sampleCheck = ref(true);
|
|
const isDialogOpen = ref(false);
|
|
|
|
// Typed Field State
|
|
const sampleCode = ref('item-2026-xyz');
|
|
const sampleDecimal = ref('1254000');
|
|
const sampleDate = ref('2026-07-26');
|
|
|
|
// Domain Field State
|
|
const sampleQty = ref('250');
|
|
const sampleMoney = ref('15000000');
|
|
const sampleLot = ref('LOT-20260726-09');
|
|
const sampleLookup = ref('CUST-001');
|
|
|
|
// AI State
|
|
const aiFieldVal = ref('일반 배송');
|
|
</script>
|
|
|
|
<template>
|
|
<div class="component-showcase flex flex-col gap-6 p-6 bg-slate-50 min-h-full select-none text-left">
|
|
<!-- Header -->
|
|
<div class="flex justify-between items-center bg-white p-4 rounded-lg shadow-sm border border-slate-200">
|
|
<div>
|
|
<div class="flex items-center gap-2">
|
|
<BaseStatusBadge variant="success" label="4-Layer Architecture" />
|
|
<h1 class="text-xl font-bold text-slate-800">OMS · WMS · ERP 4계층 입력 컴포넌트 카탈로그 쇼케이스</h1>
|
|
</div>
|
|
<p class="text-xs text-slate-500 mt-1">
|
|
명세 지침 (`docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md`) 4계층 컴포넌트 체계 실증
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- LAYER 1: PRIMITIVES -->
|
|
<div class="bg-white p-6 rounded-lg shadow-sm border border-slate-200 flex flex-col gap-4">
|
|
<div class="flex items-center gap-2 border-b pb-2">
|
|
<BaseStatusBadge variant="info" label="Layer 1" />
|
|
<h2 class="text-base font-bold text-slate-800">Primitives (시각/상호작용 무지 컴포넌트)</h2>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-end">
|
|
<BaseInput v-model="sampleInput" label="L1 BaseInput (Touch Density)" density="touch" />
|
|
<BaseSelect
|
|
v-model="sampleSelect"
|
|
label="L1 BaseSelect"
|
|
:options="[{ value: 'OPT1', label: '옵션 1' }, { value: 'OPT2', label: '옵션 2' }]"
|
|
/>
|
|
<div class="pb-2">
|
|
<BaseCheckbox v-model="sampleCheck" label="L1 BaseCheckbox 선택됨" />
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<BaseButton variant="primary" @click="isDialogOpen = true">L1 BaseDialog 열기</BaseButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- LAYER 2: TYPED FIELDS -->
|
|
<div class="bg-white p-6 rounded-lg shadow-sm border border-slate-200 flex flex-col gap-4">
|
|
<div class="flex items-center gap-2 border-b pb-2">
|
|
<BaseStatusBadge variant="info" label="Layer 2" />
|
|
<h2 class="text-base font-bold text-slate-800">Typed Fields (데이터 타입 이해 컴포넌트)</h2>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<CodeField v-model="sampleCode" label="L2 CodeField (대문자 정규화)" />
|
|
<DecimalField v-model="sampleDecimal" label="L2 DecimalField (부동소수점 오차 0)" />
|
|
<DateField v-model="sampleDate" label="L2 DateField (ISO YYYY-MM-DD)" />
|
|
<TextField label="L2 TextField (오류 예시)" :field-state="{ value: '오류값', initialValue: '초기값', status: 'invalid', source: 'user', touched: true, dirty: true, required: true, errors: [{ code: 'REQ', message: '입력 필수 항목입니다', severity: 'error', blocking: true }], warnings: [], information: [] }" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- LAYER 3: DOMAIN FIELDS -->
|
|
<div class="bg-white p-6 rounded-lg shadow-sm border border-slate-200 flex flex-col gap-4">
|
|
<div class="flex items-center gap-2 border-b pb-2">
|
|
<BaseStatusBadge variant="warning" label="Layer 3" />
|
|
<h2 class="text-base font-bold text-slate-800">Domain Fields (업무 도메인 이해 컴포넌트)</h2>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<QuantityField v-model="sampleQty" label="L3 QuantityField" uom="BOX" :max-available-qty="500" />
|
|
<MoneyField v-model="sampleMoney" label="L3 MoneyField" currency="KRW" />
|
|
<LotField v-model="sampleLot" label="L3 LotField (FEFO 권장)" />
|
|
<ReferenceLookup v-model="sampleLookup" label="L3 ReferenceLookup (300ms Debounce)" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- LAYER 4: BUSINESS COMPOSITES -->
|
|
<div class="bg-white p-6 rounded-lg shadow-sm border border-slate-200 flex flex-col gap-4">
|
|
<div class="flex items-center gap-2 border-b pb-2">
|
|
<BaseStatusBadge variant="danger" label="Layer 4" />
|
|
<h2 class="text-base font-bold text-slate-800">Business Composites (복합 업무 규칙 컴포넌트)</h2>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<BarcodeInput />
|
|
<AISuggestedField
|
|
v-model="aiFieldVal"
|
|
label="L4 AISuggestedField (R1 위험도)"
|
|
suggested-value="긴급 당일 배송 (AI 추천)"
|
|
confidence="98%"
|
|
rationale="과거 주문 패턴 분석 결과 당일 배송 선호도 높음"
|
|
/>
|
|
<AddressEditor />
|
|
<InventoryAllocationEditor />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sample BaseDialog -->
|
|
<BaseDialog :is-open="isDialogOpen" title="L1 BaseDialog 테스트" @close="isDialogOpen = false">
|
|
<p class="text-sm text-slate-600">BaseDialog 모달이 정상 동작합니다. ESC 키 또는 X 버튼을 눌러 닫을 수 있습니다.</p>
|
|
<template #footer>
|
|
<BaseButton variant="secondary" @click="isDialogOpen = false">닫기</BaseButton>
|
|
</template>
|
|
</BaseDialog>
|
|
</div>
|
|
</template>
|