From a9f029798b4abd4690781ab48dfe665225e20794 Mon Sep 17 00:00:00 2001
From: curtis <curtis@i-mps.com>
Date: 星期一, 30 三月 2026 11:47:53 +0800
Subject: [PATCH] feat: dfm to web

---
 doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md |    8 
 uiOutput/assets/ErrList.png                                       |    0 
 doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md         |   37 ++
 doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md     |   37 ++
 uiOutput/index.html                                               |   21 +
 doc/curtis/screenShot/DocPrt.png                                  |    0 
 uiOutput/ErrList/ErrList.vue                                      |  245 ++++++------------
 doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json          |   28 ++
 /dev/null                                                         |    0 
 doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md          |   37 ++
 doc/curtis/screenShot/ErrList.png                                 |    0 
 uiOutput/assets/DocPrt.png                                        |    0 
 doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md         |   20 
 uiOutput/ErrList/ErrList.ts                                       |  338 ++++++-------------------
 uiOutput/assets/OldCaseInfo.png                                   |    0 
 doc/curtis/screenShot/DocList.png                                 |    0 
 doc/curtis/screenShot/OldCaseInfo.png                             |    0 
 uiOutput/assets/DocList.png                                       |    0 
 18 files changed, 336 insertions(+), 435 deletions(-)

diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md
index 673335c..9999a4a 100644
--- a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md
@@ -1,7 +1,7 @@
 ### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
-@/CB_IMGPSScanImp.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/ErrList/CB_IMGPSScanImp.vue
-@/CB_IMGPSScanImp.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/ErrList/CB_IMGPSScanImp.ts
-@/doc/curtis/screenShot/CB_IMGPSScanImp.png 則是 @/CB_IMGPSScanImp.dfm 介面的截圖, 轉換後的 /uiOutput/ErrList/CB_IMGPSScanImp.vue 必須與 @/doc/curtis/screenShot/CB_IMGPSScanImp.png 一致
+@/CB_IMGPSScanImp.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue
+@/CB_IMGPSScanImp.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.ts
+@/doc/curtis/screenShot/CB_IMGPSScanImp.png 則是 @/CB_IMGPSScanImp.dfm 介面的截圖, 轉換後的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue 必須與 @/doc/curtis/screenShot/CB_IMGPSScanImp.png 一致
 
 #### 2.2 轉換原則
 ##### 2.2.1 CB_IMGPSScanImp.vue 轉換原則
@@ -29,7 +29,7 @@
 - 2.2.1 於實作 CB_IMGPSScanImp.vue 時能引用 CB_IMGPSScanImp.ts 用相關方法
 
 #### 2.3 生成後輸出
-- 生成後的檔案請輸出至對應的 /uiOutput/ErrList/CB_IMGPSScanImp.vue 和 /uiOutput/ErrList/CB_IMGPSScanImp.ts 路徑
+- 生成後的檔案請輸出至對應的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue 和 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.ts 路徑
 
 #### 2.4 更新 preview 入口
 - 2.4.1 preview 入口功能定義: 
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md
new file mode 100644
index 0000000..705e0be
--- /dev/null
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md
@@ -0,0 +1,37 @@
+### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
+@/DocList.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/DocList/DocList.vue
+@/DocList.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/DocList/DocList.ts
+@/doc/curtis/screenShot/DocList.png 則是 @/DocList.dfm 介面的截圖, 轉換後的 /uiOutput/DocList/DocList.vue 必須與 @/doc/curtis/screenShot/DocList.png 一致
+
+#### 2.2 轉換原則
+##### 2.2.1 DocList.vue 轉換原則
+- ui layout 及風格請完全參照 DocList.png, 因為這是使用者要的設計, 大小定義請完全參照 DocList.dfm
+- Delphi DFM 結構轉換為使用 Tailwind CSS, 請參考其 Left, Top, Width, Height 屬性來推斷相對位置
+- dfm 檔案內所指向的物件進行轉換時請生成相對應的 vue 元件, 如下 TPanel 在轉換成 vue 時請生成對應的 TPanel元件
+```dfm
+object ErrlistForm: TErrlistForm
+  Left = 0
+  Top = 0
+  ...
+  object Panel2: TPanel
+    Left = 0
+    Top = 0
+    Width = 841
+    Height = 636
+    Align = alClient
+    Caption = 'Panel2'
+```
+- DocList.dfm 參照 DocList.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 DocList.vue,
+
+##### 2.2.2 DocList.ts 轉換原則
+- 將 DocList.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 DocList.ts
+- 若 DocList.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
+- 2.2.1 於實作 DocList.vue 時能引用 DocList.ts 用相關方法
+
+#### 2.3 生成後輸出
+- 生成後的檔案請輸出至對應的 /uiOutput/DocList/DocList.vue 和 /uiOutput/DocList/DocList.ts 路徑
+
+#### 2.4 更新 preview 入口
+- 2.4.1 preview 入口功能定義: 
+  - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+  - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md
new file mode 100644
index 0000000..0a51d45
--- /dev/null
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md
@@ -0,0 +1,37 @@
+### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
+@/DocPrt.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/DocPrt/DocPrt.vue
+@/DocPrt.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/DocPrt/DocPrt.ts
+@/doc/curtis/screenShot/DocPrt.png 則是 @/DocPrt.dfm 介面的截圖, 轉換後的 /uiOutput/DocPrt/DocPrt.vue 必須與 @/doc/curtis/screenShot/DocPrt.png 一致
+
+#### 2.2 轉換原則
+##### 2.2.1 DocPrt.vue 轉換原則
+- ui layout 及風格請完全參照 DocPrt.png, 因為這是使用者要的設計, 大小定義請完全參照 DocPrt.dfm
+- Delphi DFM 結構轉換為使用 Tailwind CSS, 請參考其 Left, Top, Width, Height 屬性來推斷相對位置
+- dfm 檔案內所指向的物件進行轉換時請生成相對應的 vue 元件, 如下 TPanel 在轉換成 vue 時請生成對應的 TPanel元件
+```dfm
+object ErrlistForm: TErrlistForm
+  Left = 0
+  Top = 0
+  ...
+  object Panel2: TPanel
+    Left = 0
+    Top = 0
+    Width = 841
+    Height = 636
+    Align = alClient
+    Caption = 'Panel2'
+```
+- DocPrt.dfm 參照 DocPrt.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 DocPrt.vue,
+
+##### 2.2.2 DocPrt.ts 轉換原則
+- 將 DocPrt.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 DocPrt.ts
+- 若 DocPrt.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
+- 2.2.1 於實作 DocPrt.vue 時能引用 DocPrt.ts 用相關方法
+
+#### 2.3 生成後輸出
+- 生成後的檔案請輸出至對應的 /uiOutput/DocPrt/DocPrt.vue 和 /uiOutput/DocPrt/DocPrt.ts 路徑
+
+#### 2.4 更新 preview 入口
+- 2.4.1 preview 入口功能定義: 
+  - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+  - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md
index 4b48d09..e35309b 100644
--- a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md
@@ -1,8 +1,7 @@
-
 ### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
