feat(WEB): QMS 필터 리팩토링 및 공통 컴포넌트 추가

- ScrollableButtonGroup 아톰 컴포넌트 신규 추가
- YearQuarterFilter 분자 컴포넌트 신규 추가
- QMS Filters 컴포넌트 공통 필터로 리팩토링
- QMS Header, AuditSettingsPanel 수정
- DateRangeSelector 개선
- PerformanceReportList 필터 간소화
- ItemMasterDataManagement 수정
- CLAUDE.md 프로젝트 설정 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-04 22:40:18 +09:00
parent bb7e7a75e9
commit b587460449
12 changed files with 205 additions and 122 deletions

View File

@@ -29,13 +29,7 @@ import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { TableCell, TableRow } from '@/components/ui/table';
import { Checkbox } from '@/components/ui/checkbox';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { YearQuarterFilter } from '@/components/molecules/YearQuarterFilter';
import {
UniversalListPage,
type UniversalListConfig,
@@ -93,15 +87,6 @@ export function PerformanceReportList() {
// ===== 현재 데이터 추적 (메모 모달 개소 계산용) =====
const [currentData, setCurrentData] = useState<ReportListItem[]>([]);
// ===== 연도 옵션 =====
const yearOptions = useMemo(() => {
const years = [];
for (let y = currentYear; y >= currentYear - 5; y--) {
years.push(y);
}
return years;
}, [currentYear]);
// ===== 통계 로드 =====
useEffect(() => {
const loadStats = async () => {
@@ -118,11 +103,6 @@ export function PerformanceReportList() {
loadStats();
}, [year, quarter, refreshKey]);
// ===== 분기 버튼 클릭 =====
const handleQuarterChange = useCallback((q: Quarter | '전체') => {
setQuarter(q);
}, []);
// ===== 액션 핸들러 =====
const handleConfirm = useCallback(async (
selectedItems: Set<string>,
@@ -267,35 +247,15 @@ export function PerformanceReportList() {
// ===== 연도/분기 필터 슬롯 (dateRangeSelector.extraActions) =====
const quarterFilterSlot = useMemo(
() => (
<div className="flex items-center gap-2 flex-wrap order-first">
<Select value={String(year)} onValueChange={(v) => setYear(Number(v))}>
<SelectTrigger className="w-[100px] h-9 text-sm">
<SelectValue />
</SelectTrigger>
<SelectContent>
{yearOptions.map((y) => (
<SelectItem key={y} value={String(y)}>
{y}
</SelectItem>
))}
</SelectContent>
</Select>
<div className="flex gap-1">
{(['전체', 'Q1', 'Q2', 'Q3', 'Q4'] as const).map((q) => (
<Button
key={q}
size="sm"
variant={quarter === q ? 'default' : 'outline'}
className="h-8 px-3 text-xs"
onClick={() => handleQuarterChange(q)}
>
{q === '전체' ? '전체' : `${q.replace('Q', '')}분기`}
</Button>
))}
</div>
</div>
<YearQuarterFilter
year={year}
quarter={quarter}
onYearChange={setYear}
onQuarterChange={setQuarter}
className="order-first"
/>
),
[year, quarter, yearOptions, handleQuarterChange]
[year, quarter]
);
// ===== UniversalListPage Config =====