Files
mixtape/zero.Backoffice.UI/old_app/components/pickers/linkPicker/linkpicker.vue
T
2021-12-07 01:11:18 +01:00

203 lines
4.4 KiB
Vue

<template>
<div class="ui-linkpicker" :class="{'is-disabled': disabled }">
<input ref="input" type="hidden" :value="value" />
<div class="ui-linkpicker-previews" v-if="previews.length > 0">
<div v-for="preview in previews" class="ui-linkpicker-preview">
<ui-select-button :icon="preview.icon" :label="preview.name" :description="preview.text" :disabled="disabled" @click="pick(preview.id)" :tokens="{ id: preview.id }" />
<ui-icon-button v-if="!disabled" @click="remove(preview.id)" icon="fth-x" title="@ui.close" />
</div>
</div>
<ui-select-button v-if="canAdd" icon="fth-plus" :label="limit > 1 ? '@ui.add' : '@ui.select'" @click="pick()" :disabled="disabled" />
</div>
</template>
<script>
import LinkpickerOverlay from './overlay.vue';
import LinksApi from 'zero/api/links.js';
import Overlay from 'zero/helpers/overlay.js';
import { extend as _extend, isArray as _isArray, isEmpty as _isEmpty, clone as _clone } from 'underscore';
export default {
name: 'uiLinkpicker',
props: {
value: {
type: [Object, Array],
default: null
},
limit: {
type: Number,
default: 1
},
title: {
type: Boolean,
default: true
},
label: {
type: Boolean,
default: false
},
target: {
type: Boolean,
default: true
},
suffix: {
type: Boolean,
default: false
},
areas: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: false
},
options: {
type: Object,
default: () => {}
}
},
data: () => ({
previews: []
}),
watch: {
value()
{
this.updatePreviews();
}
},
computed: {
multiple()
{
return this.limit > 1;
},
canAdd()
{
let count = Array.isArray(this.value) ? this.value.length : (!this.value ? 0 : 1);
return !this.disabled && count < this.limit;
}
},
mounted()
{
this.updatePreviews();
},
methods: {
onChange(value)
{
this.$emit('change', value);
this.$emit('input', value);
// TODO this does not trigger the forms dirty flag
},
updatePreviews()
{
this.previews = [];
if (!this.value || _isEmpty(this.value))
{
this.$emit('previews', this.multiple ? [] : null);
this.previews = [];
return;
}
let links = Array.isArray(this.value) ? this.value : [this.value];
LinksApi.getPreviews(links).then(res =>
{
this.previews = res;
this.$emit('previews', this.multiple ? this.previews : this.previews[0]);
});
},
remove(id)
{
if (Array.isArray(this.value))
{
let index = this.value.indexOf(id);
this.value.splice(index, 1);
this.onChange(this.value);
}
else
{
this.onChange(this.multiple ? [] : null);
}
},
pick(id)
{
if (this.disabled)
{
return;
}
let options = _extend({
title: 'Select a link',
closeLabel: '@ui.close',
component: LinkpickerOverlay,
display: 'editor',
model: this.multiple ? id : this.value,
options: {
limit: this.limit,
label: this.label,
title: this.title,
target: this.target,
suffix: this.suffix,
areas: this.areas
}
}, typeof this.options === 'object' ? this.options : {});
return Overlay.open(options).then(res =>
{
if (this.multiple)
{
this.value.push(res);
this.onChange(this.value);
}
else
{
this.onChange(res);
}
return new Promise(resolve => resolve(res));
});
}
}
}
</script>
<style lang="scss">
.ui-linkpicker-preview
{
display: flex;
justify-content: space-between;
align-items: center;
.ui-icon-button
{
height: 24px;
width: 24px;
i
{
font-size: 13px;
}
}
}
.ui-linkpicker-previews + .ui-select-button,
.ui-linkpicker-preview + .ui-linkpicker-preview
{
margin-top: 10px;
}
</style>