summaryrefslogtreecommitdiff
path: root/lib/evaluation/table/evaluation-filter-sheet.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/evaluation/table/evaluation-filter-sheet.tsx')
-rw-r--r--lib/evaluation/table/evaluation-filter-sheet.tsx234
1 files changed, 160 insertions, 74 deletions
diff --git a/lib/evaluation/table/evaluation-filter-sheet.tsx b/lib/evaluation/table/evaluation-filter-sheet.tsx
index b0bf9139..c2dd9734 100644
--- a/lib/evaluation/table/evaluation-filter-sheet.tsx
+++ b/lib/evaluation/table/evaluation-filter-sheet.tsx
@@ -7,7 +7,6 @@ import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Search, X } from "lucide-react";
import { customAlphabet } from "nanoid";
-import { parseAsStringEnum, useQueryState } from "nuqs";
import { Button } from "@/components/ui/button";
import {
@@ -28,7 +27,6 @@ import {
SelectValue,
} from "@/components/ui/select";
import { cn } from "@/lib/utils";
-import { getFiltersStateParser } from "@/lib/parsers";
import { EVALUATION_TARGET_FILTER_OPTIONS } from "@/lib/evaluation-target-list/validation";
/*****************************************************************************************
@@ -49,7 +47,6 @@ const statusOptions = [
{ value: "FINALIZED", label: "결과확정" },
];
-
const documentsSubmittedOptions = [
{ value: "true", label: "제출완료" },
{ value: "false", label: "미제출" },
@@ -104,14 +101,13 @@ export function PeriodicEvaluationFilterSheet({
isLoading = false,
onFiltersApply,
}: PeriodicEvaluationFilterSheetProps) {
- /** Router (needed only for pathname) */
+ /** Router (needed for URL updates) */
const router = useRouter();
/** Track pending state while we update URL */
const [isPending, startTransition] = useTransition();
const [joinOperator, setJoinOperator] = useState<"and" | "or">("and")
-
/** React‑Hook‑Form */
const form = useForm<PeriodicEvaluationFilterFormValues>({
resolver: zodResolver(periodicEvaluationFilterSchema),
@@ -131,82 +127,156 @@ export function PeriodicEvaluationFilterSheet({
},
});
-
/*****************************************************************************************
- * 3️⃣ Submit → build filter array → push to URL (and reset page=1)
+ * 3️⃣ Submit → build filter array → callback + URL (동기적 처리)
*****************************************************************************************/
async function onSubmit(data: PeriodicEvaluationFilterFormValues) {
startTransition(() => {
try {
- const newFilters: any[] = [];
-
- const pushFilter = (
- id: string,
- value: any,
- type: "text" | "select" | "number" | "boolean",
- operator: "eq" | "iLike" | "gte" | "lte"
- ) => {
- newFilters.push({ id, value, type, operator, rowId: generateId() });
- };
-
- if (data.evaluationYear?.trim())
- pushFilter("evaluationYear", Number(data.evaluationYear), "number", "eq");
-
- if (data.division?.trim())
- pushFilter("division", data.division.trim(), "select", "eq");
-
- if (data.status?.trim())
- pushFilter("status", data.status.trim(), "select", "eq");
-
- if (data.domesticForeign?.trim())
- pushFilter("domesticForeign", data.domesticForeign.trim(), "select", "eq");
-
- if (data.materialType?.trim())
- pushFilter("materialType", data.materialType.trim(), "select", "eq");
-
- if (data.vendorCode?.trim())
- pushFilter("vendorCode", data.vendorCode.trim(), "text", "iLike");
-
- if (data.vendorName?.trim())
- pushFilter("vendorName", data.vendorName.trim(), "text", "iLike");
-
- if (data.documentsSubmitted?.trim())
- pushFilter(
- "documentsSubmitted",
- data.documentsSubmitted.trim() === "true",
- "boolean",
- "eq"
- );
-
- if (data.evaluationGrade?.trim())
- pushFilter("evaluationGrade", data.evaluationGrade.trim(), "select", "eq");
-
- if (data.finalGrade?.trim())
- pushFilter("finalGrade", data.finalGrade.trim(), "select", "eq");
-
- if (data.minTotalScore?.trim())
- pushFilter("totalScore", Number(data.minTotalScore), "number", "gte");
-
- if (data.maxTotalScore?.trim())
- pushFilter("totalScore", Number(data.maxTotalScore), "number", "lte");
-
- setJoinOperator(joinOperator);
-
-
+ const newFilters = []
+
+ // 필터 생성 로직
+ if (data.evaluationYear?.trim()) {
+ newFilters.push({
+ id: "evaluationYear",
+ value: parseInt(data.evaluationYear.trim()),
+ type: "number",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.division?.trim()) {
+ newFilters.push({
+ id: "division",
+ value: data.division.trim(),
+ type: "select",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.status?.trim()) {
+ newFilters.push({
+ id: "status",
+ value: data.status.trim(),
+ type: "select",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.domesticForeign?.trim()) {
+ newFilters.push({
+ id: "domesticForeign",
+ value: data.domesticForeign.trim(),
+ type: "select",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.materialType?.trim()) {
+ newFilters.push({
+ id: "materialType",
+ value: data.materialType.trim(),
+ type: "select",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.vendorCode?.trim()) {
+ newFilters.push({
+ id: "vendorCode",
+ value: data.vendorCode.trim(),
+ type: "text",
+ operator: "iLike",
+ rowId: generateId()
+ })
+ }
+
+ if (data.vendorName?.trim()) {
+ newFilters.push({
+ id: "vendorName",
+ value: data.vendorName.trim(),
+ type: "text",
+ operator: "iLike",
+ rowId: generateId()
+ })
+ }
+
+ if (data.documentsSubmitted?.trim()) {
+ newFilters.push({
+ id: "documentsSubmitted",
+ value: data.documentsSubmitted.trim() === "true",
+ type: "boolean",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.evaluationGrade?.trim()) {
+ newFilters.push({
+ id: "evaluationGrade",
+ value: data.evaluationGrade.trim(),
+ type: "select",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.finalGrade?.trim()) {
+ newFilters.push({
+ id: "finalGrade",
+ value: data.finalGrade.trim(),
+ type: "select",
+ operator: "eq",
+ rowId: generateId()
+ })
+ }
+
+ if (data.minTotalScore?.trim()) {
+ newFilters.push({
+ id: "totalScore",
+ value: parseFloat(data.minTotalScore.trim()),
+ type: "number",
+ operator: "gte",
+ rowId: generateId()
+ })
+ }
+
+ if (data.maxTotalScore?.trim()) {
+ newFilters.push({
+ id: "totalScore",
+ value: parseFloat(data.maxTotalScore.trim()),
+ type: "number",
+ operator: "lte",
+ rowId: generateId()
+ })
+ }
+
+ console.log("=== 생성된 필터들 ===", newFilters);
+ console.log("=== 조인 연산자 ===", joinOperator);
+
+
+ // ✅ 부모 컴포넌트에 필터 전달 (동기적으로 즉시 호출)
onFiltersApply(newFilters, joinOperator);
- } catch (err) {
- // eslint-disable-next-line no-console
- console.error("정기평가 필터 적용 오류:", err);
+
+ console.log("=== 필터 적용 완료 ===");
+ } catch (error) {
+ console.error("정기평가 필터 적용 오류:", error);
}
});
}
/*****************************************************************************************
- * 4️⃣ Reset → clear form & URL
+ * 4️⃣ Reset → clear form & URL (동기적 처리)
*****************************************************************************************/
- async function handleReset() {
+ function handleReset() {
+ // 1. 폼 초기화
form.reset({
- evaluationYear: new Date().getFullYear().toString(),
+ evaluationYear: "",
division: "",
status: "",
domesticForeign: "",
@@ -220,9 +290,26 @@ export function PeriodicEvaluationFilterSheet({
maxTotalScore: "",
});
- onFiltersApply([], "and");
+ // 2. 조인 연산자 초기화
setJoinOperator("and");
+ // 3. URL 파라미터 초기화 (필터를 빈 배열로 설정)
+ const currentUrl = new URL(window.location.href);
+ const newSearchParams = new URLSearchParams(currentUrl.search);
+
+ // 필터 관련 파라미터 초기화
+ newSearchParams.set("filters", JSON.stringify([]));
+ newSearchParams.set("joinOperator", "and");
+ newSearchParams.set("page", "1");
+ newSearchParams.delete("search"); // 검색어 제거
+
+ // URL 업데이트
+ router.replace(`${currentUrl.pathname}?${newSearchParams.toString()}`);
+
+ // 4. 빈 필터 배열 전달 (즉시 UI 업데이트를 위해)
+ onFiltersApply([], "and");
+
+ console.log("=== 필터 완전 초기화 완료 ===");
}
/*****************************************************************************************
@@ -306,7 +393,6 @@ export function PeriodicEvaluationFilterSheet({
)}
/>
-
{/* 구분 */}
<FormField
control={form.control}
@@ -472,7 +558,7 @@ export function PeriodicEvaluationFilterSheet({
className="-mr-2 h-4 w-4"
onClick={(e) => {
e.stopPropagation();
- form.setValue("materialType", "");
+ form.setValue("materialType", "");
}}
disabled={isPending}
>
@@ -798,7 +884,7 @@ export function PeriodicEvaluationFilterSheet({
type="button"
variant="outline"
onClick={handleReset}
- disabled={isPending }
+ disabled={isPending}
className="px-4"
>
초기화
@@ -806,7 +892,7 @@ export function PeriodicEvaluationFilterSheet({
<Button
type="submit"
variant="samsung"
- disabled={isPending || isLoading }
+ disabled={isPending || isLoading}
className="px-4"
>
<Search className="mr-2 size-4" />
@@ -818,4 +904,4 @@ export function PeriodicEvaluationFilterSheet({
</Form>
</div>
);
-}
+} \ No newline at end of file