diff --git a/app/components/app/division-position/entry.vue b/app/components/app/division-position/entry.vue new file mode 100644 index 00000000..da4782c0 --- /dev/null +++ b/app/components/app/division-position/entry.vue @@ -0,0 +1,192 @@ + + + diff --git a/app/components/app/division-position/list-cfg.ts b/app/components/app/division-position/list-cfg.ts index e35627d2..cc153cc5 100644 --- a/app/components/app/division-position/list-cfg.ts +++ b/app/components/app/division-position/list-cfg.ts @@ -1,5 +1,6 @@ import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' import { defineAsyncComponent } from 'vue' +import type { DivisionPosition } from '~/models/division-position' type SmallDetailDto = any @@ -10,9 +11,9 @@ export const config: Config = { headers: [ [ - { label: 'Kode' }, - { label: 'Nama' }, - { label: 'Divisi Induk' }, + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Nama Divisi ' }, { label: 'Karyawan' }, { label: 'Status Kepala' }, { label: '' }, @@ -32,8 +33,13 @@ export const config: Config = { return recX.division?.name || '-' }, employee: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - return recX.employee?.name || '-' + const recX = rec as DivisionPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' }, head: (rec: unknown): unknown => { const recX = rec as SmallDetailDto diff --git a/app/components/app/division/detail/index.vue b/app/components/app/division/detail/index.vue new file mode 100644 index 00000000..dd5a4c59 --- /dev/null +++ b/app/components/app/division/detail/index.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/app/components/app/division/detail/list-cfg.ts b/app/components/app/division/detail/list-cfg.ts new file mode 100644 index 00000000..76c3b9c8 --- /dev/null +++ b/app/components/app/division/detail/list-cfg.ts @@ -0,0 +1,65 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { DivisionPosition } from '~/models/division-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: '#' }, + { label: 'Kode Jabatan' }, + { label: 'Nama Jabatan' }, + { label: 'Pengisi Jabatan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['index', 'code', 'name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + division: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.division?.name || '-' + }, + employee: (rec: unknown): unknown => { + const recX = rec as DivisionPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/division/detail/list.vue b/app/components/app/division/detail/list.vue new file mode 100644 index 00000000..4bbebb57 --- /dev/null +++ b/app/components/app/division/detail/list.vue @@ -0,0 +1,45 @@ + + + diff --git a/app/components/app/division/list-cfg.ts b/app/components/app/division/list-cfg.ts index 54ed06a6..2d7f93ba 100644 --- a/app/components/app/division/list-cfg.ts +++ b/app/components/app/division/list-cfg.ts @@ -3,17 +3,12 @@ import { defineAsyncComponent } from 'vue' type SmallDetailDto = any -const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dud.vue')) export const config: Config = { cols: [{}, {}, {}, { width: 50 }], - headers: [[ - { label: 'Kode' }, - { label: 'Nama' }, - { label: 'Divisi Induk' }, - { label: '' }, - ]], + headers: [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Divisi Induk' }, { label: '' }]], keys: ['code', 'name', 'parent', 'action'], @@ -44,4 +39,4 @@ export const config: Config = { }, htmls: {}, -} \ No newline at end of file +} diff --git a/app/components/app/installation-position/entry-detail.vue b/app/components/app/installation-position/entry-detail.vue new file mode 100644 index 00000000..a6bfd113 --- /dev/null +++ b/app/components/app/installation-position/entry-detail.vue @@ -0,0 +1,192 @@ + + + diff --git a/app/components/app/installation-position/entry-form.vue b/app/components/app/installation-position/entry-form.vue new file mode 100644 index 00000000..4f7885a1 --- /dev/null +++ b/app/components/app/installation-position/entry-form.vue @@ -0,0 +1,207 @@ + + + diff --git a/app/components/app/installation-position/list.cfg.ts b/app/components/app/installation-position/list.cfg.ts new file mode 100644 index 00000000..fe3f6c9c --- /dev/null +++ b/app/components/app/installation-position/list.cfg.ts @@ -0,0 +1,65 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { DivisionPosition } from '~/models/division-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Nama Instalasi ' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['code', 'name', 'installation.name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + division: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.division?.name || '-' + }, + employee: (rec: unknown): unknown => { + const recX = rec as DivisionPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/installation-position/list.vue b/app/components/app/installation-position/list.vue new file mode 100644 index 00000000..6ad7dd81 --- /dev/null +++ b/app/components/app/installation-position/list.vue @@ -0,0 +1,39 @@ + + + diff --git a/app/components/app/installation/detail/index.vue b/app/components/app/installation/detail/index.vue new file mode 100644 index 00000000..8a668d1c --- /dev/null +++ b/app/components/app/installation/detail/index.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/app/components/app/installation/detail/list.cfg.ts b/app/components/app/installation/detail/list.cfg.ts new file mode 100644 index 00000000..bf341ff9 --- /dev/null +++ b/app/components/app/installation/detail/list.cfg.ts @@ -0,0 +1,65 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { DivisionPosition } from '~/models/division-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: '#' }, + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['index', 'code', 'name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + division: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.division?.name || '-' + }, + employee: (rec: unknown): unknown => { + const recX = rec as DivisionPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/installation/detail/list.vue b/app/components/app/installation/detail/list.vue new file mode 100644 index 00000000..b5884cfd --- /dev/null +++ b/app/components/app/installation/detail/list.vue @@ -0,0 +1,45 @@ + + + diff --git a/app/components/app/installation/list-cfg.ts b/app/components/app/installation/list.cfg.ts similarity index 83% rename from app/components/app/installation/list-cfg.ts rename to app/components/app/installation/list.cfg.ts index f64ecea8..e2a39d80 100644 --- a/app/components/app/installation/list-cfg.ts +++ b/app/components/app/installation/list.cfg.ts @@ -3,19 +3,12 @@ import { defineAsyncComponent } from 'vue' type SmallDetailDto = any -const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dud.vue')) export const config: Config = { cols: [{}, {}, {}, { width: 50 }], - headers: [ - [ - { label: 'Kode' }, - { label: 'Nama' }, - { label: 'Encounter Class' }, - { label: '' }, - ], - ], + headers: [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Encounter Class' }, { label: '' }]], keys: ['code', 'name', 'encounterClass_code', 'action'], diff --git a/app/components/app/installation/list.vue b/app/components/app/installation/list.vue index 1be60a60..6ad7dd81 100644 --- a/app/components/app/installation/list.vue +++ b/app/components/app/installation/list.vue @@ -6,7 +6,7 @@ import PaginationView from '~/components/pub/my-ui/pagination/pagination-view.vu import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type' // Configs -import { config } from './list-cfg' +import { config } from './list.cfg' interface Props { data: any[] @@ -31,6 +31,9 @@ function handlePageChange(page: number) { :rows="data" :skeleton-size="paginationMeta?.pageSize" /> - + diff --git a/app/components/app/specialist-position/entry-detail.vue b/app/components/app/specialist-position/entry-detail.vue new file mode 100644 index 00000000..f21ff65f --- /dev/null +++ b/app/components/app/specialist-position/entry-detail.vue @@ -0,0 +1,192 @@ + + + diff --git a/app/components/app/specialist-position/entry-form.vue b/app/components/app/specialist-position/entry-form.vue new file mode 100644 index 00000000..be031219 --- /dev/null +++ b/app/components/app/specialist-position/entry-form.vue @@ -0,0 +1,207 @@ + + + diff --git a/app/components/app/specialist-position/list.cfg.ts b/app/components/app/specialist-position/list.cfg.ts new file mode 100644 index 00000000..35f49c20 --- /dev/null +++ b/app/components/app/specialist-position/list.cfg.ts @@ -0,0 +1,61 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { DivisionPosition } from '~/models/division-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Nama Spesialis ' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['code', 'name', 'specialist.name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + employee: (rec: unknown): unknown => { + const recX = rec as DivisionPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/specialist-position/list.vue b/app/components/app/specialist-position/list.vue new file mode 100644 index 00000000..6ad7dd81 --- /dev/null +++ b/app/components/app/specialist-position/list.vue @@ -0,0 +1,39 @@ + + + diff --git a/app/components/app/specialist/detail/index.vue b/app/components/app/specialist/detail/index.vue new file mode 100644 index 00000000..3f32a78f --- /dev/null +++ b/app/components/app/specialist/detail/index.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/app/components/app/specialist/detail/list.cfg.ts b/app/components/app/specialist/detail/list.cfg.ts new file mode 100644 index 00000000..8faf9e61 --- /dev/null +++ b/app/components/app/specialist/detail/list.cfg.ts @@ -0,0 +1,61 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { UnitPosition } from '~/models/unit-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: '#' }, + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['index', 'code', 'name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + employee: (rec: unknown): unknown => { + const recX = rec as UnitPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/specialist/detail/list.vue b/app/components/app/specialist/detail/list.vue new file mode 100644 index 00000000..da83e7ca --- /dev/null +++ b/app/components/app/specialist/detail/list.vue @@ -0,0 +1,45 @@ + + + diff --git a/app/components/app/specialist/list-cfg.ts b/app/components/app/specialist/list-cfg.ts index 8ed75f28..010358c4 100644 --- a/app/components/app/specialist/list-cfg.ts +++ b/app/components/app/specialist/list-cfg.ts @@ -8,16 +8,9 @@ const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dr export const config: Config = { cols: [{}, {}, {}, { width: 50 }], - headers: [ - [ - { label: 'Kode' }, - { label: 'Nama' }, - { label: 'Unit' }, - { label: '' }, - ], - ], + headers: [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Nama Unit' }, { label: '' }]], - keys: ['code', 'name', 'unit', 'action'], + keys: ['code', 'name', 'unit.name', 'action'], delKeyNames: [ { key: 'code', label: 'Kode' }, @@ -29,10 +22,6 @@ export const config: Config = { const recX = rec as SmallDetailDto return `${recX.name}`.trim() }, - unit: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - return recX.unit_id || '-' - }, }, components: { diff --git a/app/components/app/subspecialist-position/entry-detail.vue b/app/components/app/subspecialist-position/entry-detail.vue new file mode 100644 index 00000000..fd3f91b7 --- /dev/null +++ b/app/components/app/subspecialist-position/entry-detail.vue @@ -0,0 +1,192 @@ + + + diff --git a/app/components/app/subspecialist-position/entry-form.vue b/app/components/app/subspecialist-position/entry-form.vue new file mode 100644 index 00000000..c897b2f5 --- /dev/null +++ b/app/components/app/subspecialist-position/entry-form.vue @@ -0,0 +1,207 @@ + + + diff --git a/app/components/app/subspecialist-position/list.cfg.ts b/app/components/app/subspecialist-position/list.cfg.ts new file mode 100644 index 00000000..028bc7bf --- /dev/null +++ b/app/components/app/subspecialist-position/list.cfg.ts @@ -0,0 +1,65 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { SubSpecialistPosition } from '~/models/subspecialist-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Nama Sub Spesialis ' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['code', 'name', 'subspecialist', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + subspecialist: (rec: unknown): unknown => { + const recX = rec as SubSpecialistPosition + return recX.subspecialist?.name || '-' + }, + employee: (rec: unknown): unknown => { + const recX = rec as SubSpecialistPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/subspecialist-position/list.vue b/app/components/app/subspecialist-position/list.vue new file mode 100644 index 00000000..6ad7dd81 --- /dev/null +++ b/app/components/app/subspecialist-position/list.vue @@ -0,0 +1,39 @@ + + + diff --git a/app/components/app/subspecialist/detail/index.vue b/app/components/app/subspecialist/detail/index.vue new file mode 100644 index 00000000..154acf75 --- /dev/null +++ b/app/components/app/subspecialist/detail/index.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/app/components/app/subspecialist/detail/list.cfg.ts b/app/components/app/subspecialist/detail/list.cfg.ts new file mode 100644 index 00000000..8faf9e61 --- /dev/null +++ b/app/components/app/subspecialist/detail/list.cfg.ts @@ -0,0 +1,61 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { UnitPosition } from '~/models/unit-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: '#' }, + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['index', 'code', 'name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + employee: (rec: unknown): unknown => { + const recX = rec as UnitPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/subspecialist/detail/list.vue b/app/components/app/subspecialist/detail/list.vue new file mode 100644 index 00000000..11431e25 --- /dev/null +++ b/app/components/app/subspecialist/detail/list.vue @@ -0,0 +1,45 @@ + + + diff --git a/app/components/app/subspecialist/list-cfg.ts b/app/components/app/subspecialist/list-cfg.ts index 7e9e7b79..99d34169 100644 --- a/app/components/app/subspecialist/list-cfg.ts +++ b/app/components/app/subspecialist/list-cfg.ts @@ -8,16 +8,9 @@ const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dr export const config: Config = { cols: [{}, {}, {}, { width: 50 }], - headers: [ - [ - { label: 'Kode' }, - { label: 'Nama' }, - { label: 'Specialis' }, - { label: '' }, - ], - ], + headers: [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Specialis' }, { label: '' }]], - keys: ['code', 'name', 'specialist', 'action'], + keys: ['code', 'name', 'specialist.name', 'action'], delKeyNames: [ { key: 'code', label: 'Kode' }, diff --git a/app/components/app/subspecialist/list.vue b/app/components/app/subspecialist/list.vue index 1be60a60..2f7908cb 100644 --- a/app/components/app/subspecialist/list.vue +++ b/app/components/app/subspecialist/list.vue @@ -31,6 +31,9 @@ function handlePageChange(page: number) { :rows="data" :skeleton-size="paginationMeta?.pageSize" /> - + diff --git a/app/components/app/unit-position/entry-detail.vue b/app/components/app/unit-position/entry-detail.vue new file mode 100644 index 00000000..fb84e41a --- /dev/null +++ b/app/components/app/unit-position/entry-detail.vue @@ -0,0 +1,192 @@ + + + diff --git a/app/components/app/unit-position/entry-form.vue b/app/components/app/unit-position/entry-form.vue new file mode 100644 index 00000000..b6ab8609 --- /dev/null +++ b/app/components/app/unit-position/entry-form.vue @@ -0,0 +1,206 @@ + + + diff --git a/app/components/app/unit-position/list.cfg.ts b/app/components/app/unit-position/list.cfg.ts new file mode 100644 index 00000000..fb5e319b --- /dev/null +++ b/app/components/app/unit-position/list.cfg.ts @@ -0,0 +1,61 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { UnitPosition } from '~/models/unit-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Nama Unit ' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['code', 'name', 'unit.name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + employee: (rec: unknown): unknown => { + const recX = rec as UnitPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/unit-position/list.vue b/app/components/app/unit-position/list.vue new file mode 100644 index 00000000..6ad7dd81 --- /dev/null +++ b/app/components/app/unit-position/list.vue @@ -0,0 +1,39 @@ + + + diff --git a/app/components/app/unit/detail/index.vue b/app/components/app/unit/detail/index.vue new file mode 100644 index 00000000..9b38aa2b --- /dev/null +++ b/app/components/app/unit/detail/index.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/app/components/app/unit/detail/list.cfg.ts b/app/components/app/unit/detail/list.cfg.ts new file mode 100644 index 00000000..8faf9e61 --- /dev/null +++ b/app/components/app/unit/detail/list.cfg.ts @@ -0,0 +1,61 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { UnitPosition } from '~/models/unit-position' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, { width: 50 }], + + headers: [ + [ + { label: '#' }, + { label: 'Kode Posisi' }, + { label: 'Nama Posisi' }, + { label: 'Karyawan' }, + { label: 'Status Kepala' }, + { label: '' }, + ], + ], + + keys: ['index', 'code', 'name', 'employee', 'head', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + employee: (rec: unknown): unknown => { + const recX = rec as UnitPosition + const fullName = [recX.employee?.person.frontTitle, recX.employee?.person.name, recX.employee?.person.endTitle] + .filter(Boolean) + .join(' ') + .trim() + + return fullName || '-' + }, + head: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.headStatus ? 'Ya' : 'Tidak' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/unit/detail/list.vue b/app/components/app/unit/detail/list.vue new file mode 100644 index 00000000..f878d14c --- /dev/null +++ b/app/components/app/unit/detail/list.vue @@ -0,0 +1,45 @@ + + + diff --git a/app/components/content/division-position/list.vue b/app/components/content/division-position/list.vue index 019e64a9..4fa8605d 100644 --- a/app/components/content/division-position/list.vue +++ b/app/components/content/division-position/list.vue @@ -54,6 +54,7 @@ const { sort: 'createdAt:asc', 'page-number': params['page-number'] || 0, 'page-size': params['page-size'] || 10, + includes: 'division,Employee.Person', }) return { success: result.success || false, body: result.body || {} } }, @@ -61,7 +62,7 @@ const { }) const headerPrep: HeaderPrep = { - title: 'Divisi', + title: 'Divisi - Posisi', icon: 'i-lucide-box', refSearchNav: { placeholder: 'Cari (min. 3 karakter)...', @@ -105,12 +106,12 @@ watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: getCurrentDivisionDetail(recId.value) - title.value = 'Detail Divisi' + title.value = 'Detail Divisi Position' isReadonly.value = true break case ActionEvents.showEdit: getCurrentDivisionDetail(recId.value) - title.value = 'Edit Divisi' + title.value = 'Edit Divisi Position' isReadonly.value = false break case ActionEvents.showConfirmDelete: @@ -120,9 +121,19 @@ watch([recId, recAction], () => { }) onMounted(async () => { - divisions.value = await getDivisionLabelList({ sort: 'createdAt:asc', 'page-size': 100 }) - employees.value = await getEmployeeLabelList({ sort: 'createdAt:asc', 'page-size': 100 }) - await getDivisionList() + try { + divisions.value = await getDivisionLabelList({ sort: 'createdAt:asc', 'page-size': 100 }) + employees.value = await getEmployeeLabelList({ sort: 'createdAt:asc', 'page-size': 100, includes: 'person' }) + await getDivisionList() + } catch (err) { + console.log(err) + // show toast + toast({ + title: 'Terjadi Kesalahan', + description: 'Terjadi kesalahan saat memuat data', + variant: 'destructive', + }) + } }) @@ -142,7 +153,7 @@ onMounted(async () => { +import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' +import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue' + +// Components +import Header from '~/components/pub/my-ui/nav-header/prep.vue' + +// Service +import type { Division } from '~/models/division' +import { getDetail as getDetailDivision } from '~/services/division.service' + +// #region division positions +import { config } from '~/components/app/division/detail/list-cfg' + +// Helpers +import { usePaginatedList } from '~/composables/usePaginatedList' +import { toast } from '~/components/pub/ui/toast' + +import Dialog from '~/components/pub/my-ui/modal/dialog.vue' +// Types +import { DivisionPositionSchema, type DivisionPositionFormData } from '~/schemas/division-position.schema' + +// Handlers +import { + recId, + recAction, + recItem, + isReadonly, + isProcessing, + isFormEntryDialogOpen, + isRecordConfirmationOpen, + onResetState, + handleActionSave, + handleActionEdit, + handleActionRemove, + handleCancelForm, +} from '~/handlers/division-position.handler' + +// Services +import { getList, getDetail as getDetailDivisionPosition } from '~/services/division-position.service' +import { getValueLabelList as getEmployeeLabelList } from '~/services/employee.service' + +const employees = ref<{ value: string | number; label: string }[]>([]) + +const title = ref('') +// #endregion + +// #region Props & Emits +const props = defineProps<{ + divisionId: number +}>() +const division = ref({} as Division) +// #endregion + +// #region State & Computed +const { + data, + isLoading, + paginationMeta, + searchInput, + handlePageChange, + handleSearch, + fetchData: getDivisionPositionList, +} = usePaginatedList({ + fetchFn: async (params: any) => { + const result = await getList({ + 'division-id': props.divisionId, + includes: 'Employee.Person', + search: params.search, + sort: 'createdAt:asc', + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + 'page-no-limit': true, + }) + return { success: result.success || false, body: result.body || {} } + }, + entityName: 'division-position', +}) + +const dataMap = computed(() => { + return data.value.map((v, i) => { + return { + ...v, + index: i + 1, + } + }) +}) +const headerPrep: HeaderPrep = { + title: 'Detail Divisi', + icon: 'i-lucide-user', + refSearchNav: { + placeholder: 'Cari (min. 3 karakter)...', + minLength: 3, + debounceMs: 500, + showValidationFeedback: true, + onInput: (value: string) => { + searchInput.value = value + }, + onClick: () => {}, + onClear: () => {}, + }, + addNav: { + label: 'Tambah Jabatan', + icon: 'i-lucide-plus', + onClick: () => { + recItem.value = null + recId.value = 0 + isFormEntryDialogOpen.value = true + isReadonly.value = false + }, + }, +} + +// #endregion + +// #region Lifecycle Hooks +onMounted(async () => { + try { + const result = await getDetailDivision(props.divisionId) + if (result.success) { + division.value = result.body.data || {} + } + + const res = await getEmployeeLabelList({ sort: 'createdAt:asc', 'page-size': 100, includes: 'person' }) + employees.value = res + } catch (err) { + // show toast + toast({ + title: 'Terjadi Kesalahan', + description: 'Terjadi kesalahan saat memuat data', + variant: 'destructive', + }) + } +}) +// #endregion + +// #region Functions +// #endregion region + +// #region Utilities & event handlers +// #endregion + +// #region Watchers +// #endregion +provide('rec_id', recId) +provide('rec_action', recAction) +provide('rec_item', recItem) +provide('table_data_loader', isLoading) + +// Watch for row actions when recId or recAction changes +watch([recId, recAction], () => { + console.log(recId, recAction) + switch (recAction.value) { + case ActionEvents.showEdit: + getDetailDivisionPosition(recId.value) + title.value = 'Edit Jabatan' + isReadonly.value = false + isFormEntryDialogOpen.value = true + break + case ActionEvents.showConfirmDelete: + isRecordConfirmationOpen.value = true + break + } +}) + + + diff --git a/app/components/content/division/list.vue b/app/components/content/division/list.vue index 9ccefc56..0456891b 100644 --- a/app/components/content/division/list.vue +++ b/app/components/content/division/list.vue @@ -13,7 +13,7 @@ import { toast } from '~/components/pub/ui/toast' // Types import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' import { DivisionSchema, type DivisionFormData } from '~/schemas/division.schema' -import type { Division } from "~/models/division" +import type { Division } from '~/models/division' import type { TreeItem } from '~/models/_base' // Handlers @@ -78,6 +78,7 @@ const headerPrep: HeaderPrep = { label: 'Tambah', icon: 'i-lucide-plus', onClick: () => { + recAction.value = '' recItem.value = null recId.value = 0 isFormEntryDialogOpen.value = true @@ -104,9 +105,23 @@ const getCurrentDivisionDetail = async (id: number | string) => { watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: - getCurrentDivisionDetail(recId.value) - title.value = 'Detail Divisi' - isReadonly.value = true + if (Number(recId.value) > 0) { + const id = Number(recId.value) + + recAction.value = '' + recItem.value = null + recId.value = 0 + isFormEntryDialogOpen.value = false + isReadonly.value = false + + navigateTo({ + name: 'org-src-division-id', + params: { + id, + }, + }) + } + break case ActionEvents.showEdit: getCurrentDivisionDetail(recId.value) diff --git a/app/components/content/installation-position/list.vue b/app/components/content/installation-position/list.vue new file mode 100644 index 00000000..ea60ee04 --- /dev/null +++ b/app/components/content/installation-position/list.vue @@ -0,0 +1,208 @@ + + + diff --git a/app/components/content/installation/detail.vue b/app/components/content/installation/detail.vue new file mode 100644 index 00000000..0f12ad8c --- /dev/null +++ b/app/components/content/installation/detail.vue @@ -0,0 +1,235 @@ + + + diff --git a/app/components/content/installation/entry.ts b/app/components/content/installation/entry.ts deleted file mode 100644 index c003a029..00000000 --- a/app/components/content/installation/entry.ts +++ /dev/null @@ -1,37 +0,0 @@ -import * as z from 'zod' - -export const installationConf = { - msg: { - placeholder: '---pilih encounter class (fhir7)', - }, - items: [ - { value: '1', label: 'Ambulatory', code: 'AMB' }, - { value: '2', label: 'Inpatient', code: 'IMP' }, - { value: '3', label: 'Emergency', code: 'EMER' }, - { value: '4', label: 'Observation', code: 'OBSENC' }, - { value: '5', label: 'Pre-admission', code: 'PRENC' }, - { value: '6', label: 'Short Stay', code: 'SS' }, - { value: '7', label: 'Virtual', code: 'VR' }, - { value: '8', label: 'Home Health', code: 'HH' }, - ], -} - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama instalasi harus diisi', - }) - .min(3, 'Nama instalasi minimal 3 karakter'), - - code: z - .string({ - required_error: 'Kode instalasi harus diisi', - }) - .min(3, 'Kode instalasi minimal 3 karakter'), - - encounterClassCode: z - .string({ - required_error: 'Kelompok encounter class harus dipilih', - }) - .min(1, 'Kelompok encounter class harus dipilih'), -}) diff --git a/app/components/content/installation/list.vue b/app/components/content/installation/list.vue index 31486097..553d7ebb 100644 --- a/app/components/content/installation/list.vue +++ b/app/components/content/installation/list.vue @@ -102,9 +102,23 @@ const getCurrentInstallationDetail = async (id: number | string) => { watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: - getCurrentInstallationDetail(recId.value) - title.value = 'Detail Instalasi' - isReadonly.value = true + if (Number(recId.value) > 0) { + const id = Number(recId.value) + + recAction.value = '' + recItem.value = null + recId.value = 0 + isFormEntryDialogOpen.value = false + isReadonly.value = false + + navigateTo({ + name: 'org-src-installation-id', + params: { + id, + }, + }) + } + break case ActionEvents.showEdit: getCurrentInstallationDetail(recId.value) diff --git a/app/components/content/specialist-position/list.vue b/app/components/content/specialist-position/list.vue new file mode 100644 index 00000000..1ebf697e --- /dev/null +++ b/app/components/content/specialist-position/list.vue @@ -0,0 +1,203 @@ + + + diff --git a/app/components/content/specialist/detail.vue b/app/components/content/specialist/detail.vue new file mode 100644 index 00000000..df4e79b6 --- /dev/null +++ b/app/components/content/specialist/detail.vue @@ -0,0 +1,236 @@ + + + diff --git a/app/components/content/specialist/entry.ts b/app/components/content/specialist/entry.ts deleted file mode 100644 index c89302c2..00000000 --- a/app/components/content/specialist/entry.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as z from 'zod' - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama spesialisasi harus diisi', - }) - .min(3, 'Nama spesialisasi minimal 3 karakter'), - - code: z - .string({ - required_error: 'Kode spesialisasi harus diisi', - }) - .min(3, 'Kode spesialisasi minimal 3 karakter'), - - installationId: z - .string({ - required_error: 'Instalasi harus dipilih', - }) - .min(1, 'Instalasi harus dipilih'), - - unitId: z - .string({ - required_error: 'Unit harus dipilih', - }) - .min(1, 'Unit harus dipilih'), -}) - -// Unit mapping berdasarkan installation -export const installationUnitMapping: Record = { - '1': ['1', '3', '5'], - '2': ['2', '4', '6'], - '3': ['7', '8', '9', '10', '11'], -} - -export const unitConf = { - msg: { - placeholder: '---pilih unit', - search: 'kode, nama unit', - empty: 'unit tidak ditemukan', - }, - items: [ - { value: '1', label: 'Instalasi Medis', code: 'MED' }, - { value: '2', label: 'Instalasi Keperawatan', code: 'NUR' }, - { value: '3', label: 'Instalasi Administrasi', code: 'ADM' }, - { value: '4', label: 'Instalasi Penunjang Non-Medis', code: 'SUP' }, - { value: '5', label: 'Instalasi Pendidikan & Pelatihan', code: 'EDU' }, - { value: '6', label: 'Instalasi Farmasi', code: 'PHA' }, - { value: '7', label: 'Instalasi Radiologi', code: 'RAD' }, - { value: '8', label: 'Instalasi Laboratorium', code: 'LAB' }, - { value: '9', label: 'Instalasi Keuangan', code: 'FIN' }, - { value: '10', label: 'Instalasi SDM', code: 'HR' }, - { value: '11', label: 'Instalasi Teknologi Informasi', code: 'ITS' }, - { value: '12', label: 'Instalasi Pemeliharaan & Sarana', code: 'MNT' }, - { value: '13', label: 'Instalasi Gizi / Catering', code: 'CAT' }, - { value: '14', label: 'Instalasi Keamanan', code: 'SEC' }, - { value: '15', label: 'Instalasi Gawat Darurat', code: 'EMR' }, - { value: '16', label: 'Instalasi Bedah Sentral', code: 'SUR' }, - { value: '17', label: 'Instalasi Rawat Jalan', code: 'OUT' }, - { value: '18', label: 'Instalasi Rawat Inap', code: 'INP' }, - { value: '19', label: 'Instalasi Rehabilitasi Medik', code: 'REB' }, - { value: '20', label: 'Instalasi Penelitian & Pengembangan', code: 'RSH' }, - ], -} - -export const installationConf = { - msg: { - placeholder: '---pilih instalasi', - search: 'kode, nama instalasi', - empty: 'instalasi tidak ditemukan', - }, - items: [ - { value: '1', label: 'Ambulatory', code: 'AMB' }, - { value: '2', label: 'Inpatient', code: 'IMP' }, - { value: '3', label: 'Emergency', code: 'EMER' }, - ], -} - -// Helper function untuk filter unit berdasarkan installation -export function getFilteredUnits(installationId: string) { - if (!installationId || !installationUnitMapping[installationId]) { - return [] - } - - const allowedUnitIds = installationUnitMapping[installationId] - return unitConf.items.filter((unit) => allowedUnitIds.includes(unit.value)) -} - -// Helper function untuk membuat unit config yang ter-filter -export function createFilteredUnitConf(installationId: string) { - return { - ...unitConf, - items: getFilteredUnits(installationId), - } -} diff --git a/app/components/content/specialist/list.vue b/app/components/content/specialist/list.vue index 9bbf755f..ca293026 100644 --- a/app/components/content/specialist/list.vue +++ b/app/components/content/specialist/list.vue @@ -103,9 +103,23 @@ const getCurrentSpecialistDetail = async (id: number | string) => { watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: - getCurrentSpecialistDetail(recId.value) - title.value = 'Detail Spesialis' - isReadonly.value = true + if (Number(recId.value) > 0) { + const id = Number(recId.value) + + recAction.value = '' + recItem.value = null + recId.value = 0 + isFormEntryDialogOpen.value = false + isReadonly.value = false + + navigateTo({ + name: 'org-src-specialist-id', + params: { + id, + }, + }) + } + break case ActionEvents.showEdit: getCurrentSpecialistDetail(recId.value) diff --git a/app/components/content/subspecialist-position/list.vue b/app/components/content/subspecialist-position/list.vue new file mode 100644 index 00000000..4c833ce2 --- /dev/null +++ b/app/components/content/subspecialist-position/list.vue @@ -0,0 +1,211 @@ + + + diff --git a/app/components/content/subspecialist/detail.vue b/app/components/content/subspecialist/detail.vue new file mode 100644 index 00000000..d432eb22 --- /dev/null +++ b/app/components/content/subspecialist/detail.vue @@ -0,0 +1,239 @@ + + + diff --git a/app/components/content/subspecialist/entry.ts b/app/components/content/subspecialist/entry.ts deleted file mode 100644 index 5a93847d..00000000 --- a/app/components/content/subspecialist/entry.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as z from 'zod' - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama spesialisasi harus diisi', - }) - .min(3, 'Nama spesialisasi minimal 3 karakter'), - - code: z - .string({ - required_error: 'Kode spesialisasi harus diisi', - }) - .min(3, 'Kode spesialisasi minimal 3 karakter'), - - installationId: z - .string({ - required_error: 'Instalasi harus dipilih', - }) - .min(1, 'Instalasi harus dipilih'), - - unitId: z - .string({ - required_error: 'Unit harus dipilih', - }) - .min(1, 'Unit harus dipilih'), - specialistId: z - .string({ - required_error: 'Specialist harus dipilih', - }) - .min(1, 'Specialist harus dipilih'), -}) - -// Unit mapping berdasarkan installation -export const installationUnitMapping: Record = { - '1': ['1', '3'], - '2': ['2', '3'], - '3': ['1', '2', '3'], -} - -export const unitConf = { - msg: { - placeholder: '---pilih unit', - search: 'kode, nama unit', - empty: 'unit tidak ditemukan', - }, - items: [ - { value: '1', label: 'Instalasi Medis', code: 'MED' }, - { value: '2', label: 'Instalasi Keperawatan', code: 'NUR' }, - { value: '3', label: 'Instalasi Administrasi', code: 'ADM' }, - ], -} - -export const specialistConf = { - msg: { - placeholder: '---pilih specialist', - search: 'kode, nama specialist', - empty: 'specialist tidak ditemukan', - }, - items: [ - { value: '1', label: 'Spesialis Jantung', code: 'CARD' }, - { value: '2', label: 'Spesialis Mata', code: 'OPHT' }, - { value: '3', label: 'Spesialis Bedah', code: 'SURG' }, - { value: '4', label: 'Spesialis Anak', code: 'PEDI' }, - { value: '5', label: 'Spesialis Kandungan', code: 'OBGY' }, - ], -} - -export const installationConf = { - msg: { - placeholder: '---pilih instalasi', - search: 'kode, nama instalasi', - empty: 'instalasi tidak ditemukan', - }, - items: [ - { value: '1', label: 'Ambulatory', code: 'AMB' }, - { value: '2', label: 'Inpatient', code: 'IMP' }, - { value: '3', label: 'Emergency', code: 'EMER' }, - ], -} - -// Helper function untuk filter unit berdasarkan installation -export function getFilteredUnits(installationId: string) { - if (!installationId || !installationUnitMapping[installationId]) { - return [] - } - - const allowedUnitIds = installationUnitMapping[installationId] - return unitConf.items.filter((unit) => allowedUnitIds.includes(unit.value)) -} - -// Helper function untuk membuat unit config yang ter-filter -export function createFilteredUnitConf(installationId: string) { - return { - ...unitConf, - items: getFilteredUnits(installationId), - } -} diff --git a/app/components/content/subspecialist/list.vue b/app/components/content/subspecialist/list.vue index e2c6db52..bb1b63f5 100644 --- a/app/components/content/subspecialist/list.vue +++ b/app/components/content/subspecialist/list.vue @@ -103,9 +103,23 @@ const getCurrentSubSpecialistDetail = async (id: number | string) => { watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: - getCurrentSubSpecialistDetail(recId.value) - title.value = 'Detail Sub Spesialis' - isReadonly.value = true + if (Number(recId.value) > 0) { + const id = Number(recId.value) + + recAction.value = '' + recItem.value = null + recId.value = 0 + isFormEntryDialogOpen.value = false + isReadonly.value = false + + navigateTo({ + name: 'org-src-subspecialist-id', + params: { + id, + }, + }) + } + break case ActionEvents.showEdit: getCurrentSubSpecialistDetail(recId.value) diff --git a/app/components/content/unit-position/list.vue b/app/components/content/unit-position/list.vue new file mode 100644 index 00000000..55ab3f29 --- /dev/null +++ b/app/components/content/unit-position/list.vue @@ -0,0 +1,206 @@ + + + diff --git a/app/components/content/unit/detail.vue b/app/components/content/unit/detail.vue new file mode 100644 index 00000000..6c51624f --- /dev/null +++ b/app/components/content/unit/detail.vue @@ -0,0 +1,234 @@ + + + diff --git a/app/components/content/unit/entry.ts b/app/components/content/unit/entry.ts deleted file mode 100644 index bf85a0ed..00000000 --- a/app/components/content/unit/entry.ts +++ /dev/null @@ -1,63 +0,0 @@ -import * as z from 'zod' - -export const unitConf = { - msg: { - placeholder: '--- pilih instalasi', - search: 'kode, nama instalasi', - empty: 'instalasi tidak ditemukan', - }, - items: [ - { value: '1', label: 'Instalasi Medis', code: 'MED' }, - { value: '2', label: 'Instalasi Keperawatan', code: 'NUR' }, - { value: '3', label: 'Instalasi Administrasi', code: 'ADM' }, - { value: '4', label: 'Instalasi Penunjang Non-Medis', code: 'SUP' }, - { value: '5', label: 'Instalasi Pendidikan & Pelatihan', code: 'EDU' }, - { value: '6', label: 'Instalasi Farmasi', code: 'PHA' }, - { value: '7', label: 'Instalasi Radiologi', code: 'RAD' }, - { value: '8', label: 'Instalasi Laboratorium', code: 'LAB' }, - { value: '9', label: 'Instalasi Keuangan', code: 'FIN' }, - { value: '10', label: 'Instalasi SDM', code: 'HR' }, - { value: '11', label: 'Instalasi Teknologi Informasi', code: 'ITS' }, - { value: '12', label: 'Instalasi Pemeliharaan & Sarana', code: 'MNT' }, - { value: '13', label: 'Instalasi Gizi / Catering', code: 'CAT' }, - { value: '14', label: 'Instalasi Keamanan', code: 'SEC' }, - { value: '15', label: 'Instalasi Gawat Darurat', code: 'EMR' }, - { value: '16', label: 'Instalasi Bedah Sentral', code: 'SUR' }, - { value: '17', label: 'Instalasi Rawat Jalan', code: 'OUT' }, - { value: '18', label: 'Instalasi Rawat Inap', code: 'INP' }, - { value: '19', label: 'Instalasi Rehabilitasi Medik', code: 'REB' }, - { value: '20', label: 'Instalasi Penelitian & Pengembangan', code: 'RSH' }, - ], -} - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama unit harus diisi', - }) - .min(1, 'Nama unit harus diisi'), - - code: z - .string({ - required_error: 'Kode unit harus diisi', - }) - .min(1, 'Kode unit harus diisi'), - parentId: z.preprocess( - (input: unknown) => { - if (typeof input === 'string') { - // Handle empty string case - if (input.trim() === '') { - return 0 - } - return Number(input) - } - - return input - }, - z - .number({ - required_error: 'Instalasi induk harus dipilih', - }) - .refine((num) => num > 0, 'Instalasi induk harus dipilih'), - ), -}) diff --git a/app/components/content/unit/list.vue b/app/components/content/unit/list.vue index 03edd231..34b647ef 100644 --- a/app/components/content/unit/list.vue +++ b/app/components/content/unit/list.vue @@ -103,9 +103,23 @@ const getCurrentUnitDetail = async (id: number | string) => { watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: - getCurrentUnitDetail(recId.value) - title.value = 'Detail Unit' - isReadonly.value = true + if (Number(recId.value) > 0) { + const id = Number(recId.value) + + recAction.value = '' + recItem.value = null + recId.value = 0 + isFormEntryDialogOpen.value = false + isReadonly.value = false + + navigateTo({ + name: 'org-src-unit-id', + params: { + id, + }, + }) + } + break case ActionEvents.showEdit: getCurrentUnitDetail(recId.value) diff --git a/app/components/pub/my-ui/data/dropdown-action-dud.vue b/app/components/pub/my-ui/data/dropdown-action-dud.vue index 71979c7c..dfcf1ada 100644 --- a/app/components/pub/my-ui/data/dropdown-action-dud.vue +++ b/app/components/pub/my-ui/data/dropdown-action-dud.vue @@ -2,9 +2,14 @@ import type { LinkItem, ListItemDto } from './types' import { ActionEvents } from './types' -const props = defineProps<{ +interface Props { rec: ListItemDto -}>() + size?: 'default' | 'sm' | 'lg' +} + +const props = withDefaults(defineProps(), { + size: 'lg', +}) const recId = inject>('rec_id')! const recAction = inject>('rec_action')! @@ -58,7 +63,7 @@ function del() { +const emit = defineEmits<{ + (e: 'click'): void +}>() + +function onClick() { + emit('click') +} + + + diff --git a/app/components/pub/my-ui/pagination/pagination-view.vue b/app/components/pub/my-ui/pagination/pagination-view.vue index 149d425e..8a2271b4 100644 --- a/app/components/pub/my-ui/pagination/pagination-view.vue +++ b/app/components/pub/my-ui/pagination/pagination-view.vue @@ -4,6 +4,10 @@ import Pagination from './pagination.vue' const props = defineProps<{ paginationMeta: PaginationMeta + conf?: { + showInfo: boolean + showControl: boolean + } }>() const emit = defineEmits<{ @@ -17,8 +21,10 @@ function handlePageChange(page: number) { diff --git a/app/components/pub/my-ui/pagination/pagination.vue b/app/components/pub/my-ui/pagination/pagination.vue index 4ba0da5f..9b1618c3 100644 --- a/app/components/pub/my-ui/pagination/pagination.vue +++ b/app/components/pub/my-ui/pagination/pagination.vue @@ -15,11 +15,13 @@ interface Props { paginationMeta: PaginationMeta onPageChange?: (page: number) => void showInfo?: boolean + showControl?: boolean } const props = withDefaults(defineProps(), { onPageChange: undefined, showInfo: true, + showControl: true, }) const emit = defineEmits<{ @@ -65,7 +67,7 @@ const formattedRecordCount = computed(() => { }) const startRecord = computed(() => { - const start = ((props.paginationMeta.page - 1) * props.paginationMeta.pageSize) + 1 + const start = (props.paginationMeta.page - 1) * props.paginationMeta.pageSize + 1 return Number(start).toLocaleString('id-ID') }) @@ -77,53 +79,95 @@ const endRecord = computed(() => { function getButtonClass(pageNumber: number) { const digits = pageNumber.toString().length - if (digits >= 4) { // 1000+ (1k+) + if (digits >= 4) { + // 1000+ (1k+) return 'h-9 px-4 min-w-12' - } else if (digits === 3) { // 100-999 + } else if (digits === 3) { + // 100-999 return 'h-9 px-3 min-w-10' - } else { // 1-99 + } else { + // 1-99 return 'w-9 h-9 p-0' } }