chore: update .gitignore and remove quick insert options from button configurations

- Added new entries to .gitignore for multi-agent MCP task queue and related rules.
- Removed "즉시 저장" (quick insert) options from the ScreenSettingModal and BasicTab components to streamline button configurations.
- Cleaned up unused event options in the V2ButtonConfigPanel to enhance clarity and maintainability.

These changes aim to improve project organization and simplify the user interface by eliminating redundant options.
This commit is contained in:
kjs
2026-03-17 17:37:40 +09:00
parent 2976cad0a5
commit ae4fe7a66e
38 changed files with 144 additions and 83 deletions

View File

@@ -53,7 +53,8 @@ export const DateInputComponent: React.FC<DateInputComponentProps> = ({
// 자동생성 로직
useEffect(() => {
if (finalAutoGeneration?.enabled) {
const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
const n = new Date();
const today = `${n.getFullYear()}-${String(n.getMonth() + 1).padStart(2, "0")}-${String(n.getDate()).padStart(2, "0")}`;
setAutoGeneratedValue(today);
// 인터랙티브 모드에서 폼 데이터에도 설정

View File

@@ -653,9 +653,9 @@ export function RepeaterTable({
if (typeof val === "string" && val.includes("T")) {
return val.split("T")[0];
}
// Date 객체이면 변환
// Date 객체이면 로컬 날짜로 변환
if (val instanceof Date) {
return val.toISOString().split("T")[0];
return `${val.getFullYear()}-${String(val.getMonth() + 1).padStart(2, "0")}-${String(val.getDate()).padStart(2, "0")}`;
}
return String(val);
};

View File

@@ -448,7 +448,8 @@ export function SimpleRepeaterTableComponent({
} else if (col.type === "number") {
newRow[col.field] = 0;
} else if (col.type === "date") {
newRow[col.field] = new Date().toISOString().split("T")[0];
const _n = new Date();
newRow[col.field] = `${_n.getFullYear()}-${String(_n.getMonth() + 1).padStart(2, "0")}-${String(_n.getDate()).padStart(2, "0")}`;
} else {
newRow[col.field] = "";
}

View File

@@ -2707,7 +2707,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
XLSX.utils.book_append_sheet(wb, ws, tableLabel || "데이터");
// 파일명 생성
const fileName = `${tableLabel || tableConfig.selectedTable || "export"}_${new Date().toISOString().split("T")[0]}.xlsx`;
const _en = new Date();
const fileName = `${tableLabel || tableConfig.selectedTable || "export"}_${_en.getFullYear()}-${String(_en.getMonth() + 1).padStart(2, "0")}-${String(_en.getDate()).padStart(2, "0")}.xlsx`;
// 파일 다운로드
XLSX.writeFile(wb, fileName);

View File

@@ -3006,7 +3006,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
XLSX.utils.book_append_sheet(wb, ws, tableLabel || "데이터");
// 파일명 생성
const fileName = `${tableLabel || tableConfig.selectedTable || "export"}_${new Date().toISOString().split("T")[0]}.xlsx`;
const _en = new Date();
const fileName = `${tableLabel || tableConfig.selectedTable || "export"}_${_en.getFullYear()}-${String(_en.getMonth() + 1).padStart(2, "0")}-${String(_en.getDate()).padStart(2, "0")}.xlsx`;
// 파일 다운로드
XLSX.writeFile(wb, fileName);

View File

@@ -227,7 +227,7 @@ export function TimelineSchedulerComponent({
if (onCellClick) {
onCellClick({
resourceId,
date: date.toISOString().split("T")[0],
date: `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`,
});
}
},
@@ -343,7 +343,7 @@ export function TimelineSchedulerComponent({
if (onAddSchedule && effectiveResources.length > 0) {
onAddSchedule(
effectiveResources[0].id,
new Date().toISOString().split("T")[0]
(() => { const _n = new Date(); return `${_n.getFullYear()}-${String(_n.getMonth() + 1).padStart(2, "0")}-${String(_n.getDate()).padStart(2, "0")}`; })()
);
}
}, [onAddSchedule, effectiveResources]);
@@ -383,7 +383,8 @@ export function TimelineSchedulerComponent({
const items = Array.from(grouped.entries()).map(([code, rows]) => {
const totalQty = rows.reduce((sum: number, r: any) => sum + (Number(r[qtyField]) || 0), 0);
const dates = rows.map((r: any) => r[dateField]).filter(Boolean).sort();
const earliestDate = dates[0] || new Date().toISOString().split("T")[0];
const _dn = new Date();
const earliestDate = dates[0] || `${_dn.getFullYear()}-${String(_dn.getMonth() + 1).padStart(2, "0")}-${String(_dn.getDate()).padStart(2, "0")}`;
const first = rows[0];
return {
item_code: code,

View File

@@ -28,7 +28,7 @@ interface ItemTimelineCardProps {
onScheduleClick?: (schedule: ScheduleItem) => void;
}
const toDateString = (d: Date) => d.toISOString().split("T")[0];
const toDateString = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
const addDays = (d: Date, n: number) => {
const r = new Date(d);

View File

@@ -13,7 +13,7 @@ const SCHEDULE_TABLE = "schedule_mng";
* 날짜를 ISO 문자열로 변환 (시간 제외)
*/
const toDateString = (date: Date): string => {
return date.toISOString().split("T")[0];
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
};
/**

View File

@@ -54,5 +54,5 @@ export function detectConflicts(schedules: ScheduleItem[]): Set<string> {
export function addDaysToDateString(dateStr: string, days: number): string {
const date = new Date(dateStr);
date.setDate(date.getDate() + days);
return date.toISOString().split("T")[0];
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
}

View File

@@ -251,7 +251,7 @@ export function computeDateRange(
preset: DatePresetOption
): { preset: DatePresetOption; from: string; to: string } | null {
const now = new Date();
const fmt = (d: Date) => d.toISOString().split("T")[0];
const fmt = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
switch (preset) {
case "today":

View File

@@ -349,7 +349,7 @@ export class EnhancedFormService {
if (lowerDataType.includes("date")) {
const date = new Date(value);
return isNaN(date.getTime()) ? null : date.toISOString().split("T")[0];
return isNaN(date.getTime()) ? null : `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
}
if (lowerDataType.includes("time")) {

View File

@@ -1,6 +1,7 @@
"use client";
import { AutoGenerationType, AutoGenerationConfig } from "@/types/screen";
import { toLocalDate, toLocalTime, toLocalDateTime } from "@/lib/utils/localDate";
/**
* 자동생성 값 생성 유틸리티
@@ -52,19 +53,19 @@ export class AutoGenerationUtils {
let result: string;
switch (format) {
case "date":
result = now.toISOString().split("T")[0]; // YYYY-MM-DD
result = toLocalDate(now);
break;
case "time":
result = now.toTimeString().split(" ")[0]; // HH:mm:ss
result = toLocalTime(now);
break;
case "datetime":
result = now.toISOString().replace("T", " ").split(".")[0]; // YYYY-MM-DD HH:mm:ss
result = toLocalDateTime(now);
break;
case "timestamp":
result = now.getTime().toString();
break;
default:
result = now.toISOString(); // ISO 8601 format
result = toLocalDateTime(now);
break;
}

View File

@@ -5156,7 +5156,8 @@ export class ButtonActionExecutor {
const menuName = localStorage.getItem("currentMenuName");
if (menuName) defaultFileName = menuName;
}
const fileName = config.excelFileName || `${defaultFileName}_${new Date().toISOString().split("T")[0]}.xlsx`;
const _xd = new Date();
const fileName = config.excelFileName || `${defaultFileName}_${_xd.getFullYear()}-${String(_xd.getMonth() + 1).padStart(2, "0")}-${String(_xd.getDate()).padStart(2, "0")}.xlsx`;
const sheetName = config.excelSheetName || "Sheet1";
await exportToExcel(dataToExport, fileName, sheetName, true);
@@ -5262,7 +5263,8 @@ export class ButtonActionExecutor {
}
}
const fileName = config.excelFileName || `${defaultFileName}_${new Date().toISOString().split("T")[0]}.xlsx`;
const _xd2 = new Date();
const fileName = config.excelFileName || `${defaultFileName}_${_xd2.getFullYear()}-${String(_xd2.getMonth() + 1).padStart(2, "0")}-${String(_xd2.getDate()).padStart(2, "0")}.xlsx`;
const sheetName = config.excelSheetName || "Sheet1";
const includeHeaders = config.excelIncludeHeaders !== false;

View File

@@ -440,7 +440,7 @@ const validateDateField = (fieldName: string, value: any, config?: Record<string
}
}
return { isValid: true, transformedValue: dateValue.toISOString().split("T")[0] };
return { isValid: true, transformedValue: `${dateValue.getFullYear()}-${String(dateValue.getMonth() + 1).padStart(2, "0")}-${String(dateValue.getDate()).padStart(2, "0")}` };
};
/**

View File

@@ -0,0 +1,30 @@
/**
* 로컬(한국) 시간 기준 날짜/시간 포맷 유틸리티
* DB 타임존이 Asia/Seoul로 설정되어 있어 로컬 시간 기준으로 포맷
*
* toISOString()은 항상 UTC를 반환하므로 자동값 생성 시 사용 금지
*/
export function toLocalDate(date: Date = new Date()): string {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
return `${y}-${m}-${d}`;
}
export function toLocalTime(date: Date = new Date()): string {
const h = String(date.getHours()).padStart(2, "0");
const min = String(date.getMinutes()).padStart(2, "0");
const sec = String(date.getSeconds()).padStart(2, "0");
return `${h}:${min}:${sec}`;
}
export function toLocalDateTime(date: Date = new Date()): string {
return `${toLocalDate(date)} ${toLocalTime(date)}`;
}
export function toLocalDateTimeForInput(date: Date = new Date()): string {
const h = String(date.getHours()).padStart(2, "0");
const min = String(date.getMinutes()).padStart(2, "0");
return `${toLocalDate(date)}T${h}:${min}`;
}

View File

@@ -91,8 +91,8 @@ function getDefaultPeriod(): { start: string; end: string } {
const start = new Date(now.getFullYear(), now.getMonth(), 1);
const end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
return {
start: start.toISOString().split("T")[0],
end: end.toISOString().split("T")[0],
start: `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, "0")}-${String(start.getDate()).padStart(2, "0")}`,
end: `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, "0")}-${String(end.getDate()).padStart(2, "0")}`,
};
}