Create document picklist and refactor axios call
This commit is contained in:
228
src/components/DynamicPicker.vue
Normal file
228
src/components/DynamicPicker.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<div class="dynamic-picker" :class="{ 'mt-4': !noMargin }">
|
||||
<label :for="inputName" v-if="label">
|
||||
<b>{{ label }}</b>
|
||||
</label>
|
||||
<div class="input-wrapper">
|
||||
<!-- Video Groups MultiSelect -->
|
||||
<MultiSelect
|
||||
v-if="dataSource === 'videoGroups'"
|
||||
v-model="selectedValue"
|
||||
:options="options"
|
||||
|
||||
:filter="true"
|
||||
:placeholder="placeholder || 'Select VideoGroups'"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
class="w-full md:w-80"
|
||||
@change="onSelectionChange"
|
||||
>
|
||||
<template #option="slotProps">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-video mr-2"></i>
|
||||
<div>
|
||||
<div>{{ slotProps.option.name }}</div>
|
||||
<small class="text-muted" v-if="slotProps.option.description">
|
||||
{{ slotProps.option.description }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</MultiSelect>
|
||||
|
||||
<!-- KS Documents MultiSelect -->
|
||||
<MultiSelect
|
||||
v-else-if="dataSource === 'ksDocuments'"
|
||||
v-model="selectedValue"
|
||||
:options="options"
|
||||
|
||||
:filter="true"
|
||||
:placeholder="placeholder || 'Select Documents'"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
class="w-full md:w-80"
|
||||
@change="onSelectionChange"
|
||||
>
|
||||
<template #option="slotProps">
|
||||
<div class="flex align-items-center">
|
||||
<i :class="getFileIcon(slotProps.option)" class="mr-2"></i>
|
||||
<div>
|
||||
<div>{{ slotProps.option.fileName }}</div>
|
||||
<small class="text-muted" v-if="slotProps.option.description">
|
||||
{{ slotProps.option.description }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</MultiSelect>
|
||||
|
||||
<!-- Dropdown per selezione singola -->
|
||||
<Dropdown
|
||||
v-else-if="multiple === false"
|
||||
v-model="selectedValue"
|
||||
:options="options"
|
||||
|
||||
:filter="true"
|
||||
:placeholder="placeholder || 'Select an option'"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
class="w-full md:w-80"
|
||||
@change="onSelectionChange"
|
||||
/>
|
||||
|
||||
<!-- MultiSelect generico per altri tipi -->
|
||||
<MultiSelect
|
||||
v-else
|
||||
v-model="selectedValue"
|
||||
:options="options"
|
||||
|
||||
:filter="true"
|
||||
:placeholder="placeholder || 'Select options'"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
class="w-full md:w-80"
|
||||
@change="onSelectionChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Loading indicator -->
|
||||
<div v-if="loading" class="text-sm text-gray-500 mt-1">
|
||||
<i class="pi pi-spin pi-spinner mr-1"></i>
|
||||
Loading options...
|
||||
</div>
|
||||
|
||||
<!-- Error message -->
|
||||
<div v-if="error" class="text-red-500 text-sm mt-1">
|
||||
<i class="pi pi-exclamation-triangle mr-1"></i>
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
<!-- Info message -->
|
||||
<div v-if="options.length === 0 && !loading && !error" class="text-gray-500 text-sm mt-1">
|
||||
<i class="pi pi-info-circle mr-1"></i>
|
||||
No options available
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Dropdown from 'primevue/dropdown';
|
||||
import MultiSelect from 'primevue/multiselect';
|
||||
import { computed } from 'vue';
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [Array, Object, String, Number],
|
||||
default: null
|
||||
},
|
||||
inputName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dataSource: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
error: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showStatus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
noMargin: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits(['update:modelValue', 'change']);
|
||||
|
||||
// Computed
|
||||
const selectedValue = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value);
|
||||
}
|
||||
});
|
||||
|
||||
const getFileIcon = (document) => {
|
||||
if (!document) return 'pi pi-file';
|
||||
|
||||
const fileName = document.fileName || document.name || '';
|
||||
const extension = fileName.toLowerCase().split('.').pop();
|
||||
|
||||
switch (extension) {
|
||||
case 'pdf':
|
||||
return 'pi pi-file-pdf text-red-500';
|
||||
case 'doc':
|
||||
return 'pi pi-file-word text-blue-500';
|
||||
case 'docx':
|
||||
return 'pi pi-file-word text-blue-500';
|
||||
case 'xls':
|
||||
return 'pi pi-file-excel text-green-500';
|
||||
case 'xlsx':
|
||||
return 'pi pi-file-excel text-green-500';
|
||||
case 'txt':
|
||||
return 'pi pi-file text-gray-500';
|
||||
case 'ppt':
|
||||
return 'pi pi-file text-red-500';
|
||||
case 'pptx':
|
||||
return 'pi pi-file text-red-500';
|
||||
case 'json':
|
||||
return 'pi pi-file text-orange-500';
|
||||
case 'gif':
|
||||
return 'pi pi-image text-purple-500';
|
||||
case 'rar':
|
||||
return 'pi pi-file-archive text-yellow-500';
|
||||
default:
|
||||
return 'pi pi-file text-gray-400';
|
||||
}
|
||||
};
|
||||
|
||||
const onSelectionChange = (event) => {
|
||||
emit('change', event.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #6c757d;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user