changes
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
<script setup>
|
||||
import Multiselect from "vue-multiselect";
|
||||
import { computed } from "vue";
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/Components/ui/select";
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import { Label } from "@/Components/ui/label";
|
||||
import { Input } from "@/Components/ui/input";
|
||||
import { Badge } from "@/Components/ui/badge";
|
||||
|
||||
const props = defineProps({
|
||||
isCompleted: Boolean,
|
||||
@@ -19,11 +23,11 @@ const emits = defineEmits([
|
||||
"preview",
|
||||
]);
|
||||
|
||||
function onHeaderChange(e) {
|
||||
emits("update:hasHeader", e.target.value === "true");
|
||||
function onHeaderChange(val) {
|
||||
emits("update:hasHeader", val === "true");
|
||||
}
|
||||
function onDelimiterMode(e) {
|
||||
emits("update:delimiterMode", e.target.value);
|
||||
function onDelimiterMode(val) {
|
||||
emits("update:delimiterMode", val);
|
||||
}
|
||||
function onDelimiterCustom(e) {
|
||||
emits("update:delimiterCustom", e.target.value);
|
||||
@@ -44,116 +48,119 @@ const selectedTemplateProxy = computed({
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex-1">
|
||||
<label class="block text-sm font-medium text-gray-700">Template</label>
|
||||
<Multiselect
|
||||
v-model="selectedTemplateProxy"
|
||||
:options="filteredTemplates"
|
||||
track-by="id"
|
||||
label="name"
|
||||
placeholder="Izberi predlogo..."
|
||||
:searchable="true"
|
||||
:allow-empty="true"
|
||||
class="mt-1"
|
||||
:custom-label="(o) => o.name"
|
||||
:disabled="filteredTemplates?.length === 0"
|
||||
:show-no-results="true"
|
||||
:clear-on-select="false"
|
||||
<Label class="text-sm font-medium">Template</Label>
|
||||
<Select
|
||||
:model-value="selectedTemplateProxy?.id?.toString()"
|
||||
@update:model-value="(val) => {
|
||||
const tpl = filteredTemplates.find(t => t.id.toString() === val);
|
||||
selectedTemplateProxy = tpl || null;
|
||||
}"
|
||||
>
|
||||
<template #option="{ option }">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="flex items-center gap-2">
|
||||
<span>{{ option.name }}</span>
|
||||
<span v-if="option.source_type" class="ml-2 text-xs text-gray-500"
|
||||
>({{ option.source_type }})</span
|
||||
>
|
||||
<SelectTrigger class="mt-1">
|
||||
<SelectValue placeholder="Izberi predlogo...">
|
||||
<div v-if="selectedTemplateProxy" class="flex items-center gap-2">
|
||||
<span>{{ selectedTemplateProxy.name }}</span>
|
||||
<span v-if="selectedTemplateProxy.source_type" class="text-xs text-muted-foreground">({{ selectedTemplateProxy.source_type }})</span>
|
||||
<Badge variant="outline" class="text-[10px]">{{ selectedTemplateProxy.client_id ? 'Client' : 'Global' }}</Badge>
|
||||
</div>
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded bg-gray-100 text-gray-600">{{
|
||||
option.client_id ? "Client" : "Global"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #singleLabel="{ option }">
|
||||
<div class="flex items-center gap-2">
|
||||
<span>{{ option.name }}</span>
|
||||
<span v-if="option.source_type" class="ml-1 text-xs text-gray-500"
|
||||
>({{ option.source_type }})</span
|
||||
>
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded bg-gray-100 text-gray-600">{{
|
||||
option.client_id ? "Client" : "Global"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #noResult>
|
||||
<div class="px-2 py-1 text-xs text-gray-500">Ni predlog.</div>
|
||||
</template>
|
||||
</Multiselect>
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem v-for="option in filteredTemplates" :key="option.id" :value="option.id.toString()">
|
||||
<div class="flex items-center justify-between w-full gap-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span>{{ option.name }}</span>
|
||||
<span v-if="option.source_type" class="text-xs text-muted-foreground">({{ option.source_type }})</span>
|
||||
</div>
|
||||
<Badge variant="outline" class="text-[10px]">{{
|
||||
option.client_id ? "Client" : "Global"
|
||||
}}</Badge>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div v-if="isCompleted" class="mt-2">
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
class="w-full sm:w-auto"
|
||||
@click="$emit('preview')"
|
||||
class="px-3 py-1.5 bg-indigo-600 text-white rounded text-sm hover:bg-indigo-500 w-full sm:w-auto"
|
||||
>
|
||||
Ogled CSV
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!isCompleted" class="flex flex-col gap-3">
|
||||
<div class="flex flex-col sm:flex-row gap-3">
|
||||
<div class="flex-1">
|
||||
<label class="block text-xs font-medium text-gray-600">Header row</label>
|
||||
<select
|
||||
:value="hasHeader"
|
||||
@change="onHeaderChange"
|
||||
class="mt-1 block w-full border rounded p-2 text-sm"
|
||||
<Label class="text-xs font-medium">Header row</Label>
|
||||
<Select
|
||||
:model-value="hasHeader.toString()"
|
||||
@update:model-value="onHeaderChange"
|
||||
>
|
||||
<option value="true">Has header</option>
|
||||
<option value="false">No header (positional)</option>
|
||||
</select>
|
||||
<SelectTrigger class="mt-1">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="true">Has header</SelectItem>
|
||||
<SelectItem value="false">No header (positional)</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="block text-xs font-medium text-gray-600">Delimiter</label>
|
||||
<select
|
||||
:value="delimiterState.mode"
|
||||
@change="onDelimiterMode"
|
||||
class="mt-1 block w-full border rounded p-2 text-sm"
|
||||
<Label class="text-xs font-medium">Delimiter</Label>
|
||||
<Select
|
||||
:model-value="delimiterState.mode"
|
||||
@update:model-value="onDelimiterMode"
|
||||
>
|
||||
<option value="auto">Auto-detect</option>
|
||||
<option value="comma">Comma ,</option>
|
||||
<option value="semicolon">Semicolon ;</option>
|
||||
<option value="tab">Tab \t</option>
|
||||
<option value="pipe">Pipe |</option>
|
||||
<option value="space">Space ␠</option>
|
||||
<option value="custom">Custom…</option>
|
||||
</select>
|
||||
<SelectTrigger class="mt-1">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="auto">Auto-detect</SelectItem>
|
||||
<SelectItem value="comma">Comma ,</SelectItem>
|
||||
<SelectItem value="semicolon">Semicolon ;</SelectItem>
|
||||
<SelectItem value="tab">Tab \t</SelectItem>
|
||||
<SelectItem value="pipe">Pipe |</SelectItem>
|
||||
<SelectItem value="space">Space ␠</SelectItem>
|
||||
<SelectItem value="custom">Custom…</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="delimiterState.mode === 'custom'" class="flex items-end gap-3">
|
||||
<div class="w-40">
|
||||
<label class="block text-xs font-medium text-gray-600">Custom delimiter</label>
|
||||
<input
|
||||
:value="delimiterState.custom"
|
||||
<Label class="text-xs font-medium">Custom delimiter</Label>
|
||||
<Input
|
||||
:model-value="delimiterState.custom"
|
||||
@input="onDelimiterCustom"
|
||||
maxlength="4"
|
||||
placeholder=","
|
||||
class="mt-1 block w-full border rounded p-2 text-sm"
|
||||
class="mt-1"
|
||||
/>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500">
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Template default: {{ selectedTemplateOption?.meta?.delimiter || "auto" }}
|
||||
</p>
|
||||
</div>
|
||||
<p v-else class="text-xs text-gray-500">
|
||||
<p v-else class="text-xs text-muted-foreground">
|
||||
Template default: {{ selectedTemplateOption?.meta?.delimiter || "auto" }}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
v-if="!isCompleted"
|
||||
class="px-3 py-1.5 bg-emerald-600 text-white rounded text-sm"
|
||||
:disabled="!form.import_template_id"
|
||||
<Button
|
||||
v-if="!isCompleted && form.import_template_id"
|
||||
variant="default"
|
||||
@click="$emit('apply-template')"
|
||||
class="w-full"
|
||||
>
|
||||
{{ templateApplied ? "Ponovno uporabi predlogo" : "Uporabi predlogo" }}
|
||||
</button>
|
||||
{{ templateApplied ? 'Re-apply Template' : 'Apply Template' }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user