Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into common/feat/dashboard-map
This commit is contained in:
@@ -57,6 +57,9 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||
// 폼 데이터 상태 추가
|
||||
const [formData, setFormData] = useState<Record<string, any>>({});
|
||||
|
||||
// 🆕 원본 데이터 상태 (수정 모드에서 UPDATE 판단용)
|
||||
const [originalData, setOriginalData] = useState<Record<string, any> | null>(null);
|
||||
|
||||
// 연속 등록 모드 상태 (state로 변경 - 체크박스 UI 업데이트를 위해)
|
||||
const [continuousMode, setContinuousMode] = useState(false);
|
||||
|
||||
@@ -143,10 +146,13 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||
console.log("✅ URL 파라미터 추가:", urlParams);
|
||||
}
|
||||
|
||||
// 🆕 editData가 있으면 formData로 설정 (수정 모드)
|
||||
// 🆕 editData가 있으면 formData와 originalData로 설정 (수정 모드)
|
||||
if (editData) {
|
||||
console.log("📝 [ScreenModal] 수정 데이터 설정:", editData);
|
||||
setFormData(editData);
|
||||
setOriginalData(editData); // 🆕 원본 데이터 저장 (UPDATE 판단용)
|
||||
} else {
|
||||
setOriginalData(null); // 신규 등록 모드
|
||||
}
|
||||
|
||||
setModalState({
|
||||
@@ -177,7 +183,7 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||
});
|
||||
setScreenData(null);
|
||||
setFormData({});
|
||||
setSelectedData([]); // 🆕 선택된 데이터 초기화
|
||||
setOriginalData(null); // 🆕 원본 데이터 초기화
|
||||
setContinuousMode(false);
|
||||
localStorage.setItem("screenModal_continuousMode", "false"); // localStorage에 저장
|
||||
console.log("🔄 연속 모드 초기화: false");
|
||||
@@ -365,12 +371,15 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||
"⚠️ [ScreenModal] 그룹 레코드(배열)는 formData로 설정하지 않음. SelectedItemsDetailInput만 사용합니다.",
|
||||
);
|
||||
setFormData(normalizedData); // SelectedItemsDetailInput이 직접 사용
|
||||
setOriginalData(normalizedData[0] || null); // 🆕 첫 번째 레코드를 원본으로 저장
|
||||
} else {
|
||||
setFormData(normalizedData);
|
||||
setOriginalData(normalizedData); // 🆕 원본 데이터 저장 (UPDATE 판단용)
|
||||
}
|
||||
|
||||
// setFormData 직후 확인
|
||||
console.log("🔄 setFormData 호출 완료 (날짜 정규화됨)");
|
||||
console.log("🔄 setOriginalData 호출 완료 (UPDATE 판단용)");
|
||||
} else {
|
||||
console.error("❌ 수정 데이터 로드 실패:", response.error);
|
||||
toast.error("데이터를 불러올 수 없습니다.");
|
||||
@@ -619,11 +628,17 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||
component={adjustedComponent}
|
||||
allComponents={screenData.components}
|
||||
formData={formData}
|
||||
originalData={originalData} // 🆕 원본 데이터 전달 (UPDATE 판단용)
|
||||
onFormDataChange={(fieldName, value) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[fieldName]: value,
|
||||
}));
|
||||
console.log("🔧 [ScreenModal] onFormDataChange 호출:", { fieldName, value });
|
||||
setFormData((prev) => {
|
||||
const newFormData = {
|
||||
...prev,
|
||||
[fieldName]: value,
|
||||
};
|
||||
console.log("🔧 [ScreenModal] formData 업데이트:", { prev, newFormData });
|
||||
return newFormData;
|
||||
});
|
||||
}}
|
||||
onRefresh={() => {
|
||||
// 부모 화면의 테이블 새로고침 이벤트 발송
|
||||
@@ -637,8 +652,6 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||
userId={userId}
|
||||
userName={userName}
|
||||
companyCode={user?.companyCode}
|
||||
// 🆕 선택된 데이터 전달 (RepeatScreenModal 등에서 사용)
|
||||
groupedData={selectedData.length > 0 ? selectedData : undefined}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -53,6 +53,8 @@ interface InteractiveScreenViewerProps {
|
||||
disabledFields?: string[];
|
||||
// 🆕 EditModal 내부인지 여부 (button-primary가 EditModal의 handleSave 사용하도록)
|
||||
isInModal?: boolean;
|
||||
// 🆕 원본 데이터 (수정 모드에서 UPDATE 판단용)
|
||||
originalData?: Record<string, any> | null;
|
||||
}
|
||||
|
||||
export const InteractiveScreenViewerDynamic: React.FC<InteractiveScreenViewerProps> = ({
|
||||
@@ -72,6 +74,7 @@ export const InteractiveScreenViewerDynamic: React.FC<InteractiveScreenViewerPro
|
||||
groupedData,
|
||||
disabledFields = [],
|
||||
isInModal = false,
|
||||
originalData, // 🆕 원본 데이터 (수정 모드에서 UPDATE 판단용)
|
||||
}) => {
|
||||
const { isPreviewMode } = useScreenPreview(); // 프리뷰 모드 확인
|
||||
const { userName: authUserName, user: authUser } = useAuth();
|
||||
@@ -331,6 +334,7 @@ export const InteractiveScreenViewerDynamic: React.FC<InteractiveScreenViewerPro
|
||||
component={comp}
|
||||
isInteractive={true}
|
||||
formData={formData}
|
||||
originalData={originalData || undefined} // 🆕 원본 데이터 전달 (UPDATE 판단용)
|
||||
onFormDataChange={handleFormDataChange}
|
||||
screenId={screenInfo?.id}
|
||||
tableName={screenInfo?.tableName}
|
||||
|
||||
@@ -1774,6 +1774,255 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 첫 번째 추가 테이블 설정 (위치정보와 함께 상태 변경) */}
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="geolocation-update-field">추가 필드 변경 (테이블 1)</Label>
|
||||
<p className="text-xs text-muted-foreground">위치정보와 함께 다른 테이블의 필드 값을 변경합니다</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="geolocation-update-field"
|
||||
checked={config.action?.geolocationUpdateField === true}
|
||||
onCheckedChange={(checked) => onUpdateProperty("componentConfig.action.geolocationUpdateField", checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{config.action?.geolocationUpdateField && (
|
||||
<div className="mt-3 space-y-3 rounded-md bg-amber-50 p-3 dark:bg-amber-950">
|
||||
<div>
|
||||
<Label>대상 테이블</Label>
|
||||
<Select
|
||||
value={config.action?.geolocationExtraTableName || ""}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.geolocationExtraTableName", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue placeholder="테이블 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{availableTables.map((table) => (
|
||||
<SelectItem key={table.name} value={table.name} className="text-xs">
|
||||
{table.label || table.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>변경할 필드</Label>
|
||||
<Input
|
||||
placeholder="예: status"
|
||||
value={config.action?.geolocationExtraField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.geolocationExtraField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>변경할 값</Label>
|
||||
<Input
|
||||
placeholder="예: active"
|
||||
value={config.action?.geolocationExtraValue || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.geolocationExtraValue", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>키 필드 (대상 테이블)</Label>
|
||||
<Input
|
||||
placeholder="예: id"
|
||||
value={config.action?.geolocationExtraKeyField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.geolocationExtraKeyField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>키 값 소스</Label>
|
||||
<Select
|
||||
value={config.action?.geolocationExtraKeySourceField || ""}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.geolocationExtraKeySourceField", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue placeholder="소스 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__userId__" className="text-xs font-medium text-blue-600">
|
||||
🔑 로그인 사용자 ID
|
||||
</SelectItem>
|
||||
<SelectItem value="__companyCode__" className="text-xs font-medium text-blue-600">
|
||||
🏢 회사 코드
|
||||
</SelectItem>
|
||||
<SelectItem value="__userName__" className="text-xs font-medium text-blue-600">
|
||||
👤 사용자 이름
|
||||
</SelectItem>
|
||||
{tableColumns.length > 0 && (
|
||||
<>
|
||||
<SelectItem value="__divider__" disabled className="text-xs text-muted-foreground">
|
||||
── 폼 필드 ──
|
||||
</SelectItem>
|
||||
{tableColumns.map((col) => (
|
||||
<SelectItem key={col} value={col} className="text-xs">
|
||||
{col}
|
||||
</SelectItem>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 두 번째 추가 테이블 설정 */}
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="geolocation-second-table">추가 필드 변경 (테이블 2)</Label>
|
||||
<p className="text-xs text-muted-foreground">두 번째 테이블의 필드 값도 함께 변경합니다</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="geolocation-second-table"
|
||||
checked={config.action?.geolocationSecondTableEnabled === true}
|
||||
onCheckedChange={(checked) => onUpdateProperty("componentConfig.action.geolocationSecondTableEnabled", checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{config.action?.geolocationSecondTableEnabled && (
|
||||
<div className="mt-3 space-y-3 rounded-md bg-green-50 p-3 dark:bg-green-950">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>대상 테이블</Label>
|
||||
<Select
|
||||
value={config.action?.geolocationSecondTableName || ""}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.geolocationSecondTableName", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue placeholder="테이블 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{availableTables.map((table) => (
|
||||
<SelectItem key={table.name} value={table.name} className="text-xs">
|
||||
{table.label || table.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label>작업 모드</Label>
|
||||
<Select
|
||||
value={config.action?.geolocationSecondMode || "update"}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.geolocationSecondMode", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="update" className="text-xs">UPDATE (기존 레코드 수정)</SelectItem>
|
||||
<SelectItem value="insert" className="text-xs">INSERT (새 레코드 생성)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>{config.action?.geolocationSecondMode === "insert" ? "저장할 필드" : "변경할 필드"}</Label>
|
||||
<Input
|
||||
placeholder="예: status"
|
||||
value={config.action?.geolocationSecondField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.geolocationSecondField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>{config.action?.geolocationSecondMode === "insert" ? "저장할 값" : "변경할 값"}</Label>
|
||||
<Input
|
||||
placeholder="예: inactive"
|
||||
value={config.action?.geolocationSecondValue || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.geolocationSecondValue", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>
|
||||
{config.action?.geolocationSecondMode === "insert"
|
||||
? "연결 필드 (대상 테이블)"
|
||||
: "키 필드 (대상 테이블)"}
|
||||
</Label>
|
||||
<Input
|
||||
placeholder={config.action?.geolocationSecondMode === "insert" ? "예: vehicle_id" : "예: id"}
|
||||
value={config.action?.geolocationSecondKeyField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.geolocationSecondKeyField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>키 값 소스</Label>
|
||||
<Select
|
||||
value={config.action?.geolocationSecondKeySourceField || ""}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.geolocationSecondKeySourceField", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue placeholder="소스 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__userId__" className="text-xs font-medium text-blue-600">
|
||||
🔑 로그인 사용자 ID
|
||||
</SelectItem>
|
||||
<SelectItem value="__companyCode__" className="text-xs font-medium text-blue-600">
|
||||
🏢 회사 코드
|
||||
</SelectItem>
|
||||
<SelectItem value="__userName__" className="text-xs font-medium text-blue-600">
|
||||
👤 사용자 이름
|
||||
</SelectItem>
|
||||
{tableColumns.length > 0 && (
|
||||
<>
|
||||
<SelectItem value="__divider__" disabled className="text-xs text-muted-foreground">
|
||||
── 폼 필드 ──
|
||||
</SelectItem>
|
||||
{tableColumns.map((col) => (
|
||||
<SelectItem key={col} value={col} className="text-xs">
|
||||
{col}
|
||||
</SelectItem>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{config.action?.geolocationSecondMode === "insert" && (
|
||||
<div className="flex items-center justify-between rounded bg-green-100 p-2 dark:bg-green-900">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-xs">위치정보도 함께 저장</Label>
|
||||
<p className="text-[10px] text-muted-foreground">위도/경도를 이 테이블에도 저장</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={config.action?.geolocationSecondInsertFields?.includeLocation === true}
|
||||
onCheckedChange={(checked) => onUpdateProperty("componentConfig.action.geolocationSecondInsertFields", {
|
||||
...config.action?.geolocationSecondInsertFields,
|
||||
includeLocation: checked
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-[10px] text-green-700 dark:text-green-300">
|
||||
{config.action?.geolocationSecondMode === "insert"
|
||||
? "새 레코드를 생성합니다. 연결 필드로 현재 폼 데이터와 연결됩니다."
|
||||
: "기존 레코드를 수정합니다. 키 필드로 레코드를 찾아 값을 변경합니다."}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="rounded-md bg-blue-50 p-3 dark:bg-blue-950">
|
||||
<p className="text-xs text-blue-900 dark:text-blue-100">
|
||||
<strong>사용 방법:</strong>
|
||||
@@ -1784,6 +2033,11 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||
<br />
|
||||
3. 위도/경도가 지정된 필드에 자동으로 입력됩니다
|
||||
<br />
|
||||
4. 추가 테이블 설정이 있으면 해당 테이블의 필드도 함께 변경됩니다
|
||||
<br />
|
||||
<br />
|
||||
<strong>예시:</strong> 위치정보 저장 + vehicles.status를 inactive로 변경
|
||||
<br />
|
||||
<br />
|
||||
<strong>참고:</strong> HTTPS 환경에서만 위치정보가 작동합니다.
|
||||
</p>
|
||||
@@ -1852,6 +2106,62 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 🆕 키 필드 설정 (레코드 식별용) */}
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<h5 className="mb-3 text-xs font-medium text-muted-foreground">레코드 식별 설정</h5>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="update-key-field">
|
||||
키 필드 (DB 컬럼) <span className="text-destructive">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="update-key-field"
|
||||
placeholder="예: user_id"
|
||||
value={config.action?.updateKeyField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.updateKeyField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
<p className="mt-1 text-xs text-muted-foreground">레코드를 찾을 DB 컬럼명</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="update-key-source">
|
||||
키 값 소스 <span className="text-destructive">*</span>
|
||||
</Label>
|
||||
<Select
|
||||
value={config.action?.updateKeySourceField || ""}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.updateKeySourceField", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue placeholder="키 값 소스 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__userId__" className="text-xs">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-amber-500">🔑</span> 로그인 사용자 ID
|
||||
</span>
|
||||
</SelectItem>
|
||||
<SelectItem value="__userName__" className="text-xs">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-amber-500">🔑</span> 로그인 사용자 이름
|
||||
</span>
|
||||
</SelectItem>
|
||||
<SelectItem value="__companyCode__" className="text-xs">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="text-amber-500">🔑</span> 회사 코드
|
||||
</span>
|
||||
</SelectItem>
|
||||
{tableColumns.map((column) => (
|
||||
<SelectItem key={column} value={column} className="text-xs">
|
||||
{column}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="mt-1 text-xs text-muted-foreground">키 값을 가져올 소스</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="update-auto-save">변경 후 자동 저장</Label>
|
||||
@@ -1899,15 +2209,78 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 위치정보 수집 옵션 */}
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="update-with-geolocation">위치정보도 함께 수집</Label>
|
||||
<p className="text-xs text-muted-foreground">상태 변경과 함께 현재 GPS 좌표를 수집합니다</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="update-with-geolocation"
|
||||
checked={config.action?.updateWithGeolocation === true}
|
||||
onCheckedChange={(checked) => onUpdateProperty("componentConfig.action.updateWithGeolocation", checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{config.action?.updateWithGeolocation && (
|
||||
<div className="mt-3 space-y-3 rounded-md bg-amber-50 p-3 dark:bg-amber-950">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>위도 저장 필드 <span className="text-destructive">*</span></Label>
|
||||
<Input
|
||||
placeholder="예: latitude"
|
||||
value={config.action?.updateGeolocationLatField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.updateGeolocationLatField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>경도 저장 필드 <span className="text-destructive">*</span></Label>
|
||||
<Input
|
||||
placeholder="예: longitude"
|
||||
value={config.action?.updateGeolocationLngField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.updateGeolocationLngField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>정확도 필드 (선택)</Label>
|
||||
<Input
|
||||
placeholder="예: accuracy"
|
||||
value={config.action?.updateGeolocationAccuracyField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.updateGeolocationAccuracyField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>타임스탬프 필드 (선택)</Label>
|
||||
<Input
|
||||
placeholder="예: location_time"
|
||||
value={config.action?.updateGeolocationTimestampField || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.updateGeolocationTimestampField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-[10px] text-amber-700 dark:text-amber-300">
|
||||
버튼 클릭 시 GPS 위치를 수집하여 위 필드에 저장합니다.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="rounded-md bg-blue-50 p-3 dark:bg-blue-950">
|
||||
<p className="text-xs text-blue-900 dark:text-blue-100">
|
||||
<strong>사용 예시:</strong>
|
||||
<br />
|
||||
- 운행알림 버튼: status 필드를 "active"로 변경
|
||||
- 운행알림 버튼: status를 "active"로 + 위치정보 수집
|
||||
<br />
|
||||
- 승인 버튼: approval_status 필드를 "approved"로 변경
|
||||
- 출발 버튼: status를 "inactive"로 + 위치정보 수집
|
||||
<br />
|
||||
- 완료 버튼: is_completed 필드를 "Y"로 변경
|
||||
- 완료 버튼: is_completed를 "Y"로 변경
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -360,6 +360,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
<ConfigPanelComponent
|
||||
config={config}
|
||||
onChange={handlePanelConfigChange}
|
||||
onConfigChange={handlePanelConfigChange} // 🔧 autocomplete-search-input 등 일부 컴포넌트용
|
||||
tables={tables} // 테이블 정보 전달
|
||||
allTables={allTables} // 🆕 전체 테이블 목록 전달 (selected-items-detail-input 등에서 사용)
|
||||
screenTableName={selectedComponent.tableName || currentTable?.tableName || currentTableName} // 🔧 화면 테이블명 전달
|
||||
|
||||
Reference in New Issue
Block a user