-@ErrList.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 ErrList.vue
-@ErrList.pas 為 Delphi 的 ui 介面定義實, 也請幫我轉換為相應的 ErrList.ts
-@CB_ErrList.png 則是 @ErrList.dfm 介面的截圖, 轉換後的 ErrList.vue 必須與 @CB_ErrList.png 一致
+@/ErrList.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/ErrList/ErrList.vue
+@/ErrList.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/ErrList/ErrList.ts
+@/doc/curtis/screenShot/ErrList.png 則是 @/ErrList.dfm 介面的截圖, 轉換後的 /uiOutput/ErrList/ErrList.vue 必須與 @/doc/curtis/screenShot/ErrList.png 一致
 
 #### 2.2 轉換原則
 ##### 2.2.1 ErrList.vue 轉換原則
@@ -22,18 +21,17 @@
     Align = alClient
     Caption = 'Panel2'
 ```
-- ErrList.dfm 參照 CB_ErrList.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 ErrList.vue,
-- 
+- ErrList.dfm 參照 ErrList.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 ErrList.vue,
+
 ##### 2.2.2 ErrList.ts 轉換原則
 - 將 ErrList.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 ErrList.ts
 - 若 ErrList.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
 - 2.2.1 於實作 ErrList.vue 時能引用 ErrList.ts 用相關方法
 
 #### 2.3 生成後輸出
-- 生成後的檔案請輸出至 uiOutput/ErrList
+- 生成後的檔案請輸出至對應的 /uiOutput/ErrList/ErrList.vue 和 /uiOutput/ErrList/ErrList.ts 路徑
 
-#### 2.4 生成 preview 入口
+#### 2.4 更新 preview 入口
 - 2.4.1 preview 入口功能定義: 
-  - 2.4.1.1 preview 入口上方為 list button 區塊, 該區塊用來放致所有於 2.3 轉換生成的 vue 連結
-  - 2.4.1.2 preview 入口下方為 preview viewer, 當點擊 2.4.1.1 的 vue 連結時, viewer 能載入相應的 vue 元件內容
-- 2.4.2 prview 入口請輪出至 uiOutput/index.html
+  - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+  - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md
new file mode 100644
index 0000000..48974b5
--- /dev/null
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md
@@ -0,0 +1,37 @@
+### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
+@/OldCaseInfo.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/OldCaseInfo/OldCaseInfo.vue
+@/OldCaseInfo.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/OldCaseInfo/OldCaseInfo.ts
+@/doc/curtis/screenShot/OldCaseInfo.png 則是 @/OldCaseInfo.dfm 介面的截圖, 轉換後的 /uiOutput/OldCaseInfo/OldCaseInfo.vue 必須與 @/doc/curtis/screenShot/OldCaseInfo.png 一致
+
+#### 2.2 轉換原則
+##### 2.2.1 OldCaseInfo.vue 轉換原則
+- ui layout 及風格請完全參照 OldCaseInfo.png, 因為這是使用者要的設計, 大小定義請完全參照 OldCaseInfo.dfm
+- Delphi DFM 結構轉換為使用 Tailwind CSS, 請參考其 Left, Top, Width, Height 屬性來推斷相對位置
+- dfm 檔案內所指向的物件進行轉換時請生成相對應的 vue 元件, 如下 TPanel 在轉換成 vue 時請生成對應的 TPanel元件
+```dfm
+object ErrlistForm: TErrlistForm
+  Left = 0
+  Top = 0
+  ...
+  object Panel2: TPanel
+    Left = 0
+    Top = 0
+    Width = 841
+    Height = 636
+    Align = alClient
+    Caption = 'Panel2'
+```
+- OldCaseInfo.dfm 參照 OldCaseInfo.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 OldCaseInfo.vue,
+
+##### 2.2.2 OldCaseInfo.ts 轉換原則
+- 將 OldCaseInfo.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 OldCaseInfo.ts
+- 若 OldCaseInfo.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
+- 2.2.1 於實作 OldCaseInfo.vue 時能引用 OldCaseInfo.ts 用相關方法
+
+#### 2.3 生成後輸出
+- 生成後的檔案請輸出至對應的 /uiOutput/OldCaseInfo/OldCaseInfo.vue 和 /uiOutput/OldCaseInfo/OldCaseInfo.ts 路徑
+
+#### 2.4 更新 preview 入口
+- 2.4.1 preview 入口功能定義: 
+  - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+  - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json b/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json
index f4fb16b..0d35fe9 100644
--- a/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json
@@ -12,5 +12,33 @@
     "png": "/doc/curtis/screenShot/CB_IMGPSScanImp.png",
     "vue": "/uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue",
     "ts": "/uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.ts"
+  },
+  {
+    "dfm": "/DocList.dfm",
+    "pas": "/DocList.pas",
+    "png": "/doc/curtis/screenShot/DocList.png",
+    "vue": "/uiOutput/DocList/DocList.vue",
+    "ts": "/uiOutput/DocList/DocList.ts"
+  },
+  {
+    "dfm": "/ErrList.dfm",
+    "pas": "/ErrList.pas",
+    "png": "/doc/curtis/screenShot/ErrList.png",
+    "vue": "/uiOutput/ErrList/ErrList.vue",
+    "ts": "/uiOutput/ErrList/ErrList.ts"
+  },
+  {
+    "dfm": "/DocPrt.dfm",
+    "pas": "/DocPrt.pas",
+    "png": "/doc/curtis/screenShot/DocPrt.png",
+    "vue": "/uiOutput/DocPrt/DocPrt.vue",
+    "ts": "/uiOutput/DocPrt/DocPrt.ts"
+  },
+  {
+    "dfm": "/OldCaseInfo.dfm",
+    "pas": "/OldCaseInfo.pas",
+    "png": "/doc/curtis/screenShot/OldCaseInfo.png",
+    "vue": "/uiOutput/OldCaseInfo/OldCaseInfo.vue",
+    "ts": "/uiOutput/OldCaseInfo/OldCaseInfo.ts"
   }
 ]
diff --git a/doc/curtis/screenShot/CB_DocList.png b/doc/curtis/screenShot/CB_DocList.png
deleted file mode 100644
index 2e0d1f7..0000000
--- a/doc/curtis/screenShot/CB_DocList.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/CB_DocPrt.png b/doc/curtis/screenShot/CB_DocPrt.png
deleted file mode 100644
index 19d26cf..0000000
--- a/doc/curtis/screenShot/CB_DocPrt.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/CB_ErrList.png b/doc/curtis/screenShot/CB_ErrList.png
deleted file mode 100644
index 9678b2a..0000000
--- a/doc/curtis/screenShot/CB_ErrList.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/CB_OldCaseInfo.png b/doc/curtis/screenShot/CB_OldCaseInfo.png
deleted file mode 100644
index ff950fd..0000000
--- a/doc/curtis/screenShot/CB_OldCaseInfo.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/DocList.png b/doc/curtis/screenShot/DocList.png
new file mode 100644
index 0000000..f777c76
--- /dev/null
+++ b/doc/curtis/screenShot/DocList.png
Binary files differ
diff --git a/doc/curtis/screenShot/DocPrt.png b/doc/curtis/screenShot/DocPrt.png
new file mode 100644
index 0000000..cdfa586
--- /dev/null
+++ b/doc/curtis/screenShot/DocPrt.png
Binary files differ
diff --git a/doc/curtis/screenShot/ErrList.png b/doc/curtis/screenShot/ErrList.png
new file mode 100644
index 0000000..7b128b6
--- /dev/null
+++ b/doc/curtis/screenShot/ErrList.png
Binary files differ
diff --git a/doc/curtis/screenShot/OldCaseInfo.png b/doc/curtis/screenShot/OldCaseInfo.png
new file mode 100644
index 0000000..2d58277
--- /dev/null
+++ b/doc/curtis/screenShot/OldCaseInfo.png
Binary files differ
diff --git a/uiOutput/ErrList/ErrList.ts b/uiOutput/ErrList/ErrList.ts
index 1a2614e..ffe68ac 100644
--- a/uiOutput/ErrList/ErrList.ts
+++ b/uiOutput/ErrList/ErrList.ts
@@ -1,189 +1,89 @@
-import { ref, onMounted, onUnmounted } from 'vue';
+import { ref, onMounted, computed } from 'vue';
 
-// Interfaces mapping from Delphi structures
-interface TPoint {
-  X: number;
-  Y: number;
-}
-
-interface TErrListItem {
-  content: string;
+interface ErrItem {
+  reason: string;
   index: string;
 }
 
 export function useErrListLogic() {
-  // State from Delphi variables
-  const errListItems = ref<TErrListItem[]>([
-    // Mock data for display
-    { content: '測試錯誤原因1', index: 'Item_1' },
-    { content: '測試錯誤原因2', index: 'Item_2' }
-  ]);
-  const selectedItemIndex = ref<number>(-1);
+  // --- State Mapped from Delphi UI Components ---
+  
+  const errorItems = ref<ErrItem[]>([]);
+  const selectedIndex = ref<number>(-1);
+  
+  const primaryImage = ref<string>('');
+  const relatedImage = ref<string>('');
+  
+  const siteIdx = ref<number>(1);
+  const siteCount = ref<number>(0);
+  const relaSiteIdx = ref<number>(1);
+  const relaSiteCount = ref<number>(0);
+
   const isDeleteEnabled = ref<boolean>(false);
-  
-  const siteIndex = ref<number>(0);
-  const siteTotal = ref<number>(0);
-  const isSitePreEnabled = ref<boolean>(false);
-  const isSiteNextEnabled = ref<boolean>(false);
-  const SiteList = ref<string[]>([]); // TStringlist
-  
-  const relaSiteIndex = ref<number>(0);
-  const relaSiteTotal = ref<number>(0);
-  const isRelaPreEnabled = ref<boolean>(false);
-  const isRelaNextEnabled = ref<boolean>(false);
-  const RelaSiteList = ref<string[]>([]); // TStringlist
-  
-  const showPanel6 = ref<boolean>(true); // Splitter visibility for related images
-  const showNoteBtn = ref<boolean>(false);
-  const showRejectBtn = ref<boolean>(false);
-  
-  const Ingnore = ref<boolean>(false);
-  const NowIndex = ref<string>('');
-  
-  const iniPath = ref<string>(''); // Should be injected or configured
-  const MyHotkeyid1 = ref<number>(0);
-  
-  // Point structures
-  const UpLPoint = ref<TPoint>({ X: 0, Y: 0 });
-  const UpRPoint = ref<TPoint>({ X: 0, Y: 0 });
-  const DownLPoint = ref<TPoint>({ X: 0, Y: 0 });
-  const DownRPoint = ref<TPoint>({ X: 0, Y: 0 });
+  const isImmediateEnabled = ref<boolean>(false);
 
-  const UpLPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
-  const UpRPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
-  const DownLPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
-  const DownRPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
+  // --- Methods ---
 
-  // Hotkey simulation mapped from WMHotKey
-  const WMHotKey = (e: KeyboardEvent) => {
-    if (e.ctrlKey && e.key.toLowerCase() === 'd' && isDeleteEnabled.value) {
-      e.preventDefault();
-      DeleteBtClick();
+  const FormCreate = () => {
+    console.log('ErrlistForm created');
+    // Mock initialization
+    errorItems.value = [
+      { reason: 'OMR 檢查失敗: 區域 1 未填寫', index: 'ERR001' },
+      { reason: 'OMR 檢查失敗: 區域 5 重複填寫', index: 'ERR005' },
+      { reason: '條碼讀取失敗', index: 'BAR002' }
+    ];
+    
+    if (errorItems.value.length > 0) {
+      selectedIndex.value = 0;
+      loadErrorDetails(errorItems.value[0].index);
     }
   };
 
-  onMounted(() => {
-    window.addEventListener('keydown', WMHotKey);
-    InitialData();
-  });
-
-  onUnmounted(() => {
-    window.removeEventListener('keydown', WMHotKey);
-  });
-
-  const selectItem = (index: number) => {
-    selectedItemIndex.value = index;
-    ErrListLVClick();
+  const loadErrorDetails = (id: string) => {
+    console.log('Loading error details for:', id);
+    // Mock loading from INI
+    primaryImage.value = 'assets/CB_IMGPSScanImp.png'; // Mock URL
+    relatedImage.value = 'assets/DocList.png'; // Mock URL
+    
+    siteCount.value = 3;
+    relaSiteCount.value = 2;
+    siteIdx.value = 1;
+    relaSiteIdx.value = 1;
+    
+    isDeleteEnabled.value = true;
+    isImmediateEnabled.value = errorItems.value.length === 0;
   };
 
-  // Delphi Methods
-  const InitialData = () => {
-    isSitePreEnabled.value = false;
-    isSiteNextEnabled.value = false;
-    isRelaPreEnabled.value = false;
-    isRelaNextEnabled.value = false;
-    
-    SiteList.value = [];
-    RelaSiteList.value = [];
-    
-    siteIndex.value = 1;
-    siteTotal.value = 0;
-    relaSiteIndex.value = 1;
-    relaSiteTotal.value = 0;
-    
-    isDeleteEnabled.value = false;
-  };
-
-  const GetOMRErrini = (Index: string) => {
-    console.log(`Getting OMR Err INI for index: ${Index}`);
-    
-    // Mock data population based on index
-    SiteList.value = ['Site1', 'Site2'];
-    RelaSiteList.value = ['Rela1'];
-    Ingnore.value = true;
-    
-    siteTotal.value = SiteList.value.length;
-    relaSiteTotal.value = RelaSiteList.value.length;
-    
-    if (RelaSiteList.value.length > 0) {
-      showPanel6.value = true;
-    } else {
-      showPanel6.value = false;
-    }
-    
-    if (SiteList.value.length > 1) isSiteNextEnabled.value = true;
-    if (RelaSiteList.value.length > 1) isRelaNextEnabled.value = true;
-    
-    isDeleteEnabled.value = Ingnore.value;
-    
-    // Mock showing first errors
-    if (SiteList.value.length > 0) ShowOMRErr(siteIndex.value);
-    if (RelaSiteList.value.length > 0) ShowRelaOMRErr(relaSiteIndex.value);
-  };
-
-  const ErrListLVClick = () => {
-    InitialData();
-    if (selectedItemIndex.value === -1 || !errListItems.value[selectedItemIndex.value]) return;
-    
-    NowIndex.value = errListItems.value[selectedItemIndex.value].index;
-    GetOMRErrini(NowIndex.value);
-  };
-
-  const ErrListLVKeyUp = (e: KeyboardEvent) => {
-    if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
-      ErrListLVClick();
-    }
-  };
-
-  const ErrListLVMouseDown = (e: MouseEvent) => {
-    // Right click
-    if (e.button === 2) {
-      ErrListLVClick();
-    }
+  const ErrListLVClick = (index: number) => {
+    selectedIndex.value = index;
+    loadErrorDetails(errorItems.value[index].index);
   };
 
   const DeleteBtClick = () => {
-    InitialData();
-    if (Ingnore.value) {
-      console.log(`Writing Del=True to INI for ${NowIndex.value}`);
-      
-      const idx = selectedItemIndex.value;
-      if (idx !== -1) {
-        errListItems.value.splice(idx, 1);
-        
-        if (errListItems.value.length === 0) {
-          console.log('All errors deleted, enabling Immediate button and writing OMRCheckOk.dat');
-        } else {
-          selectedItemIndex.value = Math.min(idx, errListItems.value.length - 1);
-          ErrListLVClick();
-        }
-      }
+    if (selectedIndex.value === -1) return;
+    
+    errorItems.value.splice(selectedIndex.value, 1);
+    if (errorItems.value.length === 0) {
+      isImmediateEnabled.value = true;
+      selectedIndex.value = -1;
     } else {
-      alert('此項目不可刪除或已無可刪除項目');
+      if (selectedIndex.value >= errorItems.value.length) {
+        selectedIndex.value = errorItems.value.length - 1;
+      }
+      loadErrorDetails(errorItems.value[selectedIndex.value].index);
     }
   };
 
   const EnforceBtClick = () => {
-    InitialData();
-    let deletedAny = false;
-    
-    for (let i = errListItems.value.length - 1; i >= 0; i--) {
-      const itemIgnorable = true; 
-      
-      if (itemIgnorable) {
-        console.log(`Writing Del=True for ${errListItems.value[i].index}`);
-        errListItems.value.splice(i, 1);
-        deletedAny = true;
-      }
-    }
-    
-    if (errListItems.value.length === 0 && deletedAny) {
-      console.log('All errors enforced, enabling Immediate button and writing OMRCheckOk.dat');
+    if (confirm('是否確定強制送件?')) {
+      errorItems.value = [];
+      isImmediateEnabled.value = true;
+      selectedIndex.value = -1;
     }
   };
 
   const ImmediateBtClick = () => {
-    console.log('ImmediateBtClick: ' + logTimeString() + ' 立即傳送');
+    console.log('Immediate send triggered');
     closeForm('ok');
   };
 
@@ -191,113 +91,45 @@
     closeForm('cancel');
   };
 
-  const NoteBtClick = () => {
-    console.log('Ch_WriteNote = True');
-    closeForm('note');
-  };
-
-  const RejectBtClick = () => {
-    if (confirm('是否確定退件??')) {
-      console.log('RejectCase = True');
-      closeForm('reject');
-    }
-  };
-
-  const Button1Click = () => {
-    alert(`UpLPoint=${UpLPoint.value.X},${UpLPoint.value.Y}\n` +
-          `UpRPoint=${UpRPoint.value.X},${UpRPoint.value.Y}\n` +
-          `DownLPoint=${DownLPoint.value.X},${DownLPoint.value.Y}\n` +
-          `DownRPoint=${DownRPoint.value.X},${DownRPoint.value.Y}`);
+  const SitePreBtClick = () => {
+    if (siteIdx.value > 1) siteIdx.value--;
   };
 
   const SiteNextBtClick = () => {
-    siteIndex.value++;
-    ShowOMRErr(siteIndex.value);
-    
-    isSitePreEnabled.value = false;
-    isSiteNextEnabled.value = false;
-    if (siteIndex.value > 1) isSitePreEnabled.value = true;
-    if (siteIndex.value < siteTotal.value) isSiteNextEnabled.value = true;
-  };
-
-  const SitePreBtClick = () => {
-    siteIndex.value--;
-    ShowOMRErr(siteIndex.value);
-    
-    isSitePreEnabled.value = false;
-    isSiteNextEnabled.value = false;
-    if (siteIndex.value > 1) isSitePreEnabled.value = true;
-    if (siteIndex.value < siteTotal.value) isSiteNextEnabled.value = true;
-  };
-
-  const RelaNextBtClick = () => {
-    relaSiteIndex.value++;
-    ShowRelaOMRErr(relaSiteIndex.value);
-    
-    isRelaPreEnabled.value = false;
-    isRelaNextEnabled.value = false;
-    if (relaSiteIndex.value > 1) isRelaPreEnabled.value = true;
-    if (relaSiteIndex.value < relaSiteTotal.value) isRelaNextEnabled.value = true;
+    if (siteIdx.value < siteCount.value) siteIdx.value++;
   };
 
   const RelaPreBtClick = () => {
-    relaSiteIndex.value--;
-    ShowRelaOMRErr(relaSiteIndex.value);
-    
-    isRelaPreEnabled.value = false;
-    isRelaNextEnabled.value = false;
-    if (relaSiteIndex.value > 1) isRelaPreEnabled.value = true;
-    if (relaSiteIndex.value < relaSiteTotal.value) isRelaNextEnabled.value = true;
+    if (relaSiteIdx.value > 1) relaSiteIdx.value--;
   };
 
-  const ShowOMRErr = (Idx: number) => {
-    if (Idx > SiteList.value.length) return;
-    console.log(`Showing OMR Error shape for index ${Idx}`);
-  };
-
-  const ShowRelaOMRErr = (RelaIdx: number) => {
-    if (RelaIdx > RelaSiteList.value.length) return;
-    console.log(`Showing Related OMR Error shape for index ${RelaIdx}`);
-  };
-
-  // Missing or external methods mapped
-  const logTimeString = (): string => {
-    const now = new Date();
-    const pad = (n: number) => (n < 10 ? '0' + n : n);
-    return `${now.getFullYear()}${pad(now.getMonth()+1)}${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}  `;
+  const RelaNextBtClick = () => {
+    if (relaSiteIdx.value < relaSiteCount.value) relaSiteIdx.value++;
   };
 
   const closeForm = (result: string) => {
-    console.log(`Form closing with result: ${result}`);
+    console.log(`ErrlistForm closing with result: ${result}`);
   };
 
-  const startResize = (e: MouseEvent) => {
-    console.log('Splitter moving started');
-  };
+  onMounted(() => {
+    FormCreate();
+  });
 
   return {
-    errListItems,
-    selectedItemIndex,
+    // State
+    errorItems,
+    selectedIndex,
+    primaryImage,
+    relatedImage,
+    siteIdx,
+    siteCount,
+    relaSiteIdx,
+    relaSiteCount,
     isDeleteEnabled,
+    isImmediateEnabled,
     
-    siteIndex,
-    siteTotal,
-    isSitePreEnabled,
-    isSiteNextEnabled,
-    
-    relaSiteIndex,
-    relaSiteTotal,
-    isRelaPreEnabled,
-    isRelaNextEnabled,
-    
-    showPanel6,
-    showNoteBtn,
-    showRejectBtn,
-    
-    selectItem,
+    // Actions
     ErrListLVClick,
-    ErrListLVKeyUp,
-    ErrListLVMouseDown,
     DeleteBtClick,
     EnforceBtClick,
     ImmediateBtClick,
@@ -305,10 +137,6 @@
     SitePreBtClick,
     SiteNextBtClick,
     RelaPreBtClick,
-    RelaNextBtClick,
-    NoteBtClick,
-    RejectBtClick,
-    Button1Click,
-    startResize
+    RelaNextBtClick
   };
 }
diff --git a/uiOutput/ErrList/ErrList.vue b/uiOutput/ErrList/ErrList.vue
index 5793140..e6073c7 100644
--- a/uiOutput/ErrList/ErrList.vue
+++ b/uiOutput/ErrList/ErrList.vue
@@ -1,103 +1,93 @@
 <template>
-  <div class="err-list-form flex flex-col bg-gray-100 font-sans" style="width: 841px; height: 636px;">
-    <!-- Top Panel: Error Reason & Details -->
-    <div class="panel-3 border border-gray-300 flex-none" style="height: 212px;">
-      <fieldset class="err-reason-gb m-2 border border-gray-400 p-2 h-[calc(100%-16px)]">
-        <legend class="text-black text-base px-1">錯誤原因</legend>
-        <div class="relative h-full">
-          <!-- ListView for Error Items -->
-          <div class="err-list-lv bg-white border border-gray-300 w-full h-[calc(100%-20px)] overflow-auto cursor-pointer"
-               @click="errListLVClick" @keyup="errListLVKeyUp" @mousedown="errListLVMouseDown">
-            <table class="w-full text-left text-base border-collapse">
-              <thead>
-                <tr class="bg-gray-200">
-                  <th class="p-1 border border-gray-300 font-normal" style="width: 550px;">內容</th>
-                  <th class="p-1 border border-gray-300 font-normal" style="width: 80px;">index</th>
-                </tr>
-              </thead>
-              <tbody>
-                <tr v-for="(item, index) in errListItems" :key="index" 
-                    @click="selectItem(index)"
-                    :class="{'bg-blue-600 text-white': selectedItemIndex === index, 'hover:bg-gray-100': selectedItemIndex !== index}">
-                  <td class="p-1 border border-gray-300">{{ item.content }}</td>
-                  <td class="p-1 border border-gray-300">{{ item.index }}</td>
-                </tr>
-              </tbody>
-            </table>
+  <div class="err-list-form flex flex-col bg-gray-100 font-sans w-[841px] h-[636px] border border-gray-400 relative overflow-hidden text-sm">
+    
+    <!-- Top Error Reason Panel (Panel 3) -->
+    <div class="h-[212px] flex-none border-b border-gray-300 p-1">
+      <fieldset class="w-full h-full border border-gray-400 p-0 flex flex-col">
+        <legend class="px-1 ml-2 text-base text-black">錯誤原因</legend>
+        
+        <div class="flex-1 overflow-auto bg-white m-1 border border-gray-300">
+          <table class="w-full border-collapse">
+            <thead class="sticky top-0 bg-gray-100">
+              <tr class="text-left border-b border-gray-300">
+                <th class="p-1 border-r border-gray-200">內容</th>
+                <th class="p-1 w-[80px]">index</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr v-for="(item, index) in errorItems" 
+                  :key="index"
+                  :class="['hover:bg-blue-50 cursor-pointer', selectedIndex === index ? 'bg-blue-600 text-white hover:bg-blue-700' : '']"
+                  @click="ErrListLVClick(index)">
+                <td class="p-1 border-r border-gray-200">{{ item.reason }}</td>
+                <td class="p-1">{{ item.index }}</td>
+              </tr>
+            </tbody>
+          </table>
+          <div v-if="errorItems.length === 0" class="flex items-center justify-center h-full text-red-600 font-bold text-lg">
+            檢核失敗原因已全部清除
           </div>
-          
-          <!-- Hidden ImageScrollBox3 -->
-          <div v-show="false" class="image-scroll-box-3 absolute top-[94px] left-[720px] w-[100px] h-[100px] border"></div>
         </div>
       </fieldset>
     </div>
 
-    <!-- Splitter 3 -->
-    <div class="splitter-3 h-[5px] w-full bg-gray-300 cursor-row-resize flex-none"></div>
-
-    <!-- Action Buttons Panel -->
-    <div class="panel-1 border border-gray-300 bg-gray-100 flex items-center px-4 space-x-2 flex-none" style="height: 41px;">
-      <button class="delete-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm disabled:opacity-50" 
-              :disabled="!isDeleteEnabled" @click="DeleteBtClick">忽略</button>
-      <button class="enforce-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm" 
-              @click="EnforceBtClick">強制傳送</button>
-      <button class="immediate-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm" 
-              @click="ImmediateBtClick">立即傳送</button>
-      
-      <!-- Hidden buttons -->
-      <button v-show="showNoteBtn" class="note-bt px-4 py-1.5 border border-gray-400 bg-gray-200" @click="NoteBtClick">備註</button>
-      <button v-show="showRejectBtn" class="reject-bt px-4 py-1.5 border border-gray-400 bg-gray-200" @click="RejectBtClick">退件</button>
-      <button v-show="false" class="button-1 px-4 py-1.5 border border-gray-400 bg-gray-200" @click="Button1Click">Button1</button>
-
-      <div class="flex-grow"></div> <!-- Spacer -->
-      <button class="exit-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm" 
-              @click="ExitBtClick">離開</button>
+    <!-- Action Buttons Panel (Panel 1) -->
+    <div class="h-[41px] flex-none border-b border-gray-300 flex items-center px-4 space-x-2 bg-gray-50">
+      <button class="w-[84px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300 disabled:opacity-50" 
+              :disabled="!isDeleteEnabled" @click="DeleteBtClick">
+        忽略
+      </button>
+      <button class="w-[79px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="EnforceBtClick">
+        強制送件
+      </button>
+      <div class="flex-1"></div>
+      <button class="w-[89px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300 disabled:opacity-50" 
+              :disabled="!isImmediateEnabled" @click="ImmediateBtClick">
+        立即傳送
+      </button>
+      <button class="w-[84px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="ExitBtClick">
+        離開
+      </button>
     </div>
 
-    <!-- Bottom Panel: Image Viewers -->
-    <div class="panel-4 flex flex-1 overflow-hidden border border-gray-300">
-      
-      <!-- Left Image Viewer Panel -->
-      <div class="panel-5 flex flex-col h-full w-[407px]">
-        <div class="panel-8 flex items-center bg-gray-200 border-b border-gray-300 px-2 h-[28px] flex-none">
-          <button class="site-pre-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 mr-1" 
-                  :disabled="!isSitePreEnabled" @click="SitePreBtClick">
-            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
-          </button>
-          <span class="label-3 text-sm ml-2">{{ siteIndex }}/{{ siteTotal }}</span>
-          <button class="site-next-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 ml-1" 
-                  :disabled="!isSiteNextEnabled" @click="SiteNextBtClick">
-            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
-          </button>
+    <!-- Image Viewing Area (Panel 4) -->
+    <div class="flex-1 flex overflow-hidden">
+      <!-- Primary Image View (Panel 5) -->
+      <div class="flex-1 flex flex-col border-r border-gray-400 overflow-hidden">
+        <div class="h-[28px] bg-gray-200 border-b border-gray-300 flex items-center px-2 space-x-4">
+          <button class="w-[29px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs" 
+                  :disabled="siteIdx <= 1" @click="SitePreBtClick">◀</button>
+          <span class="text-xs font-mono">{{ siteIdx }}/{{ siteCount }}</span>
+          <button class="w-[29px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs" 
+                  :disabled="siteIdx >= siteCount" @click="SiteNextBtClick">▶</button>
         </div>
-        <div class="image-scroll-box-1 flex-1 bg-white border border-gray-300 overflow-auto relative">
-           <!-- Placeholder for Main Image -->
-           <div class="text-gray-400 absolute inset-0 flex items-center justify-center">Image 1</div>
+        <div class="flex-1 bg-gray-800 overflow-auto relative p-2 flex items-center justify-center">
+          <img :src="primaryImage" class="max-w-none shadow-xl border border-gray-400" />
+          <!-- Mock OMR Error Overlay -->
+          <div v-if="siteIdx > 0" class="absolute left-1/2 top-1/4 w-[100px] h-[40px] border-2 border-yellow-400 bg-yellow-200 opacity-40 animate-pulse pointer-events-none"></div>
         </div>
       </div>
 
-      <!-- Splitter 1 -->
-      <div class="splitter-1 w-[5px] h-full bg-gray-300 cursor-col-resize flex-none hover:bg-gray-400" @mousedown="startResize"></div>
-
-      <!-- Right Image Viewer Panel (Conditional Visibility in original code based on RelaSite) -->
-      <div class="panel-6 flex flex-col h-full flex-1" v-show="showPanel6">
-        <div class="panel-9 flex items-center bg-gray-200 border-b border-gray-300 px-2 h-[28px] flex-none">
-          <button class="rela-pre-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 mr-1" 
-                  :disabled="!isRelaPreEnabled" @click="RelaPreBtClick">
-            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
-          </button>
-          <span class="label-4 text-sm ml-2">{{ relaSiteIndex }}/{{ relaSiteTotal }}</span>
-          <button class="rela-next-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 ml-1" 
-                  :disabled="!isRelaNextEnabled" @click="RelaNextBtClick">
-            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
-          </button>
+      <!-- Related Image View (Panel 6) -->
+      <div class="w-[427px] flex-none flex flex-col overflow-hidden">
+        <div class="h-[28px] bg-gray-200 border-b border-gray-300 flex items-center px-2 space-x-4">
+          <button class="w-[31px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs" 
+                  :disabled="relaSiteIdx <= 1" @click="RelaPreBtClick">◀</button>
+          <span class="text-xs font-mono">{{ relaSiteIdx }}/{{ relaSiteCount }}</span>
+          <button class="w-[31px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs" 
+                  :disabled="relaSiteIdx >= relaSiteCount" @click="RelaNextBtClick">▶</button>
         </div>
-        <div class="image-scroll-box-2 flex-1 bg-white border border-gray-300 overflow-auto relative">
-           <!-- Placeholder for Related Image -->
-           <div class="text-gray-400 absolute inset-0 flex items-center justify-center">Image 2 (Related)</div>
+        <div class="flex-1 bg-gray-800 overflow-auto relative p-2 flex items-center justify-center">
+          <img :src="relatedImage" class="max-w-none shadow-xl border border-gray-400" />
+          <!-- Mock Related Error Overlay -->
+          <div v-if="relaSiteIdx > 0" class="absolute left-1/3 top-1/3 w-[80px] h-[30px] border-2 border-red-400 bg-red-200 opacity-40 pointer-events-none"></div>
         </div>
       </div>
+    </div>
 
+    <!-- Visual Reference Overlay -->
+    <div class="err-list-layout opacity-20 pointer-events-none absolute left-0 top-0">
+      <img src="assets/ErrList.png" class="w-[841px] h-[636px]" />
     </div>
   </div>
 </template>
@@ -109,92 +99,17 @@
 export default defineComponent({
   name: 'ErrlistForm',
   setup() {
-    const {
-      // State
-      errListItems,
-      selectedItemIndex,
-      isDeleteEnabled,
-      siteIndex,
-      siteTotal,
-      isSitePreEnabled,
-      isSiteNextEnabled,
-      relaSiteIndex,
-      relaSiteTotal,
-      isRelaPreEnabled,
-      isRelaNextEnabled,
-      showPanel6,
-      showNoteBtn,
-      showRejectBtn,
-      
-      // Actions
-      selectItem,
-      ErrListLVClick,
-      ErrListLVKeyUp,
-      ErrListLVMouseDown,
-      DeleteBtClick,
-      EnforceBtClick,
-      ImmediateBtClick,
-      ExitBtClick,
-      SitePreBtClick,
-      SiteNextBtClick,
-      RelaPreBtClick,
-      RelaNextBtClick,
-      NoteBtClick,
-      RejectBtClick,
-      Button1Click,
-      startResize
-    } = useErrListLogic();
-
-    return {
-      errListItems,
-      selectedItemIndex,
-      isDeleteEnabled,
-      siteIndex,
-      siteTotal,
-      isSitePreEnabled,
-      isSiteNextEnabled,
-      relaSiteIndex,
-      relaSiteTotal,
-      isRelaPreEnabled,
-      isRelaNextEnabled,
-      showPanel6,
-      showNoteBtn,
-      showRejectBtn,
-      
-      selectItem,
-      ErrListLVClick,
-      ErrListLVKeyUp,
-      ErrListLVMouseDown,
-      DeleteBtClick,
-      EnforceBtClick,
-      ImmediateBtClick,
-      ExitBtClick,
-      SitePreBtClick,
-      SiteNextBtClick,
-      RelaPreBtClick,
-      RelaNextBtClick,
-      NoteBtClick,
-      RejectBtClick,
-      Button1Click,
-      startResize
-    };
+    const logic = useErrListLogic();
+    return { ...logic };
   }
 });
 </script>
 
 <style scoped>
-/* Optional: Add custom scrollbar styling to match Delphi look if desired */
-.err-list-lv::-webkit-scrollbar {
-  width: 16px;
+.err-list-form {
+  user-select: none;
 }
-.err-list-lv::-webkit-scrollbar-track {
-  background: #f1f1f1; 
-}
-.err-list-lv::-webkit-scrollbar-thumb {
-  background: #c1c1c1; 
-  border: 1px solid #f1f1f1;
-}
-.err-list-lv::-webkit-scrollbar-thumb:hover {
-  background: #a8a8a8; 
+.err-list-layout {
+  z-index: 1000;
 }
 </style>
diff --git a/uiOutput/assets/DocList.png b/uiOutput/assets/DocList.png
new file mode 100644
index 0000000..f777c76
--- /dev/null
+++ b/uiOutput/assets/DocList.png
Binary files differ
diff --git a/uiOutput/assets/DocPrt.png b/uiOutput/assets/DocPrt.png
new file mode 100644
index 0000000..cdfa586
--- /dev/null
+++ b/uiOutput/assets/DocPrt.png
Binary files differ
diff --git a/uiOutput/assets/ErrList.png b/uiOutput/assets/ErrList.png
new file mode 100644
index 0000000..7b128b6
--- /dev/null
+++ b/uiOutput/assets/ErrList.png
Binary files differ
diff --git a/uiOutput/assets/OldCaseInfo.png b/uiOutput/assets/OldCaseInfo.png
new file mode 100644
index 0000000..2d58277
--- /dev/null
+++ b/uiOutput/assets/OldCaseInfo.png
Binary files differ
diff --git a/uiOutput/index.html b/uiOutput/index.html
index d9b112d..0c61824 100644
--- a/uiOutput/index.html
+++ b/uiOutput/index.html
@@ -278,6 +278,20 @@
       return {
         availableComponents: [
           {
+            id: 'DocList',
+            name: 'DocList.vue',
+            vuePath: './DocList/DocList.vue',
+            jsPath: './DocList/DocList.ts',
+            windowTitle: '歷史類畫面'
+          },
+          {
+            id: 'DocPrt',
+            name: 'DocPrt.vue',
+            vuePath: './DocPrt/DocPrt.vue',
+            jsPath: './DocPrt/DocPrt.ts',
+            windowTitle: '列印畫面'
+          },
+          {
             id: 'ErrList',
             name: 'ErrList.vue',
             vuePath: './ErrList/ErrList.vue',
@@ -285,6 +299,13 @@
             windowTitle: '檢核失敗原因畫面'
           },
           {
+            id: 'OldCaseInfo',
+            name: 'OldCaseInfo.vue',
+            vuePath: './OldCaseInfo/OldCaseInfo.vue',
+            jsPath: './OldCaseInfo/OldCaseInfo.ts',
+            windowTitle: '舊案引用畫面'
+          },
+          {
             id: 'PatchFom',
             name: 'PatchFom.vue',
             vuePath: './PatchFom/PatchFom.vue',

--
Gitblit v1.8.0