From f29c9abad89fdc61aa64fe7a4423bf7b6e44587c Mon Sep 17 00:00:00 2001 From: mrifai-cata Date: Tue, 2 Sep 2025 13:58:10 +0700 Subject: [PATCH 1/7] feat (material): add list material --- app/components/app/material/list-cfg.ts | 52 +++++++++++++++ app/components/app/material/list.vue | 19 ++++++ app/components/flow/material/list.vue | 65 +++++++++++++++++++ .../tools-equipment-src/material/index.vue | 40 ++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 app/components/app/material/list-cfg.ts create mode 100644 app/components/app/material/list.vue create mode 100644 app/components/flow/material/list.vue create mode 100644 app/pages/(features)/tools-equipment-src/material/index.vue diff --git a/app/components/app/material/list-cfg.ts b/app/components/app/material/list-cfg.ts new file mode 100644 index 00000000..71ca97f6 --- /dev/null +++ b/app/components/app/material/list-cfg.ts @@ -0,0 +1,52 @@ +import type { + Col, + KeyLabel, + RecComponent, + RecStrFuncComponent, + RecStrFuncUnknown, + Th, +} from '~/components/pub/custom-ui/data/types' +import { defineAsyncComponent } from 'vue' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue')) + +export const cols: Col[] = [{ width: 100 }, { width: 250 }, { width: 100 }, { width: 100 }, { width: 50 }] + +export const header: Th[][] = [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Item' }, { label: 'Satuan' }]] + +export const keys = ['code', 'name', 'item_id', 'uom_code', 'action'] + +export const delKeyNames: KeyLabel[] = [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, +] + +export const funcParsed: Record any> = { + name: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return `${recX.name}`.trim() + }, + item_id: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.item_id + }, + uom_code: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.uom_code + }, +} + +export const funcComponent: RecStrFuncComponent = { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + } + return res + }, +} + +export const funcHtml: Record any> = {} diff --git a/app/components/app/material/list.vue b/app/components/app/material/list.vue new file mode 100644 index 00000000..5b8778d9 --- /dev/null +++ b/app/components/app/material/list.vue @@ -0,0 +1,19 @@ + + + diff --git a/app/components/flow/material/list.vue b/app/components/flow/material/list.vue new file mode 100644 index 00000000..28fb6290 --- /dev/null +++ b/app/components/flow/material/list.vue @@ -0,0 +1,65 @@ + + + diff --git a/app/pages/(features)/tools-equipment-src/material/index.vue b/app/pages/(features)/tools-equipment-src/material/index.vue new file mode 100644 index 00000000..503056cb --- /dev/null +++ b/app/pages/(features)/tools-equipment-src/material/index.vue @@ -0,0 +1,40 @@ + + + From 7e4444a427766de9f428ea0d1ec91a849f061558 Mon Sep 17 00:00:00 2001 From: mrifai-cata Date: Tue, 2 Sep 2025 14:04:33 +0700 Subject: [PATCH 2/7] feat (material): add form material --- app/components/app/material/entry-form.vue | 53 +++++++++++++++++++ app/components/flow/material/entry.vue | 31 +++++++++++ .../tools-equipment-src/material/add.vue | 41 ++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 app/components/app/material/entry-form.vue create mode 100644 app/components/flow/material/entry.vue create mode 100644 app/pages/(features)/tools-equipment-src/material/add.vue diff --git a/app/components/app/material/entry-form.vue b/app/components/app/material/entry-form.vue new file mode 100644 index 00000000..e8729829 --- /dev/null +++ b/app/components/app/material/entry-form.vue @@ -0,0 +1,53 @@ + + + diff --git a/app/components/flow/material/entry.vue b/app/components/flow/material/entry.vue new file mode 100644 index 00000000..6259785e --- /dev/null +++ b/app/components/flow/material/entry.vue @@ -0,0 +1,31 @@ + + + diff --git a/app/pages/(features)/tools-equipment-src/material/add.vue b/app/pages/(features)/tools-equipment-src/material/add.vue new file mode 100644 index 00000000..56803533 --- /dev/null +++ b/app/pages/(features)/tools-equipment-src/material/add.vue @@ -0,0 +1,41 @@ + + + From da9830e16dc53582bed3b6e67b352478b57a72cd Mon Sep 17 00:00:00 2001 From: mrifai-cata Date: Tue, 2 Sep 2025 15:59:02 +0700 Subject: [PATCH 3/7] feat (material): modify entry form of materiak --- app/components/app/material/entry-form.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/components/app/material/entry-form.vue b/app/components/app/material/entry-form.vue index e8729829..ae45edba 100644 --- a/app/components/app/material/entry-form.vue +++ b/app/components/app/material/entry-form.vue @@ -46,6 +46,12 @@ const items = [ + + From e5d995b9ee71e61b944617a1ab1a2fb128a39adf Mon Sep 17 00:00:00 2001 From: riefive Date: Wed, 3 Sep 2025 12:23:21 +0700 Subject: [PATCH 4/7] feat (material): add zod validation for stock field to ensure number input in entry-form --- app/components/app/material/entry-form.vue | 22 ++++++++++++++++++++-- package.json | 2 +- pnpm-lock.yaml | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/components/app/material/entry-form.vue b/app/components/app/material/entry-form.vue index ae45edba..979c6970 100644 --- a/app/components/app/material/entry-form.vue +++ b/app/components/app/material/entry-form.vue @@ -3,14 +3,32 @@ import Block from '~/components/pub/custom-ui/form/block.vue' import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue' import Field from '~/components/pub/custom-ui/form/field.vue' import Label from '~/components/pub/custom-ui/form/label.vue' +import { z } from 'zod' const props = defineProps<{ modelValue: any }>() const emit = defineEmits(['update:modelValue', 'event']) +const schema = z.object({ + code: z.string(), + name: z.string(), + type: z.string(), + stock: z.preprocess((val) => Number(val), z.number({ invalid_type_error: "Stok harus berupa angka" })), +}) + const data = computed({ get: () => props.modelValue, - set: (val) => emit('update:modelValue', val), + set: (val) => { + const result = schema.safeParse(val) + if (!result.success) { + // You can handle the error here, e.g. show a message + const errorMessage = result.error.errors[0]?.message ?? 'Validation error occurred' + alert(errorMessage) + return + } + emit('update:modelValue', val) + }, }) + const items = [ { value: 'item1', label: 'Item 1' }, { value: 'item2', label: 'Item 2' }, @@ -43,7 +61,7 @@ const items = [ - diff --git a/package.json b/package.json index 00158330..905dee25 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,6 @@ "vue-router": "^4.5.1", "vue-sonner": "^1.3.0", "vue-tsc": "^2.1.10", - "zod": "^3.24.2" + "zod": "^3.25.76" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a3ef8de..bcbed231 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -161,7 +161,7 @@ devDependencies: specifier: ^2.1.10 version: 2.2.12(typescript@5.9.2) zod: - specifier: ^3.24.2 + specifier: ^3.25.76 version: 3.25.76 packages: From 6afa968b7bb237e8d39ef703b48156deac3e1293 Mon Sep 17 00:00:00 2001 From: riefive Date: Wed, 3 Sep 2025 12:50:41 +0700 Subject: [PATCH 5/7] feat (material): update logic validate --- app/components/app/material/entry-form.vue | 29 ++++++---------- app/components/flow/material/entry.vue | 39 ++++++++++++++++++++-- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/app/components/app/material/entry-form.vue b/app/components/app/material/entry-form.vue index 979c6970..52214e3f 100644 --- a/app/components/app/material/entry-form.vue +++ b/app/components/app/material/entry-form.vue @@ -3,28 +3,13 @@ import Block from '~/components/pub/custom-ui/form/block.vue' import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue' import Field from '~/components/pub/custom-ui/form/field.vue' import Label from '~/components/pub/custom-ui/form/label.vue' -import { z } from 'zod' -const props = defineProps<{ modelValue: any }>() +const props = defineProps<{ modelValue: any; errors: any }>() const emit = defineEmits(['update:modelValue', 'event']) -const schema = z.object({ - code: z.string(), - name: z.string(), - type: z.string(), - stock: z.preprocess((val) => Number(val), z.number({ invalid_type_error: "Stok harus berupa angka" })), -}) - const data = computed({ get: () => props.modelValue, set: (val) => { - const result = schema.safeParse(val) - if (!result.success) { - // You can handle the error here, e.g. show a message - const errorMessage = result.error.errors[0]?.message ?? 'Validation error occurred' - alert(errorMessage) - return - } emit('update:modelValue', val) }, }) @@ -46,12 +31,20 @@ const items = [ + + + {{ props.errors.code }} + + + + {{ props.errors.name }} + @@ -61,13 +54,13 @@ const items = [ - - + diff --git a/app/components/flow/material/entry.vue b/app/components/flow/material/entry.vue index 6259785e..b5c8c491 100644 --- a/app/components/flow/material/entry.vue +++ b/app/components/flow/material/entry.vue @@ -1,11 +1,20 @@ @@ -24,7 +57,7 @@ function onClick(type: string) { Tambah BMHP - +
From 06a26c8b077ae8b9b45536ad6cffee9296e3196a Mon Sep 17 00:00:00 2001 From: riefive Date: Wed, 3 Sep 2025 15:34:59 +0700 Subject: [PATCH 6/7] feat: add RBAC role-based access control and permission checks to device index page --- app/components/app/device/entry-form.vue | 64 ++++++++++++++++++ app/components/app/device/list-cfg.ts | 52 +++++++++++++++ app/components/app/device/list.vue | 19 ++++++ app/components/flow/device/entry.vue | 64 ++++++++++++++++++ app/components/flow/device/list.vue | 65 +++++++++++++++++++ app/components/flow/material/entry.vue | 2 +- .../tools-equipment-src/device/add.vue | 41 ++++++++++++ .../tools-equipment-src/device/index.vue | 40 ++++++++++++ 8 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 app/components/app/device/entry-form.vue create mode 100644 app/components/app/device/list-cfg.ts create mode 100644 app/components/app/device/list.vue create mode 100644 app/components/flow/device/entry.vue create mode 100644 app/components/flow/device/list.vue create mode 100644 app/pages/(features)/tools-equipment-src/device/add.vue create mode 100644 app/pages/(features)/tools-equipment-src/device/index.vue diff --git a/app/components/app/device/entry-form.vue b/app/components/app/device/entry-form.vue new file mode 100644 index 00000000..38b4aea0 --- /dev/null +++ b/app/components/app/device/entry-form.vue @@ -0,0 +1,64 @@ + + + diff --git a/app/components/app/device/list-cfg.ts b/app/components/app/device/list-cfg.ts new file mode 100644 index 00000000..71ca97f6 --- /dev/null +++ b/app/components/app/device/list-cfg.ts @@ -0,0 +1,52 @@ +import type { + Col, + KeyLabel, + RecComponent, + RecStrFuncComponent, + RecStrFuncUnknown, + Th, +} from '~/components/pub/custom-ui/data/types' +import { defineAsyncComponent } from 'vue' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue')) + +export const cols: Col[] = [{ width: 100 }, { width: 250 }, { width: 100 }, { width: 100 }, { width: 50 }] + +export const header: Th[][] = [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Item' }, { label: 'Satuan' }]] + +export const keys = ['code', 'name', 'item_id', 'uom_code', 'action'] + +export const delKeyNames: KeyLabel[] = [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, +] + +export const funcParsed: Record any> = { + name: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return `${recX.name}`.trim() + }, + item_id: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.item_id + }, + uom_code: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.uom_code + }, +} + +export const funcComponent: RecStrFuncComponent = { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + } + return res + }, +} + +export const funcHtml: Record any> = {} diff --git a/app/components/app/device/list.vue b/app/components/app/device/list.vue new file mode 100644 index 00000000..5b8778d9 --- /dev/null +++ b/app/components/app/device/list.vue @@ -0,0 +1,19 @@ + + + diff --git a/app/components/flow/device/entry.vue b/app/components/flow/device/entry.vue new file mode 100644 index 00000000..b5c8c491 --- /dev/null +++ b/app/components/flow/device/entry.vue @@ -0,0 +1,64 @@ + + + diff --git a/app/components/flow/device/list.vue b/app/components/flow/device/list.vue new file mode 100644 index 00000000..8c7bd672 --- /dev/null +++ b/app/components/flow/device/list.vue @@ -0,0 +1,65 @@ + + + diff --git a/app/components/flow/material/entry.vue b/app/components/flow/material/entry.vue index b5c8c491..17d2f7c0 100644 --- a/app/components/flow/material/entry.vue +++ b/app/components/flow/material/entry.vue @@ -55,7 +55,7 @@ function onClick(type: string) {