<template> <div class="rolesTable"> <b-table :id="id" :fields="headers" :items="items" :busy="busy" :locale="$i18n.locale" :filter="filter" :sort-by="sortBy" :sort-desc.sync="sortDesc" :show-empty="true" :empty-text="emptyText" :empty-filtered-text="emptyFilteredText" fixed sticky-header="100%" no-border-collapse bordered sort-icon-right striped hover head-variant="dark" @filtered="onFiltered" > <div slot="table-busy" class="text-center text-danger my-2"> <b-spinner class="align-middle"></b-spinner> <strong style="margin-left: 1%">{{ $t("loading") }}</strong> </div> <template v-slot:cell(roleName)="row"> <div class="noOverflow"> <b-form-select v-model="row.item.role.id" :options="roles" v-on:change="role(row.item)" :disabled="!row.item.enabledControls" /> </div> </template> <template v-slot:cell(memberActions)="row"> <div class="noOverflow"> <coscine-button-delete :btnText="removeText" :disabled="!row.item.enabledControls" @delete="deleteItem(row.item)" ></coscine-button-delete> </div> </template> <template v-slot:cell(expiration)="row"> <div :class="{ 'text-danger': checkExpiration(row.item.expiration), }" > {{ getStatus(row.item.expiration) }} </div> </template> <template v-slot:cell(invitationActions)="selectedInvitation"> <div class="noOverflow"> <coscine-button-delete class="leftActionBtn" :btnText="removeText" @delete="revokeInvitation(selectedInvitation.item)" ></coscine-button-delete> <b-button class="rightActionBtn" @click="resendInvitation(selectedInvitation.item)" :disabled="!checkExpiration(selectedInvitation.item.expiration)" >{{ $t("resendBtn") }} </b-button> </div> </template> </b-table> </div> </template> <script lang="ts"> import Vue from "vue"; import { CoscineButtonDelete } from "@coscine/component-library"; import "@coscine/component-library/dist/index.css"; export default Vue.extend({ name: "MembersTable", components: { CoscineButtonDelete, }, data() { return { sortDesc: false, filteredRows: 0, }; }, props: { headers: { required: true, type: Array, }, id: String, items: { required: true, type: Array, }, filter: String, busy: Boolean, emptyText: String, emptyFilteredText: String, removeText: String, roles: { required: true, type: Array, }, sortBy: { default: "lastName", type: String, }, }, methods: { onFiltered(filteredItems: []) { this.filteredRows = filteredItems.length; this.$emit("tableFilteredRows", this.filteredRows); }, deleteItem(item: any) { this.$emit("selectedItem", item); }, role(item: any) { this.$emit("setRole", item); }, checkExpiration(expiration: string) { const today = new Date(); const expirationDate = new Date(expiration); if (expirationDate > today) { return false; } else { return true; } }, getStatus(expiration: string) { if (this.checkExpiration(expiration)) { return this.$t("expiredStatus"); } else { return this.$t("pendingStatus"); } }, revokeInvitation(selectedInvitation: any) { this.$emit("revokeInvitation", selectedInvitation); }, resendInvitation(selectedInvitation: any) { this.$emit("resendInvitation", selectedInvitation); }, }, }); </script> <style> .rolesTable { max-height: 65vh; table-layout: fixed; border: 1px solid #e5e5e5; height: 100vh; } .rolesTable td, th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; text-align: center; } .rolesTable td .noOverflow { text-overflow: clip; } </style>