Как отображать таблицу reports из pages/reports/index.vue в табе на странице pages/organization/id.vue? Какими способами делают это?
У меня есть страница pages/reports/index.vue, который содержит таблицу с данными.
<template>
<div class="flex flex-col gap-2">
<h1 class="text-2xl font-bold mb-4">{{ $t('reports') }}</h1>
<div
class="flex flex-col gap-4 bg-white border border-gray-200 shadow-sm rounded-xl p-4 h-[calc(100vh-200px)]"
>
<div class="flex justify-end gap-2">
<custom-search
type="text"
class="w-[20rem]"
v-model="search"
></custom-search>
<custom-button-light type="button" :text="$t('download_excel')">
<template #icon>
<icon-download class="w-5 h-5" :fontControlled="false" />
</template>
</custom-button-light>
</div>
<custom-data-table :columns="columns" :data="data" :loading="isLoading">
<template #cell-createdAt="{ row }">
{{ moment(row.createdAt).format('DD.MM.YYYY HH:mm') }}
</template>
<template #cell-status="{ row }">
<div class="flex justify-center items-center">
<span
class="w-full text-center text-sm bg-gray-100 border border-gray-600 text-gray-600 font-semibold px-4 py-1 rounded-full"
v-if="(row as ReportResponse).status === ReportStatus.DRAFT"
>
Qaralama
</span>
<span
class="w-full text-center text-sm bg-blue-100 border border-blue-600 text-blue-600 font-semibold px-4 py-1 rounded-full"
v-else-if="(row as ReportResponse).status === ReportStatus.SENT"
>
Hesabat göndərildi
</span>
<span
class="w-full text-center text-sm bg-green-100 border border-green-600 text-green-600 font-semibold px-4 py-1 rounded-full"
v-else-if="(row as ReportResponse).status === ReportStatus.ACCEPTED"
>
Təsdiq olundu
</span>
<span
class="w-full text-center text-sm bg-red-100 border border-red-600 text-red-600 font-semibold px-4 py-1 rounded-full"
v-else-if="
(row as ReportResponse).status === ReportStatus.CORRECTION
"
>
Düzəlişə göndərildi
</span>
</div>
</template>
<template #cell-actions="{ row }">
<div class="w-full flex justify-end items-center gap-2 relative">
<custom-drop-down>
<template #custom>
<button
v-if="(row as ReportResponse).status === ReportStatus.SENT"
@click="acceptRequest(row.id)"
class="flex items-center bg-[#F9F9F9] px-4 py-2 transition-all duration-200 rounded-t-md w-full font-semibold hover:bg-[#009FC2] hover:text-white group"
>
<icon-check-circle
:fontControlled="false"
class="w-5 h-5 text-[#767676] group-hover:text-white"
/>
<span class="ms-2 text-[#767676] group-hover:text-white">{{
$t('accept')
}}</span>
</button>
<button
v-if="(row as ReportResponse).status === ReportStatus.SENT"
@click="showRejectModal(row.id)"
class="flex items-center bg-[#F9F9F9] px-4 py-2 transition-all duration-200 w-full font-semibold hover:bg-[#009FC2] hover:text-white group"
>
<icon-reject
:fontControlled="false"
class="w-5 h-5 text-[#767676] group-hover:text-white"
/>
<span class="ms-2 text-[#767676] group-hover:text-white">{{
$t('reject')
}}</span>
</button>
<button
@click="showDetails(row.id)"
class="flex items-center bg-[#F9F9F9] px-4 py-2 rounded-b-md transition-all duration-200 w-full font-semibold hover:bg-[#009FC2] hover:text-white group"
>
<icon-eye-open
:fontControlled="false"
class="w-5 h-5 text-[#767676] group-hover:text-white"
/>
<span class="ms-2 text-[#767676] group-hover:text-white">
{{ $t('details') }}
</span>
</button>
</template>
</custom-drop-down>
</div>
</template>
</custom-data-table>
</div>
<!-- Reject modal -->
<custom-modal
v-model="isRejectModalShowed"
title=""
:confirm-text="$t('confirm')"
:show-cancel="true"
@confirm="rejectRequest"
>
<div class="">
<p class="text-[#D22519] font-semibold text-base">
{{ $t('requirement_about_form_components') }}
</p>
<div class="mt-4">
<p>{{ $t('rejection_cause') }}</p>
<textarea
rows="3"
class="block w-full rounded-xl border border-[#DFDFDF] focus:outline-none p-2 mt-2"
v-model="description"
></textarea>
</div>
</div>
</custom-modal>
</div>
</template>
<script lang="ts" setup>
import moment from 'moment'
import { ReportStatus, type ReportResponse } from '@/types'
import { useApi } from '@/composables/useApi'
import _ from 'lodash'
const { debounce } = _
const { $toast } = useNuxtApp()
const api = useApi()
const router = useRouter()
const search = ref<string>('')
const data = ref<ReportResponse[]>([])
const isLoading = ref(true)
const isRejectModalShowed = ref<boolean>(false)
const description = ref<string>('')
let selectedId = ref<string>('')
const showRejectModal = (id: string) => {
isRejectModalShowed.value = true
selectedId.value = id
}
onMounted(async () => {
await loadData()
})
const loadData = async () => {
try {
isLoading.value = true
data.value = await api.get<ReportResponse[]>(
`/api/report?search=${search.value}`
)
} finally {
isLoading.value = false
}
}
const debouncedLoadData = debounce(loadData, 300)
watch(search, (newValue) => {
debouncedLoadData()
})
const acceptRequest = async (id: string) => {
try {
await api.patch(`/api/report/${id}/accept`)
await loadData()
} catch (error: any) {
console.error(error)
$toast.error(error.message)
}
}
const rejectRequest = async () => {
try {
if (!description.value) {
$toast.error('Açıqlama daxil edilməlidir')
return
}
await api.patch(`/api/report/${selectedId.value}/reject`, {
note: description.value,
})
isRejectModalShowed.value = false
await loadData()
} catch (error: any) {
console.error(error)
$toast.error(error.message)
}
}
const showDetails = async (id: string) => {
router.push(`/reports/${id}`)
}
const columns = [
{ key: 'organizationName', label: 'Təşkilatın adı' },
{ key: 'createdAt', label: 'Tarix' },
{ key: 'year', label: 'Hesabat ili' },
{ key: 'status', label: 'Status' },
{ key: 'actions', label: '' },
]
</script>
Мне надо чтоб это часть из выше приведенного кода reports/index.vue отображалась в табе.
class="flex flex-col gap-4 bg-white border border-gray-200 shadow-sm rounded-xl p-4 h-[calc(100vh-200px)]"
>
<div class="flex justify-end gap-2">
<custom-search
type="text"
class="w-[20rem]"
v-model="search"
></custom-search>
<custom-button-light type="button" :text="$t('download_excel')">
<template #icon>
<icon-download class="w-5 h-5" :fontControlled="false" />
</template>
</custom-button-light>
</div>
<custom-data-table :columns="columns" :data="data" :loading="isLoading">
<template #cell-createdAt="{ row }">
{{ moment(row.createdAt).format('DD.MM.YYYY HH:mm') }}
</template>
<template #cell-status="{ row }">
<div class="flex justify-center items-center">
<span
class="w-full text-center text-sm bg-gray-100 border border-gray-600 text-gray-600 font-semibold px-4 py-1 rounded-full"
v-if="(row as ReportResponse).status === ReportStatus.DRAFT"
>
Qaralama
</span>
<span
class="w-full text-center text-sm bg-blue-100 border border-blue-600 text-blue-600 font-semibold px-4 py-1 rounded-full"
v-else-if="(row as ReportResponse).status === ReportStatus.SENT"
>
Hesabat göndərildi
</span>
<span
class="w-full text-center text-sm bg-green-100 border border-green-600 text-green-600 font-semibold px-4 py-1 rounded-full"
v-else-if="(row as ReportResponse).status === ReportStatus.ACCEPTED"
>
Təsdiq olundu
</span>
<span
class="w-full text-center text-sm bg-red-100 border border-red-600 text-red-600 font-semibold px-4 py-1 rounded-full"
v-else-if="
(row as ReportResponse).status === ReportStatus.CORRECTION
"
>
Düzəlişə göndərildi
</span>
</div>
</template>
<template #cell-actions="{ row }">
<div class="w-full flex justify-end items-center gap-2 relative">
<custom-drop-down>
<template #custom>
<button
v-if="(row as ReportResponse).status === ReportStatus.SENT"
@click="acceptRequest(row.id)"
class="flex items-center bg-[#F9F9F9] px-4 py-2 transition-all duration-200 rounded-t-md w-full font-semibold hover:bg-[#009FC2] hover:text-white group"
>
<icon-check-circle
:fontControlled="false"
class="w-5 h-5 text-[#767676] group-hover:text-white"
/>
<span class="ms-2 text-[#767676] group-hover:text-white">{{
$t('accept')
}}</span>
</button>
<button
v-if="(row as ReportResponse).status === ReportStatus.SENT"
@click="showRejectModal(row.id)"
class="flex items-center bg-[#F9F9F9] px-4 py-2 transition-all duration-200 w-full font-semibold hover:bg-[#009FC2] hover:text-white group"
>
<icon-reject
:fontControlled="false"
class="w-5 h-5 text-[#767676] group-hover:text-white"
/>
<span class="ms-2 text-[#767676] group-hover:text-white">{{
$t('reject')
}}</span>
</button>
<button
@click="showDetails(row.id)"
class="flex items-center bg-[#F9F9F9] px-4 py-2 rounded-b-md transition-all duration-200 w-full font-semibold hover:bg-[#009FC2] hover:text-white group"
>
<icon-eye-open
:fontControlled="false"
class="w-5 h-5 text-[#767676] group-hover:text-white"
/>
<span class="ms-2 text-[#767676] group-hover:text-white">
{{ $t('details') }}
</span>
</button>
</template>
</custom-drop-down>
</div>
</template>
</custom-data-table>
</div>
А таб находится на странице pages/organization/id.vue
<template>
<div class="flex flex-col sm:w-full md:w-4/5 mt-2">
<!-- Ensuring this div takes full width -->
<div class="sm:block md:flex w-full justify-between items-center min-w-0">
<!-- Left section -->
<div class="flex items-center min-w-0 sm:mb-2">
<nuxt-link to="/organization/requests">
<icon-arrow-left
:fontControlled="false"
class="w-6 cursor-pointer text-[#101010]"
/></nuxt-link>
<span class="ms-2 font-semibold text-xl truncate">
{{ $t('detail_view') }}
</span>
</div>
</div>
<div class="block border border-[#DFDFDF] p-4 bg-white rounded-xl mt-4">
<div class="flex w-full items-center justify-start gap-2">
<custom-button-tab
@click="toggleTab('general')"
type="button"
:text="$t('general_info')"
:isActive="currentTab === 'general'"
>
</custom-button-tab>
<custom-button-tab
@click="toggleTab('document')"
type="button"
:text="$t('documents')"
:isActive="currentTab === 'document'"
>
</custom-button-tab>
</div>
<div class="block mt-4" v-if="currentTab === 'general'">
<div class="block w-full">
<p class="text-[#101010] font-semibold text-xl">
{{ $t('general_info') }}
</p>
</div>
<div class="sm:block md:flex justify-between">
<div class="block sm:w-full md:w-1/2">
<div class="mt-4">
<p class="block text-sm text-[#767676]">
{{ $t('organization_name') }}
</p>
<p class="text-black text-base font-semibold mt-2">
{{ dataOrg?.name }}
</p>
</div>
<div class="mt-4">
<p class="block text-sm text-[#767676]">
{{ $t('phone_number') }}
</p>
<p class="text-black text-base font-semibold mt-2">
{{ dataOrg?.userData?.phoneNumber }}
</p>
</div>
</div>
<div class="block sm:w-full md:w-1/2 ">
<div class="mt-4">
<p class="block text-sm text-[#767676]">
{{ $t('tin') }}
</p>
<p class="text-black text-base font-semibold mt-2">
{{ dataOrg?.tin }}
</p>
</div>
<div class="mt-4">
<p class="block text-sm text-[#767676]">
{{ $t('email') }}
</p>
<p class="text-black text-base font-semibold mt-2">
{{ dataOrg?.email }}
</p>
</div>
</div>
</div>
</div>
</div>
<div class="flex flex-col sm:w-full md:w-4/5 mt-4">
<custom-tabs :tabs="tabs" :initialTab="tabs[0].name">
<template #reports>
</template>
<template #auditorRequests>
<auditor-requests :organizationId="id" />
</template>
<template #energyManagers>
<energy-managers :organizationId="id" />
</template>
</custom-tabs>
</div>
</div>
</template>
<script setup lang="ts">
import CustomTabs from '@/components/CustomTabs.vue';
import {
type Tab,
type OrganizationDataResponse,
} from '@/types'
const api = useApi()
const route = useRoute()
const id = computed(() => route.params.id)
const currentTab = ref<string>('general')
const dataOrg= ref<OrganizationDataResponse | null>(null)
const { $toast } = useNuxtApp()
const toggleTab = (tab: string) => {
currentTab.value = tab
}
const getOrganization = async (id: string) => {
try {
dataOrg.value= await api.get<OrganizationDataResponse>(`/api/organization/${id}`);
} catch (error: any) {
console.error(error);
$toast.error(error.message);
}
};
onMounted(() => {
getOrganization(id.value.toString());
});
const tabs = ref<Tab[]>([
{ name: 'reports', label: 'Hesabatlar' },
{ name: 'auditorRequests', label: 'Auditor ixtisası müraciəti' },
{ name: 'energyManagers', label: 'Enerji idarəçisi tayini' },
] as Tab[]);
</script>
Каким образом делают это?
[![Надо чтоб так выглядел репорт в табе][1]][1]
[![А у меня выглядит так][2]][2]
[![А страница pages/reports/index.vue выглядит так][3]][3]
Надо чтоб так выглядел репорт в табе [1]: https://i.sstatic.net/rU55h2Zk.png
А у меня выглядит так [2]: https://i.sstatic.net/65lyIqpB.png
А страница pages/reports/index.vue выглядит так [3]: https://i.sstatic.net/pDUVgbfg.png
Мне надо только таблица отчетов чтоб в табе отображался, а не весь страница