pre updating version control
This commit is contained in:
@@ -42,8 +42,17 @@ type Props = {
|
||||
entityTypeOptions: EntityTypeOption[];
|
||||
geometryMetaForm: GeometryMetaFormState;
|
||||
onGeometryMetaFormChange: (key: keyof GeometryMetaFormState, value: string) => void;
|
||||
bindingGeometrySearchQuery: string;
|
||||
onBindingGeometrySearchQueryChange: (value: string) => void;
|
||||
bindingGeometrySearchResults: Array<{
|
||||
id: string;
|
||||
label: string;
|
||||
}>;
|
||||
selectedBindingGeometryId: string | null;
|
||||
onSelectBindingGeometryId: (value: string | null) => void;
|
||||
onAddSelectedBindingGeometry: () => void;
|
||||
isEntitySubmitting: boolean;
|
||||
onCreateEntityAndAttach: () => void;
|
||||
onCreateEntityOnly: () => void;
|
||||
onApplyEntitiesForSelectedGeometry: () => void;
|
||||
changeCount: number;
|
||||
entityFormStatus: string | null;
|
||||
@@ -68,8 +77,14 @@ export default function SelectedGeometryPanel({
|
||||
entityTypeOptions,
|
||||
geometryMetaForm,
|
||||
onGeometryMetaFormChange,
|
||||
bindingGeometrySearchQuery,
|
||||
onBindingGeometrySearchQueryChange,
|
||||
bindingGeometrySearchResults,
|
||||
selectedBindingGeometryId,
|
||||
onSelectBindingGeometryId,
|
||||
onAddSelectedBindingGeometry,
|
||||
isEntitySubmitting,
|
||||
onCreateEntityAndAttach,
|
||||
onCreateEntityOnly,
|
||||
onApplyEntitiesForSelectedGeometry,
|
||||
changeCount,
|
||||
entityFormStatus,
|
||||
@@ -84,13 +99,13 @@ export default function SelectedGeometryPanel({
|
||||
const visibleGroupedEntityTypeOptions = groupedEntityTypeOptions.filter((group) =>
|
||||
allowedGroupIds.includes(group.id)
|
||||
);
|
||||
const groupedEntityTypeOptionsForCreate = selectedFeature
|
||||
? visibleGroupedEntityTypeOptions
|
||||
: groupedEntityTypeOptions;
|
||||
const selectedTypeOption = findEntityTypeOption(entityForm.type_id);
|
||||
const hasCurrentVisibleTypeOption = visibleGroupedEntityTypeOptions.some((group) =>
|
||||
const hasCurrentVisibleTypeOption = groupedEntityTypeOptionsForCreate.some((group) =>
|
||||
group.options.some((option) => option.value === entityForm.type_id)
|
||||
);
|
||||
const isGeometryCompatible = selectedTypeOption
|
||||
? allowedGroupIds.includes(selectedTypeOption.groupId)
|
||||
: true;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -102,12 +117,12 @@ export default function SelectedGeometryPanel({
|
||||
}}
|
||||
>
|
||||
<div style={{ fontWeight: 700, marginBottom: "8px", fontSize: "14px" }}>
|
||||
Selected Geometry
|
||||
Entity & Geometry
|
||||
</div>
|
||||
|
||||
{!selectedFeature ? (
|
||||
<div style={{ color: "#94a3b8", fontSize: "13px" }}>
|
||||
Vào mode Select và chọn 1 geometry để điền entity.
|
||||
Chưa chọn geometry. Tạo entity mới ở khối bên dưới, hoặc vào mode Select để bind entity cho geometry.
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: "grid", gap: "8px", fontSize: "13px" }}>
|
||||
@@ -187,11 +202,10 @@ export default function SelectedGeometryPanel({
|
||||
}}
|
||||
>
|
||||
<div style={{ color: "#e2e8f0", fontWeight: 700, fontSize: "12px" }}>
|
||||
Metadata geometry (áp dụng cho cả 2 luồng bên dưới)
|
||||
Metadata geometry (chỉ áp dụng khi bind entity)
|
||||
</div>
|
||||
<div style={{ color: "#94a3b8", fontSize: "11px" }}>
|
||||
`time_start`, `time_end`, `binding` sẽ được dùng cho cả luồng gắn entity có sẵn
|
||||
và luồng tạo entity mới.
|
||||
`time_start`, `time_end`, `binding` chỉ được áp dụng khi bấm nút bind entity cho geometry.
|
||||
</div>
|
||||
<input
|
||||
value={geometryMetaForm.time_start}
|
||||
@@ -214,6 +228,38 @@ export default function SelectedGeometryPanel({
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
/>
|
||||
<input
|
||||
value={bindingGeometrySearchQuery}
|
||||
onChange={(event) =>
|
||||
onBindingGeometrySearchQueryChange(event.target.value)
|
||||
}
|
||||
placeholder="Search geometry để thêm vào binding..."
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
/>
|
||||
<select
|
||||
value={selectedBindingGeometryId || ""}
|
||||
onChange={(event) =>
|
||||
onSelectBindingGeometryId(event.target.value ? event.target.value : null)
|
||||
}
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
>
|
||||
<option value="">-- Chọn geometry từ kết quả search binding --</option>
|
||||
{bindingGeometrySearchResults.map((item) => (
|
||||
<option key={item.id} value={item.id}>
|
||||
{item.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onAddSelectedBindingGeometry}
|
||||
disabled={isEntitySubmitting}
|
||||
style={secondaryActionButtonStyle}
|
||||
>
|
||||
Thêm geometry đã chọn vào binding
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -227,7 +273,7 @@ export default function SelectedGeometryPanel({
|
||||
}}
|
||||
>
|
||||
<div style={{ color: "#bfdbfe", fontWeight: 700, fontSize: "12px" }}>
|
||||
Luồng 1: Gắn entity có sẵn
|
||||
Bind entity có sẵn
|
||||
</div>
|
||||
<div style={{ color: "#93c5fd", fontSize: "11px" }}>
|
||||
Dùng khi entity đã tồn tại. Tìm kiếm, thêm vào danh sách rồi bấm nút áp dụng.
|
||||
@@ -285,112 +331,112 @@ export default function SelectedGeometryPanel({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gap: "8px",
|
||||
border: "1px solid #1e3a8a",
|
||||
borderRadius: "8px",
|
||||
padding: "8px",
|
||||
background: "#0f172a",
|
||||
}}
|
||||
>
|
||||
<div style={{ color: "#bfdbfe", fontWeight: 700, fontSize: "12px" }}>
|
||||
Luồng 2: Tạo entity mới rồi gắn
|
||||
</div>
|
||||
<div style={{ color: "#93c5fd", fontSize: "11px" }}>
|
||||
Dùng khi chưa có entity phù hợp. Điền form bên dưới rồi bấm nút tạo + gắn.
|
||||
</div>
|
||||
|
||||
<input
|
||||
value={entityForm.name}
|
||||
onChange={(event) => onEntityFormChange("name", event.target.value)}
|
||||
placeholder="Tên entity mới"
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
/>
|
||||
<input
|
||||
value={entityForm.slug}
|
||||
onChange={(event) => onEntityFormChange("slug", event.target.value)}
|
||||
placeholder="Slug"
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
/>
|
||||
<div style={{ color: "#e2e8f0", fontWeight: 600, fontSize: "12px" }}>
|
||||
Chọn loại entity
|
||||
</div>
|
||||
<select
|
||||
value={entityForm.type_id}
|
||||
onChange={(event) => onEntityFormChange("type_id", event.target.value)}
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
>
|
||||
{!hasCurrentVisibleTypeOption && entityForm.type_id ? (
|
||||
<option value={entityForm.type_id}>
|
||||
Custom Type ({entityForm.type_id})
|
||||
</option>
|
||||
) : null}
|
||||
{visibleGroupedEntityTypeOptions.map((group) => (
|
||||
<optgroup
|
||||
key={group.id}
|
||||
label={`${group.label} (${group.geometryLabel})`}
|
||||
>
|
||||
{group.options.map((option) => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
|
||||
{selectedTypeOption ? (
|
||||
<div style={{ color: "#cbd5e1", fontSize: "12px" }}>
|
||||
Type đang chọn: <b>{selectedTypeOption.label}</b> ({selectedTypeOption.groupLabel})
|
||||
</div>
|
||||
) : entityForm.type_id ? (
|
||||
<div style={{ color: "#cbd5e1", fontSize: "12px" }}>
|
||||
Type đang chọn: <b>{entityForm.type_id}</b>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{!isGeometryCompatible && selectedTypeOption ? (
|
||||
<div style={{ color: "#fbbf24", fontSize: "12px" }}>
|
||||
Type <b>{selectedTypeOption.label}</b> thuộc nhóm <b>{selectedTypeOption.groupLabel}</b>, nhưng geometry hiện tại là <b>{formatGeometryPresetLabel(featureGeometryPreset)}</b>.
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<button
|
||||
onClick={onCreateEntityAndAttach}
|
||||
disabled={isEntitySubmitting}
|
||||
style={{
|
||||
border: "none",
|
||||
borderRadius: "6px",
|
||||
padding: "7px 8px",
|
||||
cursor: isEntitySubmitting ? "not-allowed" : "pointer",
|
||||
background: "#2563eb",
|
||||
color: "#ffffff",
|
||||
opacity: isEntitySubmitting ? 0.7 : 1,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
Tạo entity mới + gắn + áp metadata
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{changeCount > 0 ? (
|
||||
<div style={{ color: "#fca5a5", fontSize: "12px" }}>
|
||||
Geometry mới sẽ lưu entity khi bấm Save.
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{entityFormStatus ? (
|
||||
<div style={{ color: "#93c5fd", fontSize: "12px" }}>
|
||||
{entityFormStatus}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gap: "8px",
|
||||
border: "1px solid #1e3a8a",
|
||||
borderRadius: "8px",
|
||||
padding: "8px",
|
||||
background: "#0f172a",
|
||||
marginTop: "10px",
|
||||
}}
|
||||
>
|
||||
<div style={{ color: "#bfdbfe", fontWeight: 700, fontSize: "12px" }}>
|
||||
Tạo entity mới (độc lập)
|
||||
</div>
|
||||
<div style={{ color: "#93c5fd", fontSize: "11px" }}>
|
||||
Chỉ tạo entity, không tự bind vào geometry.
|
||||
</div>
|
||||
{selectedFeature ? (
|
||||
<div style={{ color: "#93c5fd", fontSize: "11px" }}>
|
||||
Type đang bị giới hạn theo geometry: <b>{formatGeometryPresetLabel(featureGeometryPreset)}</b>.
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<input
|
||||
value={entityForm.name}
|
||||
onChange={(event) => onEntityFormChange("name", event.target.value)}
|
||||
placeholder="Tên entity mới"
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
/>
|
||||
<input
|
||||
value={entityForm.slug}
|
||||
onChange={(event) => onEntityFormChange("slug", event.target.value)}
|
||||
placeholder="Slug"
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
/>
|
||||
<div style={{ color: "#e2e8f0", fontWeight: 600, fontSize: "12px" }}>
|
||||
Chọn loại entity
|
||||
</div>
|
||||
<select
|
||||
value={entityForm.type_id}
|
||||
onChange={(event) => onEntityFormChange("type_id", event.target.value)}
|
||||
disabled={isEntitySubmitting}
|
||||
style={entityInputStyle}
|
||||
>
|
||||
{!selectedFeature && !hasCurrentVisibleTypeOption && entityForm.type_id ? (
|
||||
<option value={entityForm.type_id}>
|
||||
Custom Type ({entityForm.type_id})
|
||||
</option>
|
||||
) : null}
|
||||
{groupedEntityTypeOptionsForCreate.map((group) => (
|
||||
<optgroup
|
||||
key={group.id}
|
||||
label={`${group.label} (${group.geometryLabel})`}
|
||||
>
|
||||
{group.options.map((option) => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
|
||||
{selectedTypeOption ? (
|
||||
<div style={{ color: "#cbd5e1", fontSize: "12px" }}>
|
||||
Type đang chọn: <b>{selectedTypeOption.label}</b> ({selectedTypeOption.groupLabel})
|
||||
</div>
|
||||
) : entityForm.type_id ? (
|
||||
<div style={{ color: "#cbd5e1", fontSize: "12px" }}>
|
||||
Type đang chọn: <b>{entityForm.type_id}</b>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<button
|
||||
onClick={onCreateEntityOnly}
|
||||
disabled={isEntitySubmitting}
|
||||
style={{
|
||||
border: "none",
|
||||
borderRadius: "6px",
|
||||
padding: "7px 8px",
|
||||
cursor: isEntitySubmitting ? "not-allowed" : "pointer",
|
||||
background: "#2563eb",
|
||||
color: "#ffffff",
|
||||
opacity: isEntitySubmitting ? 0.7 : 1,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
Tạo entity mới
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{entityFormStatus ? (
|
||||
<div style={{ color: "#93c5fd", fontSize: "12px", marginTop: "8px" }}>
|
||||
{entityFormStatus}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user