Skip to content

Instantly share code, notes, and snippets.

@dansp89
Created March 3, 2024 19:27
Show Gist options
  • Save dansp89/6cf9e88a0632ed6755fbed214c8df525 to your computer and use it in GitHub Desktop.
Save dansp89/6cf9e88a0632ed6755fbed214c8df525 to your computer and use it in GitHub Desktop.
Coluna 'Actions' não está renderizando
<template>
<!--begin::Card-->
<div class="card">
<!--begin::Card header-->
<div class="card-header border-0 pt-6">
<!--begin::Card title-->
<div class="card-title">
<!--begin::Search-->
<div class="d-flex align-items-center position-relative my-1">
<KTIcon icon-name="magnifier" icon-class="fs-1 position-absolute ms-6" />
<input
v-model="search"
@input="searchItems()"
type="text"
data-kt-item-table-filter="search"
class="form-control form-control-solid w-250px ps-14"
:placeholder="`Pesquisar ${nameSingle}`"
/>
</div>
<!--end::Search-->
</div>
<!--begin::Card title-->
<!--begin::Card toolbar-->
<div class="card-toolbar">
<!--begin::Toolbar-->
<div
v-if="selectedIds.length === 0"
class="d-flex justify-content-end"
data-kt-item-table-toolbar="base"
>
<!--begin::Export-->
<button
type="button"
class="btn btn-light-primary me-3"
data-bs-toggle="modal"
data-bs-target="#kt_items_export_modal"
>
<KTIcon icon-name="exit-up" icon-class="fs-2" />
Export
</button>
<!--end::Export-->
<!--begin::Add item-->
<router-link to="/apps/items/add-item" class="btn btn-primary">
<KTIcon icon-name="plus" icon-class="fs-2" />
Add Item
</router-link>
<!--end::Add item-->
</div>
<!--end::Toolbar-->
<!--begin::Group actions-->
<div v-else class="d-flex justify-content-end align-items-center">
<div class="fw-bold me-5">
<span class="me-2">{{ selectedIds.length }}</span>
Selected
</div>
<button type="button" class="btn btn-danger" @click="deleteFewItems()">
Delete Selected
</button>
</div>
<!--end::Group actions-->
</div>
<!--end::Card toolbar-->
</div>
<!--end::Card header-->
<!--begin::Card body-->
<div class="card-body pt-0">
<KTDatatable
@on-sort="sort"
@on-items-select="onItemSelect"
@on-items-per-page-change="onItemsPerPageChange"
:data="data"
:header="headerConfig"
:checkbox-enabled="true"
>
<template v-slot:id="{ row }">
{{ row.id }}
</template>
<!-- Renderização automática dos slots para cada coluna -->
<template
v-for="(column, index) in headerConfig"
:key="index"
v-slot:[column.columnLabel]="{ row }"
>
{{ row[column.columnLabel] }}
</template>
<template v-slot:actions="{ row }">
<a
href="#"
class="btn btn-sm btn-light btn-active-light-primary"
data-kt-menu-trigger="click"
data-kt-menu-placement="bottom-end"
data-kt-menu-flip="top-end"
>
Ações
<KTIcon icon-name="down" icon-class="fs-5 m-0" />
</a>
<!--begin::Menu-->
<div
class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-semibold fs-7 w-125px py-4"
data-kt-menu="true"
>
<!--begin::Menu item-->
<div class="menu-item px-3">
<router-link :to="`/apps/customers/${row.id}`" class="menu-link px-3">
Ver
</router-link>
</div>
<!--end::Menu item-->
<!--begin::Menu item-->
<div class="menu-item px-3">
<a @click="deleteItem(row.id)" class="menu-link px-3">Apagar</a>
</div>
<!--end::Menu item-->
</div>
<!--end::Menu-->
</template>
</KTDatatable>
</div>
<!--end::Card body-->
</div>
<!--end::Card-->
</template>
<script lang="ts">
import { defineComponent, ref, type PropType, onMounted } from "vue";
import KTDatatable from "@/components/kt-datatable/KTDataTable.vue";
import type { Sort } from "@/components/kt-datatable/table-partials/models";
import arraySort from "array-sort";
import { MenuComponent } from "@/assets/ts/components";
import ApiService from "@/core/services/ApiService";
interface HeaderConfigItem {
columnName: string;
columnLabel: string;
sortEnabled?: boolean;
}
interface EndpointConfig {
endpoint: string;
params?: string;
}
export default defineComponent({
name: "kt-table-list",
components: {
KTDatatable
},
props: {
nameSingle: {
type: String,
default: "item",
required: true
},
cols: {
type: Object,
required: true,
default: () => ({})
},
readAll: {
type: Object as PropType<EndpointConfig>,
required: true
},
create: {
type: Object as PropType<EndpointConfig>,
required: true
},
read: {
type: Object as PropType<EndpointConfig>,
required: true
},
update: {
type: Object as PropType<EndpointConfig>,
required: true
},
delete: {
type: Object as PropType<EndpointConfig>,
required: true
}
},
setup(props) {
const data = ref();
const headerConfig = ref<HeaderConfigItem[]>([]);
const initData = ref<Array<any>>([]);
const loadDatas = async () => {
try {
const { data } = await ApiService.get(props.readAll.endpoint, props.readAll?.params);
let items = data.data;
items = await items.map((a) => {
const b = a.attributes;
return {
id: a?.id,
title: b?.title,
description: b?.description,
descriptionResume: b?.descriptionResume,
priceRegular: b?.priceRegular,
priceSale: b?.priceSale,
priceSaleStart: b?.priceSaleStart,
priceSaleEnd: b?.priceSaleEnd,
sku: b?.sku,
stock: b?.stock,
productCode: b?.productCode,
createdAt: b?.createdAt,
updatedAt: b?.updatedAt,
priceSaleActiveCron: b?.priceSaleActiveCron
};
});
return items;
} catch (error) {
console.error("[TABLE][ERROR]: ", error);
return false;
}
};
onMounted(async () => {
const datasArr = await loadDatas();
data.value = datasArr;
const headers = Object.keys(data.value?.[0])?.map((a) => {
const cols = Object.keys(props.cols);
// console.log("COLS:", cols, a, cols, props.cols[a]);
if (cols.includes(a)) {
return {
columnName: props.cols[a],
columnLabel: a,
sortEnabled: true
};
}
});
headerConfig.value = headers.filter(Boolean);
headerConfig.value.push({
columnName: "Ações",
columnLabel: "actions"
});
console.log("[TABLE][DATAS]", JSON.stringify(data.value, null, 2));
initData.value.splice(0, data.value.length, ...data.value);
});
const selectedIds = ref<Array<number>>([]);
const deleteFewItems = () => {
selectedIds.value.forEach((item) => {
deleteItem(item);
});
selectedIds.value.length = 0;
};
const deleteItem = (id: number) => {
for (let i = 0; i < data.value.length; i++) {
if (data.value[i]["id"] === id) {
data.value.splice(i, 1);
}
}
};
const sort = (sort: Sort) => {
const reverse: boolean = sort.order === "asc";
if (sort.label) {
arraySort(data.value, sort.label, { reverse });
}
};
const onItemSelect = (selectedItems: Array<number>) => {
selectedIds.value = selectedItems;
};
const search = ref<string>("");
const searchItems = () => {
data.value.splice(0, data.value.length, ...initData.value);
if (search.value !== "") {
let results: Array<any> = [];
for (let j = 0; j < initData.value.length; j++) {
if (searchingFunc(initData.value[j], search.value)) {
results.push(initData.value[j]);
}
}
data.value.splice(0, data.value.length, ...results);
}
MenuComponent.reinitialization();
};
const searchingFunc = (obj: any, value: string): boolean => {
for (let key in obj) {
if (!Number.isInteger(obj[key]) && !(typeof obj[key] === "object")) {
if (obj[key].toLowerCase().indexOf(value.toLowerCase()) != -1) {
return true;
}
}
}
return false;
};
const onItemsPerPageChange = () => {
setTimeout(() => {
MenuComponent.reinitialization();
}, 0);
};
return {
search,
searchItems,
data,
headerConfig,
sort,
onItemSelect,
selectedIds,
deleteFewItems,
deleteItem,
onItemsPerPageChange
};
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment