Files
template-nuxtsim/components/table/EditableTable.vue

229 lines
9.1 KiB
Vue

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useContactStore } from '~/stores/apps/contact';
import user from '~/assets/images/profile/user-3.jpg';
import contact from '~/_mockApis/apps/contact';
import { usePermission } from '@/composables/sidebarMenu/useSidebarAkses'
const canAction = usePermission(useRoute().path); // cek permission halaman
const canAkses = canAction.canAkses;
if(canAkses?.includes('view')){
console.log('permision halaman',canAkses);
}
const store = useContactStore();
onMounted(() => {
store.fetchContacts();
});
const getContacts: any = computed(() => {
return store.contacts;
});
const valid = ref(true);
const dialog = ref(false);
const search = ref('');
const rolesbg = ref(['primary', 'secondary', 'error', 'success', 'warning']);
const desserts = ref(contact);
const editedIndex = ref(-1);
const editedItem = ref({
id: '',
avatar: user,
userinfo: '',
usermail: '',
phone: '',
jdate: '',
role: '',
rolestatus: ''
});
const defaultItem = ref({
id: '',
avatar: user,
userinfo: '',
usermail: '',
phone: '',
jdate: '',
role: '',
rolestatus: ''
});
//Methods
const filteredList = computed(() => {
return desserts.value.filter((user: any) => {
return user.userinfo.toLowerCase().includes(search.value.toLowerCase());
});
});
function editItem(item: any) {
editedIndex.value = desserts.value.indexOf(item);
editedItem.value = Object.assign({}, item);
dialog.value = true;
}
function deleteItem(item: any) {
const index = desserts.value.indexOf(item);
confirm('Are you sure you want to delete this item?') && desserts.value.splice(index, 1);
}
function close() {
dialog.value = false;
setTimeout(() => {
editedItem.value = Object.assign({}, defaultItem.value);
editedIndex.value = -1;
}, 300);
}
function save() {
if (editedIndex.value > -1) {
Object.assign(desserts.value[editedIndex.value], editedItem.value);
} else {
desserts.value.push(editedItem.value);
}
close();
}
//Computed Property
const formTitle = computed(() => {
return editedIndex.value === -1 ? 'New Contact' : 'Edit Contact';
});
</script>
<template>
<v-row>
<v-col cols="12" lg="4" md="6">
<v-text-field density="compact" v-model="search" label="Search Contacts" hide-details variant="outlined"></v-text-field>
</v-col>
<v-col cols="12" lg="8" md="6" class="text-right">
<v-dialog v-model="dialog" max-width="500">
<template v-slot:activator="{ props }">
<v-btn :disabled="!canAkses?.includes('create')" color="primary" v-bind="props" flat class="ml-auto">
<v-icon class="mr-2">mdi-account-multiple-plus</v-icon>Add Contact
</v-btn>
</template>
<v-card>
<v-card-title class="pa-4 bg-primary">
<span class="title text-white">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-form ref="form" v-model="valid" lazy-validation>
<v-row>
<v-col cols="12" sm="6">
<v-text-field variant="outlined" hide-details v-model="editedItem.id" label="Id"></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.userinfo"
label="User info"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.usermail"
label="User email"
type="email"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.phone"
label="Phone"
type="phone"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.jdate"
label="Joining Date"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field variant="outlined" hide-details v-model="editedItem.role" label="Role"></v-text-field>
</v-col>
<v-col cols="12" sm="12">
<v-select
variant="outlined"
hide-details
:items="rolesbg"
v-model="editedItem.rolestatus"
label="Role Background"
></v-select>
</v-col>
</v-row>
</v-form>
</v-card-text>
<v-card-actions class="pa-4">
<v-spacer></v-spacer>
<v-btn color="error" variant="flat" @click="close">Cancel</v-btn>
<v-btn
color="primary"
:disabled="editedItem.userinfo == '' || editedItem.usermail == ''"
variant="flat"
@click="save"
>Save</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</v-col>
</v-row>
<v-table class="mt-5">
<thead>
<tr>
<th class="text-body-1">Id</th>
<th class="text-body-1">UserInfo</th>
<th class="text-body-1">Phone</th>
<th class="text-body-1">Joining Date</th>
<th class="text-body-1">Role</th>
<th class="text-body-1">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="item in filteredList" :key="item.id">
<td class="text-subtitle-1">{{ item.id }}</td>
<td>
<div class="d-flex align-center">
<div>
<v-img :src="item.avatar" width="45px" class="rounded-circle img-fluid"></v-img>
</div>
<div class="ml-5">
<h4 class="text-subtitle-1 text-no-wrap">{{ item.userinfo }}</h4>
<span class="text-subtitle-1 d-block mt-1 textSecondary">{{ item.usermail }}</span>
</div>
</div>
</td>
<td class="text-subtitle-1">{{ item.phone }}</td>
<td class="text-subtitle-1">{{ item.jdate }}</td>
<td>
<v-chip :color="item.rolestatus" size="small" rounded="sm" label>{{ item.role }}</v-chip>
</td>
<td>
<div class="d-flex align-center">
<v-tooltip text="Edit">
<template v-slot:activator="{ props }">
<v-btn :disabled="!canAkses?.includes('update')" icon flat @click="editItem(item)" v-bind="props"
><PencilIcon stroke-width="1.5" size="20" class="text-primary"
/></v-btn>
</template>
</v-tooltip>
<v-tooltip text="Delete">
<template v-slot:activator="{ props }">
<v-btn :disabled="!canAkses?.includes('delete')" icon flat @click="deleteItem(item)" v-bind="props"
><TrashIcon stroke-width="1.5" size="20" class="text-error"
/></v-btn>
</template>
</v-tooltip>
</div>
</td>
</tr>
</tbody>
</v-table>
</template>