Merge branch 'dev' into feat/kfr-kemoterapi-174

This commit is contained in:
Muhammad Hasyim Chaidir Ali
2025-11-24 10:25:15 +07:00
committed by GitHub
186 changed files with 8018 additions and 852 deletions
@@ -85,7 +85,7 @@ function handleActionCellClick(event: Event, _cellRef: string) {
v-for="(th, idx) in headers[hrIdx]"
:key="`head-${idx}`"
:class="`border ${th.classVal || ''}`"
:style="{ width: cols[idx]?.width ? `${cols[idx].width}px` : undefined }"
:style="{ width: cols[idx]?.width ? `${cols[idx].width}${cols[idx].widthUnit ?? 'px'}` : '' }"
>
{{ th.label }}
</TableHead>
@@ -0,0 +1,80 @@
<script setup lang="ts">
import type { LinkItem, ListItemDto } from './types'
import { ActionEvents } from './types'
const props = defineProps<{
rec: ListItemDto
}>()
const recId = inject<Ref<number>>('rec_id')!
const recAction = inject<Ref<string>>('rec_action')!
const recItem = inject<Ref<any>>('rec_item')!
const timestamp = inject<Ref<number>>('timestamp')!
const activeKey = ref<string | null>(null)
const linkItems: LinkItem[] = [
{
label: 'Detail',
onClick: () => {
detail()
},
icon: 'i-lucide-eye',
},
{
label: 'Hapus',
onClick: () => {
del()
},
icon: 'i-lucide-trash',
},
]
function detail() {
recId.value = props.rec.id || 0
recAction.value = ActionEvents.showDetail
recItem.value = props.rec
timestamp.value = Date.now()
}
function del() {
recId.value = props.rec.id || 0
recAction.value = ActionEvents.showConfirmDelete
recItem.value = props.rec
timestamp.value = Date.now()
}
</script>
<template>
<div>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<SidebarMenuButton
size="lg"
class="data-[state=open]:text-sidebar-accent-foreground data-[state=open]:bg-white dark:data-[state=open]:bg-slate-800"
>
<Icon
name="i-lucide-chevrons-up-down"
class="ml-auto size-4"
/>
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
class="w-[--radix-dropdown-menu-trigger-width] min-w-40 rounded-lg border border-slate-200 bg-white text-black dark:border-slate-700 dark:bg-slate-800 dark:text-white"
align="end"
>
<DropdownMenuGroup>
<DropdownMenuItem
v-for="item in linkItems"
:key="item.label"
class="hover:bg-gray-100 dark:hover:bg-slate-700"
@click="item.onClick"
@mouseenter="activeKey = item.label"
@mouseleave="activeKey = null"
>
<Icon :name="item.icon ?? ''" />
<span :class="activeKey === item.label ? 'text-sidebar-accent-foreground' : ''">{{ item.label }}</span>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</div>
</template>
@@ -2,14 +2,9 @@
import type { LinkItem, ListItemDto } from './types'
import { ActionEvents } from './types'
interface Props {
const props = defineProps<{
rec: ListItemDto
size?: 'default' | 'sm' | 'lg'
}
const props = withDefaults(defineProps<Props>(), {
size: 'lg',
})
}>()
const recId = inject<Ref<number>>('rec_id')!
const recAction = inject<Ref<string>>('rec_action')!
@@ -63,7 +58,7 @@ function del() {
<DropdownMenu>
<DropdownMenuTrigger as-child>
<SidebarMenuButton
:size="size"
size="lg"
class="data-[state=open]:text-sidebar-accent-foreground data-[state=open]:bg-white dark:data-[state=open]:bg-slate-800"
>
<Icon
@@ -100,4 +100,4 @@ function print() {
</DropdownMenuContent>
</DropdownMenu>
</div>
</template>
</template>
+6
View File
@@ -42,6 +42,12 @@ export interface RefSearchNav {
onClear: () => void
}
export interface RefExportNav {
onExportPdf?: () => void
onExportCsv?: () => void
onExportExcel?: () => void
}
// prepared header for relatively common usage
export interface HeaderPrep {
title?: string
+1 -1
View File
@@ -62,7 +62,7 @@ async function onFileChange(event: Event, handleChange: (value: any) => void) {
@change="onFileChange($event, handleChange)"
type="file"
:disabled="isDisabled"
v-bind="componentField"
v-bind="{ onBlur: componentField.onBlur }"
:placeholder="placeholder"
:class="cn('focus:border-primary focus:ring-2 focus:ring-primary focus:ring-offset-0')"
/>
+3 -3
View File
@@ -63,14 +63,14 @@ function handleInput(event: Event) {
v-slot="{ componentField }"
:name="fieldName"
>
<FormItem :class="`relative`">
<FormItem :class="cn(`relative`,)">
<FormControl>
<Input
:disabled="isDisabled"
v-bind="componentField"
:placeholder="placeholder"
:maxlength="maxLength"
:class="cn('focus:border-primary focus:ring-2 focus:ring-primary focus:ring-offset-0')"
:class="cn('focus:border-primary focus:ring-2 focus:ring-primary focus:ring-offset-0', props.class)"
autocomplete="off"
aria-autocomplete="none"
autocorrect="off"
@@ -84,6 +84,6 @@ function handleInput(event: Event) {
</FormItem>
</FormField>
</DE.Field>
<p v-show="bottomLabel" class="text-gray-400">{{ bottomLabel }}</p>
<p v-show="bottomLabel" class="text-gray-400 mt-1">{{ bottomLabel }}</p>
</DE.Cell>
</template>
@@ -47,7 +47,7 @@ function handleInput(event: Event) {
<template>
<DE.Cell :col-span="colSpan || 1">
<DE.Label
class="font-medium"
class="font-medium mb-1"
v-if="label !== ''"
:label-for="fieldName"
:is-required="isRequired && !isDisabled"
@@ -43,4 +43,4 @@ function onClick(type: ClickType) {
</Button>
</div>
</div>
</template>
</template>