From 18bb82ac199e98405f77f1880c163702a829a265 Mon Sep 17 00:00:00 2001 From: faiztyanirh Date: Fri, 3 Apr 2026 13:29:14 +0700 Subject: [PATCH] initial testmap menu --- src/lib/components/app-sidebar.svelte | 12 +- .../dictionary/testmap/api/testmap-api.js | 18 ++ .../testmap/config/testmap-config.js | 61 +++++++ .../testmap/config/testmap-form-config.js | 154 ++++++++++++++++++ .../testmap/page/create-page.svelte | 1 + .../dictionary/testmap/page/edit-page.svelte | 1 + .../testmap/page/master-page.svelte | 68 ++++++++ .../dictionary/testmap/page/view-page.svelte | 91 +++++++++++ .../testmap/table/testmap-columns.js | 14 ++ src/lib/config/api.js | 1 + src/routes/+layout.server.js | 5 +- src/routes/dictionary/testmap/+page.svelte | 52 ++++++ 12 files changed, 476 insertions(+), 2 deletions(-) create mode 100644 src/lib/components/dictionary/testmap/api/testmap-api.js create mode 100644 src/lib/components/dictionary/testmap/config/testmap-config.js create mode 100644 src/lib/components/dictionary/testmap/config/testmap-form-config.js create mode 100644 src/lib/components/dictionary/testmap/page/create-page.svelte create mode 100644 src/lib/components/dictionary/testmap/page/edit-page.svelte create mode 100644 src/lib/components/dictionary/testmap/page/master-page.svelte create mode 100644 src/lib/components/dictionary/testmap/page/view-page.svelte create mode 100644 src/lib/components/dictionary/testmap/table/testmap-columns.js create mode 100644 src/routes/dictionary/testmap/+page.svelte diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte index 4c1a0aa..d1478e1 100644 --- a/src/lib/components/app-sidebar.svelte +++ b/src/lib/components/app-sidebar.svelte @@ -113,8 +113,18 @@ }, { title: "Test", - url: "/dictionary/test", + url: "/dictionary", icon: FlaskConicalIcon, + submenus: [ + { + title: "Test List", + url: "/test", + }, + { + title: "Test Map", + url: "/testmap", + }, + ] }, ] }; diff --git a/src/lib/components/dictionary/testmap/api/testmap-api.js b/src/lib/components/dictionary/testmap/api/testmap-api.js new file mode 100644 index 0000000..bc934a7 --- /dev/null +++ b/src/lib/components/dictionary/testmap/api/testmap-api.js @@ -0,0 +1,18 @@ +import { API } from '$lib/config/api.js'; +import { getById, searchWithParams, create, update } from '$lib/api/api-client'; + +export async function getTestMaps(searchQuery) { + return await searchWithParams(API.TESTMAP, searchQuery) +} + +export async function getTestMap(searchQuery) { + return await getById(API.TESTMAP, searchQuery) +} + +export async function createTestMap(newTestMapForm) { + return await create(API.TESTMAP, newTestMapForm) +} + +export async function editTestMap(editTestMapForm, id) { + return await update(API.TESTMAP, editTestMapForm, id) +} \ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/config/testmap-config.js b/src/lib/components/dictionary/testmap/config/testmap-config.js new file mode 100644 index 0000000..c96f8fe --- /dev/null +++ b/src/lib/components/dictionary/testmap/config/testmap-config.js @@ -0,0 +1,61 @@ +import PlusIcon from "@lucide/svelte/icons/plus"; +import Settings2Icon from "@lucide/svelte/icons/settings-2"; +import PencilIcon from "@lucide/svelte/icons/pencil"; +import { API } from "$lib/config/api"; + +export const searchFields = [ + { + key: "TestSiteCode", + label: "Test Code", + type: "text", + }, + { + key: "TestSiteName", + label: "Test Name", + type: "text", + }, + { + key: "TestMapType", + label: "TestMap Type", + type: "text", + }, + +]; + +export const detailSections = [ + { + class: "grid grid-cols-2 gap-4 items-center", + fields: [ + { key: "HostType", label: "Host Type" }, + { key: "HostID", label: "Host ID" }, + { key: "HostName", label: "Host Name" }, + { key: "ClientType", label: "Client Type" }, + { key: "ClientID", label: "Client ID" }, + { key: "ClientName", label: "Client Name" }, + ] + }, +]; + +export function testMapActions(masterDetail) { + return [ + { + Icon: PlusIcon, + label: 'Add TestMap', + onClick: () => masterDetail.enterCreate(), + }, + { + Icon: Settings2Icon, + label: 'Search Parameters', + }, + ]; +} + +export function viewActions(handlers){ + return [ + { + Icon: PencilIcon, + label: 'Edit TestMap', + onClick: handlers.editTestMap, + }, + ] +} \ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/config/testmap-form-config.js b/src/lib/components/dictionary/testmap/config/testmap-form-config.js new file mode 100644 index 0000000..a25cdda --- /dev/null +++ b/src/lib/components/dictionary/testmap/config/testmap-form-config.js @@ -0,0 +1,154 @@ +import { API } from '$lib/config/api'; +import EraserIcon from '@lucide/svelte/icons/eraser'; +import { z } from 'zod'; +import { cleanEmptyStrings } from '$lib/utils/cleanEmptyStrings'; + +export const testMapSchema = z + .object({ + HostID: z.string().optional(), + ClientID: z.string().optional() + }) + .superRefine((data, ctx) => { + const hostID = data.HostID; + const clientID = data.ClientID; + + if (hostID && clientID && hostID === clientID) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'ClientID must be different from HostID', + path: ['ClientID'] + }); + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'HostID must be different from ClientID', + path: ['HostID'] + }); + } + }); + +export const testMapInitialForm = { + TestMapID: '', + HostType: '', + HostID: '', + HostTestCode: '', + HostTestName: '', + ClientType: '', + ClientID: '', + ClientTestCode: '', + ClientTestName: '', + ConDefID: '' +}; + +export const testMapDefaultErrors = { + HostID: null, + ClientID: null +}; + +export const testMapFormFields = [ + { + title: 'Host & Client Information', + rows: [ + { + type: 'row', + columns: [ + { + key: 'HostType', + label: 'Host Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/entity_type` + }, + { + key: 'ClientType', + label: 'Client Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/entity_type` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'HostID', + label: 'Host ID', + required: false, + type: 'text', + validateOn: ['input'] + }, + { + key: 'ClientID', + label: 'Client ID', + required: false, + type: 'text', + validateOn: ['input'] + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'HostTestCode', + label: 'Host Test Code', + required: false, + type: 'text' + }, + { + key: 'ClientTestCode', + label: 'Client Test Code', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'HostTestName', + label: 'Host Test Name', + required: false, + type: 'text' + }, + { + key: 'ClientTestName', + label: 'Client Test Name', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'ConDefID', + label: 'Container Definition', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.CONTAINER}`, + valueKey: 'ConDefID', + labelKey: (item) => `${item.ConCode} - ${item.ConName}`, + fullWidth: false + } + ] + } + ] + } +]; + +export function getTestMapFormActions(handlers) { + return [ + { + Icon: EraserIcon, + label: 'Clear Form', + onClick: handlers.clearForm + } + ]; +} + +export function buildTestPayload() { + +} \ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/page/create-page.svelte b/src/lib/components/dictionary/testmap/page/create-page.svelte new file mode 100644 index 0000000..4649907 --- /dev/null +++ b/src/lib/components/dictionary/testmap/page/create-page.svelte @@ -0,0 +1 @@ +cr \ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/page/edit-page.svelte b/src/lib/components/dictionary/testmap/page/edit-page.svelte new file mode 100644 index 0000000..9a58f89 --- /dev/null +++ b/src/lib/components/dictionary/testmap/page/edit-page.svelte @@ -0,0 +1 @@ +ed \ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/page/master-page.svelte b/src/lib/components/dictionary/testmap/page/master-page.svelte new file mode 100644 index 0000000..d1466a5 --- /dev/null +++ b/src/lib/components/dictionary/testmap/page/master-page.svelte @@ -0,0 +1,68 @@ + + +{#snippet searchParamSnippet()} + +{/snippet} + +
props.masterDetail.isFormMode && props.masterDetail.exitForm()} + onkeydown={(e) => e.key === 'Enter' && props.masterDetail.isFormMode && props.masterDetail.exitForm()} + class={` + ${props.masterDetail.isMobile ? "w-full" : props.masterDetail.isFormMode ? "w-[3%] cursor-pointer" : "w-[35%]"} + transition-all duration-300 flex flex-col items-center p-2 h-full overflow-y-auto + `} +> +
+ {#if props.masterDetail.isFormMode} + + {#each "TEST MAP".split("") as c} + {c} + {/each} + + {/if} + + {#if !props.masterDetail.isFormMode} +
e.stopPropagation()} onkeydown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + e.stopPropagation(); + } + }}> + +
+ {#if search.searchData.length > 0} + + {:else} +
+ +
+ {/if} +
+
+ {/if} +
+
\ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/page/view-page.svelte b/src/lib/components/dictionary/testmap/page/view-page.svelte new file mode 100644 index 0000000..c88d841 --- /dev/null +++ b/src/lib/components/dictionary/testmap/page/view-page.svelte @@ -0,0 +1,91 @@ + + +{#snippet Fieldset({ value, label, isUTCDate = false })} +
+
+ {label} +
+
+ {#if isUTCDate} + {formatUTCDate(value)} + {:else} + {value ?? "-"} + {/if} +
+
+{/snippet} + +{#if masterDetail.selectedItem} +
+ +
+ {#each detailSections as section} +
+ {#if section.groups} +
+ {#each section.groups as group} +
+
+ {#each group.fields as field} + {@render Fieldset({ + label: field.label, + value: getFieldValue(field), + isUTCDate: field.isUTCDate + })} + {/each} +
+
+ {/each} +
+ {:else} +
+ {#each section.fields as field} + {@render Fieldset({ + label: field.label, + value: getFieldValue(field), + isUTCDate: field.isUTCDate + })} + {/each} +
+ {/if} +
+ {/each} +
+
+{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/dictionary/testmap/table/testmap-columns.js b/src/lib/components/dictionary/testmap/table/testmap-columns.js new file mode 100644 index 0000000..46673b1 --- /dev/null +++ b/src/lib/components/dictionary/testmap/table/testmap-columns.js @@ -0,0 +1,14 @@ +export const testMapColumns = [ + { + accessorKey: "HostType", + header: "Host", + }, + { + accessorKey: "ClientType", + header: "Client", + }, + { + accessorKey: "TestMapType", + header: "Type", + }, +]; \ No newline at end of file diff --git a/src/lib/config/api.js b/src/lib/config/api.js index 764c4eb..1dce259 100644 --- a/src/lib/config/api.js +++ b/src/lib/config/api.js @@ -25,4 +25,5 @@ export const API = { DEPARTMENT: '/api/organization/department', WORKSTATION: '/api/organization/workstation', TEST: '/api/test', + TESTMAP: '/api/test/testmap', }; diff --git a/src/routes/+layout.server.js b/src/routes/+layout.server.js index 0e8d945..819b22b 100644 --- a/src/routes/+layout.server.js +++ b/src/routes/+layout.server.js @@ -37,7 +37,10 @@ export async function load({ url }) { title: 'Workstation' }, '/dictionary/test': { - title: 'Test' + title: 'Test List' + }, + '/dictionary/testmap': { + title: 'Test Map' }, }; diff --git a/src/routes/dictionary/testmap/+page.svelte b/src/routes/dictionary/testmap/+page.svelte new file mode 100644 index 0000000..fa38563 --- /dev/null +++ b/src/routes/dictionary/testmap/+page.svelte @@ -0,0 +1,52 @@ + + +
+ {#if masterDetail.showMaster} + + {/if} + + {#if masterDetail.showDetail} +
+ {#if masterDetail.mode === "view"} + + {:else if masterDetail.mode === "create"} + + {:else if masterDetail.mode === "edit"} + + {/if} +
+ {/if} +
\ No newline at end of file