Add remote selector
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
8c3dc2211b
commit
6aaeb75b2a
|
@ -0,0 +1 @@
|
|||
<svg height="512" viewBox="0 0 48 48" width="512" xmlns="http://www.w3.org/2000/svg"><g data-name="Open Folder"><path d="M45 18h-4v-4a2.996 2.996 0 0 0-3-3H22.75a3 3 0 0 1-2.33-1.11l-1.96-2.41A3.985 3.985 0 0 0 15.36 6H4a2.996 2.996 0 0 0-3 3v29.57a3.367 3.367 0 0 0 1.01 2.42A3.367 3.367 0 0 0 4.43 42h33.66a3.441 3.441 0 0 0 3.3-2.47l5.53-18.97A2.003 2.003 0 0 0 45 18z" fill="rgba(currentColor, 0.5)"/><path d="M44.999 18H16.572a3.43 3.43 0 0 0-3.292 2.47L7.72 39.531A3.429 3.429 0 0 1 4.429 42h33.663a3.43 3.43 0 0 0 3.294-2.47l5.533-18.97a2 2 0 0 0-1.92-2.56z" fill="currentColor" style="filter: brightness(150%)"/></g></svg>
|
After Width: | Height: | Size: 631 B |
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<ui-popup v-if="selecting !== false" heading="Resource auswählen" @close="selecting = false">
|
||||
<ui-remote-selector :value="selecting" @input="set"></ui-remote-selector>
|
||||
</ui-popup>
|
||||
<label class="flex flex-col group" :for="id" :class="sizeClass(size)">
|
||||
<f-label v-if="label" :required="false" :value="label"></f-label>
|
||||
<div class="relative flex-none flex">
|
||||
<div class="w-full flex flex-col justify-center" :class="[fieldHeight, fieldAppearance, paddingX]" @click.prevent="selecting = modelValue === null ? null : {...modelValue}">
|
||||
<div v-if="modelValue !== null" v-text="modelValue.resource"></div>
|
||||
<div v-else>Datei auswählen</div>
|
||||
</div>
|
||||
<f-hint v-if="hint" :value="hint"></f-hint>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useFieldSize from '../../composables/useFieldSize';
|
||||
import {ref} from 'vue';
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const {fieldHeight, fieldAppearance, paddingX, sizeClass} = useFieldSize();
|
||||
|
||||
const selecting = ref(false);
|
||||
|
||||
function set(resource) {
|
||||
emit('update:modelValue', resource);
|
||||
selecting.value = false;
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: String,
|
||||
default: () => 'base',
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
hint: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
modelValue: {
|
||||
validator: (v) => typeof v === 'object' || v === null,
|
||||
required: true,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,90 @@
|
|||
<template>
|
||||
<div>
|
||||
<f-select id="connection" v-model="innerConnection" label="Verbindung" name="connection" class="mt-2" :options="data"></f-select>
|
||||
|
||||
<div v-if="innerConnection" class="mt-4">
|
||||
<div class="flex space-x-3 items-center bg-zinc-700 rounded-lg mt-3 py-1 px-2">
|
||||
<ui-sprite class="w-4 h-4 text-primary-700" src="open-folder"></ui-sprite>
|
||||
<div class="text-sm grow" v-text="structure.parent"></div>
|
||||
<ui-icon-button icon="undo" @click="emit('input', null)">löschen</ui-icon-button>
|
||||
<ui-icon-button icon="undo" @click="updateFiles(getParentDir(structure.parent))">Zurück</ui-icon-button>
|
||||
</div>
|
||||
<a
|
||||
v-for="(file, index) in structure.files"
|
||||
:key="index"
|
||||
href="#"
|
||||
class="flex space-x-3 items-center mt-1 transition duration-200 hover:bg-zinc-600 py-1 px-2 rounded"
|
||||
@click.prevent="updateFiles(file.path)"
|
||||
>
|
||||
<ui-sprite class="w-8 h-8 text-primary-700" src="open-folder"></ui-sprite>
|
||||
<span class="grow" :value="file.name">
|
||||
{{ file.name }}
|
||||
</span>
|
||||
<button class="btn btn-primary btn-sm" @click.self.prevent.stop="select(file)">Auswählen</button>
|
||||
<ui-sprite class="w-3 h-3 -rotate-90 text-primary-400" src="chevron"></ui-sprite>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, watch} from 'vue';
|
||||
import {useApiIndex} from '../../composables/useApiIndex';
|
||||
|
||||
const {reload, data, axios} = useApiIndex('/api/fileshare');
|
||||
|
||||
const emit = defineEmits(['input']);
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
validator: (v) => typeof v === 'object' || v === null,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const innerConnection = ref(props.value === null ? null : props.value.connection_id);
|
||||
|
||||
const structure = ref({
|
||||
parent: props.value === null ? '/' : getParentDir(props.value.resource),
|
||||
files: [],
|
||||
});
|
||||
|
||||
function select(file) {
|
||||
emit('input', {
|
||||
connection_id: innerConnection.value,
|
||||
resource: file.path,
|
||||
});
|
||||
}
|
||||
|
||||
function getParentDir(dir) {
|
||||
if (!dir) {
|
||||
return '/';
|
||||
}
|
||||
return '/' + dir.split('/').slice(1, -1).join('/');
|
||||
}
|
||||
|
||||
watch(innerConnection, () => updateFiles('/'));
|
||||
|
||||
async function updateFiles(parentDir) {
|
||||
console.log(innerConnection);
|
||||
if (innerConnection.value === null) {
|
||||
structure.value = {
|
||||
parent: '/',
|
||||
files: [],
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await axios.post(`/api/fileshare/${innerConnection.value}/files`, {
|
||||
parent: parentDir,
|
||||
});
|
||||
|
||||
structure.value = {
|
||||
parent: parentDir,
|
||||
files: response.data.data,
|
||||
};
|
||||
}
|
||||
|
||||
await reload();
|
||||
updateFiles(structure.value.parent);
|
||||
</script>
|
Loading…
Reference in New Issue