merge dev
This commit is contained in:
@@ -1,114 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormErrors } from '~/types/error'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import FieldGroup from '~/components/pub/my-ui/form/field-group.vue'
|
||||
import Field from '~/components/pub/my-ui/form/field.vue'
|
||||
import Label from '~/components/pub/my-ui/form/label.vue'
|
||||
import Select from '~/components/pub/my-ui/form/select.vue'
|
||||
import { Form } from '~/components/pub/ui/form'
|
||||
|
||||
interface InstallationFormData {
|
||||
name: string
|
||||
code: string
|
||||
encounterClassCode: string
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
installation: {
|
||||
msg: {
|
||||
placeholder: string
|
||||
}
|
||||
items: {
|
||||
value: string
|
||||
label: string
|
||||
code: string
|
||||
}[]
|
||||
}
|
||||
schema: any
|
||||
initialValues?: Partial<InstallationFormData>
|
||||
errors?: FormErrors
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
submit: [values: InstallationFormData, resetForm: () => void]
|
||||
cancel: [resetForm: () => void]
|
||||
}>()
|
||||
|
||||
const formSchema = toTypedSchema(props.schema)
|
||||
|
||||
// Form submission handler
|
||||
function onSubmitForm(values: any, { resetForm }: { resetForm: () => void }) {
|
||||
const formData: InstallationFormData = {
|
||||
name: values.name || '',
|
||||
code: values.code || '',
|
||||
encounterClassCode: values.encounterClassCode || '',
|
||||
}
|
||||
emit('submit', formData, resetForm)
|
||||
}
|
||||
|
||||
// Form cancel handler
|
||||
function onCancelForm({ resetForm }: { resetForm: () => void }) {
|
||||
emit('cancel', resetForm)
|
||||
}
|
||||
|
||||
const items = ref([
|
||||
{ label: 'Rujukan Internal', value: 'ri' },
|
||||
{ label: 'SEP Rujukan', value: 'sr' },
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Form
|
||||
v-slot="{ handleSubmit, resetForm }"
|
||||
as=""
|
||||
keep-values
|
||||
:validation-schema="formSchema"
|
||||
:initial-values="initialValues"
|
||||
>
|
||||
<form id="entry-form" @submit="handleSubmit($event, (values) => onSubmitForm(values, { resetForm }))">
|
||||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||||
<div class="flex flex-col justify-between">
|
||||
<FieldGroup>
|
||||
<Label label-for="parentId">Cara Bayar</Label>
|
||||
<Field id="encounterClassCode" :errors="errors">
|
||||
<FormField v-slot="{ componentField }" name="encounterClassCode">
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Select v-bind="componentField" :items="items" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label label-for="parentId">Poliklinik</Label>
|
||||
<Field id="encounterClassCode" :errors="errors">
|
||||
<FormField v-slot="{ componentField }" name="encounterClassCode">
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Select v-bind="componentField" :items="items" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label label-for="parentId">Kunjungan</Label>
|
||||
<Field id="encounterClassCode" :errors="errors">
|
||||
<FormField v-slot="{ componentField }" name="encounterClassCode">
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Select v-bind="componentField" :items="items" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</template>
|
||||
@@ -1,41 +1,46 @@
|
||||
<script setup lang="ts">
|
||||
// Components
|
||||
import { Calendar, Hospital, UserCheck, UsersRound } from 'lucide-vue-next'
|
||||
import SummaryCard from '~/components/pub/my-ui/summary-card/summary-card.vue'
|
||||
import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
|
||||
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
|
||||
import Filter from '~/components/pub/my-ui/nav-header/filter.vue'
|
||||
import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue'
|
||||
import { useSidebar } from '~/components/pub/ui/sidebar/utils'
|
||||
|
||||
// Libs
|
||||
import { getPositionAs } from '~/lib/roles'
|
||||
|
||||
// Types
|
||||
// Pub components
|
||||
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
|
||||
import type { Summary } from '~/components/pub/my-ui/summary-card/type'
|
||||
import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/data/types'
|
||||
import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/nav-header/index'
|
||||
import { toast } from '~/components/pub/ui/toast'
|
||||
import { ActionEvents } from '~/components/pub/my-ui/data/types'
|
||||
import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
|
||||
// import Header from '~/components/pub/my-ui/nav-header/prep.vue'
|
||||
import * as CH from '~/components/pub/my-ui/content-header'
|
||||
import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue'
|
||||
import { useSidebar } from '~/components/pub/ui/sidebar/utils'
|
||||
|
||||
// Services
|
||||
import { getList as getEncounterList, remove as removeEncounter, cancel as cancelEncounter } from '~/services/encounter.service'
|
||||
|
||||
// UI
|
||||
import { toast } from '~/components/pub/ui/toast'
|
||||
// Apps
|
||||
import Content from '~/components/app/encounter/list.vue'
|
||||
import FilterNav from '~/components/app/encounter/filter-nav.vue'
|
||||
import FilterForm from '~/components/app/encounter/filter-form.vue'
|
||||
|
||||
// Props
|
||||
const props = defineProps<{
|
||||
classCode?: 'ambulatory' | 'emergency' | 'inpatient'
|
||||
subClassCode?: 'reg' | 'rehab' | 'chemo' | 'emg' | 'eon' | 'op' | 'icu' | 'hcu' | 'vk'
|
||||
canCreate?: boolean
|
||||
canUpdate?: boolean
|
||||
canDelete?: boolean
|
||||
}>()
|
||||
|
||||
//
|
||||
const { setOpen } = useSidebar()
|
||||
setOpen(true)
|
||||
|
||||
const { getActiveRole } = useUserStore()
|
||||
const activeRole = getActiveRole()
|
||||
const activePosition = ref(getPositionAs(activeRole))
|
||||
const props = defineProps<{
|
||||
classCode?: 'ambulatory' | 'emergency' | 'inpatient' | 'outpatient'
|
||||
subClassCode?: 'reg' | 'rehab' | 'chemo' | 'emg' | 'eon' | 'op' | 'icu' | 'hcu' | 'vk'
|
||||
type: string
|
||||
}>()
|
||||
|
||||
|
||||
// Main data
|
||||
const data = ref([])
|
||||
const isLoading = reactive<DataTableLoader>({
|
||||
summary: false,
|
||||
@@ -48,33 +53,49 @@ const isFormEntryDialogOpen = ref(false)
|
||||
const isRecordConfirmationOpen = ref(false)
|
||||
const isRecordCancelOpen = ref(false)
|
||||
|
||||
const hreaderPrep: HeaderPrep = {
|
||||
// Headers
|
||||
const hreaderPrep: CH.Config = {
|
||||
title: 'Kunjungan',
|
||||
icon: 'i-lucide-users',
|
||||
addNav: {
|
||||
label: 'Tambah',
|
||||
onClick: () => {
|
||||
if (props.classCode === 'ambulatory' && props.subClassCode === 'rehab') {
|
||||
navigateTo('/rehab/encounter/add')
|
||||
}
|
||||
if (props.classCode === 'ambulatory' && props.subClassCode === 'reg') {
|
||||
navigateTo('/outpatient/encounter/add')
|
||||
}
|
||||
if (props.classCode === 'emergency') {
|
||||
navigateTo('/emergency/encounter/add')
|
||||
}
|
||||
if (props.classCode === 'inpatient') {
|
||||
navigateTo('/inpatient/encounter/add')
|
||||
}
|
||||
navigateTo(`/${props.classCode}/encounter/add`)
|
||||
},
|
||||
},
|
||||
}
|
||||
if (!props.canCreate) {
|
||||
delete hreaderPrep.addNav
|
||||
}
|
||||
|
||||
const filter = ref<{
|
||||
installation: {
|
||||
msg: {
|
||||
placeholder: string
|
||||
}
|
||||
items: {
|
||||
value: string
|
||||
label: string
|
||||
code: string
|
||||
}[]
|
||||
}
|
||||
schema: any
|
||||
initialValues?: Partial<any>
|
||||
errors?: any
|
||||
}>({
|
||||
installation: {
|
||||
msg: {
|
||||
placeholder: 'Pilih',
|
||||
},
|
||||
items: [],
|
||||
},
|
||||
schema: {},
|
||||
})
|
||||
|
||||
const refSearchNav: RefSearchNav = {
|
||||
onClick: () => {
|
||||
// open filter modal
|
||||
isFormEntryDialogOpen.value = true
|
||||
console.log(' 1open filter modal')
|
||||
},
|
||||
onInput: (_val: string) => {
|
||||
// filter patient list
|
||||
@@ -84,27 +105,31 @@ const refSearchNav: RefSearchNav = {
|
||||
},
|
||||
}
|
||||
|
||||
// Loading state management
|
||||
// Reactivities
|
||||
provide('rec_id', recId)
|
||||
provide('rec_action', recAction)
|
||||
provide('rec_item', recItem)
|
||||
provide('table_data_loader', isLoading)
|
||||
|
||||
/**
|
||||
* Get base path for encounter routes based on classCode and subClassCode
|
||||
*/
|
||||
function getBasePath(): string {
|
||||
if (props.classCode === 'ambulatory' && props.subClassCode === 'rehab') {
|
||||
return '/rehab/encounter'
|
||||
watch(() => recAction.value, () => {
|
||||
const basePath = `/${props.classCode}/encounter`
|
||||
if (recAction.value === ActionEvents.showDetail) {
|
||||
navigateTo(`${basePath}/${recId.value}`)
|
||||
} else if (recAction.value === ActionEvents.showEdit) {
|
||||
navigateTo(`${basePath}/${recId.value}/edit`)
|
||||
} else if (recAction.value === ActionEvents.showProcess) {
|
||||
navigateTo(`${basePath}/${recId.value}/process`)
|
||||
} else if (recAction.value === ActionEvents.showConfirmDelete) {
|
||||
isRecordConfirmationOpen.value = true
|
||||
}
|
||||
if (props.classCode === 'ambulatory' && props.subClassCode === 'reg') {
|
||||
return '/outpatient/encounter'
|
||||
}
|
||||
if (props.classCode === 'emergency') {
|
||||
return '/emergency/encounter'
|
||||
}
|
||||
if (props.classCode === 'inpatient') {
|
||||
return '/inpatient/encounter'
|
||||
}
|
||||
return '/encounter' // fallback
|
||||
}
|
||||
recAction.value = '' // reset
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getPatientList()
|
||||
})
|
||||
|
||||
// Functions
|
||||
async function getPatientList() {
|
||||
isLoading.isTableLoading = true
|
||||
try {
|
||||
@@ -273,18 +298,11 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Header
|
||||
:prep="{ ...hreaderPrep }"
|
||||
:ref-search-nav="refSearchNav"
|
||||
/>
|
||||
<Separator class="my-4 xl:my-5" />
|
||||
<CH.ContentHeader v-bind="hreaderPrep">
|
||||
<FilterNav />
|
||||
</CH.ContentHeader>
|
||||
|
||||
<Filter
|
||||
:prep="hreaderPrep"
|
||||
:ref-search-nav="refSearchNav"
|
||||
/>
|
||||
|
||||
<AppEncounterList :data="data" />
|
||||
<Content :data="data" />
|
||||
|
||||
<Dialog
|
||||
v-model:open="isFormEntryDialogOpen"
|
||||
@@ -292,13 +310,7 @@ onMounted(() => {
|
||||
size="lg"
|
||||
prevent-outside
|
||||
>
|
||||
<AppEncounterFilter
|
||||
:installation="{
|
||||
msg: { placeholder: 'Pilih' },
|
||||
items: [],
|
||||
}"
|
||||
:schema="{}"
|
||||
/>
|
||||
<FilterForm v-bind="filter" />
|
||||
</Dialog>
|
||||
|
||||
<!-- Record Confirmation Modal -->
|
||||
@@ -326,6 +338,7 @@ onMounted(() => {
|
||||
</RecordConfirmation>
|
||||
|
||||
<RecordConfirmation
|
||||
v-if="canDelete"
|
||||
v-model:open="isRecordConfirmationOpen"
|
||||
action="delete"
|
||||
:record="recItem"
|
||||
@@ -349,4 +362,11 @@ onMounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
</RecordConfirmation>
|
||||
<Dialog
|
||||
title="Hapus data"
|
||||
size="md"
|
||||
v-model:open="isRecordConfirmationOpen"
|
||||
>
|
||||
Hak akses tidak memenuhi kriteria untuk proses ini.
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
@@ -48,9 +48,18 @@ async function setMenu() {
|
||||
const activeRoleParts = activeRole ? activeRole.split('|') : []
|
||||
const role = activeRoleParts[0]+(activeRoleParts.length > 1 ? `-${activeRoleParts[1]}` : '')
|
||||
try {
|
||||
|
||||
const res = await fetch(`/side-menu-items/${role.toLowerCase()}.json`)
|
||||
const rawMenu = await res.text()
|
||||
navMenu.value = JSON.parse(rawMenu)
|
||||
const parsedMenu = JSON.parse(rawMenu)
|
||||
|
||||
const { user } = useUserStore()
|
||||
if(user.unit_code == 'rehab') {
|
||||
parsedMenu[0].heading = 'Rehab Medik'
|
||||
parsedMenu[0].items = parsedMenu[0].items.filter((item: any) => item.title != 'IGD')
|
||||
}
|
||||
|
||||
navMenu.value = parsedMenu
|
||||
} catch (e) {
|
||||
const res = await fetch(`/side-menu-items/blank.json`)
|
||||
const rawMenu = await res.text()
|
||||
|
||||
@@ -37,6 +37,10 @@ function btnClick() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<!-- For components as slots -->
|
||||
<slot />
|
||||
|
||||
<!-- For components passed by props -->
|
||||
<div v-if="prep.components">
|
||||
<template v-for="cwp in prep.components">
|
||||
<component
|
||||
|
||||
@@ -32,7 +32,7 @@ function btnClick() {
|
||||
/>
|
||||
</div>
|
||||
<div v-if="prep.addNav" class="m-2 flex items-center">
|
||||
<Button size="md" class="rounded-md border border-gray-300 px-4 py-2 text-white sm:text-sm" @click="btnClick">
|
||||
<Button size="default" class="rounded-md border border-gray-300 px-4 py-2 text-white sm:text-sm" @click="btnClick">
|
||||
<Icon name="i-lucide-plus" class="mr-2 h-4 w-4 align-middle" />
|
||||
{{ prep.addNav.label }}
|
||||
</Button>
|
||||
|
||||
+23
-15
@@ -1,4 +1,5 @@
|
||||
import type { Permission, RoleAccess } from '~/models/role'
|
||||
import type { Permission, RoleAccesses } from '~/models/role'
|
||||
import { systemCode } from '~/const/common/role'
|
||||
|
||||
export interface PageOperationPermission {
|
||||
canRead: boolean
|
||||
@@ -7,7 +8,6 @@ export interface PageOperationPermission {
|
||||
canDelete: boolean
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if user has access to a page
|
||||
*/
|
||||
@@ -15,19 +15,27 @@ export function useRBAC() {
|
||||
// NOTE: this roles was dummy for testing only, it should taken from the user store
|
||||
const authStore = useUserStore()
|
||||
|
||||
const checkRole = (roleAccess: RoleAccess, _userRoles?: string[]): boolean => {
|
||||
const roles = authStore.userRole
|
||||
return roles.some((role: string) => role === 'system' || (role in roleAccess)) // system by-passes this check
|
||||
const checkRole = (roleAccesses: RoleAccesses, _userRoles?: string[]): boolean => {
|
||||
const activeRole = authStore.getActiveRole() || ''
|
||||
if (activeRole === systemCode) {
|
||||
return true
|
||||
}
|
||||
return (activeRole in roleAccesses);
|
||||
}
|
||||
|
||||
const checkPermission = (roleAccess: RoleAccess, permission: Permission, _userRoles?: string[]): boolean => {
|
||||
const roles = authStore.userRole
|
||||
return roles.some((role: string) => role === 'system' || roleAccess[role]?.includes(permission)) // system by-passes this check
|
||||
const checkPermission = (roleAccesses: RoleAccesses, permission: Permission, _userRoles?: string[]): boolean => {
|
||||
const activeRole = authStore.getActiveRole() || ''
|
||||
if (activeRole === systemCode) {
|
||||
return true
|
||||
}
|
||||
if (activeRole in roleAccesses && roleAccesses[activeRole]) {
|
||||
return roleAccesses[activeRole].includes(permission)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const getUserPermissions = (roleAccess: RoleAccess, _userRoles?: string[]): Permission[] => {
|
||||
const getUserPermissions = (roleAccess: RoleAccesses, _userRoles?: string[]): Permission[] => {
|
||||
const roles = authStore.userRole
|
||||
// const roles = ['admisi']
|
||||
const permissions = new Set<Permission>()
|
||||
|
||||
roles.forEach((role: string) => {
|
||||
@@ -39,12 +47,12 @@ export function useRBAC() {
|
||||
return Array.from(permissions)
|
||||
}
|
||||
|
||||
const hasCreateAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'C')
|
||||
const hasReadAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'R')
|
||||
const hasUpdateAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'U')
|
||||
const hasDeleteAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'D')
|
||||
const hasCreateAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'C')
|
||||
const hasReadAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'R')
|
||||
const hasUpdateAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'U')
|
||||
const hasDeleteAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'D')
|
||||
|
||||
const getPagePermissions = (roleAccess: RoleAccess): PageOperationPermission => ({
|
||||
const getPagePermissions = (roleAccess: RoleAccesses): PageOperationPermission => ({
|
||||
canRead : hasReadAccess(roleAccess),
|
||||
canCreate: hasCreateAccess(roleAccess),
|
||||
canUpdate: hasUpdateAccess(roleAccess),
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import type { Permission } from "~/models/role";
|
||||
|
||||
// Should we define the keys first?
|
||||
// export type Keys = 'key1' | 'key2' | 'key3' | etc
|
||||
|
||||
export const permissions: Record<string, Record<string, Permission[]>> = {
|
||||
'/outpatient/registration-queue': {
|
||||
'emp|reg': ['R', 'U', 'D'],
|
||||
},
|
||||
'/outpatient/encounter-queue': {
|
||||
'emp|nur': ['R', 'U', 'D'],
|
||||
},
|
||||
'/outpatient/encounter': {
|
||||
'emp|reg': ['C', 'R', 'U', 'D'],
|
||||
'emp|doc': ['R'],
|
||||
'emp|nur': ['R'],
|
||||
'emp|thr': ['R'],
|
||||
'emp|miw': ['R'],
|
||||
'emp|nut': ['R'],
|
||||
'emp|pha': ['R'],
|
||||
'emp|lab': ['R'],
|
||||
'emp|rad': ['R'],
|
||||
},
|
||||
'/outpatient/encounter/add': {
|
||||
'emp|reg': ['C', 'R', 'U', 'D'],
|
||||
},
|
||||
'/outpatient/encounter/[id]/detail': {
|
||||
'emp|reg': ['C', 'R', 'U', 'D'],
|
||||
'emp|doc': ['R'],
|
||||
'emp|nur': ['R'],
|
||||
'emp|thr': ['R'],
|
||||
'emp|miw': ['R'],
|
||||
'emp|nut': ['R'],
|
||||
'emp|pha': ['R'],
|
||||
'emp|lab': ['R'],
|
||||
'emp|rad': ['R'],
|
||||
},
|
||||
'/outpatient/encounter/[id]/edit': {
|
||||
'emp|reg': ['C', 'R', 'U', 'D'],
|
||||
},
|
||||
'/outpatient/encounter/[id]/process': {
|
||||
'emp|doc': ['R', 'U'],
|
||||
'emp|nur': ['R', 'U'],
|
||||
'emp|thr': ['R', 'U'],
|
||||
'emp|miw': ['R', 'U'],
|
||||
'emp|nut': ['R', 'U'],
|
||||
'emp|pha': ['R', 'U'],
|
||||
'emp|lab': ['R', 'U'],
|
||||
'emp|rad': ['R', 'U'],
|
||||
},
|
||||
'/outpatient/consulation': {
|
||||
'emp|doc': ['R'],
|
||||
},
|
||||
'/outpatient/consulation/[id]/process': {
|
||||
'emp|doc': ['R', 'U'],
|
||||
},
|
||||
}
|
||||
+3
-3
@@ -14,9 +14,9 @@ export interface AuthState {
|
||||
|
||||
export type Permission = 'C' | 'R' | 'U' | 'D'
|
||||
|
||||
export interface RoleAccess {
|
||||
export interface RoleAccesses {
|
||||
[role: string]: Permission[]
|
||||
}
|
||||
|
||||
export type PagePath = keyof typeof PAGE_PERMISSIONS
|
||||
export type PagePermission = (typeof PAGE_PERMISSIONS)[PagePath]
|
||||
// export type PagePath = keyof typeof PAGE_PERMISSIONS
|
||||
// export type PagePermission = (typeof PAGE_PERMISSIONS)[PagePath]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import { permissions } from '~/const/page-permission/ambulatory'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
|
||||
import Content from '~/components/content/encounter/entry.vue'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import { permissions } from '~/const/page-permission/emergency'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
|
||||
import Content from '~/components/content/encounter/list.vue'
|
||||
@@ -13,7 +13,8 @@ definePageMeta({
|
||||
})
|
||||
|
||||
// Preps role checking
|
||||
const roleAccess: Record<string, Permission[]> = permissions['/outpatient/encounter'] || {}
|
||||
const route = useRoute()
|
||||
const roleAccess: Record<string, Permission[]> = permissions[route.path] || {}
|
||||
const { checkRole, hasReadAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
@@ -26,18 +27,12 @@ if (!hasAccess) {
|
||||
const canRead = hasReadAccess(roleAccess)
|
||||
|
||||
// Page needs
|
||||
const route = useRoute()
|
||||
useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
const { user, getActiveRole } = useUserStore()
|
||||
// const activeRole = getActiveRole()
|
||||
// const activeRoleParts = activeRole ? activeRole.split('|') : ['', '']
|
||||
// const activeRolePos = activeRoleParts[0] // reaching this page means it is already set
|
||||
// const activeRoleType = activeRoleParts[1] == 'rehab' ? activeRoleParts[1] : ''
|
||||
const { user } = useUserStore()
|
||||
const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -45,7 +40,7 @@ const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
||||
<div v-if="canRead">
|
||||
<Content
|
||||
class-code="emergency"
|
||||
sub-class-code="reg"
|
||||
:sub-class-code="subClassCode"
|
||||
type="encounter"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import { permissions } from '~/const/page-permission/ambulatory'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
|
||||
import Content from '~/components/content/encounter/entry.vue'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import { permissions } from '~/const/page-permission/inpatient'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
|
||||
import Content from '~/components/content/encounter/list.vue'
|
||||
@@ -13,7 +13,7 @@ definePageMeta({
|
||||
})
|
||||
|
||||
// Preps role checking
|
||||
const roleAccess: Record<string, Permission[]> = permissions['/outpatient/encounter'] || {}
|
||||
const roleAccess: Record<string, Permission[]> = permissions['/inpatient/encounter'] || {}
|
||||
const { checkRole, hasReadAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
@@ -31,11 +31,7 @@ useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
const { user, getActiveRole } = useUserStore()
|
||||
// const activeRole = getActiveRole()
|
||||
// const activeRoleParts = activeRole ? activeRole.split('|') : ['', '']
|
||||
// const activeRolePos = activeRoleParts[0] // reaching this page means it is already set
|
||||
// const activeRoleType = activeRoleParts[1] == 'rehab' ? activeRoleParts[1] : ''
|
||||
const { user } = useUserStore()
|
||||
const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-10 text-center">
|
||||
<div class="mb-5 text-base font-semibold">Hello world!!</div>
|
||||
<div>You are accessing "{{ route.fullPath }}"</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,10 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-10 text-center">
|
||||
<div class="mb-5 text-base font-semibold">Hello world!!</div>
|
||||
<div>You are accessing "{{ route.fullPath }}"</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,56 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { PagePermission } from '~/models/role'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
import { PAGE_PERMISSIONS } from '~/lib/page-permission'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||
title: 'Edit Kunjungan',
|
||||
contentFrame: 'cf-full-width',
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
useHead({
|
||||
title: () => `${route.meta.title}`, // backtick to avoid the ts-plugin(2322) warning
|
||||
})
|
||||
|
||||
const roleAccess: PagePermission = PAGE_PERMISSIONS['/outpatient/encounter']
|
||||
|
||||
const { checkRole, hasUpdateAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
const hasAccess = checkRole(roleAccess)
|
||||
if (!hasAccess) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: 'Access denied',
|
||||
})
|
||||
}
|
||||
|
||||
// Define permission-based computed properties
|
||||
const canUpdate = hasUpdateAccess(roleAccess)
|
||||
|
||||
// Get encounter ID from route params
|
||||
const encounterId = computed(() => {
|
||||
const id = route.params.id
|
||||
return typeof id === 'string' ? parseInt(id) : 0
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="canUpdate">
|
||||
<ContentEncounterEntry
|
||||
:id="encounterId"
|
||||
class-code="ambulatory"
|
||||
sub-class-code="reg"
|
||||
form-type="Edit"
|
||||
/>
|
||||
</div>
|
||||
<Error
|
||||
v-else
|
||||
:status-code="403"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { PagePermission } from '~/models/role'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
import { PAGE_PERMISSIONS } from '~/lib/page-permission'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||
title: 'Detail Surat Kontrol',
|
||||
contentFrame: 'cf-container-md',
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
const roleAccess: PagePermission = PAGE_PERMISSIONS['/patient']
|
||||
|
||||
const { checkRole, hasReadAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
const hasAccess = checkRole(roleAccess)
|
||||
// if (!hasAccess) {
|
||||
// navigateTo('/403')
|
||||
// }
|
||||
|
||||
// Define permission-based computed properties
|
||||
// const canRead = hasReadAccess(roleAccess)
|
||||
const canRead = true
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="canRead">
|
||||
<ContentOutpatientEncounterDetail :patient-id="Number(route.params.id)" />
|
||||
</div>
|
||||
<Error v-else :status-code="403" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,39 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
import Content from '~/components/content/encounter/process-next.vue'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['emp|doc', 'emp|nur', 'emp|reg', 'emp|pha', 'emp|pay', 'emp|mng'],
|
||||
title: 'Tambah Kunjungan',
|
||||
contentFrame: 'cf-full-width',
|
||||
})
|
||||
|
||||
// Preps role checking
|
||||
const roleAccess: Record<string, Permission[]> = permissions['/outpatient/encounter'] || {}
|
||||
const { checkRole, hasReadAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
const hasAccess = checkRole(roleAccess)
|
||||
if (!hasAccess) {
|
||||
navigateTo('/403')
|
||||
}
|
||||
|
||||
// Define permission-based computed properties
|
||||
const canRead = hasReadAccess(roleAccess)
|
||||
|
||||
// Page needs
|
||||
const route = useRoute()
|
||||
useHead({
|
||||
title: () => `${route.meta.title}`,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="canRead">
|
||||
<Content class-code="ambulatory" sub-class-code="reg" />
|
||||
</div>
|
||||
<Error v-else :status-code="403" />
|
||||
</template>
|
||||
@@ -1,51 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
|
||||
import Content from '~/components/content/encounter/entry.vue'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['emp|reg'],
|
||||
title: 'Tambah Kunjungan',
|
||||
contentFrame: 'cf-full-width',
|
||||
})
|
||||
|
||||
// Preps role checking
|
||||
const roleAccess: Record<string, Permission[]> = permissions['/outpatient/encounter'] || {}
|
||||
const { checkRole, hasReadAccess, hasCreateAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
const hasAccess = checkRole(roleAccess)
|
||||
if (!hasAccess) {
|
||||
navigateTo('/403')
|
||||
}
|
||||
|
||||
// Define permission-based computed properties
|
||||
const canRead = hasReadAccess(roleAccess)
|
||||
|
||||
// Page needs
|
||||
const route = useRoute()
|
||||
useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
// Define permission-based computed properties
|
||||
const canCreate = hasCreateAccess(roleAccess)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="canCreate">
|
||||
<Content
|
||||
:id="0"
|
||||
class-code="ambulatory"
|
||||
sub-class-code="reg"
|
||||
form-type="Tambah"
|
||||
/>
|
||||
</div>
|
||||
<Error
|
||||
v-else
|
||||
:status-code="403"
|
||||
/>
|
||||
</template>
|
||||
@@ -1,57 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { Permission } from '~/models/role'
|
||||
import { permissions } from '~/const/page-permission/outpatient'
|
||||
import Error from '~/components/pub/my-ui/error/error.vue'
|
||||
|
||||
import Content from '~/components/content/encounter/list.vue'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['emp|reg', 'emp|nur', 'emp|doc', 'emp|miw', 'emp|thr', 'emp|nut', 'emp|pha', 'emp|lab'],
|
||||
title: 'Daftar Kunjungan',
|
||||
contentFrame: 'cf-full-width',
|
||||
})
|
||||
|
||||
// Preps role checking
|
||||
const roleAccess: Record<string, Permission[]> = permissions['/outpatient/encounter'] || {}
|
||||
const { checkRole, hasReadAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
const hasAccess = checkRole(roleAccess)
|
||||
if (!hasAccess) {
|
||||
navigateTo('/403')
|
||||
}
|
||||
|
||||
// Define permission-based computed properties
|
||||
const canRead = hasReadAccess(roleAccess)
|
||||
|
||||
// Page needs
|
||||
const route = useRoute()
|
||||
useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
const { user, getActiveRole } = useUserStore()
|
||||
// const activeRole = getActiveRole()
|
||||
// const activeRoleParts = activeRole ? activeRole.split('|') : ['', '']
|
||||
// const activeRolePos = activeRoleParts[0] // reaching this page means it is already set
|
||||
// const activeRoleType = activeRoleParts[1] == 'rehab' ? activeRoleParts[1] : ''
|
||||
const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="canRead">
|
||||
<Content
|
||||
class-code="ambulatory"
|
||||
:sub-class-code="subClassCode"
|
||||
type="encounter"
|
||||
/>
|
||||
</div>
|
||||
<Error
|
||||
v-else
|
||||
:status-code="403"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,10 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-10 text-center">
|
||||
<div class="mb-5 text-base font-semibold">Hello world!!</div>
|
||||
<div>You are accessing "{{ route.fullPath }}"</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,5 +0,0 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<FlowRehabRegistrationHome />
|
||||
</template>
|
||||
@@ -1,40 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { PagePermission } from '~/models/role'
|
||||
import { PAGE_PERMISSIONS } from '~/lib/page-permission'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||
title: 'Tambah SEP Prosedur',
|
||||
contentFrame: 'cf-full-width',
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
const roleAccess: PagePermission = PAGE_PERMISSIONS['/doctor']
|
||||
|
||||
const { checkRole, hasCreateAccess } = useRBAC()
|
||||
|
||||
// Check if user has access to this page
|
||||
const hasAccess = checkRole(roleAccess)
|
||||
if (!hasAccess) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: 'Access denied',
|
||||
})
|
||||
}
|
||||
|
||||
// Define permission-based computed properties
|
||||
const canCreate = hasCreateAccess(roleAccess)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="canCreate">
|
||||
<ContentDoctorAdd />
|
||||
</div>
|
||||
<PubMyUiError v-else :status-code="403" />
|
||||
</template>
|
||||
@@ -5,7 +5,7 @@ import { PAGE_PERMISSIONS } from '~/lib/page-permission'
|
||||
|
||||
definePageMeta({
|
||||
middleware: ['rbac'],
|
||||
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||
roles: [],
|
||||
title: 'Daftar Dokter',
|
||||
contentFrame: 'cf-full-width',
|
||||
})
|
||||
@@ -16,7 +16,7 @@ useHead({
|
||||
title: () => route.meta.title as string,
|
||||
})
|
||||
|
||||
const roleAccess: PagePermission = PAGE_PERMISSIONS['/doctor']
|
||||
const roleAccess: PagePermission = PAGE_PERMISSIONS['/tools-equipment-src/medicine']!
|
||||
|
||||
const { checkRole, hasReadAccess } = useRBAC()
|
||||
|
||||
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
export const useUserStore = defineStore(
|
||||
'user',
|
||||
() => {
|
||||
// should be auth type
|
||||
const user = ref<any | null>(null)
|
||||
// const token = useCookie('authentication')
|
||||
|
||||
@@ -28,7 +29,7 @@ export const useUserStore = defineStore(
|
||||
}
|
||||
}
|
||||
|
||||
const getActiveRole = () => {
|
||||
const getActiveRole = (): string | null => {
|
||||
if (user.value?.activeRole) {
|
||||
return user.value.activeRole
|
||||
}
|
||||
@@ -36,6 +37,7 @@ export const useUserStore = defineStore(
|
||||
user.value.activeRole = user.value.roles[0]
|
||||
return user.value.activeRole
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
{
|
||||
"title": "Kunjungan",
|
||||
"icon": "i-lucide-stethoscope",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
},
|
||||
{
|
||||
"title": "Konsultasi",
|
||||
"icon": "i-lucide-building-2",
|
||||
"link": "/outpatient/consultation"
|
||||
"link": "/ambulatory/consultation"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{
|
||||
"title": "Rawat Jalan",
|
||||
"icon": "i-lucide-stethoscope",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
},
|
||||
{
|
||||
"title": "IGD",
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
"children": [
|
||||
{
|
||||
"title": "Antrian Poliklinik",
|
||||
"link": "/outpatient/encounter-queue"
|
||||
"link": "/ambulatory/encounter-queue"
|
||||
},
|
||||
{
|
||||
"title": "Kunjungan",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{
|
||||
"title": "Rawat Jalan",
|
||||
"icon": "i-lucide-stethoscope",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
},
|
||||
{
|
||||
"title": "IGD",
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
"children": [
|
||||
{
|
||||
"title": "Antrian Pendaftaran",
|
||||
"link": "/outpatient/registration-queue"
|
||||
"link": "/ambulatory/registration-queue"
|
||||
},
|
||||
{
|
||||
"title": "Kunjungan",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,19 +13,19 @@
|
||||
"children": [
|
||||
{
|
||||
"title": "Antrian Pendaftaran",
|
||||
"link": "/outpatient/registration-queue"
|
||||
"link": "/ambulatory/registration-queue"
|
||||
},
|
||||
{
|
||||
"title": "Antrian Poliklinik",
|
||||
"link": "/outpatient/encounter-queue"
|
||||
"link": "/ambulatory/encounter-queue"
|
||||
},
|
||||
{
|
||||
"title": "Kunjungan",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
},
|
||||
{
|
||||
"title": "Konsultasi",
|
||||
"link": "/outpatient/consultation"
|
||||
"link": "/ambulatory/consultation"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,19 +13,19 @@
|
||||
"children": [
|
||||
{
|
||||
"title": "Antrian Pendaftaran",
|
||||
"link": "/outpatient/registration-queue"
|
||||
"link": "/ambulatory/registration-queue"
|
||||
},
|
||||
{
|
||||
"title": "Antrian Poliklinik",
|
||||
"link": "/outpatient/encounter-queue"
|
||||
"link": "/ambulatory/encounter-queue"
|
||||
},
|
||||
{
|
||||
"title": "Kunjungan",
|
||||
"link": "/outpatient/encounter"
|
||||
"link": "/ambulatory/encounter"
|
||||
},
|
||||
{
|
||||
"title": "Konsultasi",
|
||||
"link": "/outpatient/consultation"
|
||||
"link": "/ambulatory/consultation"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -389,4 +389,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user