공차등록성공
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user