conflict-nuxt-4/app/components/auto-import/HeaderTools.vue
2026-02-14 13:20:18 +03:30

472 lines
21 KiB
Vue
Executable File

<template>
<div :ref="selectedTabDetails" class="w-full">
<div class="container-fluid max-w-full px-3">
<div class="row">
<div class="col-12 px-3">
<div
class="mt-3 mb-1 flex h-auto items-center justify-between bg-gray-100 dark:bg-dark-primary-800 rounded-md p-1"
>
<div class="w-full">
<div
v-for="(headerItems, index) in headerTools"
:key="index"
class="flex justify-between items-center my-2"
>
<div class="flex justify-between w-full flex-wrap px-2">
<div
v-for="(my_item, idx) in getArrayItems(headerItems)"
:key="idx"
class="flex items-center flex-wrap"
>
<template v-if="isArrayItems(my_item)">
<div
v-for="(headItem, myItemIndex) in getArrayItems(
my_item,
)"
:key="myItemIndex"
class="flex items-center"
>
<DropdownSetting
v-if="headItem.type === 'dropdownSetting'"
:schema="headItem"
@dropdown-setting-btn-clicked="
(val) =>
emitHandler('dropdown-setting', { data: val })
"
/>
<div v-else-if="headItem.key === 'label'" class="mr-3">
<span class="text-primary font-medium px-3">{{
headItem.label
}}</span>
</div>
<div v-else-if="headItem.key === 'text'" class="mr-3">
<span class="text-primary font-medium px-3"
>{{ headItem.label }}:</span
>
<span>{{ getDataValue(headItem.source_key) }}</span>
</div>
<div v-else-if="headItem.key === 'switch'" class="mr-2">
<SwitchButtons
:switchSchema="headItem.switchSchema"
@update:model-value="
(val) =>
emitHandler('switch-component-change', {
data: {
name: headItem.name,
value: val,
item: headItem,
},
})
"
/>
</div>
<div
v-else-if="headItem.key === 'range'"
class="flex items-center mx-1"
>
<label
v-if="headItem.label"
class="text-sm text-gray-600 me-2"
>
{{ headItem.label }}
</label>
<input
type="range"
class="form-range appearance-none h-1.5 w-24 bg-gray-200 rounded-lg outline-none"
:min="headItem.min || 0"
:max="headItem.max || 5"
:step="headItem.step || 1"
:value="headItem.value"
@input="(e) => handleRange(e, headItem)"
/>
<span class="ms-2 text-sm min-w-[18px] text-center">{{
headItem.value
}}</span>
</div>
<button
v-else-if="headItem.key === 'icon'"
class="btn p-2 rounded hover:text-primary transition-colors"
:title="headItem.label"
@click="emitHandler('icon-click', { data: headItem })"
>
<!-- <svg :class="'icon icon-' + headItem.icon">
<use :xlink:href="'#icon-' + headItem.icon" />
</svg> -->
<UIcon
:name="headItem.icon"
:class="headItem.size"
class="cursor-pointer"
/>
</button>
<div
v-else-if="
headItem.key === 'multiSelect' ||
headItem.key === 'dropdown'
"
class="mx-1"
>
<MySelect
v-model:dropdownSchema="headItem.dropdownSchema"
:selectSchema="headItem.dropdownSchema"
@dropdownSelectEvents="
(event) => {
if (!event) return;
if (event.action !== 'change') return;
emitHandler('multiselect-click', {
data: {
name: headItem.name,
value: event.payload,
item: headItem,
},
});
}
"
/>
</div>
<div v-else-if="headItem.key === 'button'">
<button
class="btn bg-primary text-white px-3 py-1 rounded hover:bg-primary-dark"
@click="
emitHandler('button-click', { data: headItem })
"
>
{{ headItem.label }}
</button>
</div>
<div v-else-if="headItem.key === 'iconButton'">
<button
class="btn flex items-center gap-1 px-2 py-1 rounded hover:text-primary"
@click="
emitHandler('iconButton-click', {
data: headItem,
})
"
:style="{ color: headItem.color }"
>
<svg
v-if="headItem.side === 'right'"
:class="'icon icon-' + headItem.icon"
>
<use :xlink:href="'#icon-' + headItem.icon" />
</svg>
{{ headItem.label }}
<svg
v-if="headItem.side === 'left'"
:class="'icon icon-' + headItem.icon"
>
<use :xlink:href="'#icon-' + headItem.icon" />
</svg>
</button>
</div>
<div
v-else-if="
headItem.key === 'rangeDate' && !headItem.isShow
"
>
<RangeDateToolsHeader
@date-picker-handler="
(val) => emitHandler('date-picker', { data: val })
"
/>
</div>
<div v-else-if="headItem.key === 'autoComplation'">
<AutoComplation
@auto-complation-handler="
(val) =>
emitHandler('auto-complation', { data: val })
"
:autoComplationSchema="{
placeholder: headItem.placeholder,
autocompleteUrl: headItem.autocompleteUrl,
debounceTime: headItem.debounceTime,
minCharsForAutocomplete:
headItem.minCharsForAutocomplete,
maxHistoryItems: headItem.maxHistoryItems,
showSearchButton: headItem.showSearchButton,
filters: headItem.filters,
}"
/>
</div>
<div
v-else-if="headItem.key === 'prevNext'"
class="flex items-center gap-2"
>
<button
class="flex items-center btn bg-primary text-white pl-2 py-1 rounded hover:bg-primary-700 transition-colors duration-300 ease-in-out disabled:cursor-not-allowed"
:disabled="headItem.prevDisabled"
@click="
emitHandler('prev-click', { data: headItem })
"
>
<UIcon
name="i-lucide-chevron-right"
class="w-6 h-6"
/>
<span>قبلی</span>
</button>
<button
class="flex items-center btn bg-primary text-white pr-2 py-1 rounded hover:bg-primary-700 transition-colors duration-300 ease-in-out disabled:cursor-not-allowed"
:disabled="headItem.nextDisabled"
@click="
emitHandler('next-click', { data: headItem })
"
>
<span>بعدی</span>
<UIcon
name="i-lucide-chevron-left"
class="w-6 h-6"
/>
</button>
</div>
</div>
</template>
<!-- Non-array items -->
<template v-else>
<DropdownSetting
v-if="my_item.type === 'dropdownSetting'"
:schema="my_item"
@dropdown-setting-btn-clicked="
(val) =>
emitHandler('dropdown-setting', { data: val })
"
/>
<div v-else-if="my_item.key === 'label'" class="mr-3">
<span class="text-primary font-medium px-3">{{
my_item.label
}}</span>
</div>
<div v-else-if="my_item.key === 'text'" class="mr-3">
<span class="text-primary font-medium px-3"
>{{ my_item.label }}:</span
>
<span>{{ getDataValue(my_item.source_key) }}</span>
</div>
<!-- جایگزینی سوئیچ قدیمی -->
<div v-else-if="my_item.key === 'switch'" class="mr-2">
<SwitchButtons
:switchSchema="my_item.switchSchema"
@update:model-value="
(val) =>
emitHandler('switch-component-change', {
data: {
name: my_item.name,
value: val,
item: my_item,
},
})
"
/>
</div>
<div
v-else-if="my_item.key === 'range'"
class="flex items-center mx-1"
>
<label
v-if="my_item.label"
class="text-sm text-gray-600 me-2"
>
{{ my_item.label }}
</label>
<input
type="range"
class="form-range appearance-none h-1.5 w-24 bg-gray-200 rounded-lg outline-none"
:min="my_item.min || 0"
:max="my_item.max || 5"
:step="my_item.step || 1"
:value="my_item.value"
@input="(e) => handleRange(e, my_item)"
/>
<span class="ms-2 text-sm min-w-[18px] text-center">{{
my_item.value
}}</span>
</div>
<button
v-else-if="my_item.key === 'icon'"
class="btn p-2 rounded hover:text-primary transition-colors"
:title="my_item.label"
@click="emitHandler('icon-click', { data: my_item })"
>
<!-- <svg :class="'icon icon-' + my_item.icon">
<use :xlink:href="'#icon-' + my_item.icon" />
</svg> -->
<UIcon :name="my_item.icon" :class="my_item.size" />
</button>
<div
v-else-if="
my_item.key === 'multiSelect' ||
my_item.key === 'dropdown'
"
class="mx-1"
>
<MySelect
v-model:dropdownSelectConfig="my_item.dropdownSchema"
:selectSchema="my_item.dropdownSchema"
@dropdownSelectEvents="
(event) => {
if (event.action !== 'change') return;
emitHandler('multiselect-click', {
data: {
name: my_item.name,
value: event.payload,
item: my_item,
},
});
}
"
/>
</div>
<div v-else-if="my_item.key === 'button'">
<button
class="btn bg-primary text-white px-3 py-1 rounded hover:bg-primary-dark"
@click="
emitHandler('button-click', { data: my_item })
"
>
{{ my_item.label }}
</button>
</div>
<div v-else-if="my_item.key === 'iconButton'">
<button
class="btn flex items-center gap-1 px-2 py-1 rounded hover:text-primary"
@click="
emitHandler('iconButton-click', { data: my_item })
"
:style="{ color: my_item.color }"
>
<svg
v-if="my_item.side === 'right'"
:class="'icon icon-' + my_item.icon"
>
<use :xlink:href="'#icon-' + my_item.icon" />
</svg>
{{ my_item.label }}
<svg
v-if="my_item.side === 'left'"
:class="'icon icon-' + my_item.icon"
>
<use :xlink:href="'#icon-' + my_item.icon" />
</svg>
</button>
</div>
<div
v-else-if="
my_item.key === 'rangeDate' && !my_item.isShow
"
>
<RangeDateToolsHeader
@date-picker-handler="
(val) => emitHandler('date-picker', { data: val })
"
/>
</div>
<div v-else-if="my_item.key === 'autoComplation'">
<AutoComplation
@auto-complation-handler="
(val) =>
emitHandler('auto-complation', { data: val })
"
:autoComplationSchema="{
autocompleteUrl: my_item.autocompleteUrl,
placeholder: my_item.placeholder,
debounceTime: my_item.debounceTime,
minCharsForAutocomplete:
my_item.minCharsForAutocomplete,
maxHistoryItems: my_item.maxHistoryItems,
showSearchButton: my_item.showSearchButton,
filters: my_item.filters,
}"
/>
</div>
<div
v-else-if="my_item.key === 'prevNext'"
class="flex items-center gap-2"
>
<button
class="flex items-center btn bg-primary text-white pl-2 py-1 rounded hover:bg-primary-700 transition-colors duration-300 ease-in-out disabled:cursor-not-allowed"
:disabled="my_item.prevDisabled"
@click="emitHandler('prev-click', { data: my_item })"
>
<UIcon
name="i-lucide-chevron-right"
class="w-6 h-6"
/>
<span>قبلی</span>
</button>
<button
class="flex items-center btn bg-primary text-white pr-2 py-1 rounded hover:bg-primary-700 transition-colors duration-300 ease-in-out disabled:cursor-not-allowed"
:disabled="my_item.nextDisabled"
@click="emitHandler('next-click', { data: my_item })"
>
<span>بعدی</span>
<UIcon name="i-lucide-chevron-left" class="w-6 h-6" />
</button>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from "vue";
const props = defineProps({
headerTools: { type: Array, default: () => [] },
entity: { type: Object, default: () => ({}) },
});
const emit = defineEmits(["header-tools-action"]);
function emitHandler(action, payload) {
emit("header-tools-action", {
action,
data: payload.data,
});
}
const selectedTabDetails = ref(null);
const localEntity = computed(() => props.entity || {});
function isArrayItems(item) {
return Array.isArray(item) || (item && item.items && !item.type);
}
function getArrayItems(item) {
return item.items ? item.items : Array.isArray(item) ? item : [];
}
function getDataValue(key) {
if (!localEntity.value) return "--";
const _source = localEntity.value._source || localEntity.value;
let res = "";
const keys = key.split("/");
for (const k of keys) {
const kv = k.split(".");
const value = kv.length === 2 ? _source[kv[0]]?.[kv[1]] : _source[k];
if (value) {
res = res ? `${res} / ${value}` : value;
}
}
return res || _source[key] || _source.qanon_title || _source.title || "--";
}
function handleRange(event, item) {
const value = parseInt(event.target.value, 10);
item.value = value;
emitHandler("range-change", { data: { name: item.name, value, item } });
}
</script>