123 lines
3.2 KiB
Vue
123 lines
3.2 KiB
Vue
<script setup>
|
|
import { ref } from 'vue';
|
|
import { useArrayData } from 'composables/useArrayData';
|
|
const model = defineModel({ type: Object });
|
|
const $props = defineProps({
|
|
name: {
|
|
type: [String, Boolean],
|
|
default: '',
|
|
},
|
|
label: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
dataKey: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
searchUrl: {
|
|
type: String,
|
|
default: 'table',
|
|
},
|
|
vertical: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
align: {
|
|
type: String,
|
|
default: 'end',
|
|
},
|
|
});
|
|
const hover = ref();
|
|
const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl });
|
|
|
|
async function orderBy(name, direction) {
|
|
if (!name) return;
|
|
switch (direction) {
|
|
case 'DESC':
|
|
direction = undefined;
|
|
break;
|
|
case undefined:
|
|
direction = 'ASC';
|
|
break;
|
|
case 'ASC':
|
|
direction = 'DESC';
|
|
break;
|
|
}
|
|
if (!direction) return await arrayData.deleteOrder(name);
|
|
|
|
await arrayData.addOrder(name, direction);
|
|
}
|
|
|
|
defineExpose({ orderBy });
|
|
|
|
function textAlignToFlex(textAlign) {
|
|
return `justify-content: ${
|
|
{
|
|
'text-center': 'center',
|
|
'text-left': 'start',
|
|
'text-right': 'end',
|
|
}[textAlign] || 'start'
|
|
};`;
|
|
}
|
|
</script>
|
|
<template>
|
|
<div
|
|
@mouseenter="hover = true"
|
|
@mouseleave="hover = false"
|
|
@click="orderBy(name, model?.direction)"
|
|
class="items-center no-wrap cursor-pointer title"
|
|
:style="textAlignToFlex(align)"
|
|
>
|
|
<span :title="label">{{ label }}</span>
|
|
<div v-if="name">
|
|
<QChip
|
|
:label="!vertical ? model?.index : ''"
|
|
:icon="
|
|
(model?.index || hover) && !vertical
|
|
? model?.direction == 'DESC'
|
|
? 'arrow_downward'
|
|
: 'arrow_upward'
|
|
: undefined
|
|
"
|
|
:size="vertical ? '' : 'sm'"
|
|
:class="[
|
|
model?.index ? 'color-vn-text' : 'bg-transparent',
|
|
vertical ? 'q-px-none' : '',
|
|
]"
|
|
class="no-box-shadow"
|
|
:clickable="true"
|
|
style="min-width: 40px; max-height: 30px"
|
|
>
|
|
<div
|
|
class="column justify-center text-center"
|
|
v-if="vertical"
|
|
:style="!model?.index && 'color: #5d5d5d'"
|
|
>
|
|
{{ model?.index }}
|
|
<QIcon
|
|
:name="
|
|
model?.index
|
|
? model?.direction == 'DESC'
|
|
? 'arrow_downward'
|
|
: 'arrow_upward'
|
|
: 'swap_vert'
|
|
"
|
|
size="xs"
|
|
/>
|
|
</div>
|
|
</QChip>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<style lang="scss" scoped>
|
|
.title {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 30px;
|
|
width: 100%;
|
|
color: var(--vn-label-color);
|
|
white-space: nowrap;
|
|
}
|
|
</style>
|