jws-frontend/src/components/shared/SelectZone.vue

77 lines
2 KiB
Vue

<script setup lang="ts">
const search = defineModel<string>('search');
const selectedItem = defineModel<unknown[]>('selectedItem', { default: [] });
const props = withDefaults(
defineProps<{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
items: any;
color?: string;
}>(),
{
items: () => [],
color: 'var(--brand-1)',
},
);
function select(item: unknown) {
if (selectedItem.value.includes(item)) {
let index = selectedItem.value.indexOf(item);
selectedItem.value.splice(index, 1);
} else selectedItem.value.push(item);
}
</script>
<template>
<section class="full-width column q-pa-md">
<header class="row items-center no-wrap q-mb-md">
<div class="col"><slot name="top"></slot></div>
<q-input
for="input-search"
outlined
dense
:label="$t('general.search')"
class="q-ml-auto"
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
v-model="search"
debounce="200"
>
<template #prepend>
<q-icon name="mdi-magnify" />
</template>
</q-input>
</header>
<section class="col">
<div class="row q-col-gutter-md">
<div
v-for="(item, i) in items"
:key="i"
class="col-md-2 col-sm-6 col-12"
>
<div
class="rounded cursor-pointer relative-position"
:style="`border: 1px solid ${selectedItem.includes(item) ? color : 'transparent'}`"
@click="() => select(item)"
>
<div
v-if="selectedItem.includes(item)"
class="badge absolute-top-right flex justify-center q-ma-sm"
:style="`background-color: ${color}`"
>
{{ selectedItem.indexOf(item) + 1 }}
</div>
<slot name="data" :item="item"></slot>
</div>
</div>
</div>
</section>
</section>
</template>
<style lang="scss" scoped>
.badge {
border-radius: 50%;
width: 20px;
height: 20px;
color: var(--surface-1);
}
</style>