fix(sn): 조사관리 팝업 레이아웃과 등록 흐름 개선
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
import LoadingOverlay from "@/components/ui/LoadingBar";
|
||||
import { getStartYearArray } from "@/components/ui/YearRangeSelectBox";
|
||||
import useStore from "@/store/useStore";
|
||||
import { postPopupMessage } from "@/features/windowPopup/lib/popupMessage";
|
||||
import {
|
||||
postPopupMessage,
|
||||
postPopupMessageAndClose,
|
||||
} from "@/features/windowPopup/lib/popupMessage";
|
||||
import { WINDOW_POPUP_MESSAGE_TYPE } from "@/features/windowPopup/model/types";
|
||||
import {
|
||||
StandardFormField,
|
||||
@@ -319,19 +322,24 @@ export function ExmnBusinessRegisterPopupPage({
|
||||
: await createExmnBusiness(request);
|
||||
|
||||
setSavedBusiness(persisted);
|
||||
const popupPayload = {
|
||||
exmnBizId: persisted.exmnBizId,
|
||||
};
|
||||
if (!isEditMode) {
|
||||
postPopupMessageAndClose(
|
||||
WINDOW_POPUP_MESSAGE_TYPE.EXMN_BUSINESS_CREATED,
|
||||
popupPayload,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
postPopupMessage(
|
||||
isEditMode
|
||||
? WINDOW_POPUP_MESSAGE_TYPE.EXMN_BUSINESS_UPDATED
|
||||
: WINDOW_POPUP_MESSAGE_TYPE.EXMN_BUSINESS_CREATED,
|
||||
{
|
||||
exmnBizId: persisted.exmnBizId,
|
||||
},
|
||||
WINDOW_POPUP_MESSAGE_TYPE.EXMN_BUSINESS_UPDATED,
|
||||
popupPayload,
|
||||
);
|
||||
setNotice({
|
||||
type: "success",
|
||||
text: isEditMode
|
||||
? "사업정보를 수정했습니다. 변경된 처리분구 기준으로 양식을 다시 받을 수 있습니다."
|
||||
: "사업정보와 처리분구별 기본 요약행을 저장했습니다.",
|
||||
text: "사업정보를 수정했습니다. 변경된 처리분구 기준으로 양식을 다시 받을 수 있습니다.",
|
||||
});
|
||||
} catch (error) {
|
||||
setNotice({
|
||||
@@ -447,7 +455,7 @@ export function ExmnBusinessRegisterPopupPage({
|
||||
{notice && (
|
||||
<div
|
||||
role="alert"
|
||||
className={`rounded-sm border px-4 py-3 text-[1.3rem] ${
|
||||
className={`shrink-0 rounded-sm border px-4 py-3 text-[1.3rem] ${
|
||||
notice.type === "error"
|
||||
? "border-red-200 bg-red-50 text-red-700"
|
||||
: notice.type === "success"
|
||||
@@ -583,7 +591,7 @@ export function ExmnBusinessRegisterPopupPage({
|
||||
</StandardFormField>
|
||||
</StandardFormSection>
|
||||
|
||||
<section className="card card-border !m-0 min-h-0 overflow-hidden !p-[0.6rem]">
|
||||
<section className="card card-border !m-0 min-h-0 shrink-0 overflow-hidden !p-[0.6rem]">
|
||||
<div className="card-header flex min-h-[5.2rem] flex-wrap items-center justify-between gap-4">
|
||||
<h2 className="text-2xl font-medium text-label">사업대상 처리분구</h2>
|
||||
<div className="flex flex-wrap items-center justify-end gap-2">
|
||||
|
||||
@@ -98,6 +98,8 @@ export function ExmnRegistrationPage() {
|
||||
const [selectedBusinessId, setSelectedBusinessId] = useState<string | null>(
|
||||
null,
|
||||
);
|
||||
// 목록 행을 선택한 뒤 스크롤과 키보드 포커스를 함께 이동할 상세현황 영역이다.
|
||||
const detailPanelRef = useRef<HTMLDivElement>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [notice, setNotice] = useState<Notice>(null);
|
||||
|
||||
@@ -122,6 +124,17 @@ export function ExmnRegistrationPage() {
|
||||
[businesses, selectedBusinessId],
|
||||
);
|
||||
|
||||
/** 목록 행 선택 후 렌더링된 상세현황을 화면 상단으로 이동하고 포커스를 부여한다. */
|
||||
const handleBusinessRowClick = (business: ExmnBusiness) => {
|
||||
setSelectedBusinessId(business.exmnBizId);
|
||||
window.requestAnimationFrame(() => {
|
||||
const detailPanel = detailPanelRef.current;
|
||||
if (!detailPanel) return;
|
||||
detailPanel.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
detailPanel.focus({ preventScroll: true });
|
||||
});
|
||||
};
|
||||
|
||||
/** 사업 목록의 숫자·행정구역·사업보고서 파일명을 표시 전용 값으로 변환한다. */
|
||||
const businessRows = useMemo(
|
||||
() =>
|
||||
@@ -598,7 +611,7 @@ export function ExmnRegistrationPage() {
|
||||
className={EXMN_TABLE_HEADER_CLASS}
|
||||
scrollMode="horizontal"
|
||||
minTableWidth="110rem"
|
||||
onRowClick={(row) => setSelectedBusinessId(row.exmnBizId)}
|
||||
onRowClick={handleBusinessRowClick}
|
||||
actions={
|
||||
<>
|
||||
<Button
|
||||
@@ -629,7 +642,14 @@ export function ExmnRegistrationPage() {
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<ExmnStatusDetailPanel business={selectedBusiness} />
|
||||
<div
|
||||
ref={detailPanelRef}
|
||||
tabIndex={-1}
|
||||
aria-label="조사 상세현황"
|
||||
className="scroll-mt-[1.2rem] focus:outline-none"
|
||||
>
|
||||
<ExmnStatusDetailPanel business={selectedBusiness} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ export function ExmnResultRegisterPopupPage({
|
||||
{notice && notice.type !== "success" && (
|
||||
<div
|
||||
role="alert"
|
||||
className={`whitespace-pre-line rounded-sm border px-4 py-3 text-[1.3rem] ${
|
||||
className={`shrink-0 whitespace-pre-line rounded-sm border px-4 py-3 text-[1.3rem] ${
|
||||
notice.type === "error"
|
||||
? "border-red-200 bg-red-50 text-red-700"
|
||||
: "border-primary bg-primary-transparent text-primary"
|
||||
@@ -472,7 +472,7 @@ export function ExmnResultRegisterPopupPage({
|
||||
</StandardFormField>
|
||||
</StandardFormSection>
|
||||
|
||||
<section className="overflow-hidden rounded-sm border border-border bg-background">
|
||||
<section className="shrink-0 overflow-hidden rounded-sm border border-border bg-background">
|
||||
<div
|
||||
className="grid items-center gap-3 bg-primary px-3 py-3 text-center text-[1.3rem] font-semibold text-primary-foreground"
|
||||
style={{ gridTemplateColumns: "180px minmax(0, 1fr) 80px 112px" }}
|
||||
@@ -568,7 +568,7 @@ export function ExmnResultRegisterPopupPage({
|
||||
|
||||
{visibleValidationTypes.length > 0 && (
|
||||
<section
|
||||
className="overflow-hidden rounded-sm border border-border bg-background"
|
||||
className="shrink-0 overflow-hidden rounded-sm border border-border bg-background"
|
||||
aria-label="데이터 검토 내역"
|
||||
>
|
||||
<div className="flex items-center border-b border-border bg-container px-4 py-3">
|
||||
|
||||
Reference in New Issue
Block a user