In my laravel vue application I have following datatable with some filters in a vue component(department-user-list.vue).
<template>
<div>
<cs-card
:cardButton="false"
:title="`Team members`"
>
<template slot="header-action">
<div class="inline-block mr-4" direction-from="top">
<open-overlay identifier="corporateInviteEmployeeToDepartmentModal">
<cs-button size="small" variant="secondary">
Invite team member
</cs-button>
</open-overlay>
</div>
<div class="inline-block" direction-from="top">
<cs-button @click="redirectToAssignation" size="small">
Assign team member
</cs-button>
</div>
</template>
<Datatable
v-model="selectedForAction"
:data="dataset"
:headers="headers"
:is-loading="isLoading"
:has-action-bar-column="true"
:key-id="`id`"
:search-panel="{placeholder: 'Search team member...'}"
@change="handlePaginationChange"
@paginate="loadDepartmentEmployees"
>
<!--Filter Slot-->
<template v-slot:filters>
<!--Nationality filter-->
<div class="w-2/12 pl-4 h-auto">
<cs-multiple-select
v-model="nationalitiesFilter"
:options="countries"
key-id="id"
label="name"
name="nationality"
placeholder="Nationality"
>
</cs-multiple-select>
</div>
<!--Certificate Status filter-->
<div class="w-6/12 pl-4 h-auto">
<cs-multiple-select
v-model="certificateStatusFilter"
:options="certificateStatus"
name="certificateStatusFilter"
placeholder="Qualification status"
@input="loadDepartmentEmployees"
/>
</div>
<!--Matrix Status filter-->
<div class="w-4/12 pl-4 h-auto">
<cs-multiple-select
v-model="matrixStatusFilter"
:options="matrixStatus"
key-id="value"
label="label"
name="matrixStatusFilter"
placeholder="Matrix status"
@input="loadDepartmentEmployees"
/>
</div>
<!--Employee Type filter-->
<div class="w-4/12 pl-4 h-auto">
<cs-multiple-select
v-model="selectedEmployeeTypes"
:options="employeeType"
key-id="value"
label="label"
name="selectedEmployeeTypes"
placeholder="Employee type"
@input="loadDepartmentEmployees"
>
</cs-multiple-select>
</div>
</template>
<!--Table Header-->
<template v-slot:header.country="{ header}">
<span class="material-icons-outlined">language</span>
</template>
<!--Table Body-->
<template v-slot:item.name="{ item }">
<div class="flex items-center cursor-pointer">
<div class="rounded-full w-8 h-8 mr-4 overflow-hidden">
<img :src="item.profile_image[0].url" alt=""
class="w-full h-full object-cover">
</div>
<a :href="employeeDetailRoute(item)">
<span class="text-certstyle-titles font-bold leading-loose"></span>
</a>
<span
v-if="item.is_subcontractor && item.company_name"
:title="item.company_name"
class="text-certstyle-text-light bg-certstyle-background flex font-semibold cursor-help text-xs rounded mx-2 py-1 px-2"
>
<span v-if="item.company_name.length > 10">...</span>
</span>
</div>
</template>
<template v-slot:item.job_title="{ item }">
</template>
<template v-slot:item.country="{ item }">
<span v-if="item.country" class="font-normal">
<country-flag width="w-5" :country-code="item.country.country_code"></country-flag>
</span>
</template>
<template v-slot:item.certificate_status="{ item }">
<div class="status--summary--component inline-block mr-2 relative"
@click="getValidityStatus(item.certificate_matrix) !== 'all valid' &&
getValidityStatus(item.certificate_matrix) !== '-'
? openCertificatesModal(item) : null
">
<label :class="getValidityStatusClass(item.certificate_matrix)" class="badge">
</label>
</div>
</template>
<template v-slot:item.matrix_status="{ item }">
<div class="status--summary--component inline-block mr-2 relative"
@click="getMatrixStatus(item.certificate_matrix) === 'non compliant'
? openCertificatesModal(item)
: null
">
<label :class="getMatrixStatusClass(item.certificate_matrix)" class="badge">
</label>
</div>
</template>
<template v-slot:actionItems="slotProps">
<DatatableActionbarItem
:slot-props="slotProps"
identifier="removeConfirmationModal"
label="Remove"
variant="danger"
/>
</template>
<template v-slot:rowActionItems="slotProps">
<DatatableActionbarItem
icon=""
label="Contact details"
@click.native="openContactDetailsModal(slotProps.item)"
:slot-props="slotProps"
/>
</template>
</Datatable>
<modal-md
v-if="selectedEmployee !== null"
:options="{ useDefaultContentStyling: false }"
:identifier="`statusSummaryComponent`">
<template slot="modal_title">
Qualifications
<span v-if="selectedEmployee !== null && selectedEmployee !== undefined">
</span>
</template>
<div class="bg-white" slot="modal_content">
<div
class="flex items-center justify-between text-certstyle-text-light bg-white border-certstyle-border border-b text-sm py-2 px-10">
<cs-dashboard-table-header-item-unstyled :item="`statusSummaryCertificateTitle`">
<p>Qualification</p>
</cs-dashboard-table-header-item-unstyled>
<cs-dashboard-table-header-item-unstyled :item="`statusSummaryCertificateStatus`">
<p>Validity Status</p>
</cs-dashboard-table-header-item-unstyled>
<cs-dashboard-table-header-item-unstyled :item="`statusSummaryMatrixStatus`">
<p>Matrix Status</p>
</cs-dashboard-table-header-item-unstyled>
</div>
<!--Certificates-->
<div class="text-certstyle-titles">
<div v-for="certificate in selectedEmployee.certificate_matrix"
v-if="selectedEmployee.certificate_matrix.length > 0"
class="table--row flex items-center justify-between border-certstyle-border last:border-b-0 border-b px-10 py-4">
<!-- Title -->
<cs-dashboard-table-item-unstyled
class="w-1/2"
:item="`statusSummaryCertificateTitle`">
<p :title="certificate.title" class=" ">
</p>
</cs-dashboard-table-item-unstyled>
<cs-dashboard-table-item-unstyled class="w-32" :item="`statusSummaryCertificateStatus`">
<div class="flex items-center justify-start w-full">
<!--Expired styling-->
<label v-if="certificate.matrix_status === 0"
class="badge badge-danger">
-
</label>
<!--Expires styling-->
<label v-if="certificate.matrix_status && certificate.expired === 1"
class="badge badge-danger">
expired
</label>
<!--Expires styling-->
<label v-if="certificate.matrix_status && certificate.expire_soon === 1"
class="badge badge-danger">
expires soon
</label>
<!--Active styling-->
<label
v-if="certificate.matrix_status && certificate.expire_soon === 0 && certificate.expired === 0"
class="badge badge-success">
active
</label>
</div>
</cs-dashboard-table-item-unstyled>
<cs-dashboard-table-item-unstyled
class="w-32"
:item="`statusSummaryMatrixStatus`">
<!--Active styling-->
<label v-if="certificate.matrix_status"
class="badge badge-success">
compliant
</label>
<label v-else
class="badge badge-danger">
non-compliant
</label>
</cs-dashboard-table-item-unstyled>
</div>
<div v-else
class="table--row flex items-center justify-between border-certstyle-border last:border-b-0 border-b px-10 py-4">
<cs-dashboard-table-item-unstyled
class="w-1/2"
:item="`statusSummaryCertificateTitle`">
No certificates found
</cs-dashboard-table-item-unstyled>
<cs-dashboard-table-item-unstyled class="w-32"
:item="`statusSummaryCertificateStatus`">
</cs-dashboard-table-item-unstyled>
<cs-dashboard-table-item-unstyled
class="w-32"
:item="`statusSummaryMatrixStatus`">
</cs-dashboard-table-item-unstyled>
</div>
</div>
</div>
</modal-md>
</cs-card>
<contact-details
v-if="userToShowContactDetails"
:user="userToShowContactDetails"
/>
<add-employee-modal
:countries="countries"
:identifier="`addEmployeeModal`"
:invite-modal-title="`Invite to department`"
:suggestion-url="userSuggestionApiURL"
:title="`Assign to ${department ? department.name: ''}`"
@inviteEmployees="handleInvitedEmployees"
@selectEmployee="addEmployeeToDepartment"
@removeEmployee="handleRemoveEmployee"
/>
<cs-confirmation-modal
v-if="checkRole(['admin', 'planner'])"
@proceed="handleRemoveEmployee"
identifier="removeConfirmationModal">
<div class="text-certstyle-titles font-normal" slot="content">
Removing employees from this department can not be undo.
</div>
<div slot="cancelButton"
class="cursor-pointer hover:bg-certstyle-background border border-certstyle-border rounded px-6 py-2 text-certstyle-text-light mr-4">
Cancel
</div>
<cs-button slot="proceedButton">
Remove
</cs-button>
</cs-confirmation-modal>
</div>
</template>
This list and the filters works fine but when I try to search a user by typing their names, it kept giving me following error,
Duplicate keys detected: '1025'. This may cause an update error.
found in
---> at resources/js/components/reusable/datatable/Datatable.vue at resources/js/components/reusable/csCard.vue at resources/js/components/dashboard/communities/department/one-departments/department-user-list.vue
But when I try to filter the list by some other param, they get filtered without any error.
I'm struggling to find what I'm doing wrong here....
UPDATE
following is my non-filtered json data for a single user
{
"id": 1038,
"unique_id": "0a3938c1-07d5-3884-9df0-a8fe3201a3e5",
"first_name": "Mango",
"last_name": "F1",
"job_title": null,
"email": "mangoF1@gmail.com",
"phone_number": null,
"phone_country_calling_code": null,
"country_id": null,
"company_name": null,
"is_subcontractor": 0,
"current_jobtitle": "Deck Foreman",
"department_jobtitle": "Rigging Engineers",
"language": "en",
"email_verified_at": "2022-04-12T12:47:55.000000Z",
"gender": null,
"state": null,
"postal_code": null,
"house_number": null,
"street": null,
"city": null,
"date_of_birth": null,
"city_of_birth": null,
"emergency_number": null,
"opt_in": null,
"created_at": "2022-04-12T12:46:34.000000Z",
"updated_at": "2022-04-12T12:47:55.000000Z",
"emergency_number_country_calling_code": null,
"deleted_at": null,
"has_ip_restriction": 0,
"address": null,
"latitude": null,
"longitude": null,
"place_id": null,
"bouwpas_worker_id": null,
"bouwpas_certificate_id": null,
"certificate_matrix": [
{
"id": 463,
.....
}
]
},
Following is my controller function,
public function index($locale, Company $company, Department $department, Request $request)
{
$this->authorize('viewUsers', [Department::class, $company, $department]);
$users = $department->usersWithSubcontractors()
// ->notApiUser()
->select(
'users.id',
'unique_id',
'first_name',
'last_name',
'job_title',
'email',
'phone_number',
'unique_id',
'phone_country_calling_code',
'country_id',
'company_name',
'is_subcontractor',
)->addSelect([
'current_jobtitle' => JobTitle::selectRaw('IFNULL(project_specific_job_titles.title, job_titles.title)')
->join('project_track_records', 'project_track_records.user_id', 'users.id', 'inner')
->join('project_specific_job_titles', 'project_track_records.project_specific_job_title_id', 'project_specific_job_titles.id', 'inner')
->whereColumn('job_titles.id', 'project_specific_job_titles.job_title_id')
->whereDate('project_track_records.start_date', '<=', Carbon::now())
->whereDate('project_track_records.end_date', '>=', Carbon::now())
->limit(1),
'department_jobtitle' => JobTitle::selectRaw('title')->whereColumn('job_titles.id', 'department_user.job_title_id'),
])->when(request('q'), function ($q) {
$q->where(function ($q) {
$q->whereRaw("CONCAT_WS(' ', `first_name`, `last_name`) like '%" . request('q') . "%'");
});
})->when($request->get('employeeType'), function ($q) use ($request) {
$q->whereIn('users.is_subcontractor', $request->get('employeeType'));
})->paginate(\request('per_page', config('repository.pagination.limit')));
$users->load('country');
$users->append(['profile_image']);
$users->makeVisible(['unique_id']);
$users->map(fn ($item) => $item->certificate_matrix = (new GetCertificationMatrixQueryAction())->execute($item->id, $department->id));
if ($request->filled('certificateStatus')) {
$valid = in_array('valid', $request->get('certificateStatus'));
$expire_soon = in_array('expire soon', $request->get('certificateStatus'));
$expired = in_array('expired', $request->get('certificateStatus'));
if ($valid) $users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && !$certificate->expire_soon && !$certificate->expired)->count() === $item->certificate_matrix->count())->values());
if ($expire_soon && !$expired) $users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && $certificate->expire_soon)->count() > 0)->values());
if ($expired && !$expire_soon) $users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && $certificate->expired)->count() > 0)->values());
}
if ($request->filled('matrixStatus')) {
$compliant = in_array('compliant', $request->get('matrixStatus'));
$non_compliant = in_array('non-compliant', $request->get('matrixStatus'));
if ($non_compliant && !$compliant)
$users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status === 0 || $certificate->expire_soon || !$certificate->expired)->count() > 0)->values());
if ($compliant && !$non_compliant)
$users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && !$certificate->expire_soon && !$certificate->expired)->count() == $item->certificate_matrix->count())->values());
}
return response()->json($users);
}
from Duplicate keys detected: 'X'. This may cause an update error. in VueJS datatable search
No comments:
Post a Comment