feat: Filter validasi
This commit is contained in:
parent
b78cbc4fe6
commit
5388ef03bc
|
|
@ -1,4 +1,4 @@
|
||||||
import { Controller, Get, Param, Post, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Param, Post, Query, UseGuards } from '@nestjs/common';
|
||||||
import { AuthGuard } from '../auth/guard/auth.guard';
|
import { AuthGuard } from '../auth/guard/auth.guard';
|
||||||
import { ValidationService } from './validation.service';
|
import { ValidationService } from './validation.service';
|
||||||
import { CurrentUser } from '../auth/decorator/current-user.decorator';
|
import { CurrentUser } from '../auth/decorator/current-user.decorator';
|
||||||
|
|
@ -10,8 +10,29 @@ export class ValidationController {
|
||||||
|
|
||||||
@Get('/')
|
@Get('/')
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
async getValidationStatus() {
|
async getValidationStatus(
|
||||||
return this.validationService.getAllValidationsQueue();
|
@Query('take') take: number,
|
||||||
|
@Query('skip') skip: number,
|
||||||
|
@Query('page') page: number,
|
||||||
|
@Query('orderBy') orderBy: string,
|
||||||
|
@Query('searchIdRecord') searchIdRecord: string,
|
||||||
|
@Query('order') order: 'asc' | 'desc',
|
||||||
|
@Query('kelompok_data') kelompok_data: string,
|
||||||
|
@Query('aksi') aksi: string,
|
||||||
|
@Query('status') status: string,
|
||||||
|
) {
|
||||||
|
const queryParams = {
|
||||||
|
take,
|
||||||
|
skip,
|
||||||
|
page,
|
||||||
|
orderBy,
|
||||||
|
searchIdRecord,
|
||||||
|
order,
|
||||||
|
kelompok_data,
|
||||||
|
aksi,
|
||||||
|
status,
|
||||||
|
};
|
||||||
|
return this.validationService.getAllValidationsQueue(queryParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('/:id')
|
@Get('/:id')
|
||||||
|
|
|
||||||
|
|
@ -109,12 +109,56 @@ export class ValidationService {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async getAllValidationsQueue() {
|
async getAllValidationsQueue(params: any) {
|
||||||
|
const {
|
||||||
|
take,
|
||||||
|
skip,
|
||||||
|
page,
|
||||||
|
orderBy,
|
||||||
|
order,
|
||||||
|
searchIdRecord,
|
||||||
|
kelompok_data,
|
||||||
|
aksi,
|
||||||
|
status,
|
||||||
|
} = params;
|
||||||
|
const skipValue = skip
|
||||||
|
? parseInt(skip.toString())
|
||||||
|
: page
|
||||||
|
? (parseInt(page.toString()) - 1) * take
|
||||||
|
: 0;
|
||||||
|
console.log('Params', params);
|
||||||
const result = await this.prisma.validation_queue.findMany({
|
const result = await this.prisma.validation_queue.findMany({
|
||||||
where: { status: 'PENDING' },
|
take,
|
||||||
|
skip: skipValue,
|
||||||
|
orderBy: orderBy ? { [orderBy]: order || 'asc' } : { created_at: 'desc' },
|
||||||
|
where: {
|
||||||
|
record_id: searchIdRecord
|
||||||
|
? {
|
||||||
|
contains: searchIdRecord,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
table_name:
|
||||||
|
kelompok_data && kelompok_data !== 'all'
|
||||||
|
? kelompok_data.toLowerCase()
|
||||||
|
: undefined,
|
||||||
|
action: aksi && aksi !== 'all' ? aksi.toUpperCase() : undefined,
|
||||||
|
status: status && status !== 'all' ? status.toUpperCase() : undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const totalCount = await this.prisma.validation_queue.count({
|
const totalCount = await this.prisma.validation_queue.count({
|
||||||
where: { status: 'PENDING' },
|
where: {
|
||||||
|
record_id: searchIdRecord
|
||||||
|
? {
|
||||||
|
contains: searchIdRecord,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
table_name:
|
||||||
|
kelompok_data && kelompok_data !== 'all'
|
||||||
|
? kelompok_data.toLowerCase()
|
||||||
|
: undefined,
|
||||||
|
action: aksi && aksi !== 'all' ? aksi.toUpperCase() : undefined,
|
||||||
|
status: status && status !== 'all' ? status.toUpperCase() : undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return { data: result, totalCount };
|
return { data: result, totalCount };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ const handleResetFilters = () => {
|
||||||
pagination.reset();
|
pagination.reset();
|
||||||
fetchData();
|
fetchData();
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => pagination.page.value,
|
() => pagination.page.value,
|
||||||
() => {
|
() => {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import SortDropdown from "../../../components/dashboard/SortDropdown.vue";
|
||||||
import DataTable from "../../../components/dashboard/DataTable.vue";
|
import DataTable from "../../../components/dashboard/DataTable.vue";
|
||||||
import PaginationControls from "../../../components/dashboard/PaginationControls.vue";
|
import PaginationControls from "../../../components/dashboard/PaginationControls.vue";
|
||||||
import type { ValidationLog } from "../../../constants/interfaces";
|
import type { ValidationLog } from "../../../constants/interfaces";
|
||||||
|
import Footer from "../../../components/dashboard/Footer.vue";
|
||||||
|
|
||||||
interface ApiResponse {
|
interface ApiResponse {
|
||||||
data: ValidationLog[];
|
data: ValidationLog[];
|
||||||
|
|
@ -26,7 +27,7 @@ interface ApiResponse {
|
||||||
|
|
||||||
const data = ref<ValidationLog[]>([]);
|
const data = ref<ValidationLog[]>([]);
|
||||||
const searchValidation = ref("");
|
const searchValidation = ref("");
|
||||||
const sortBy = ref("id");
|
const sortBy = ref("created_at");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const pagination = usePagination({
|
const pagination = usePagination({
|
||||||
|
|
@ -34,10 +35,16 @@ const pagination = usePagination({
|
||||||
initialPageSize: Number(route.query.pageSize) || DEFAULT_PAGE_SIZE,
|
initialPageSize: Number(route.query.pageSize) || DEFAULT_PAGE_SIZE,
|
||||||
});
|
});
|
||||||
const sortOrder = ref<"asc" | "desc">(
|
const sortOrder = ref<"asc" | "desc">(
|
||||||
(route.query.order as "asc" | "desc") || "asc"
|
(route.query.order as "asc" | "desc") || "desc"
|
||||||
);
|
);
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
const { debounce } = useDebounce();
|
const { debounce } = useDebounce();
|
||||||
|
const searchId = ref("");
|
||||||
|
const filters = ref({
|
||||||
|
kelompok_data: (route.query.kelompok_data as string) || "initial",
|
||||||
|
aksi: (route.query.aksi as string) || "initial",
|
||||||
|
status: (route.query.status as string) || "PENDING",
|
||||||
|
});
|
||||||
|
|
||||||
const updateQueryParams = () => {
|
const updateQueryParams = () => {
|
||||||
const query: Record<string, string> = {
|
const query: Record<string, string> = {
|
||||||
|
|
@ -53,6 +60,21 @@ const updateQueryParams = () => {
|
||||||
query.sortBy = sortBy.value;
|
query.sortBy = sortBy.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filters.value.status !== "all") {
|
||||||
|
query.status = filters.value.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.value.aksi !== "all" && filters.value.aksi !== "initial") {
|
||||||
|
query.aksi = filters.value.aksi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
filters.value.kelompok_data !== "all" &&
|
||||||
|
filters.value.kelompok_data !== "initial"
|
||||||
|
) {
|
||||||
|
query.kelompok_data = filters.value.kelompok_data;
|
||||||
|
}
|
||||||
|
|
||||||
query.order = sortOrder.value;
|
query.order = sortOrder.value;
|
||||||
|
|
||||||
router.replace({ query });
|
router.replace({ query });
|
||||||
|
|
@ -137,6 +159,14 @@ const normalizedData = (rawData: any[]): ValidationLog[] => {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleResetFilters = () => {
|
||||||
|
filters.value.kelompok_data = "all";
|
||||||
|
filters.value.aksi = "all";
|
||||||
|
searchId.value = "";
|
||||||
|
pagination.reset();
|
||||||
|
fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
const queryParams = new URLSearchParams({
|
const queryParams = new URLSearchParams({
|
||||||
|
|
@ -144,6 +174,12 @@ const fetchData = async () => {
|
||||||
page: pagination.page.value.toString(),
|
page: pagination.page.value.toString(),
|
||||||
orderBy: sortBy.value,
|
orderBy: sortBy.value,
|
||||||
order: sortOrder.value,
|
order: sortOrder.value,
|
||||||
|
kelompok_data:
|
||||||
|
filters.value.kelompok_data !== "initial"
|
||||||
|
? filters.value.kelompok_data
|
||||||
|
: "",
|
||||||
|
aksi: filters.value.aksi !== "initial" ? filters.value.aksi : "",
|
||||||
|
status: filters.value.status !== "initial" ? filters.value.status : "",
|
||||||
...(searchValidation.value && { validation: searchValidation.value }),
|
...(searchValidation.value && { validation: searchValidation.value }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -220,6 +256,30 @@ watch(searchValidation, (newValue, oldValue) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => filters.value.kelompok_data,
|
||||||
|
() => {
|
||||||
|
pagination.reset();
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => filters.value.aksi,
|
||||||
|
() => {
|
||||||
|
pagination.reset();
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => filters.value.status,
|
||||||
|
() => {
|
||||||
|
pagination.reset();
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (route.query.search) {
|
if (route.query.search) {
|
||||||
searchValidation.value = route.query.search as string;
|
searchValidation.value = route.query.search as string;
|
||||||
|
|
@ -244,6 +304,87 @@ onMounted(async () => {
|
||||||
<div class="flex h-full p-2">
|
<div class="flex h-full p-2">
|
||||||
<Sidebar>
|
<Sidebar>
|
||||||
<PageHeader title="Validasi" subtitle="Manajemen Validasi" />
|
<PageHeader title="Validasi" subtitle="Manajemen Validasi" />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="collapse collapse-arrow bg-white border-white border shadow-sm mb-2"
|
||||||
|
>
|
||||||
|
<input type="checkbox" />
|
||||||
|
<div
|
||||||
|
class="collapse-title font-semibold after:start-5 after:end-auto pe-4 ps-12"
|
||||||
|
>
|
||||||
|
Filter
|
||||||
|
</div>
|
||||||
|
<div class="collapse-content text-sm flex flex-col gap-4">
|
||||||
|
<div class="flex gap-x-4">
|
||||||
|
<div class="flex gap-x-4 items-end">
|
||||||
|
<div class="h-full">
|
||||||
|
<label for="jenis_kelamin" class="font-bold"
|
||||||
|
>Kelompok Data</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
v-model="filters.kelompok_data"
|
||||||
|
class="select bg-white border border-gray-300 mt-1"
|
||||||
|
>
|
||||||
|
<option disabled selected value="initial">
|
||||||
|
Pilih Kelompok Data
|
||||||
|
</option>
|
||||||
|
<option value="rekam_medis">Rekam Medis</option>
|
||||||
|
<option value="pemberian_tindakan">Tindakan</option>
|
||||||
|
<option value="pemberian_obat">Obat</option>
|
||||||
|
<option value="all">Semua Tipe</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-x-4 items-end">
|
||||||
|
<div class="h-full">
|
||||||
|
<label for="jenis_kelamin" class="font-bold"
|
||||||
|
>Jenis Aksi</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
v-model="filters.aksi"
|
||||||
|
class="select bg-white border border-gray-300 mt-1"
|
||||||
|
>
|
||||||
|
<option disabled selected value="initial">
|
||||||
|
Pilih Jenis Aksi
|
||||||
|
</option>
|
||||||
|
<option value="CREATE">Create</option>
|
||||||
|
<option value="UPDATE">Update</option>
|
||||||
|
<option value="DELETE">Delete</option>
|
||||||
|
<option value="all">Semua</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-x-4 items-end">
|
||||||
|
<div class="h-full">
|
||||||
|
<label for="jenis_kelamin" class="font-bold"
|
||||||
|
>Status Validasi</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
v-model="filters.status"
|
||||||
|
class="select bg-white border border-gray-300 mt-1"
|
||||||
|
>
|
||||||
|
<option disabled selected value="initial">
|
||||||
|
Pilih Status Validasi
|
||||||
|
</option>
|
||||||
|
<option value="PENDING">Pending</option>
|
||||||
|
<option value="APPROVED">Approved</option>
|
||||||
|
<option value="REJECTED">Rejected</option>
|
||||||
|
<option value="all">Semua</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<button
|
||||||
|
@click="handleResetFilters"
|
||||||
|
class="btn btn-sm btn-outline btn-dark hover:bg-dark hover:text-light"
|
||||||
|
>
|
||||||
|
Reset Filter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="bg-white rounded-xl shadow-md">
|
<div class="bg-white rounded-xl shadow-md">
|
||||||
<div
|
<div
|
||||||
class="flex flex-col md:flex-row md:items-center md:justify-between gap-4 px-4 pt-4 pb-2"
|
class="flex flex-col md:flex-row md:items-center md:justify-between gap-4 px-4 pt-4 pb-2"
|
||||||
|
|
@ -315,6 +456,7 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
</div>
|
</div>
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user