summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/common/discipline-hardcoded/discipline-data.ts14
-rw-r--r--components/common/discipline-hardcoded/discipline-hardcoded-selector.tsx48
-rw-r--r--components/common/discipline-hardcoded/index.ts3
-rw-r--r--components/common/material/material-group-selector-dialog-single.tsx4
-rw-r--r--components/common/selectors/place-of-shipping/place-of-shipping-selector.tsx31
-rw-r--r--components/common/vendor/vendor-selector-dialog-single.tsx4
-rw-r--r--components/data-table/editable-cell.tsx58
7 files changed, 123 insertions, 39 deletions
diff --git a/components/common/discipline-hardcoded/discipline-data.ts b/components/common/discipline-hardcoded/discipline-data.ts
new file mode 100644
index 00000000..4910e272
--- /dev/null
+++ b/components/common/discipline-hardcoded/discipline-data.ts
@@ -0,0 +1,14 @@
+export const HARDCODED_DISCIPLINES = [
+ 'ARCHITECTURE',
+ 'CCS',
+ 'ELECTRICAL',
+ 'INSTRUMENT',
+ 'INSULATION',
+ 'MACHINERY',
+ 'MECHANICAL',
+ 'PIPING',
+ 'STRUCTURE',
+ 'SURFACE PROTECTION',
+] as const
+
+export type HardcodedDiscipline = typeof HARDCODED_DISCIPLINES[number]
diff --git a/components/common/discipline-hardcoded/discipline-hardcoded-selector.tsx b/components/common/discipline-hardcoded/discipline-hardcoded-selector.tsx
new file mode 100644
index 00000000..6de0a285
--- /dev/null
+++ b/components/common/discipline-hardcoded/discipline-hardcoded-selector.tsx
@@ -0,0 +1,48 @@
+'use client'
+
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from '@/components/ui/select'
+import { HARDCODED_DISCIPLINES, HardcodedDiscipline } from './discipline-data'
+
+export interface DisciplineHardcodedSelectorProps {
+ selectedDiscipline?: string
+ onDisciplineSelect: (discipline: string) => void
+ disabled?: boolean
+ placeholder?: string
+ className?: string
+}
+
+export function DisciplineHardcodedSelector({
+ selectedDiscipline,
+ onDisciplineSelect,
+ disabled,
+ placeholder = "설계공종 선택",
+ className
+}: DisciplineHardcodedSelectorProps) {
+
+ return (
+ <Select
+ value={selectedDiscipline}
+ onValueChange={onDisciplineSelect}
+ disabled={disabled}
+ >
+ <SelectTrigger className={`w-full ${className || ''}`}>
+ <SelectValue placeholder={placeholder}>
+ {selectedDiscipline || <span className="text-muted-foreground">{placeholder}</span>}
+ </SelectValue>
+ </SelectTrigger>
+ <SelectContent>
+ {HARDCODED_DISCIPLINES.map((discipline) => (
+ <SelectItem key={discipline} value={discipline}>
+ {discipline}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ )
+}
diff --git a/components/common/discipline-hardcoded/index.ts b/components/common/discipline-hardcoded/index.ts
new file mode 100644
index 00000000..bd55175f
--- /dev/null
+++ b/components/common/discipline-hardcoded/index.ts
@@ -0,0 +1,3 @@
+export * from './discipline-data'
+export * from './discipline-hardcoded-selector'
+
diff --git a/components/common/material/material-group-selector-dialog-single.tsx b/components/common/material/material-group-selector-dialog-single.tsx
index bb039d0a..1aeaec33 100644
--- a/components/common/material/material-group-selector-dialog-single.tsx
+++ b/components/common/material/material-group-selector-dialog-single.tsx
@@ -130,9 +130,9 @@ export function MaterialGroupSelectorDialogSingle({
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
- <Button variant={triggerVariant} disabled={disabled}>
+ <Button variant={triggerVariant} disabled={disabled} className="h-auto whitespace-normal">
{selectedMaterial ? (
- <span className="truncate">
+ <span className="whitespace-normal text-left break-words">
{selectedMaterial.displayText}
</span>
) : (
diff --git a/components/common/selectors/place-of-shipping/place-of-shipping-selector.tsx b/components/common/selectors/place-of-shipping/place-of-shipping-selector.tsx
index 2e9756a0..1d1aaa5e 100644
--- a/components/common/selectors/place-of-shipping/place-of-shipping-selector.tsx
+++ b/components/common/selectors/place-of-shipping/place-of-shipping-selector.tsx
@@ -236,27 +236,30 @@ export function PlaceOfShippingSelectorDialogSingle({
}, [])
useEffect(() => {
- const loadData = async () => {
- try {
- const data = await getPlaceOfShippingForSelection()
- setPlaceOfShippingData(data)
- } catch (error) {
- console.error('선적지/하역지 데이터 로드 실패:', error)
- setPlaceOfShippingData([])
- } finally {
- setIsLoading(false)
+ if (open && placeOfShippingData.length === 0) {
+ const loadData = async () => {
+ setIsLoading(true)
+ try {
+ const data = await getPlaceOfShippingForSelection()
+ setPlaceOfShippingData(data)
+ } catch (error) {
+ console.error('선적지/하역지 데이터 로드 실패:', error)
+ setPlaceOfShippingData([])
+ } finally {
+ setIsLoading(false)
+ }
}
- }
- loadData()
- }, [])
+ loadData()
+ }
+ }, [open, placeOfShippingData.length])
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
- <Button variant={triggerVariant} disabled={disabled}>
+ <Button variant={triggerVariant} disabled={disabled} className="h-auto whitespace-normal">
{selectedPlace ? (
- <span className="truncate">
+ <span className="whitespace-normal text-left break-words">
{selectedPlace.code} - {selectedPlace.description}
</span>
) : (
diff --git a/components/common/vendor/vendor-selector-dialog-single.tsx b/components/common/vendor/vendor-selector-dialog-single.tsx
index 7bb4b14c..ba4243cf 100644
--- a/components/common/vendor/vendor-selector-dialog-single.tsx
+++ b/components/common/vendor/vendor-selector-dialog-single.tsx
@@ -135,9 +135,9 @@ export function VendorSelectorDialogSingle({
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
- <Button variant={triggerVariant} disabled={disabled}>
+ <Button variant={triggerVariant} disabled={disabled} className="h-auto whitespace-normal">
{selectedVendor ? (
- <span className="truncate">
+ <span className="whitespace-normal text-left break-words">
{selectedVendor.displayText}
</span>
) : (
diff --git a/components/data-table/editable-cell.tsx b/components/data-table/editable-cell.tsx
index 05f5c4cb..aa43606e 100644
--- a/components/data-table/editable-cell.tsx
+++ b/components/data-table/editable-cell.tsx
@@ -59,13 +59,6 @@ export function EditableCell<T = any>({
const [isEditing, setIsEditing] = React.useState(initialEditMode)
const [editValue, setEditValue] = React.useState<T>(value)
const [error, setError] = React.useState<string | null>(null)
- const handleStartEdit = useCallback((e: React.MouseEvent) => {
- e.stopPropagation()
- if (disabled) return
- setIsEditing(true)
- setEditValue(value)
- setError(null)
- }, [disabled, value])
const handleFinishEdit = useCallback((overrideValue?: T) => {
const currentValue = overrideValue !== undefined ? overrideValue : editValue
@@ -88,6 +81,35 @@ export function EditableCell<T = any>({
setError(null)
}, [editValue, validation, value, onSave])
+ const handleCheckboxChange = useCallback((checked: boolean) => {
+ const convertedValue = checked as T
+ setEditValue(convertedValue)
+ if (autoSave) {
+ // 체크박스 변경 시 자동 저장 - 값 직접 전달
+ handleFinishEdit(convertedValue)
+ } else {
+ // 일괄 저장 모드에서는 실시간 표시를 위해 즉시 onSave 호출
+ onSave(convertedValue)
+ }
+ }, [autoSave, handleFinishEdit, onSave])
+
+ const handleStartEdit = useCallback((e: React.MouseEvent) => {
+ e.stopPropagation()
+ if (disabled) return
+
+ // 체크박스의 경우 즉시 토글
+ if (type === "checkbox") {
+ // T가 boolean이라고 가정
+ const newValue = !value
+ handleCheckboxChange(!!newValue)
+ return
+ }
+
+ setIsEditing(true)
+ setEditValue(value)
+ setError(null)
+ }, [disabled, value, type, handleCheckboxChange])
+
const handleCancelEdit = useCallback(() => {
// 취소 시 원래 값으로 복원하되, pendingChanges에서도 제거
onCancel?.()
@@ -165,18 +187,6 @@ export function EditableCell<T = any>({
}
}, [type, value, autoSave, onSave, onChange])
- const handleCheckboxChange = useCallback((checked: boolean) => {
- const convertedValue = checked as T
- setEditValue(convertedValue)
- if (autoSave) {
- // 체크박스 변경 시 자동 저장 - 값 직접 전달
- handleFinishEdit(convertedValue)
- } else {
- // 일괄 저장 모드에서는 실시간 표시를 위해 즉시 onSave 호출
- onSave(convertedValue)
- }
- }, [autoSave, handleFinishEdit, onSave])
-
// 읽기 전용 모드
if (!isEditing) {
return (
@@ -192,7 +202,13 @@ export function EditableCell<T = any>({
>
<div className="flex-1 truncate">
{type === "checkbox" ? (
- <Checkbox checked={!!value} disabled />
+ <div onClick={(e) => e.stopPropagation()}>
+ <Checkbox
+ checked={!!value}
+ onCheckedChange={handleCheckboxChange}
+ disabled={disabled}
+ />
+ </div>
) : (
<span className={cn(
"block truncate",
@@ -207,7 +223,7 @@ export function EditableCell<T = any>({
</span>
)}
</div>
- {!disabled && (
+ {!disabled && type !== "checkbox" && (
<Edit2 className="w-4 h-4 opacity-0 group-hover:opacity-50 transition-opacity flex-shrink-0 ml-2" />
)}
</div>