st: feat: 수식 다이얼로그 컬럼 검색 추가
This commit is contained in:
+106
-26
@@ -10,6 +10,7 @@ import {
|
||||
DialogClose,
|
||||
Textarea,
|
||||
Skeleton,
|
||||
Input,
|
||||
} from "@common/components";
|
||||
import { CodeSelect } from "@/entities/code";
|
||||
|
||||
@@ -41,6 +42,9 @@ const FomulaDialog = ({ open, onOpenChange, data, trgtStatsCd, trgtStatsNm, onCo
|
||||
const [showCommonColumns, setShowCommonColumns] = useState<boolean>(true);
|
||||
const [showTargetColumns, setShowTargetColumns] = useState<boolean>(true);
|
||||
const [showRefColumns, setShowRefColumns] = useState<boolean>(true);
|
||||
const [commonColumnSearchValue, setCommonColumnSearchValue] = useState<string>('');
|
||||
const [targetColumnSearchValue, setTargetColumnSearchValue] = useState<string>('');
|
||||
const [refColumnSearchValue, setRefColumnSearchValue] = useState<string>('');
|
||||
/** 참조 통계 - 다이얼로그 내부에서만 사용. 열 때마다 해당 행(data)의 저장값으로 초기화, 저장 시에만 부모에 반영 예정 */
|
||||
const [refStatsCdLocal, setRefStatsCdLocal] = useState<string>('');
|
||||
/** 수식 = 토큰 배열. 한글명 중복 시 출처(공통/대상/참조)별 engColNm 보존 */
|
||||
@@ -207,7 +211,7 @@ const FomulaDialog = ({ open, onOpenChange, data, trgtStatsCd, trgtStatsNm, onCo
|
||||
refStatsCd: data.refStatsCd,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (response?.status === 'success') {
|
||||
setColumnInfo(response.data);
|
||||
@@ -359,10 +363,57 @@ const FomulaDialog = ({ open, onOpenChange, data, trgtStatsCd, trgtStatsNm, onCo
|
||||
setFormulaSaveError(null);
|
||||
setSelectedColumnInfo(null);
|
||||
setRefStatsCdLocal('');
|
||||
setCommonColumnSearchValue('');
|
||||
setTargetColumnSearchValue('');
|
||||
setRefColumnSearchValue('');
|
||||
}
|
||||
onOpenChange?.(nextOpen);
|
||||
};
|
||||
|
||||
const handleSearchColumn = (value: string, type: string) => {
|
||||
if (type === 'common') {
|
||||
setCommonColumnSearchValue(value);
|
||||
} else if (type === 'target') {
|
||||
setTargetColumnSearchValue(value);
|
||||
} else {
|
||||
setRefColumnSearchValue(value);
|
||||
}
|
||||
};
|
||||
|
||||
const normalizeSearch = (v: string) => v.replace(/\s+/g, "").toLowerCase();
|
||||
|
||||
const commonSearch = normalizeSearch(commonColumnSearchValue);
|
||||
const commonColumns = columnInfo?.commonColumnInfo ?? [];
|
||||
const filteredCommonColumns =
|
||||
commonSearch.length > 0
|
||||
? commonColumns.filter((c) => {
|
||||
const korn = normalizeSearch(c.kornColNm ?? '');
|
||||
const eng = normalizeSearch(c.engColNm ?? '');
|
||||
return korn.includes(commonSearch) || eng.includes(commonSearch);
|
||||
})
|
||||
: commonColumns;
|
||||
|
||||
const targetSearch = normalizeSearch(targetColumnSearchValue);
|
||||
const targetColumns = columnInfo?.targetColumnInfo?.colList ?? [];
|
||||
const filteredTargetColumns =
|
||||
targetSearch.length > 0
|
||||
? targetColumns.filter((t) => {
|
||||
const korn = normalizeSearch(t.kornColNm ?? '');
|
||||
const eng = normalizeSearch(t.engColNm ?? '');
|
||||
return korn.includes(targetSearch) || eng.includes(targetSearch);
|
||||
})
|
||||
: targetColumns;
|
||||
|
||||
const refSearch = normalizeSearch(refColumnSearchValue);
|
||||
const filterdRefColumns =
|
||||
refSearch.length > 0
|
||||
? refColList.filter((r) => {
|
||||
const korn = normalizeSearch(r.kornColNm ?? '');
|
||||
const eng = normalizeSearch(r.engColNm ?? '');
|
||||
return korn.includes(refSearch) || eng.includes(refSearch);
|
||||
})
|
||||
: refColList;
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||
<DialogContent aria-describedby={undefined} className="max-w-[100rem] w-full max-h-[90%] overflow-auto">
|
||||
@@ -446,21 +497,30 @@ const FomulaDialog = ({ open, onOpenChange, data, trgtStatsCd, trgtStatsNm, onCo
|
||||
{showCommonColumns ? "접기" : "펼치기"}
|
||||
</Button>
|
||||
</div>
|
||||
{showCommonColumns &&
|
||||
<div className="mb-2">
|
||||
<Input
|
||||
className="w-[20rem] rounded-sm !text-[1.3rem] focus-visible:ring-0 focus-visible:ring-offset-0"
|
||||
value={commonColumnSearchValue}
|
||||
onChange={(e) => handleSearchColumn(e.target.value, 'common')}
|
||||
placeholder="검색어를 입력하세요."
|
||||
/>
|
||||
</div>}
|
||||
{showCommonColumns ? (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{columnInfo?.commonColumnInfo?.length && columnInfo.commonColumnInfo.length > 0 ?
|
||||
columnInfo.commonColumnInfo.map((c) => (
|
||||
<Button
|
||||
key={c.engColNm}
|
||||
type="button"
|
||||
value={c.engColNm}
|
||||
size="sm"
|
||||
color="lightGray"
|
||||
onClick={() => handleFormulaColumn(c.kornColNm, c.engColNm)}
|
||||
>
|
||||
{c.kornColNm}
|
||||
</Button>
|
||||
))
|
||||
filteredCommonColumns.map((c) => (
|
||||
<Button
|
||||
key={c.engColNm}
|
||||
type="button"
|
||||
value={c.engColNm}
|
||||
size="sm"
|
||||
color="lightGray"
|
||||
onClick={() => handleFormulaColumn(c.kornColNm, c.engColNm)}
|
||||
>
|
||||
{c.kornColNm}
|
||||
</Button>
|
||||
))
|
||||
:
|
||||
<Skeleton className="h-[12rem] w-full rounded-xl" />
|
||||
}
|
||||
@@ -479,20 +539,30 @@ const FomulaDialog = ({ open, onOpenChange, data, trgtStatsCd, trgtStatsNm, onCo
|
||||
{showTargetColumns ? "접기" : "펼치기"}
|
||||
</Button>
|
||||
</div>
|
||||
{showTargetColumns &&
|
||||
<div className="mb-2">
|
||||
<Input
|
||||
className="w-[20rem] rounded-sm !text-[1.3rem] focus-visible:ring-0 focus-visible:ring-offset-0"
|
||||
value={targetColumnSearchValue}
|
||||
onChange={(e) => handleSearchColumn(e.target.value, 'target')}
|
||||
placeholder="검색어를 입력하세요."
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{showTargetColumns ? (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{columnInfo?.targetColumnInfo?.colList.length && columnInfo.targetColumnInfo.colList.length > 0 ?
|
||||
columnInfo.targetColumnInfo.colList.map((t) => (
|
||||
<Button
|
||||
key={t.engColNm}
|
||||
type="button"
|
||||
value={t.engColNm}
|
||||
size="sm"
|
||||
onClick={() => handleFormulaColumn(t.kornColNm, t.engColNm)}
|
||||
>
|
||||
{t.kornColNm}
|
||||
</Button>
|
||||
))
|
||||
filteredTargetColumns.map((t) => (
|
||||
<Button
|
||||
key={t.engColNm}
|
||||
type="button"
|
||||
value={t.engColNm}
|
||||
size="sm"
|
||||
onClick={() => handleFormulaColumn(t.kornColNm, t.engColNm)}
|
||||
>
|
||||
{t.kornColNm}
|
||||
</Button>
|
||||
))
|
||||
:
|
||||
<Skeleton className="h-[12rem] w-full rounded-xl" />
|
||||
}
|
||||
@@ -529,10 +599,20 @@ const FomulaDialog = ({ open, onOpenChange, data, trgtStatsCd, trgtStatsNm, onCo
|
||||
{refStatsChangeNotice}
|
||||
</p>
|
||||
)}
|
||||
{(refStatsCdLocal && showRefColumns) &&
|
||||
<div className="mb-2">
|
||||
<Input
|
||||
className="w-[20rem] rounded-sm !text-[1.3rem] focus-visible:ring-0 focus-visible:ring-offset-0"
|
||||
value={refColumnSearchValue}
|
||||
onChange={(e) => handleSearchColumn(e.target.value, 'ref')}
|
||||
placeholder="검색어를 입력하세요."
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{showRefColumns ? (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{(refColList?.length ?? 0) > 0 ?
|
||||
refColList.map((r) => (
|
||||
{(filterdRefColumns?.length ?? 0) > 0 ?
|
||||
filterdRefColumns.map((r) => (
|
||||
<Button
|
||||
key={r.engColNm}
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user