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">
|
<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
|
// Libs
|
||||||
import { getPositionAs } from '~/lib/roles'
|
import { getPositionAs } from '~/lib/roles'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
// Pub components
|
||||||
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
|
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/nav-header/index'
|
||||||
import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/data/types'
|
import { toast } from '~/components/pub/ui/toast'
|
||||||
import { ActionEvents } from '~/components/pub/my-ui/data/types'
|
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
|
// Services
|
||||||
import { getList as getEncounterList, remove as removeEncounter, cancel as cancelEncounter } from '~/services/encounter.service'
|
import { getList as getEncounterList, remove as removeEncounter, cancel as cancelEncounter } from '~/services/encounter.service'
|
||||||
|
|
||||||
// UI
|
// Apps
|
||||||
import { toast } from '~/components/pub/ui/toast'
|
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()
|
const { setOpen } = useSidebar()
|
||||||
setOpen(true)
|
setOpen(true)
|
||||||
|
|
||||||
const { getActiveRole } = useUserStore()
|
const { getActiveRole } = useUserStore()
|
||||||
const activeRole = getActiveRole()
|
const activeRole = getActiveRole()
|
||||||
const activePosition = ref(getPositionAs(activeRole))
|
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 data = ref([])
|
||||||
const isLoading = reactive<DataTableLoader>({
|
const isLoading = reactive<DataTableLoader>({
|
||||||
summary: false,
|
summary: false,
|
||||||
@@ -48,33 +53,49 @@ const isFormEntryDialogOpen = ref(false)
|
|||||||
const isRecordConfirmationOpen = ref(false)
|
const isRecordConfirmationOpen = ref(false)
|
||||||
const isRecordCancelOpen = ref(false)
|
const isRecordCancelOpen = ref(false)
|
||||||
|
|
||||||
const hreaderPrep: HeaderPrep = {
|
// Headers
|
||||||
|
const hreaderPrep: CH.Config = {
|
||||||
title: 'Kunjungan',
|
title: 'Kunjungan',
|
||||||
icon: 'i-lucide-users',
|
icon: 'i-lucide-users',
|
||||||
addNav: {
|
addNav: {
|
||||||
label: 'Tambah',
|
label: 'Tambah',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (props.classCode === 'ambulatory' && props.subClassCode === 'rehab') {
|
navigateTo(`/${props.classCode}/encounter/add`)
|
||||||
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')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
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 = {
|
const refSearchNav: RefSearchNav = {
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
// open filter modal
|
// open filter modal
|
||||||
isFormEntryDialogOpen.value = true
|
isFormEntryDialogOpen.value = true
|
||||||
console.log(' 1open filter modal')
|
|
||||||
},
|
},
|
||||||
onInput: (_val: string) => {
|
onInput: (_val: string) => {
|
||||||
// filter patient list
|
// 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)
|
||||||
|
|
||||||
/**
|
watch(() => recAction.value, () => {
|
||||||
* Get base path for encounter routes based on classCode and subClassCode
|
const basePath = `/${props.classCode}/encounter`
|
||||||
*/
|
if (recAction.value === ActionEvents.showDetail) {
|
||||||
function getBasePath(): string {
|
navigateTo(`${basePath}/${recId.value}`)
|
||||||
if (props.classCode === 'ambulatory' && props.subClassCode === 'rehab') {
|
} else if (recAction.value === ActionEvents.showEdit) {
|
||||||
return '/rehab/encounter'
|
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') {
|
recAction.value = '' // reset
|
||||||
return '/outpatient/encounter'
|
})
|
||||||
}
|
|
||||||
if (props.classCode === 'emergency') {
|
|
||||||
return '/emergency/encounter'
|
|
||||||
}
|
|
||||||
if (props.classCode === 'inpatient') {
|
|
||||||
return '/inpatient/encounter'
|
|
||||||
}
|
|
||||||
return '/encounter' // fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getPatientList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Functions
|
||||||
async function getPatientList() {
|
async function getPatientList() {
|
||||||
isLoading.isTableLoading = true
|
isLoading.isTableLoading = true
|
||||||
try {
|
try {
|
||||||
@@ -273,18 +298,11 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Header
|
<CH.ContentHeader v-bind="hreaderPrep">
|
||||||
:prep="{ ...hreaderPrep }"
|
<FilterNav />
|
||||||
:ref-search-nav="refSearchNav"
|
</CH.ContentHeader>
|
||||||
/>
|
|
||||||
<Separator class="my-4 xl:my-5" />
|
|
||||||
|
|
||||||
<Filter
|
<Content :data="data" />
|
||||||
:prep="hreaderPrep"
|
|
||||||
:ref-search-nav="refSearchNav"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AppEncounterList :data="data" />
|
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
v-model:open="isFormEntryDialogOpen"
|
v-model:open="isFormEntryDialogOpen"
|
||||||
@@ -292,13 +310,7 @@ onMounted(() => {
|
|||||||
size="lg"
|
size="lg"
|
||||||
prevent-outside
|
prevent-outside
|
||||||
>
|
>
|
||||||
<AppEncounterFilter
|
<FilterForm v-bind="filter" />
|
||||||
:installation="{
|
|
||||||
msg: { placeholder: 'Pilih' },
|
|
||||||
items: [],
|
|
||||||
}"
|
|
||||||
:schema="{}"
|
|
||||||
/>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<!-- Record Confirmation Modal -->
|
<!-- Record Confirmation Modal -->
|
||||||
@@ -326,6 +338,7 @@ onMounted(() => {
|
|||||||
</RecordConfirmation>
|
</RecordConfirmation>
|
||||||
|
|
||||||
<RecordConfirmation
|
<RecordConfirmation
|
||||||
|
v-if="canDelete"
|
||||||
v-model:open="isRecordConfirmationOpen"
|
v-model:open="isRecordConfirmationOpen"
|
||||||
action="delete"
|
action="delete"
|
||||||
:record="recItem"
|
:record="recItem"
|
||||||
@@ -349,4 +362,11 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</RecordConfirmation>
|
</RecordConfirmation>
|
||||||
|
<Dialog
|
||||||
|
title="Hapus data"
|
||||||
|
size="md"
|
||||||
|
v-model:open="isRecordConfirmationOpen"
|
||||||
|
>
|
||||||
|
Hak akses tidak memenuhi kriteria untuk proses ini.
|
||||||
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -48,9 +48,18 @@ async function setMenu() {
|
|||||||
const activeRoleParts = activeRole ? activeRole.split('|') : []
|
const activeRoleParts = activeRole ? activeRole.split('|') : []
|
||||||
const role = activeRoleParts[0]+(activeRoleParts.length > 1 ? `-${activeRoleParts[1]}` : '')
|
const role = activeRoleParts[0]+(activeRoleParts.length > 1 ? `-${activeRoleParts[1]}` : '')
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const res = await fetch(`/side-menu-items/${role.toLowerCase()}.json`)
|
const res = await fetch(`/side-menu-items/${role.toLowerCase()}.json`)
|
||||||
const rawMenu = await res.text()
|
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) {
|
} catch (e) {
|
||||||
const res = await fetch(`/side-menu-items/blank.json`)
|
const res = await fetch(`/side-menu-items/blank.json`)
|
||||||
const rawMenu = await res.text()
|
const rawMenu = await res.text()
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ function btnClick() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
<!-- For components as slots -->
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<!-- For components passed by props -->
|
||||||
<div v-if="prep.components">
|
<div v-if="prep.components">
|
||||||
<template v-for="cwp in prep.components">
|
<template v-for="cwp in prep.components">
|
||||||
<component
|
<component
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function btnClick() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="prep.addNav" class="m-2 flex items-center">
|
<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" />
|
<Icon name="i-lucide-plus" class="mr-2 h-4 w-4 align-middle" />
|
||||||
{{ prep.addNav.label }}
|
{{ prep.addNav.label }}
|
||||||
</Button>
|
</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 {
|
export interface PageOperationPermission {
|
||||||
canRead: boolean
|
canRead: boolean
|
||||||
@@ -7,7 +8,6 @@ export interface PageOperationPermission {
|
|||||||
canDelete: boolean
|
canDelete: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if user has access to a page
|
* 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
|
// NOTE: this roles was dummy for testing only, it should taken from the user store
|
||||||
const authStore = useUserStore()
|
const authStore = useUserStore()
|
||||||
|
|
||||||
const checkRole = (roleAccess: RoleAccess, _userRoles?: string[]): boolean => {
|
const checkRole = (roleAccesses: RoleAccesses, _userRoles?: string[]): boolean => {
|
||||||
const roles = authStore.userRole
|
const activeRole = authStore.getActiveRole() || ''
|
||||||
return roles.some((role: string) => role === 'system' || (role in roleAccess)) // system by-passes this check
|
if (activeRole === systemCode) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return (activeRole in roleAccesses);
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkPermission = (roleAccess: RoleAccess, permission: Permission, _userRoles?: string[]): boolean => {
|
const checkPermission = (roleAccesses: RoleAccesses, permission: Permission, _userRoles?: string[]): boolean => {
|
||||||
const roles = authStore.userRole
|
const activeRole = authStore.getActiveRole() || ''
|
||||||
return roles.some((role: string) => role === 'system' || roleAccess[role]?.includes(permission)) // system by-passes this check
|
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 = authStore.userRole
|
||||||
// const roles = ['admisi']
|
|
||||||
const permissions = new Set<Permission>()
|
const permissions = new Set<Permission>()
|
||||||
|
|
||||||
roles.forEach((role: string) => {
|
roles.forEach((role: string) => {
|
||||||
@@ -39,12 +47,12 @@ export function useRBAC() {
|
|||||||
return Array.from(permissions)
|
return Array.from(permissions)
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasCreateAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'C')
|
const hasCreateAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'C')
|
||||||
const hasReadAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'R')
|
const hasReadAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'R')
|
||||||
const hasUpdateAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'U')
|
const hasUpdateAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'U')
|
||||||
const hasDeleteAccess = (roleAccess: RoleAccess) => checkPermission(roleAccess, 'D')
|
const hasDeleteAccess = (roleAccess: RoleAccesses) => checkPermission(roleAccess, 'D')
|
||||||
|
|
||||||
const getPagePermissions = (roleAccess: RoleAccess): PageOperationPermission => ({
|
const getPagePermissions = (roleAccess: RoleAccesses): PageOperationPermission => ({
|
||||||
canRead : hasReadAccess(roleAccess),
|
canRead : hasReadAccess(roleAccess),
|
||||||
canCreate: hasCreateAccess(roleAccess),
|
canCreate: hasCreateAccess(roleAccess),
|
||||||
canUpdate: hasUpdateAccess(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 type Permission = 'C' | 'R' | 'U' | 'D'
|
||||||
|
|
||||||
export interface RoleAccess {
|
export interface RoleAccesses {
|
||||||
[role: string]: Permission[]
|
[role: string]: Permission[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PagePath = keyof typeof PAGE_PERMISSIONS
|
// export type PagePath = keyof typeof PAGE_PERMISSIONS
|
||||||
export type PagePermission = (typeof PAGE_PERMISSIONS)[PagePath]
|
// export type PagePermission = (typeof PAGE_PERMISSIONS)[PagePath]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Permission } from '~/models/role'
|
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 Error from '~/components/pub/my-ui/error/error.vue'
|
||||||
|
|
||||||
import Content from '~/components/content/encounter/entry.vue'
|
import Content from '~/components/content/encounter/entry.vue'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Permission } from '~/models/role'
|
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 Error from '~/components/pub/my-ui/error/error.vue'
|
||||||
|
|
||||||
import Content from '~/components/content/encounter/list.vue'
|
import Content from '~/components/content/encounter/list.vue'
|
||||||
@@ -13,7 +13,8 @@ definePageMeta({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Preps role checking
|
// 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()
|
const { checkRole, hasReadAccess } = useRBAC()
|
||||||
|
|
||||||
// Check if user has access to this page
|
// Check if user has access to this page
|
||||||
@@ -26,18 +27,12 @@ if (!hasAccess) {
|
|||||||
const canRead = hasReadAccess(roleAccess)
|
const canRead = hasReadAccess(roleAccess)
|
||||||
|
|
||||||
// Page needs
|
// Page needs
|
||||||
const route = useRoute()
|
|
||||||
useHead({
|
useHead({
|
||||||
title: () => route.meta.title as string,
|
title: () => route.meta.title as string,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { user, getActiveRole } = useUserStore()
|
const { user } = 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'
|
const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -45,7 +40,7 @@ const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
|||||||
<div v-if="canRead">
|
<div v-if="canRead">
|
||||||
<Content
|
<Content
|
||||||
class-code="emergency"
|
class-code="emergency"
|
||||||
sub-class-code="reg"
|
:sub-class-code="subClassCode"
|
||||||
type="encounter"
|
type="encounter"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Permission } from '~/models/role'
|
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 Error from '~/components/pub/my-ui/error/error.vue'
|
||||||
|
|
||||||
import Content from '~/components/content/encounter/entry.vue'
|
import Content from '~/components/content/encounter/entry.vue'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Permission } from '~/models/role'
|
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 Error from '~/components/pub/my-ui/error/error.vue'
|
||||||
|
|
||||||
import Content from '~/components/content/encounter/list.vue'
|
import Content from '~/components/content/encounter/list.vue'
|
||||||
@@ -13,7 +13,7 @@ definePageMeta({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Preps role checking
|
// Preps role checking
|
||||||
const roleAccess: Record<string, Permission[]> = permissions['/outpatient/encounter'] || {}
|
const roleAccess: Record<string, Permission[]> = permissions['/inpatient/encounter'] || {}
|
||||||
const { checkRole, hasReadAccess } = useRBAC()
|
const { checkRole, hasReadAccess } = useRBAC()
|
||||||
|
|
||||||
// Check if user has access to this page
|
// Check if user has access to this page
|
||||||
@@ -31,11 +31,7 @@ useHead({
|
|||||||
title: () => route.meta.title as string,
|
title: () => route.meta.title as string,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { user, getActiveRole } = useUserStore()
|
const { user } = 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'
|
const subClassCode = user.unit_code == 'rehab' ? 'rehab' : 'reg'
|
||||||
|
|
||||||
</script>
|
</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({
|
definePageMeta({
|
||||||
middleware: ['rbac'],
|
middleware: ['rbac'],
|
||||||
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
roles: [],
|
||||||
title: 'Daftar Dokter',
|
title: 'Daftar Dokter',
|
||||||
contentFrame: 'cf-full-width',
|
contentFrame: 'cf-full-width',
|
||||||
})
|
})
|
||||||
@@ -16,7 +16,7 @@ useHead({
|
|||||||
title: () => route.meta.title as string,
|
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()
|
const { checkRole, hasReadAccess } = useRBAC()
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,7 @@
|
|||||||
export const useUserStore = defineStore(
|
export const useUserStore = defineStore(
|
||||||
'user',
|
'user',
|
||||||
() => {
|
() => {
|
||||||
|
// should be auth type
|
||||||
const user = ref<any | null>(null)
|
const user = ref<any | null>(null)
|
||||||
// const token = useCookie('authentication')
|
// const token = useCookie('authentication')
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ export const useUserStore = defineStore(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActiveRole = () => {
|
const getActiveRole = (): string | null => {
|
||||||
if (user.value?.activeRole) {
|
if (user.value?.activeRole) {
|
||||||
return user.value.activeRole
|
return user.value.activeRole
|
||||||
}
|
}
|
||||||
@@ -36,6 +37,7 @@ export const useUserStore = defineStore(
|
|||||||
user.value.activeRole = user.value.roles[0]
|
user.value.activeRole = user.value.roles[0]
|
||||||
return user.value.activeRole
|
return user.value.activeRole
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
{
|
{
|
||||||
"title": "Kunjungan",
|
"title": "Kunjungan",
|
||||||
"icon": "i-lucide-stethoscope",
|
"icon": "i-lucide-stethoscope",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Konsultasi",
|
"title": "Konsultasi",
|
||||||
"icon": "i-lucide-building-2",
|
"icon": "i-lucide-building-2",
|
||||||
"link": "/outpatient/consultation"
|
"link": "/ambulatory/consultation"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Rawat Jalan",
|
"title": "Rawat Jalan",
|
||||||
"icon": "i-lucide-stethoscope",
|
"icon": "i-lucide-stethoscope",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "IGD",
|
"title": "IGD",
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Antrian Poliklinik",
|
"title": "Antrian Poliklinik",
|
||||||
"link": "/outpatient/encounter-queue"
|
"link": "/ambulatory/encounter-queue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Kunjungan",
|
"title": "Kunjungan",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Rawat Jalan",
|
"title": "Rawat Jalan",
|
||||||
"icon": "i-lucide-stethoscope",
|
"icon": "i-lucide-stethoscope",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "IGD",
|
"title": "IGD",
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Antrian Pendaftaran",
|
"title": "Antrian Pendaftaran",
|
||||||
"link": "/outpatient/registration-queue"
|
"link": "/ambulatory/registration-queue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Kunjungan",
|
"title": "Kunjungan",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,19 +13,19 @@
|
|||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Antrian Pendaftaran",
|
"title": "Antrian Pendaftaran",
|
||||||
"link": "/outpatient/registration-queue"
|
"link": "/ambulatory/registration-queue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Antrian Poliklinik",
|
"title": "Antrian Poliklinik",
|
||||||
"link": "/outpatient/encounter-queue"
|
"link": "/ambulatory/encounter-queue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Kunjungan",
|
"title": "Kunjungan",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Konsultasi",
|
"title": "Konsultasi",
|
||||||
"link": "/outpatient/consultation"
|
"link": "/ambulatory/consultation"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,19 +13,19 @@
|
|||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"title": "Antrian Pendaftaran",
|
"title": "Antrian Pendaftaran",
|
||||||
"link": "/outpatient/registration-queue"
|
"link": "/ambulatory/registration-queue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Antrian Poliklinik",
|
"title": "Antrian Poliklinik",
|
||||||
"link": "/outpatient/encounter-queue"
|
"link": "/ambulatory/encounter-queue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Kunjungan",
|
"title": "Kunjungan",
|
||||||
"link": "/outpatient/encounter"
|
"link": "/ambulatory/encounter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Konsultasi",
|
"title": "Konsultasi",
|
||||||
"link": "/outpatient/consultation"
|
"link": "/ambulatory/consultation"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -389,4 +389,4 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user