Major update of Vue Website Template

This commit is contained in:
Flook 2025-07-13 23:14:01 +07:00
parent 010be2c2bc
commit 300e6ee4db
4 changed files with 21 additions and 46 deletions

View File

@ -108,12 +108,10 @@ const setupD3Tree = (preserveState = false) => {
rootNode = d3.hierarchy(dataToHierarchy, d => d.children);
// --- LOG ---
console.log("D3 Hierarchy - Root Node children:", rootNode.children ? rootNode.children.map(c => c.id) : "No children (single root)");
rootNode.descendants().forEach(d => {
console.log(`D3 Hierarchy - Node: ${d.id}, Depth: ${d.depth}, isDashed: ${d.data.isDashed}, reportsTo: ${d.data.reportsTo}`);
});
// ----------------------
treemap(rootNode); // Compute initial layout for all nodes
@ -171,19 +169,14 @@ const update = (source) => {
const isArrayRoot = Array.isArray(props.treeData);
// Filter visible nodes based on current children/depth
// A node is visible if it's the root, or if its parent is visible and it's in the parent's 'children' array
const visibleNodes = allNodesInLayout.filter(d => {
// The dummy_root is always "visible" in terms of layout calculation,
// but not rendered as a node.
if (d.id === 'dummy_root') return true;
// For any other node, it's visible if it's a direct child of an expanded node
// or if it's the actual root (depth 0 for object root, depth 1 for array root).
const isActualRoot = (!isArrayRoot && d.depth === 0) || (isArrayRoot && d.depth === 1 && d.parent.id === 'dummy_root');
// If it's a root or if its parent is expanded (has children, not _children)
// AND it's one of the current direct children of its parent
return isActualRoot || (d.parent && d.parent.children && d.parent.children.includes(d));
});
@ -197,18 +190,13 @@ const update = (source) => {
// Find the actual main root node (e.g., alpha_root) among all nodes in layout
const mainRoot = allNodesInLayout.find(d => d.id === 'alpha_root');
// 1. Generate standard D3 links (parent-child relationships) for visible nodes
// Ensure source and target are both visible for the link to be considered.
treemap(rootNode).links().forEach(link => {
// If using dummy_root, only draw links *from* dummy_root if they lead to an actual root node,
// AND that actual root node is NOT a dashed one.
if (isArrayRoot && link.source.id === 'dummy_root') {
// Check if target node's data exists and is not marked as dashed itself
if (link.target.data && !link.target.data.isDashed && nodesToRender.some(n => n.id === link.target.id)) {
links.push(link);
}
} else {
// For normal parent-child links, both source and target must be visible nodes to render
const sourceVisible = nodesToRender.some(n => n.id === link.source.id);
const targetVisible = nodesToRender.some(n => n.id === link.target.id);
if (sourceVisible && targetVisible) {
@ -217,7 +205,6 @@ const update = (source) => {
}
});
// 2. Add custom dashed links (e.g., independent units reporting to mainRoot)
if (mainRoot) { // Only add dashed links if mainRoot exists
allNodesInLayout.forEach(node => {
if (node.data.isDashed && node.data.reportsTo === mainRoot.id) {
@ -225,13 +212,11 @@ const update = (source) => {
const isSourceVisible = nodesToRender.some(n => n.id === mainRoot.id); // mainRoot should always be visible if it's the core.
if (isNodeVisible && isSourceVisible) {
// Create a new link object for the dashed line
// Ensure it uses the actual D3 node objects for source and target
// Add a 'data' property directly to this link object to mark it as dashed
links.push({
source: mainRoot, // The D3 node object for alpha_root
target: node, // The D3 node object for the dashed node
data: { // This 'data' property is specific to this link object
source: mainRoot,
target: node,
data: {
isDashed: true
}
});
@ -243,7 +228,6 @@ const update = (source) => {
console.log("Final links (including custom):", links.map(d => {
const sourceId = d.source ? d.source.id : 'N/A';
const targetId = d.target ? d.target.id : 'N/A';
// Check for dashed status on the link object first, then target node
const isDashed = (d.data && d.data.isDashed) || (d.target && d.target.data && d.target.data.isDashed);
return `${sourceId} -> ${targetId} (Dashed: ${isDashed})`;
}));

View File

@ -13,8 +13,7 @@ export const useAppStore = defineStore('app', {
{ title: "Press Release", title_en: "Press Release", category: "GeneralPublic" },
{ title: "ข่าวบริการประชาชน", title_en: "Public Service News", category: "EventActivities" },
],
// *** ข้อมูลสำหรับ Header ***
// *** ข้อมูลสำหรับ Header ที่ปรับปรุงแล้ว ***
headers: {
header_background: { url: '/images/news_header_bg_b815923058.png' },
logo: { url: '/images/Enter.png' }, // ใช้รูปโลโก้ตามที่ระบุ
@ -174,8 +173,7 @@ export const useAppStore = defineStore('app', {
{ id: 58, title_th: 'ถาม ตอบ', title_en: 'Q&A / FAQ', link: '/contact/faq-new', order: 8, active: true, active_en: true },
]
},
// คุณสามารถเพิ่มกลุ่ม "ร้องทุกข์ร้องเรียน" แยกออกมาได้หากต้องการให้เป็นคอลัมน์ของตัวเอง
// หรือจะรวมไว้ในกลุ่ม "บริการช่วยเหลือ" ก็ได้
// {
// group_title_th: 'ร้องทุกข์',
// group_title_en: 'Complaints',

View File

@ -97,7 +97,7 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
embedUrl: state.getYoutubeEmbedUrl(v.rawUrl), // ตรงนี้คือที่สร้าง embedUrl
thumb: state.getYoutubeThumbnail(v.rawUrl),
}));
// **เพิ่ม console.log นี้:**
console.log('getVideosForDisplay output (ตรวจสอบ embedUrl):', videos);
return videos;
},
@ -109,7 +109,7 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
return sourceGalleries;
},
getAudioForDisplay: (state) => {
// **แก้ไข: ลบ () ออก** เพราะ getMockAudioData เป็น getter ที่คืนค่า Array โดยตรง
const sourceAudio = state.audio.length > 0 ? state.audio : state.getMockAudioData;
console.log('getAudioForDisplay output:', sourceAudio);
return sourceAudio;
@ -161,8 +161,8 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
},
getFilteredDocuments: (state) => {
const appStore = useAppStore(); // <--- Import และเรียกใช้ appStore ภายใน getter
// **แก้ไข: ลบ () ออก**
const appStore = useAppStore();
const allDocs = state.allRawDocuments.length > 0 ? state.allRawDocuments : state.getMockDocumentsData;
if (appStore.isTh) { // <--- ใช้ appStore.isTh
return allDocs.filter(doc => doc.active);
@ -172,8 +172,8 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
},
getFilteredPublications: (state) => {
const appStore = useAppStore(); // <--- Import และเรียกใช้ appStore ภายใน getter
// **แก้ไข: ลบ () ออก**
const appStore = useAppStore();
let filteredData = state.allRawPublications.length > 0 ? state.allRawPublications : state.getMockPublicationsData;
if (appStore.isTh) { // <--- ใช้ appStore.isTh
filteredData = filteredData.filter(pub => pub.Active);
@ -184,9 +184,6 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
return filteredData;
},
// Getter เหล่านี้ไม่จำเป็นต้องใช้โดยตรงใน JournalView.vue แล้ว
// เพราะเราจะใช้ allPublications แล้วกรองด้วย computed property ใน JournalView.vue แทน
// แต่ถ้ามี component อื่นที่ยังใช้ สามารถเก็บไว้ได้
getMagazinePublications: (state) => {
return state.getFilteredPublications.filter(pub => pub.type === 'magazine');
},
@ -223,18 +220,14 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
actions: {
async fetchDocuments() {
// **แก้ไข: ลบ () ออก**
this.allRawDocuments = this.getMockDocumentsData;
},
async fetchPublications() {
// ดึงข้อมูล Publications ดิบจาก Mock
// **แก้ไข: ลบ () ออก**
const rawPublications = this.getMockPublicationsData;
this.allRawPublications = rawPublications;
// กรองข้อมูลตามประเภท (คล้ายกับ logic ใน getters แต่ทำใน action เพื่อคืนค่า)
// Note: Journal (ตัว J ใหญ่) เป็นค่า type ที่ถูกต้องตาม mock data
const journal = rawPublications.filter(pub => pub.type === 'Journal');
const dailynews = rawPublications.filter(pub => pub.type === 'dailynews');
const magazine = rawPublications.filter(pub => pub.type === 'magazine');
@ -319,7 +312,7 @@ export const useInfoDisseminationStore = defineStore('infoDissemination', {
this.isLoading.audio = false;
}
},
// เพิ่มฟังก์ชันนี้กลับเข้าไป
async simulateDelay() {
return new Promise(resolve => setTimeout(resolve, 500));
},

View File

@ -124,7 +124,7 @@ import { useInfoDisseminationStore } from '@/stores/infoDisseminationStore';
import { useAppStore } from '@/stores/app';
// Import Flipbook component
import Flipbook from 'flipbook-vue'; // import Flipbook path '@/components/Flipbook.vue';
import Flipbook from 'flipbook-vue';
// Constants
const INITIAL_ITEMS = 8;
@ -141,8 +141,8 @@ const itemsToShow = ref(INITIAL_ITEMS);
const searchTerm = ref('');
const overlay = ref(false);
const currentFlipbookPages = ref([]); // 'pages' 'currentFlipbookPages'
const flipbookComponent = ref(null); // 'flip' 'flipbookComponent'
const currentFlipbookPages = ref([]);
const flipbookComponent = ref(null);
const isFlipping = ref(false);
// Computed Properties