mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-21 13:23:14 +01:00
* feat: implement example of data table * feat: load item data into table * chore: begin switching dialogs * feat: implement old dialog for controlling headers and page size * feat: get table into relatively usable state * feat: enhance dropdown actions for multi-selection and CSV download * feat: enhance table cell and dropdown button styles for better usability * feat: json download for table * feat: add expanded row component for item details in data table * chore: add translation support * feat: restore table on home page * fix: oops need ids * feat: move card view to use tanstack to allow for pagination * feat: switch the items search to use ItemViewSelectable * fix: update pagination handling and improve button click logic * feat: improve selectable table * feat: add indeterminate to checkbox * feat: overhaul maintenance dialog to use new system and add maintenance options to table * feat: add label ids and location id to item patch api * feat: change location and labels in table view * feat: add quick actions preference and enable toggle in table settings * fix: lint * fix: remove sized 1 pages * fix: attempt to fix type error * fix: various issues * fix: remove * fix: refactor item fetching logic to use useAsyncData for improved reactivity and improve use confirm * fix: sort backend issues * fix: enhance CSV export functionality by escaping fields to prevent formula injection * fix: put aria sort on th not button * chore: update api types
67 lines
2.3 KiB
Vue
67 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import ItemCard from "@/components/Item/Card.vue";
|
|
import type { ItemSummary } from "~/lib/api/types/data-contracts";
|
|
import type { Table as TableType } from "@tanstack/vue-table";
|
|
import MdiSelectSearch from "~icons/mdi/select-search";
|
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
import DropdownAction from "./data-table-dropdown.vue";
|
|
|
|
const preferences = useViewPreferences();
|
|
|
|
const props = defineProps<{
|
|
table: TableType<ItemSummary>;
|
|
locationFlatTree?: FlatTreeItem[];
|
|
}>();
|
|
|
|
defineEmits<{
|
|
(e: "refresh"): void;
|
|
}>();
|
|
|
|
const selectedCount = computed(() => props.table.getSelectedRowModel().rows.length);
|
|
</script>
|
|
|
|
<template>
|
|
<Teleport to="#selectable-subtitle" defer>
|
|
<Checkbox
|
|
class="size-6 p-0"
|
|
:model-value="
|
|
table.getIsAllPageRowsSelected() ? true : table.getSelectedRowModel().rows.length > 0 ? 'indeterminate' : false
|
|
"
|
|
:aria-label="$t('components.item.view.selectable.select_all')"
|
|
@update:model-value="table.toggleAllPageRowsSelected(!!$event)"
|
|
/>
|
|
|
|
<div class="grow" />
|
|
|
|
<div :class="['relative inline-flex items-center', selectedCount === 0 ? 'pointer-events-none opacity-50' : '']">
|
|
<DropdownAction
|
|
:multi="{ items: table.getSelectedRowModel().rows, columns: table.getAllColumns() }"
|
|
view="card"
|
|
:table="table"
|
|
@refresh="$emit('refresh')"
|
|
/>
|
|
|
|
<span v-if="selectedCount > 0" class="absolute -right-1 -top-1 flex size-4">
|
|
<span
|
|
class="pointer-events-none relative flex size-4 items-center justify-center whitespace-nowrap rounded-full bg-primary p-1 text-xs text-primary-foreground"
|
|
>
|
|
{{ String(selectedCount) }}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</Teleport>
|
|
<div v-if="table.getRowModel().rows?.length === 0" class="flex flex-col items-center gap-2">
|
|
<MdiSelectSearch class="size-10" />
|
|
<p>{{ $t("items.no_results") }}</p>
|
|
</div>
|
|
<div v-else class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
|
<ItemCard
|
|
v-for="item in table.getRowModel().rows"
|
|
:key="item.original.id"
|
|
:item="item.original"
|
|
:table-row="preferences.quickActions.enabled ? item : undefined"
|
|
:location-flat-tree="locationFlatTree"
|
|
/>
|
|
</div>
|
|
</template>
|