[st] - feat: realgrid 셀 편집 체크 설정 수정, 컴포넌트 url 방식 테스트 중
This commit is contained in:
@@ -52,6 +52,142 @@ if (typeof window !== "undefined") {
|
||||
|
||||
RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || "");
|
||||
|
||||
function isDropDownEditorColumn(column: {
|
||||
editor?: { type?: string };
|
||||
values?: string[];
|
||||
}): boolean {
|
||||
const type = column.editor?.type;
|
||||
return (
|
||||
type === "dropdown" ||
|
||||
type === "list" ||
|
||||
type === "dropDown" ||
|
||||
(column.values != null && column.values.length > 0)
|
||||
);
|
||||
}
|
||||
|
||||
type GridViewWithSetColumnProperty = {
|
||||
setColumnProperty?: (col: string, key: string, value: unknown) => void;
|
||||
};
|
||||
|
||||
type GridViewWithEditOptions = {
|
||||
setEditOptions?: (options: { commitWhenLeave?: boolean }) => void;
|
||||
};
|
||||
|
||||
/** 포커스가 그리드 밖으로 나갈 때 편집 중인 값을 자동 commit */
|
||||
function applyDefaultGridEditOptions(
|
||||
gridView: GridViewWithEditOptions | null | undefined,
|
||||
) {
|
||||
gridView?.setEditOptions?.({ commitWhenLeave: true });
|
||||
}
|
||||
|
||||
function isDateEditorColumn(column: {
|
||||
editor?: { type?: string };
|
||||
}): boolean {
|
||||
return column.editor?.type === "date";
|
||||
}
|
||||
|
||||
/** RealGrid 날짜(date) 편집기 컬럼 속성 적용 */
|
||||
function applyColumnDateEditorProperties(
|
||||
gridView: GridViewWithSetColumnProperty,
|
||||
column: import("../type/DataGrid.type").ColumnConfig,
|
||||
) {
|
||||
if (!gridView.setColumnProperty) return;
|
||||
const fmt =
|
||||
column.datetimeFormat ??
|
||||
column.editor?.datetimeFormat ??
|
||||
"yyyy-MM-dd";
|
||||
gridView.setColumnProperty(column.name, "datetimeFormat", fmt);
|
||||
gridView.setColumnProperty(column.name, "editor", {
|
||||
type: "date",
|
||||
datetimeFormat: fmt,
|
||||
dropDownWhenClick: column.editor?.dropDownWhenClick ?? true,
|
||||
showToday: column.editor?.showToday ?? true,
|
||||
});
|
||||
gridView.setColumnProperty(column.name, "editButtonVisibility", "always");
|
||||
}
|
||||
|
||||
/** RealGrid 드롭다운·날짜 등 컬럼 편집기 속성 적용 */
|
||||
function applyColumnListEditorProperties(
|
||||
gridView: GridViewWithSetColumnProperty,
|
||||
column: import("../type/DataGrid.type").ColumnConfig,
|
||||
) {
|
||||
if (!gridView.setColumnProperty) return;
|
||||
|
||||
if (isDateEditorColumn(column)) {
|
||||
applyColumnDateEditorProperties(gridView, column);
|
||||
return;
|
||||
}
|
||||
|
||||
const values = column.values ?? column.editor?.values;
|
||||
const labels = column.labels ?? column.editor?.labels ?? values;
|
||||
const isDropDown = isDropDownEditorColumn(column);
|
||||
|
||||
if (!isDropDown) {
|
||||
if (column.editor) {
|
||||
gridView.setColumnProperty(column.name, "editor", column.editor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (values?.length) {
|
||||
gridView.setColumnProperty(column.name, "values", values);
|
||||
gridView.setColumnProperty(column.name, "labels", labels ?? values);
|
||||
}
|
||||
if (column.lookupDisplay) {
|
||||
gridView.setColumnProperty(column.name, "lookupDisplay", true);
|
||||
}
|
||||
gridView.setColumnProperty(column.name, "editor", {
|
||||
type: "dropdown",
|
||||
domainOnly: column.editor?.domainOnly ?? true,
|
||||
textReadOnly: column.editor?.textReadOnly ?? true,
|
||||
commitOnSelect: column.editor?.commitOnSelect ?? true,
|
||||
dropDownWhenClick: column.editor?.dropDownWhenClick ?? true,
|
||||
values,
|
||||
labels: labels ?? values,
|
||||
});
|
||||
gridView.setColumnProperty(column.name, "editButtonVisibility", "always");
|
||||
}
|
||||
|
||||
/** 그리드 마운트·데이터 로드 후 드롭다운 컬럼 재적용용 */
|
||||
export function applyDropDownColumnToGrid(
|
||||
gridView: GridViewWithSetColumnProperty | null | undefined,
|
||||
columnName: string,
|
||||
options: string[],
|
||||
) {
|
||||
if (!gridView?.setColumnProperty || options.length === 0) return;
|
||||
(
|
||||
gridView as {
|
||||
setEditOptions?: (opts: { editable?: boolean }) => void;
|
||||
}
|
||||
).setEditOptions?.({ editable: true });
|
||||
gridView.setColumnProperty(columnName, "editable", true);
|
||||
gridView.setColumnProperty(columnName, "values", options);
|
||||
gridView.setColumnProperty(columnName, "labels", options);
|
||||
gridView.setColumnProperty(columnName, "lookupDisplay", true);
|
||||
gridView.setColumnProperty(columnName, "editor", {
|
||||
type: "dropdown",
|
||||
domainOnly: true,
|
||||
textReadOnly: true,
|
||||
commitOnSelect: true,
|
||||
dropDownWhenClick: true,
|
||||
values: options,
|
||||
labels: options,
|
||||
});
|
||||
gridView.setColumnProperty(columnName, "editButtonVisibility", "always");
|
||||
(gridView as { refresh?: () => void }).refresh?.();
|
||||
}
|
||||
|
||||
function reapplyListEditorsOnGrid(
|
||||
gridView: GridViewWithSetColumnProperty | null | undefined,
|
||||
cols: import("../type/DataGrid.type").ColumnConfig[],
|
||||
) {
|
||||
if (!gridView) return;
|
||||
cols.forEach((col) => applyColumnListEditorProperties(gridView, col));
|
||||
if (cols.some((c) => isDropDownEditorColumn(c) || isDateEditorColumn(c))) {
|
||||
(gridView as { refresh?: () => void }).refresh?.();
|
||||
}
|
||||
}
|
||||
|
||||
type GridViewWithCheckApi = {
|
||||
checkItem?: (itemIndex: number, checked: boolean, exclusive?: boolean) => void;
|
||||
checkRow?: (dataRow: number, checked: boolean, exclusive?: boolean) => void;
|
||||
@@ -325,6 +461,8 @@ function buildFieldsFromColumns(
|
||||
columns: {
|
||||
fieldName: string;
|
||||
valueType?: ValueType;
|
||||
datetimeFormat?: string;
|
||||
editor?: { type?: string; datetimeFormat?: string };
|
||||
computed?: import("../type/DataGrid.type").ComputedFieldConfig;
|
||||
}[],
|
||||
) {
|
||||
@@ -332,6 +470,7 @@ function buildFieldsFromColumns(
|
||||
const field: {
|
||||
fieldName: string;
|
||||
dataType: string;
|
||||
datetimeFormat?: string;
|
||||
valueCallback?: (
|
||||
prod: unknown,
|
||||
dataRow: number,
|
||||
@@ -341,8 +480,19 @@ function buildFieldsFromColumns(
|
||||
) => number;
|
||||
} = {
|
||||
fieldName: col.fieldName,
|
||||
dataType: col.valueType === ValueType.NUMBER ? "number" : "text",
|
||||
dataType:
|
||||
col.editor?.type === "date"
|
||||
? "datetime"
|
||||
: col.valueType === ValueType.NUMBER
|
||||
? "number"
|
||||
: "text",
|
||||
};
|
||||
if (col.editor?.type === "date") {
|
||||
field.datetimeFormat =
|
||||
col.datetimeFormat ??
|
||||
col.editor.datetimeFormat ??
|
||||
"yyyy-MM-dd";
|
||||
}
|
||||
if (col.computed) {
|
||||
const hasFields =
|
||||
"fields" in col.computed && col.computed.fields.length > 0;
|
||||
@@ -844,6 +994,7 @@ const DataGrid = ({
|
||||
|
||||
const gridView = gridRef.current.gridView;
|
||||
const dataProvider = gridRef.current.dataProvider;
|
||||
applyDefaultGridEditOptions(gridView as GridViewWithEditOptions);
|
||||
|
||||
// mergeCells: true인 컬럼이 있으면 onSorting에서 클라이언트 정렬로 처리
|
||||
const hasMergeCells = columns.some((col) => col.mergeCells === true);
|
||||
@@ -894,15 +1045,8 @@ const DataGrid = ({
|
||||
(gridView.header as { showTooltip?: boolean }).showTooltip = true;
|
||||
}
|
||||
columns.forEach((column) => {
|
||||
(
|
||||
gridView as {
|
||||
setColumnProperty?: (
|
||||
col: string,
|
||||
key: string,
|
||||
value: unknown,
|
||||
) => void;
|
||||
}
|
||||
).setColumnProperty?.(
|
||||
const gv = gridView as GridViewWithSetColumnProperty;
|
||||
gv.setColumnProperty?.(
|
||||
column.name,
|
||||
"header",
|
||||
realGridHeaderWithTooltip({
|
||||
@@ -910,7 +1054,11 @@ const DataGrid = ({
|
||||
tooltip: resolveColumnTooltip(column),
|
||||
}),
|
||||
);
|
||||
applyColumnListEditorProperties(gv, column);
|
||||
});
|
||||
if (columns.some((c) => isDropDownEditorColumn(c))) {
|
||||
(gridView as { refresh?: () => void }).refresh?.();
|
||||
}
|
||||
(
|
||||
gridView as {
|
||||
onShowHeaderTooltip?: (
|
||||
@@ -1095,6 +1243,12 @@ const DataGrid = ({
|
||||
(currentGridView as GridViewWithSetColumns).setColumns?.(
|
||||
columnsWithFooter,
|
||||
);
|
||||
columns.forEach((col) =>
|
||||
applyColumnListEditorProperties(
|
||||
currentGridView as GridViewWithSetColumnProperty,
|
||||
col,
|
||||
),
|
||||
);
|
||||
applyFooterSettings(currentGridView);
|
||||
if (hasFooterUserSpans) {
|
||||
currentGridView.setColumnLayout?.(columnLayout);
|
||||
@@ -1499,6 +1653,12 @@ const DataGrid = ({
|
||||
autoGenerateField={true}
|
||||
layout={columnLayout}
|
||||
rows={rowData}
|
||||
onRGDataColumnsChanged={(grid) => {
|
||||
reapplyListEditorsOnGrid(
|
||||
grid as GridViewWithSetColumnProperty,
|
||||
columnsRef.current,
|
||||
);
|
||||
}}
|
||||
onInitialized={(grid) => {
|
||||
if (!grid) return;
|
||||
(
|
||||
@@ -1538,6 +1698,9 @@ const DataGrid = ({
|
||||
dataProvider.setRows(rowData);
|
||||
if (getGridRef) getGridRef.current = gridRef.current;
|
||||
const gridView = gridRef.current?.gridView ?? grid;
|
||||
applyDefaultGridEditOptions(
|
||||
gridView as GridViewWithEditOptions,
|
||||
);
|
||||
if (!gridView?.columnByName) return;
|
||||
setTimeout(() => {
|
||||
const gv = gridRef.current?.gridView;
|
||||
@@ -1653,6 +1816,10 @@ const DataGrid = ({
|
||||
tooltip: resolveColumnTooltip(column),
|
||||
}),
|
||||
);
|
||||
applyColumnListEditorProperties(
|
||||
gv as GridViewWithSetColumnProperty,
|
||||
column,
|
||||
);
|
||||
if (cellTooltipCallbackRef.current) {
|
||||
(
|
||||
gv as {
|
||||
@@ -1707,9 +1874,15 @@ const DataGrid = ({
|
||||
{columns.map((column) => {
|
||||
const baseStyleName = column.styleName;
|
||||
|
||||
const columnReactKey =
|
||||
column.values?.length &&
|
||||
isDropDownEditorColumn(column)
|
||||
? `${column.name}-dropdown-${column.values.length}`
|
||||
: column.name;
|
||||
|
||||
return (
|
||||
<RGDataColumn
|
||||
key={column.name}
|
||||
key={columnReactKey}
|
||||
name={column.name}
|
||||
fieldName={column.fieldName}
|
||||
valueType={
|
||||
@@ -1727,6 +1900,32 @@ const DataGrid = ({
|
||||
tooltip: resolveColumnTooltip(column),
|
||||
})}
|
||||
editable={column.editable}
|
||||
{...(column.editor != null && {
|
||||
editor: column.editor,
|
||||
})}
|
||||
{...(column.values != null && {
|
||||
values: column.values,
|
||||
})}
|
||||
{...(column.labels != null && {
|
||||
labels: column.labels,
|
||||
})}
|
||||
{...(column.lookupDisplay === true && {
|
||||
lookupDisplay: true,
|
||||
})}
|
||||
{...(isDateEditorColumn(column) && {
|
||||
field: {
|
||||
fieldName: column.fieldName,
|
||||
dataType: ValueType.DATETIME,
|
||||
datetimeFormat:
|
||||
column.datetimeFormat ??
|
||||
column.editor?.datetimeFormat ??
|
||||
"yyyy-MM-dd",
|
||||
},
|
||||
datetimeFormat:
|
||||
column.datetimeFormat ??
|
||||
column.editor?.datetimeFormat ??
|
||||
"yyyy-MM-dd",
|
||||
})}
|
||||
{...(column.width != null && {
|
||||
width: column.width,
|
||||
})}
|
||||
|
||||
@@ -47,6 +47,47 @@ const getSggListFetcher = async (
|
||||
});
|
||||
};
|
||||
|
||||
function buildSearchFormValues(
|
||||
props: SearchFormProps,
|
||||
sidoList: ApiResponse<SearchCondition> | undefined,
|
||||
defaultYear: number,
|
||||
): SearchFormValues {
|
||||
const d = props.defaultValues;
|
||||
const initialClsfCd: SearchFormClsfCd =
|
||||
d?.clsfCd === "ALL" || d?.clsfCd === "INPT" || d?.clsfCd === "VRFC"
|
||||
? d.clsfCd
|
||||
: "ALL";
|
||||
|
||||
if (d?.sido) {
|
||||
return {
|
||||
sido: d.sido,
|
||||
gugun: d.gugun || "",
|
||||
year: d.year || defaultYear.toString(),
|
||||
order: d.order || "",
|
||||
fctName: d.fctName || "",
|
||||
bsnmCd: d.bsnmCd || "",
|
||||
isDetail: false,
|
||||
isSummary: d.isSummary || "",
|
||||
clsfCd: initialClsfCd,
|
||||
};
|
||||
}
|
||||
|
||||
const first = sidoList?.data?.sidoList?.[0];
|
||||
const useFirstSido = (props.sido ?? defaultSearchFormProps.sido) && first;
|
||||
|
||||
return {
|
||||
sido: useFirstSido ? first.sido : "",
|
||||
gugun: "",
|
||||
year: d?.year || defaultYear.toString(),
|
||||
order: d?.order || "",
|
||||
fctName: d?.fctName || "",
|
||||
bsnmCd: useFirstSido ? first.bsnmCd : "",
|
||||
isDetail: false,
|
||||
isSummary: d?.isSummary || "",
|
||||
clsfCd: initialClsfCd,
|
||||
};
|
||||
}
|
||||
|
||||
const SearchForm = (props: SearchFormProps = {}) => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const userInfo = useUserStore((state) => state.userInfo);
|
||||
@@ -82,23 +123,27 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
},
|
||||
);
|
||||
|
||||
const initialClsfCd: SearchFormClsfCd = (() => {
|
||||
const d = props.defaultValues?.clsfCd;
|
||||
if (d === "ALL" || d === "INPT" || d === "VRFC") return d;
|
||||
return "ALL";
|
||||
})();
|
||||
// 마운트 시 SWR 캐시의 시도 목록으로 초기값 설정 (탭 닫았다 열 때 API 재호출 없이 동작)
|
||||
const [values, setValues] = useState<SearchFormValues>(() =>
|
||||
buildSearchFormValues(props, sidoList, defaultYear),
|
||||
);
|
||||
|
||||
const [values, setValues] = useState<SearchFormValues>({
|
||||
sido: props.defaultValues?.sido || "",
|
||||
gugun: props.defaultValues?.gugun || "",
|
||||
year: props.defaultValues?.year || defaultYear.toString(),
|
||||
order: props.defaultValues?.order || "",
|
||||
fctName: props.defaultValues?.fctName || "",
|
||||
bsnmCd: props.defaultValues?.bsnmCd || "",
|
||||
isDetail: false,
|
||||
isSummary: props.defaultValues?.isSummary || "",
|
||||
clsfCd: initialClsfCd,
|
||||
});
|
||||
// 최초 진입만 시도 API가 늦게 오는 경우
|
||||
useEffect(() => {
|
||||
if (props.defaultValues?.sido) return;
|
||||
const first = sidoList?.data?.sidoList?.[0];
|
||||
if (!first || !mergedProps.sido) return;
|
||||
setValues((prev) =>
|
||||
prev.sido
|
||||
? prev
|
||||
: {
|
||||
...prev,
|
||||
sido: first.sido,
|
||||
gugun: "",
|
||||
bsnmCd: first.bsnmCd,
|
||||
},
|
||||
);
|
||||
}, [sidoList, props.defaultValues?.sido, mergedProps.sido]);
|
||||
|
||||
const sggKey: [string, string, string, string] | null =
|
||||
values.sido && values.sido !== "ALL"
|
||||
@@ -133,18 +178,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
const resetValues: SearchFormValues = {
|
||||
sido: "",
|
||||
gugun: "",
|
||||
year: String(defaultYear),
|
||||
order: "",
|
||||
fctName: "",
|
||||
bsnmCd: "",
|
||||
isDetail: false,
|
||||
isSummary: "",
|
||||
clsfCd: "ALL",
|
||||
};
|
||||
setValues(resetValues);
|
||||
setValues(buildSearchFormValues(props, sidoList, defaultYear));
|
||||
props.onReset?.();
|
||||
};
|
||||
|
||||
|
||||
@@ -143,7 +143,6 @@ const verificationResultColumnInfo: ColumnInfo = {
|
||||
{ name: "nowVlCn", fieldName: "nowVlCn", header: { text: "입력값" }, editable: false },
|
||||
{ name: "compVlCn", fieldName: "compVlCn", header: { text: "기준값" }, editable: false },
|
||||
{ name: "prcsYnNm", fieldName: "prcsYnNm", header: { text: "처리여부" }, editable: false },
|
||||
{ name: "pbcpAprvYn", fieldName: "pbcpAprvYn", header: { text: "공단승인여부" }, editable: false },
|
||||
{ name: "regDt", fieldName: "regDt", header: { text: "등록일시" }, editable: false },
|
||||
{ name: "mdfcnDt", fieldName: "mdfcnDt", header: { text: "갱신일시" }, editable: false },
|
||||
{ name: "prcsYn", fieldName: "prcsYn", header: { text: "검증결과상태코드" }, editable: false, visible: false },
|
||||
@@ -157,7 +156,6 @@ const verificationResultColumnInfo: ColumnInfo = {
|
||||
"nowVlCn",
|
||||
"compVlCn",
|
||||
"prcsYnNm",
|
||||
"pbcpAprvYn",
|
||||
"regDt",
|
||||
"mdfcnDt",
|
||||
"prcsYn",
|
||||
|
||||
Reference in New Issue
Block a user