diff --git a/commit_snapshot.md b/commit_snapshot.md
index 70026bf..5a2097f 100644
--- a/commit_snapshot.md
+++ b/commit_snapshot.md
@@ -1,301 +1,154 @@
-# Commit Snapshot (`commits.snapshot_json`) - Cấu Trúc Hiện Tại
+# Commit Snapshot (`commits.snapshot_json`) - Chuẩn Hiện Tại (FrontEndAdmin)
-Tài liệu này mô tả **commit snapshot** đang được lưu trong `BackEndGo.commits.snapshot_json` (JSONB) và được `FrontEndAdmin` tạo ra khi bấm **Commit** trong `/editor`.
-
-Mục tiêu: nhìn vào đây là hiểu commit snapshot gồm những phần nào, ý nghĩa ra sao, và `source`/`operation` có vai trò gì.
+Tài liệu này mô tả **commit snapshot** được `FrontEndAdmin` tạo ra khi bấm **Commit** trong `/editor`, và được lưu vào `BackEndGo.commits.snapshot_json` (JSONB).
Nguồn tham chiếu trong code:
- Type snapshot: `FrontEndAdmin/src/uhm/types/sections.ts` (`EditorSnapshot`)
-- Build snapshot khi commit: `FrontEndAdmin/src/uhm/lib/editor/snapshot/editorSnapshot.ts` (`buildEditorSnapshot`)
+- Build snapshot: `FrontEndAdmin/src/uhm/lib/editor/snapshot/editorSnapshot.ts` (`buildEditorSnapshot`)
-## 1) Schema tổng quan (v2)
+## 1) Tổng Quan Schema
-Hiện tại snapshot mới được ghi với `schema_version: 2` và **đã bỏ hẳn `section`** (vì flow BEGo đã có `commits.project_id`).
+Snapshot hiện tại:
+
+- Không có `schema_version`.
+- Không lưu `section` (project/section được xác định bằng context record `commits.project_id`).
+- Không dùng `ref:{id}` nữa: **`id` là canonical**, `source:"ref"` nghĩa là tham chiếu theo `id`.
```ts
-export type CommitSnapshotV2 = {
- schema_version: 2;
-
- // GeoJSON draft để render map + làm nguồn dựng geometries/link_scopes
+export type CommitSnapshot = {
editor_feature_collection?: FeatureCollection;
- // Operation-based rows
entities?: EntitySnapshot[];
geometries?: GeometrySnapshot[];
- link_scopes?: LinkScopeSnapshot[];
-
- // Wiki list (tiptap JSON hoặc reference)
wikis?: WikiSnapshot[];
- // Join table inside snapshot: links between entities and wikis (project-level)
- entity_wikis?: EntityWikiLinkSnapshot[];
+ geometry_entity?: GeometryEntitySnapshot[]; // geometry ↔ entity (many-to-many)
+ entity_wikis?: EntityWikiLinkSnapshot[]; // entity ↔ wiki
};
```
-## 2) `operation` có những giá trị nào?
+## 2) Quy Ước `source` và `operation`
-Trong commit snapshot hiện tại có 4 nơi dùng `operation`:
+### 2.1 `source` (bắt buộc)
-1. `entities[].operation`:
+`source` bắt buộc là một trong:
-- `create` | `update` | `delete` | `reference`
+- `inline`: dữ liệu được embed trong snapshot_json.
+- `ref`: dữ liệu là tham chiếu (theo `id`), cần fetch bên ngoài nếu muốn đầy đủ.
-2. `geometries[].operation`:
+FE hiện tại luôn ghi `source` cho `entities[]`, `geometries[]`, `wikis[]`.
-- `create` | `update` | `delete` | `reference`
+### 2.2 `operation` (tùy chọn)
-3. `link_scopes[].operation`:
+`operation` là tùy chọn. Khi **không có** `operation` thì hiểu là:
-- `reference`
+- row được đưa vào snapshot như **project context** (hoặc không đổi trong commit này),
+- commit này không sửa record, và cũng không cần đánh dấu là `"reference"` để làm “đầu mối nối”.
-4. `wikis[].operation`:
+`operation` có thể xuất hiện ở:
-- `create` | `update` | `delete` | `reference`
+- `entities[].operation`: `create` | `update` | `delete` | `reference`
+- `geometries[].operation`: `create` | `update` | `delete` | `reference`
+- `wikis[].operation`: `create` | `update` | `delete` | `reference`
-Ghi chú về semantics:
+`geometry_entity[]` không có `operation` (join table state).
-- `create/update/delete`: bản ghi bị thay đổi trong commit này
-- `reference`: bản ghi được đưa vào snapshot để làm đầu mối **nối (link)** (vd: geometry↔entity, entity↔wiki), không phải “không đổi”
+`entity_wikis[]` dùng `operation:"reference"|"delete"` để biểu diễn link/unlink **trong snapshot** (không phải delete trong DB).
-Ngoài ra snapshot có `entity_wikis[]` để nối entity <-> wiki.
+## 3) Ý Nghĩa Từng Phần
-## 3) Sơ đồ trực quan (Mermaid)
-
-```mermaid
-classDiagram
-class CommitSnapshotV2 {
- +number schema_version
- +FeatureCollection editor_feature_collection?
- +EntitySnapshot[] entities?
- +GeometrySnapshot[] geometries?
- +LinkScopeSnapshot[] link_scopes?
- +WikiSnapshot[] wikis?
- +EntityWikiLinkSnapshot[] entity_wikis?
- }
-
-
- class FeatureCollection {
- +string type // "FeatureCollection"
- +Feature[] features
- }
-
- class Feature {
- +string type // "Feature"
- +FeatureProperties properties
- +Geometry geometry
- }
-
- class FeatureProperties {
- +string|number id
- +string type?
- +number time_start?
- +number time_end?
- +string[] binding?
- +string entity_id?
- +string[] entity_ids?
- +string entity_name?
- +string[] entity_names?
- +string entity_type_id?
- }
-
- class EntitySnapshot {
- +string id
- +string source? // inline|ref
- +Ref ref?
- +string operation? // create|update|delete|reference
- +string name?
- +string slug?
- +string description?
- +string type_id?
- +number status?
- +number is_deleted?
- +string base_updated_at?
- +string base_hash?
- }
-
- class GeometrySnapshot {
- +string id
- +string source? // inline|ref
- +Ref ref?
- +string operation? // create|update|delete|reference
- +string type?
- +Geometry draw_geometry?
- +string[] binding?
- +number time_start?
- +number time_end?
- +BBox bbox?
- +number is_deleted?
- +string base_updated_at?
- +string base_hash?
- }
-
- class BBox {
- +number min_lng
- +number min_lat
- +number max_lng
- +number max_lat
- }
-
- class LinkScopeSnapshot {
- +string geometry_id
- +string operation // reference
- +string[] entity_ids
- +string base_links_hash?
- }
-
- class WikiSnapshot {
- +string id
- +string source? // inline|ref
- +Ref ref?
- +string operation? // create|update|delete|reference
- +string title
- +any doc
- +string updated_at?
- +number is_deleted?
- }
-
- class EntityWikiLinkSnapshot {
- +string entity_id
- +string wiki_id
- +string operation? // reference|delete
- +number is_deleted?
- }
-
- class Ref {
- +string id
- }
-
- CommitSnapshotV2 --> FeatureCollection
- FeatureCollection --> Feature
- Feature --> FeatureProperties
- CommitSnapshotV2 --> EntitySnapshot
- CommitSnapshotV2 --> GeometrySnapshot
- CommitSnapshotV2 --> LinkScopeSnapshot
- CommitSnapshotV2 --> WikiSnapshot
- CommitSnapshotV2 --> EntityWikiLinkSnapshot
-```
-
-## 4) Ý nghĩa từng phần
-
-### 4.1 (Bỏ) `section`
-
-Từ `schema_version: 2`, snapshot **không còn** field `section`.
-
-Nguồn chuẩn để biết commit thuộc project nào là `commits.project_id` (record/endpoint context), không phải snapshot.
-
-### 4.2 `editor_feature_collection`
+### 3.1 `editor_feature_collection`
GeoJSON `FeatureCollection` là nguồn để:
-- render map trong editor
-- build `geometries[]` + `link_scopes[]` khi commit
+- render map trong editor,
+- làm cơ sở build `geometries[]` và join table `geometry_entity[]`.
-Trong thực tế, nó là “bản đồ draft state” của commit.
+Lưu ý quan trọng:
-### 4.3 `entities[]`
+- Snapshot persist **không lưu** các field entity denormalize trên `feature.properties`:
+ `entity_id/entity_ids/entity_name/entity_names/entity_type_id`.
+- Quan hệ geometry ↔ entity nằm ở `geometry_entity[]`.
+- Khi load commit vào editor, FE có thể rehydrate `entity_ids/entity_id` lên features từ `geometry_entity[]` để UI hoạt động, nhưng đó không phải dữ liệu persist.
-`entities[]` là tập các entity rows kèm `source`/`operation`. Trong `buildEditorSnapshot` hiện tại, nó được dựng từ:
+### 3.2 `entities[]`
-1. `pending entities` tạo trong editor:
- - `source: "inline"`, `operation: "create"`
-2. `projectEntityRefs` (entity được user “pin” vào project từ thanh search):
- - `source: "ref"`, `ref: {id}`, `operation: "reference"`
-3. Các entity IDs đang được gắn vào geometries trong `editor_feature_collection` (nếu chưa có trong list):
- - `source: "ref"`, `ref: {id}`, `operation: "reference"`
-4. Các entity IDs xuất hiện trong `entity_wikis[]`:
- - `source: "ref"`, `ref: {id}`, `operation: "reference"`
+`entities[]` là danh sách entity liên quan tới project/commit. Mỗi row có `source` và có thể có/không có `operation`.
-=> Nghĩa là: `entities[]` trong commit snapshot hiện tại hoạt động như một “danh sách entity liên quan tới project”, không nhất thiết phải gắn vào một geometry cụ thể.
+FE build `entities[]` từ:
-### 4.4 `geometries[]`
+1. Pending entities tạo mới trong editor:
+`source:"inline"`, `operation:"create"`.
-Mỗi `Feature` trong `editor_feature_collection.features[]` sẽ sinh ra một `GeometrySnapshot` row:
+2. Entity được user “pin” vào project từ search (không gắn geometry, không link wiki):
+`source:"ref"`, không có `operation`.
-- `id`: `String(feature.properties.id)`
-- `draw_geometry`: lấy từ `feature.geometry`
-- `type`: `feature.properties.type || getDefaultTypeIdForFeature(feature)`
-- `binding`: normalize từ `feature.properties.binding`
-- `time_start/time_end`
-- `bbox`: tính từ geometry
-- `is_deleted: 0`
+3. Entities xuất hiện trong `geometry_entity[]`:
+`source:"ref"`, `operation:"reference"`.
-`operation` được suy ra dựa vào `changes` + so sánh với snapshot trước:
+4. Entities xuất hiện trong `entity_wikis[]`:
+`source:"ref"`, `operation:"reference"`.
+
+### 3.3 `geometries[]`
+
+Mỗi `Feature` trong `editor_feature_collection.features[]` sinh 1 `GeometrySnapshot` row:
+
+- `id = String(feature.properties.id)`
+- `source:"inline"`
+- `draw_geometry = feature.geometry`
+- kèm `type`, `binding`, `time_start/time_end`, `bbox` (nếu tính được)
+
+`operation` cho geometry:
- `create`: feature mới
- `update`: feature thay đổi
- (không có `operation`): feature không đổi (không delta trong commit)
-- `delete`: feature bị xoá khỏi draft (FE sẽ thêm 1 row `{ id, operation:"delete", is_deleted:1 }`)
-### 4.5 `link_scopes[]`
+Nếu feature bị xoá khỏi draft, FE thêm 1 delete row:
-FE build link scopes từ GeoJSON features:
-
-- `geometry_id = String(feature.properties.id)`
-- `operation = "reference"`
-- `entity_ids` lấy từ `feature.properties.entity_ids` hoặc `entity_id`
-
-Chỉ add scope nếu `entity_ids.length > 0`.
-
-### 4.6 `wikis[]`
-
-`wikis[]` là danh sách wiki của project tại thời điểm commit.
-
-Type hiện tại:
-
-```ts
-export type WikiSnapshot = {
- id: string;
- source?: "inline" | "ref";
- ref?: { id: string };
- operation?: "create" | "update" | "delete" | "reference";
- title: string;
- doc: unknown; // tiptap JSON doc (inline) hoặc null (reference)
- updated_at?: string;
- is_deleted?: number;
-};
+```json
+{ "id": "g_1", "source": "ref", "operation": "delete" }
```
-Quy ước FE đang dùng:
+Lưu ý: geometry `operation:"delete"` **không xuất hiện trên map**, vì map render theo `editor_feature_collection.features[]`.
-- Wiki tạo mới trong editor: `operation: "create"`, `doc` là tiptap JSON.
-- Wiki sửa: `operation: "update"`, `doc` là tiptap JSON.
-- Wiki không đổi so với snapshot trước: thường **không có** `operation` (không delta).
-- Wiki add từ thanh search (wiki đã tồn tại trong DB): `source:"ref"`, `ref:{id}`, `operation:"reference"`, **`doc` có thể là `null`**.
+### 3.4 `geometry_entity[]` (join table Geometry ↔ Entity)
-Ghi chú quan trọng:
+Join table many-to-many giữa geometry và entity. Mỗi cặp geometry↔entity là một row:
-- Hiện tại FE **chưa generate “delete rows” cho wikis** (khác với geometries). Khi bạn remove một wiki khỏi list thì snapshot mới sẽ đơn giản là không còn wiki đó nữa.
+```ts
+{ geometry_id: string; entity_id: string }
+```
-### 4.7 `entity_wikis[]` (bảng nối Entity ↔ Wiki)
+### 3.5 `wikis[]`
-`entity_wikis[]` là bảng nối trong snapshot để thể hiện “wiki nào thuộc entity nào” ở mức project/commit.
+Danh sách wiki của project tại thời điểm commit:
+
+- Wiki tạo mới: `source:"inline"`, `operation:"create"`, `doc` là tiptap JSON.
+- Wiki sửa: `source:"inline"`, `operation:"update"`, `doc` là tiptap JSON.
+- Wiki không đổi: thường không có `operation`.
+- Wiki add từ search (wiki đã có trong DB): `source:"ref"`, `operation:"reference"`, `doc` có thể là `null`.
+
+### 3.6 `entity_wikis[]` (join table Entity ↔ Wiki)
```ts
export type EntityWikiLinkSnapshot = {
entity_id: string;
wiki_id: string;
operation?: "reference" | "delete";
- is_deleted?: number;
};
```
-FE hiện dùng panel “Entity ↔ Wiki” để toggle link:
+Toggle link trong UI:
-- Tick checkbox => `{ operation:"reference", is_deleted:0 }`
-- Untick checkbox => `{ operation:"delete", is_deleted:1 }`
+- Tick checkbox: `{ operation: "reference" }`
+- Untick checkbox: `{ operation: "delete" }`
-## 5) Ví dụ JSON (rút gọn)
-
-Ví dụ dưới đây thể hiện:
-
-- 1 geometry gắn entity `e_1`
-- 1 entity ref “pin” vào project (`e_2`) dù chưa gắn geometry
-- 1 wiki inline và 1 wiki reference (search từ DB)
+## 4) Ví Dụ JSON (rút gọn)
```json
{
- "schema_version": 2,
"editor_feature_collection": {
"type": "FeatureCollection",
"features": [
@@ -306,31 +159,32 @@ Ví dụ dưới đây thể hiện:
"type": "city",
"time_start": 1200,
"time_end": 1300,
- "entity_ids": ["e_1"],
- "entity_names": ["Ha Noi"]
+ "binding": []
},
"geometry": { "type": "Point", "coordinates": [105.8, 21.0] }
}
]
},
"entities": [
- { "id": "e_2", "operation": "reference", "name": "Pinned Entity", "is_deleted": 0 },
- { "id": "e_1", "operation": "reference", "name": "Ha Noi", "type_id": "city", "status": 1, "is_deleted": 0 }
+ { "id": "e_2", "source": "ref", "name": "Pinned Entity" },
+ { "id": "e_1", "source": "ref", "operation": "reference", "name": "Ha Noi", "type_id": "city", "status": 1 }
],
"geometries": [
{
"id": "g_1",
+ "source": "inline",
"operation": "update",
"type": "city",
"draw_geometry": { "type": "Point", "coordinates": [105.8, 21.0] },
"binding": [],
"time_start": 1200,
"time_end": 1300,
- "bbox": { "min_lng": 105.8, "min_lat": 21.0, "max_lng": 105.8, "max_lat": 21.0 },
- "is_deleted": 0
+ "bbox": { "min_lng": 105.8, "min_lat": 21.0, "max_lng": 105.8, "max_lat": 21.0 }
}
],
- "link_scopes": [{ "geometry_id": "g_1", "operation": "reference", "entity_ids": ["e_1"] }],
+ "geometry_entity": [
+ { "geometry_id": "g_1", "entity_id": "e_1" }
+ ],
"wikis": [
{
"id": "w_inline_1",
@@ -342,26 +196,13 @@ Ví dụ dưới đây thể hiện:
{
"id": "019d...wiki_from_db",
"source": "ref",
- "ref": { "id": "019d...wiki_from_db" },
"operation": "reference",
"title": "Existing Wiki (DB)",
"doc": null
}
],
"entity_wikis": [
- { "entity_id": "e_1", "wiki_id": "w_inline_1", "operation": "reference", "is_deleted": 0 }
+ { "entity_id": "e_1", "wiki_id": "w_inline_1", "operation": "reference" }
]
}
```
-
-## 6) Các điểm cần chốt khi muốn đi xa hơn với “ref”
-
-Để `source:"ref"` thực sự “lấy từ bên ngoài snapshot”, cần thống nhất:
-
-1. Wiki DB format:
-- BackEndGo `wikis.content` hiện là `TEXT`, trong khi editor wiki dùng TipTap JSON (`doc`).
-- Nếu muốn `ref` load content khi cần, phải chốt format lưu trữ (JSON string / HTML / Markdown).
-
-2. Semantics `operation:"reference"`:
-- `reference` được dùng theo nghĩa “đầu mối để nối (link)” và thường đi kèm `source:"ref"` (ref tới DB/global).
-- Các bản ghi inline không thay đổi nên **không có `operation`** (không delta).
diff --git a/package-lock.json b/package-lock.json
index 645c1f2..31751da 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -41,6 +41,7 @@
"sweetalert2": "^11.26.24",
"swiper": "^11.2.10",
"tailwind-merge": "^2.6.0",
+ "uuid": "^13.0.0",
"yet-another-react-lightbox": "^3.30.1"
},
"devDependencies": {
@@ -9261,6 +9262,16 @@
"react-dom": "16.x || 17.x || 18.x || 19.x"
}
},
+ "node_modules/react-d3-tree/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/react-dnd": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
@@ -10639,13 +10650,16 @@
}
},
"node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.1.tgz",
+ "integrity": "sha512-9ezox2roIft6ExBVTVqibSd5dc5/47Sw/uY6b4SjQUT2TzQ0tltNquWA46y4xPQmdZYqvnio22SgWd41M86+jw==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
"license": "MIT",
"bin": {
- "uuid": "dist/bin/uuid"
+ "uuid": "dist-node/bin/uuid"
}
},
"node_modules/w3c-keyname": {
diff --git a/package.json b/package.json
index 4eb290e..ec109c7 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
"react-dropzone": "^14.3.8",
"react-quill-new": "^3.8.3",
"react-redux": "^9.2.0",
+ "uuid": "^13.0.0",
"sonner": "^2.0.7",
"sweetalert2": "^11.26.24",
"swiper": "^11.2.10",
diff --git a/src/app/user/role-upgrade/page.tsx b/src/app/user/role-upgrade/page.tsx
index ca8c1b5..de0de40 100644
--- a/src/app/user/role-upgrade/page.tsx
+++ b/src/app/user/role-upgrade/page.tsx
@@ -16,6 +16,7 @@ import "yet-another-react-lightbox/styles.css";
import "yet-another-react-lightbox/plugins/captions.css";
import { createHistorianCV } from "@/service/historianService";
import { toast } from "sonner";
+import { newId } from "@/uhm/lib/id";
import Swal from "sweetalert2";
import { PresignedUrlResponse } from "@/interface/media";
@@ -94,7 +95,7 @@ export default function RoleUpgrade() {
const presigned = await getPresignedUrl(file);
return {
- id: Math.random().toString(36).substring(7),
+ id: newId(),
file: file,
previewUrl: isImage ? URL.createObjectURL(file) : "",
name: file.name,
diff --git a/src/app/user/submissions/[id]/page.tsx b/src/app/user/submissions/[id]/page.tsx
index 776afd4..eb67587 100644
--- a/src/app/user/submissions/[id]/page.tsx
+++ b/src/app/user/submissions/[id]/page.tsx
@@ -13,6 +13,7 @@ import Map from "@/uhm/components/Map";
import { DEFAULT_BACKGROUND_LAYER_VISIBILITY } from "@/uhm/lib/backgroundLayers";
import { EMPTY_FEATURE_COLLECTION } from "@/uhm/lib/geo/constants";
import { fetchSectionCommits } from "@/uhm/api/sections";
+import { normalizeEditorSnapshot } from "@/uhm/lib/editor/snapshot/editorSnapshot";
import type { EditorSnapshot, SectionCommit } from "@/uhm/types/sections";
import type { EntitySnapshot } from "@/uhm/types/entities";
@@ -89,7 +90,7 @@ export default function SubmissionDetailPage() {
setCommits(commitRows || []);
const commit = (commitRows || []).find((c) => c.id === row.commit_id) || null;
- const snap = (commit?.snapshot_json || null) as EditorSnapshot | null;
+ const snap = normalizeEditorSnapshot(commit?.snapshot_json || null);
setSnapshot(snap);
setSnapshotEntities((snap?.entities || []) as EntitySnapshot[]);
} catch (err) {
@@ -197,9 +198,7 @@ export default function SubmissionDetailPage() {
{isLoadingExtras ? (
Dang tai snapshot/commits...
) : snapshot ? (
-
- Snapshot schema_version: {snapshot.schema_version}
-
+ Da tai snapshot.
) : (
Khong tim thay snapshot cho commit nay.
diff --git a/src/components/calendar/Calendar.tsx b/src/components/calendar/Calendar.tsx
index 75657fb..58b79dc 100644
--- a/src/components/calendar/Calendar.tsx
+++ b/src/components/calendar/Calendar.tsx
@@ -12,6 +12,7 @@ import {
} from "@fullcalendar/core";
import { useModal } from "@/hooks/useModal";
import { Modal } from "@/components/ui/modal";
+import { newId } from "@/uhm/lib/id";
interface CalendarEvent extends EventInput {
extendedProps: {
@@ -99,7 +100,7 @@ const Calendar: React.FC = () => {
} else {
// Add new event
const newEvent: CalendarEvent = {
- id: Date.now().toString(),
+ id: newId(),
title: eventTitle,
start: eventStartDate,
end: eventEndDate,
diff --git a/src/uhm/components/EntityWikiBindingsPanel.tsx b/src/uhm/components/EntityWikiBindingsPanel.tsx
index df82ba3..99cf9aa 100644
--- a/src/uhm/components/EntityWikiBindingsPanel.tsx
+++ b/src/uhm/components/EntityWikiBindingsPanel.tsx
@@ -41,7 +41,7 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin
const set = new Set
();
for (const l of links || []) {
if (!l || l.entity_id !== activeEntityId) continue;
- if (l.is_deleted) continue;
+ if (l.operation === "delete") continue;
set.add(l.wiki_id);
}
return set;
@@ -57,11 +57,10 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin
const idx = next.findIndex((l) => l.entity_id === activeEntityId && l.wiki_id === id);
if (idx >= 0) {
const existing = next[idx];
- const currentlyOn = !existing.is_deleted;
+ const currentlyOn = existing.operation !== "delete";
next[idx] = {
...existing,
operation: currentlyOn ? "delete" : "reference",
- is_deleted: currentlyOn ? 1 : 0,
};
return next;
}
@@ -69,7 +68,6 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin
entity_id: activeEntityId,
wiki_id: id,
operation: "reference",
- is_deleted: 0,
});
return next;
});
@@ -125,7 +123,7 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin
{wikiChoices.slice(0, 12).map((w) => {
const checked = activeLinks.has(w.id);
- const isRefWiki = (wikis.find((x) => x.id === w.id)?.source || "inline") === "ref";
+ const isRefWiki = wikis.find((x) => x.id === w.id)?.source === "ref";
return (