+
Belum Ada Data
-
-
+
+
+ Order #{{ data.length - idx }} - {{ item.issuedAt?.substring(0, 10) || item.createdAt?.substring(0, 10) }} - {{ item.status_code }}
+
+
+
+ DPJP
+
+ {{ item.doctor?.employee?.person?.name || '-' }}
+
+
+
+ PPDS
+
+ ...........
+
+
+
+
+
+
+
+
diff --git a/app/components/app/sep/entry-form.vue b/app/components/app/sep/entry-form.vue
index e48d23ec..35956ad7 100644
--- a/app/components/app/sep/entry-form.vue
+++ b/app/components/app/sep/entry-form.vue
@@ -1,91 +1,245 @@
-
-
diff --git a/app/components/app/sep/table-history-sep.vue b/app/components/app/sep/table-history-sep.vue
deleted file mode 100644
index bfe00e51..00000000
--- a/app/components/app/sep/table-history-sep.vue
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
diff --git a/app/components/app/sep/table-search-letter.vue b/app/components/app/sep/table-search-letter.vue
deleted file mode 100644
index 64e65ff6..00000000
--- a/app/components/app/sep/table-search-letter.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
-
diff --git a/app/components/app/sep/table-search-patient.vue b/app/components/app/sep/table-search-patient.vue
deleted file mode 100644
index 13a78651..00000000
--- a/app/components/app/sep/table-search-patient.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
diff --git a/app/components/app/sep/view-history.vue b/app/components/app/sep/view-history.vue
new file mode 100644
index 00000000..a6a6091c
--- /dev/null
+++ b/app/components/app/sep/view-history.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
diff --git a/app/components/app/sep/view-letter.vue b/app/components/app/sep/view-letter.vue
new file mode 100644
index 00000000..e1c0ecf2
--- /dev/null
+++ b/app/components/app/sep/view-letter.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
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 @@
+
+
+
+ {{ specialist.code || '-' }}
+ {{ specialist.name || '-' }}
+
+ {{ [specialist.unit?.code, specialist.unit?.name].filter(Boolean).join(' / ') || '-' }}
+
+
+
+
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 @@
+
+
+
+ {{ subspecialist.code || '-' }}
+ {{ subspecialist.name || '-' }}
+
+ {{ [subspecialist.specialist?.code, subspecialist.specialist?.name].filter(Boolean).join(' / ') || '-' }}
+
+
+ {{
+ [subspecialist.specialist?.unit?.code, subspecialist.specialist?.unit?.name].filter(Boolean).join(' / ') || '-'
+ }}
+
+
+ {{
+ [subspecialist.specialist?.unit?.installation?.code, subspecialist.specialist?.unit?.installation?.name]
+ .filter(Boolean)
+ .join(' / ') || '-'
+ }}
+
+
+
+
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 @@
+
+
+
+ {{ unit.code || '-' }}
+ {{ unit.name || '-' }}
+
+
+
+
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/chemotherapy/admin-list.vue b/app/components/content/chemotherapy/admin-list.vue
new file mode 100644
index 00000000..be6d5810
--- /dev/null
+++ b/app/components/content/chemotherapy/admin-list.vue
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
Administrasi Pasien Rawat Jalan Kemoterapi
+
+ Manajemen pendaftaran serta monitoring terapi pasien tindakan rawat jalan
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/content/chemotherapy/list.vue b/app/components/content/chemotherapy/list.vue
new file mode 100644
index 00000000..d4104f03
--- /dev/null
+++ b/app/components/content/chemotherapy/list.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
Daftar Kunjungan Rawat Jalan Kemoterapi
+
+ Manajemen pendaftaran serta monitoring terapi pasien tindakan rawat jalan
+
+
+
+
+
+
+
+
diff --git a/app/components/content/chemotherapy/process.vue b/app/components/content/chemotherapy/process.vue
new file mode 100644
index 00000000..7f355b4b
--- /dev/null
+++ b/app/components/content/chemotherapy/process.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/app/components/content/chemotherapy/protocol.vue b/app/components/content/chemotherapy/protocol.vue
new file mode 100644
index 00000000..82050d79
--- /dev/null
+++ b/app/components/content/chemotherapy/protocol.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
diff --git a/app/components/content/chemotherapy/verification.vue b/app/components/content/chemotherapy/verification.vue
new file mode 100644
index 00000000..3243547a
--- /dev/null
+++ b/app/components/content/chemotherapy/verification.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+
+
+
+
+
Data Pasien:
+
+
+
+
+ No. RM:
+ {{ patientData.noRm }}
+
+
+ Nama:
+ {{ patientData.nama }}
+
+
+ Jenis Pembayaran:
+ {{ patientData.jenisPembayaran }}
+
+
+ No Billing:
+ {{ patientData.noBilling }}
+
+
+
+
+
+ Tanggal Lahir / Usia:
+ {{ patientData.tanggalLahir }} / {{ patientData.usia }}
+
+
+ Jenis Kelamin:
+ {{ patientData.jenisKelamin }}
+
+
+ Diagnosis:
+ {{ patientData.diagnosis }}
+
+
+ Klinik:
+ {{ patientData.klinik }}
+
+
+
+
+
+
+
+
Verifikasi Jadwal Pasien
+
+ Pantau riwayat masuk, dokter penanggung jawab, dan status pasien secara real-time.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/content/cp-lab-order/entry.vue b/app/components/content/cp-lab-order/entry.vue
new file mode 100644
index 00000000..4d0aa002
--- /dev/null
+++ b/app/components/content/cp-lab-order/entry.vue
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/content/cp-lab-order/list.vue b/app/components/content/cp-lab-order/list.vue
new file mode 100644
index 00000000..73b9361c
--- /dev/null
+++ b/app/components/content/cp-lab-order/list.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+ handleActionRemove(recId, getMyList, toast)"
+ @cancel=""
+ />
+
diff --git a/app/components/content/cp-lab-order/main.vue b/app/components/content/cp-lab-order/main.vue
new file mode 100644
index 00000000..033d093f
--- /dev/null
+++ b/app/components/content/cp-lab-order/main.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
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 () => {
+
+
+
+
+
+
+ ID:
+ {{ record?.id }}
+
+
+ Pasien:
+ {{ record.patient.person.name }}
+
+
+ Kelas:
+ {{ record.class_code }}
+
+
+
+
diff --git a/app/components/content/encounter/process.vue b/app/components/content/encounter/process.vue
index 5e0f8062..23640af7 100644
--- a/app/components/content/encounter/process.vue
+++ b/app/components/content/encounter/process.vue
@@ -14,7 +14,9 @@ import Status from '~/components/content/encounter/status.vue'
import AssesmentFunctionList from '~/components/content/soapi/entry.vue'
import EarlyMedicalAssesmentList from '~/components/content/soapi/entry.vue'
import EarlyMedicalRehabList from '~/components/content/soapi/entry.vue'
-import PrescriptionList from '~/components/content/prescription/list.vue'
+import Prescription from '~/components/content/prescription/main.vue'
+import CpLabOrder from '~/components/content/cp-lab-order/main.vue'
+import Radiology from '~/components/content/radiology-order/main.vue'
import Consultation from '~/components/content/consultation/list.vue'
import ControlLetterList from '~/components/content/control-letter/list.vue'
@@ -61,10 +63,10 @@ const tabs: TabItem[] = [
{ value: 'education-assessment', label: 'Asesmen Kebutuhan Edukasi' },
{ value: 'consent', label: 'General Consent' },
{ value: 'patient-note', label: 'CPRJ' },
- { value: 'prescription', label: 'Order Obat', component: PrescriptionList },
+ { value: 'prescription', label: 'Order Obat', component: Prescription, props: { encounter_id: data.id } },
{ value: 'device', label: 'Order Alkes' },
- { value: 'mcu-radiology', label: 'Order Radiologi' },
- { value: 'mcu-lab-pc', label: 'Order Lab PK' },
+ { value: 'mcu-radiology', label: 'Order Radiologi', component: Radiology, props: { encounter_id: data.id } },
+ { value: 'mcu-lab-cp', label: 'Order Lab PK', component: CpLabOrder, props: { encounter_id: data.id } },
{ value: 'mcu-lab-micro', label: 'Order Lab Mikro' },
{ value: 'mcu-lab-pa', label: 'Order Lab PA' },
{ value: 'medical-action', label: 'Order Ruang Tindakan' },
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 @@
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ if (recId > 0) {
+ handleActionEdit(recId, values, getInstallationPositionList, resetForm, toast)
+ return
+ }
+ handleActionSave(values, getInstallationPositionList, resetForm, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+
+
+ handleActionRemove(recId, getInstallationPositionList, toast)"
+ @cancel=""
+ >
+
+
+
+ ID:
+ {{ record?.id }}
+
+
+ Nama:
+ {{ record.name }}
+
+
+ Kode:
+ {{ record.code }}
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ console.log(values)
+ if (recId > 0) {
+ handleActionEdit(recId, values, getInstallationPositionList, onResetState, toast)
+ return
+ }
+ handleActionSave(values, getInstallationPositionList, onResetState, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+ handleActionRemove(recId, getInstallationPositionList, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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/prescription/entry.vue b/app/components/content/prescription/entry.vue
new file mode 100644
index 00000000..4b3fa663
--- /dev/null
+++ b/app/components/content/prescription/entry.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/content/prescription/list.vue b/app/components/content/prescription/list.vue
index f8059b9d..844cb04f 100644
--- a/app/components/content/prescription/list.vue
+++ b/app/components/content/prescription/list.vue
@@ -1,37 +1,82 @@
-
+
+
-
-
-
-
-
-
-
-
+ handleActionRemove(recId, getMyList, toast)"
+ @cancel=""
+ >
+
diff --git a/app/components/content/prescription/main.vue b/app/components/content/prescription/main.vue
new file mode 100644
index 00000000..033d093f
--- /dev/null
+++ b/app/components/content/prescription/main.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/components/content/radiology-order/entry.vue b/app/components/content/radiology-order/entry.vue
new file mode 100644
index 00000000..4d0aa002
--- /dev/null
+++ b/app/components/content/radiology-order/entry.vue
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pickerDialogOpen = false" class="justify-center" />
+
+
diff --git a/app/components/content/radiology-order/list.vue b/app/components/content/radiology-order/list.vue
new file mode 100644
index 00000000..b2c8571d
--- /dev/null
+++ b/app/components/content/radiology-order/list.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+ handleActionRemove(recId, getMyList, toast)"
+ @cancel=""
+ />
+
diff --git a/app/components/content/radiology-order/main.vue b/app/components/content/radiology-order/main.vue
new file mode 100644
index 00000000..033d093f
--- /dev/null
+++ b/app/components/content/radiology-order/main.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/components/content/sep/entry.vue b/app/components/content/sep/entry.vue
index 61107232..3a916c4d 100644
--- a/app/components/content/sep/entry.vue
+++ b/app/components/content/sep/entry.vue
@@ -1,113 +1,552 @@
-
- Tambah SEP
+
+ Tambah
+ SEP
-
-
+ {
+ if (value.search && value.search.length >= 3) {
+ // Use identifier search for specific searches (NIK, RM, etc.)
+ getPatientByIdentifierSearch(value.search)
+ } else {
+ // Use regular search for general searches
+ getPatientsList({ ...value, 'page-size': 10, includes: 'person' })
+ }
+ }
+ "
@save="handleSavePatient"
/>
-
-
-
+ getLetterMappers(value.admissionType, value.search)"
+ @save="handleSaveLetter"
+ />
diff --git a/app/components/content/sep/list.vue b/app/components/content/sep/list.vue
index bb4165a0..013b076a 100644
--- a/app/components/content/sep/list.vue
+++ b/app/components/content/sep/list.vue
@@ -1,4 +1,5 @@
-
+
-
-
+
@@ -226,9 +241,7 @@ provide('table_data_loader', isLoading)
Hapus SEP
-
- Apakah anda yakin ingin menghapus SEP dengan data:
-
+
Apakah anda yakin ingin menghapus SEP dengan data:
No. SEP : {{ sepData.no_sep }}
@@ -237,11 +250,21 @@ provide('table_data_loader', isLoading)
-
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 @@
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ if (recId > 0) {
+ handleActionEdit(recId, values, getSpecialistList, resetForm, toast)
+ return
+ }
+ handleActionSave(values, getSpecialistList, resetForm, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+
+ handleActionRemove(recId, getSpecialistList, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ console.log(values)
+ if (recId > 0) {
+ handleActionEdit(recId, values, getPositionList, onResetState, toast)
+ return
+ }
+ handleActionSave(values, getPositionList, onResetState, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+ handleActionRemove(recId, getPositionList, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ if (recId > 0) {
+ handleActionEdit(recId, values, getSubSpecialistList, onResetState, toast)
+ return
+ }
+ handleActionSave(values, getSubSpecialistList, onResetState, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+
+
+ handleActionRemove(recId, getSubSpecialistList, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ console.log(values)
+ if (recId > 0) {
+ handleActionEdit(recId, values, getPositionList, onResetState, toast)
+ return
+ }
+ handleActionSave(values, getPositionList, onResetState, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+ handleActionRemove(recId, getPositionList, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ if (recId > 0) {
+ handleActionEdit(recId, values, getListUnit, resetForm, toast)
+ return
+ }
+ handleActionSave(values, getListUnit, resetForm, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+
+ handleActionRemove(recId, getListUnit, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+ {
+ onResetState()
+ isFormEntryDialogOpen = value
+ }
+ "
+ >
+ , resetForm: () => void) => {
+ console.log(values)
+ if (recId > 0) {
+ handleActionEdit(recId, values, getPositionList, onResetState, toast)
+ return
+ }
+ handleActionSave(values, getPositionList, onResetState, toast)
+ }
+ "
+ @cancel="handleCancelForm"
+ />
+
+ handleActionRemove(recId, getPositionList, toast)"
+ @cancel=""
+ >
+
+
+
+ {{ field.label }}:
+ {{ record[field.key] }}
+
+
+
+
+
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/layout/AppSidebar.vue b/app/components/layout/AppSidebar.vue
index 4f51e42c..a14b2137 100644
--- a/app/components/layout/AppSidebar.vue
+++ b/app/components/layout/AppSidebar.vue
@@ -1,5 +1,12 @@
diff --git a/app/components/layout/SidebarNavFooter.vue b/app/components/layout/SidebarNavFooter.vue
index 68d8d9a2..2c1e942c 100644
--- a/app/components/layout/SidebarNavFooter.vue
+++ b/app/components/layout/SidebarNavFooter.vue
@@ -10,8 +10,8 @@ import { useSidebar } from '~/components/pub/ui/sidebar'
// }>()
const { isMobile } = useSidebar()
-const { logout } = useUserStore()
-const userStore = useUserStore().user
+const { user, logout, setActiveRole, getActiveRole } = useUserStore()
+// const userStore = useUserStore().user
function handleLogout() {
navigateTo('/auth/login')
@@ -32,19 +32,19 @@ const showModalTheme = ref(false)
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
>
-
+
{{
- userStore?.user_name
+ user.user_name
?.split(' ')
- .map((n) => n[0])
+ .map((n: string) => n[0])
.join('') || ''
}}
- {{ userStore?.user_name || '' }}
- {{ userStore?.user_email || '' }}
+ {{ user.user_name || '' }}
+ {{ user.user_email || '' }}
@@ -52,35 +52,40 @@ const showModalTheme = ref(false)
diff --git a/app/components/pub/my-ui/combobox/combobox.vue b/app/components/pub/my-ui/combobox/combobox.vue
index 23505393..713edd57 100644
--- a/app/components/pub/my-ui/combobox/combobox.vue
+++ b/app/components/pub/my-ui/combobox/combobox.vue
@@ -16,22 +16,23 @@ const props = defineProps<{
const emit = defineEmits<{
'update:modelValue': [value: string]
+ 'update:searchText': [value: string]
}>()
const open = ref(false)
-
+const searchText = ref('')
+const debouncedSearchText = refDebounced(searchText, 500) // 500ms debounce
const selectedItem = computed(() => props.items.find((item) => item.value === props.modelValue))
const displayText = computed(() => {
- console.log(selectedItem)
if (selectedItem.value?.label) {
return selectedItem.value.label
}
return props.placeholder || 'Pilih item'
})
-watch(props, () => {
- console.log(props.modelValue)
+watch(debouncedSearchText, (newValue) => {
+ emit('update:searchText', newValue)
})
const searchableItems = computed(() => {
@@ -106,6 +107,11 @@ function onSelect(item: Item) {
class="h-9 border-0 border-b border-gray-200 bg-white text-black focus:ring-0 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
:placeholder="searchPlaceholder || 'Cari...'"
:aria-label="`Cari ${displayText}`"
+ @input="
+ (evt: any) => {
+ searchText = evt?.target?.value || ''
+ }
+ "
/>
{{ emptyMessage || 'Item tidak ditemukan.' }}
diff --git a/app/components/pub/my-ui/combobox/index.ts b/app/components/pub/my-ui/combobox/index.ts
index 82a3b3cd..e4864f7f 100644
--- a/app/components/pub/my-ui/combobox/index.ts
+++ b/app/components/pub/my-ui/combobox/index.ts
@@ -20,4 +20,17 @@ export function recStrToItem(input: Record): Item[] {
return items
}
+export function objectsToItems(input: object[], key = 'id', label = 'name'): Item[] {
+ const items: Item[] = []
+ for (const item of input) {
+ if (item.hasOwnProperty(key) && item.hasOwnProperty(label)) {
+ items.push({
+ value: item[key as keyof typeof item], // the hasOwnProperty check should be enough
+ label: item[label as keyof typeof item], // the hasOwnProperty check should be enough
+ })
+ }
+ }
+ return items
+}
+
export { default as Combobox } from './combobox.vue'
diff --git a/app/components/pub/my-ui/comp-tab/type.ts b/app/components/pub/my-ui/comp-tab/type.ts
index e6faacce..ba21d0b7 100644
--- a/app/components/pub/my-ui/comp-tab/type.ts
+++ b/app/components/pub/my-ui/comp-tab/type.ts
@@ -2,5 +2,6 @@ export interface TabItem {
value: string
label: string
component?: any
+ groups?: string[]
props?: Record
}
diff --git a/app/components/pub/my-ui/data-table/data-table.vue b/app/components/pub/my-ui/data-table/data-table.vue
index f3e2ef43..431df276 100644
--- a/app/components/pub/my-ui/data-table/data-table.vue
+++ b/app/components/pub/my-ui/data-table/data-table.vue
@@ -22,7 +22,7 @@ const selected = ref([])
function toggleSelection(row: any, event?: Event) {
if (event) event.stopPropagation() // cegah event bubble ke TableRow
- const isMultiple = props.selectMode === 'multi' || props.selectMode === 'multiple'
+ const isMultiple = props.selectMode === 'multiple' // props.selectMode === 'multi' ||
// gunakan pembanding berdasarkan id atau stringify data
const findIndex = selected.value.findIndex((r) => JSON.stringify(r) === JSON.stringify(row))
@@ -128,7 +128,7 @@ function handleActionCellClick(event: Event, _cellRef: string) {
'bg-green-50':
props.selectMode === 'single' && selected.some((r) => JSON.stringify(r) === JSON.stringify(row)),
'bg-blue-50':
- (props.selectMode === 'multi' || props.selectMode === 'multiple') &&
+ (props.selectMode === 'multiple') && // props.selectMode === 'multi' ||
selected.some((r) => JSON.stringify(r) === JSON.stringify(row)),
}"
@click="toggleSelection(row)"
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() {
]