start new media picker
This commit is contained in:
+1
-1
@@ -64,7 +64,7 @@
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'uiMedia',
|
||||
name: 'uiMediaOld',
|
||||
|
||||
props: {
|
||||
disabled: {
|
||||
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div class="ui-iconpicker" :class="{'is-disabled': disabled }">
|
||||
<input ref="input" type="hidden" :value="value" />
|
||||
<ui-select-button icon="fth-plus" label="@mediapicker.select_text" description="@mediapicker.select_description" @click="pick" :disabled="disabled" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import PickMediaOverlay from './overlay';
|
||||
import Overlay from 'zero/services/overlay';
|
||||
import { each as _each, extend as _extend, debounce as _debounce, isArray as _isArray } from 'underscore';
|
||||
import Strings from 'zero/services/strings.js';
|
||||
|
||||
const TYPES = {
|
||||
ALL: 'all',
|
||||
IMAGE: 'image',
|
||||
VIDEO: 'video',
|
||||
DOCUMENT: 'document',
|
||||
OTHER: 'other'
|
||||
};
|
||||
|
||||
const DISPLAY = {
|
||||
DEFAULT: 'default',
|
||||
BIG: 'big',
|
||||
GRID: 'grid'
|
||||
};
|
||||
|
||||
const MAX_FILENAME_LENGTH = 32;
|
||||
|
||||
const defaultConfig = {
|
||||
// maximum media items
|
||||
limit: 1,
|
||||
// media type
|
||||
type: TYPES.ALL,
|
||||
// how the previews are displayed
|
||||
display: DISPLAY.DEFAULT,
|
||||
// whether the select button is disallowed
|
||||
disallowSelect: false,
|
||||
// whether file upload is disallowed
|
||||
disallowUpload: false,
|
||||
// allowed file extensions
|
||||
fileExtensions: [],
|
||||
// maximum file size in MiB
|
||||
maxFileSize: 10
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'uiMediapicker',
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [Array, String],
|
||||
default: null
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
default: () =>
|
||||
{
|
||||
return defaultConfig;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
onChange(value)
|
||||
{
|
||||
this.$emit('change', value);
|
||||
this.$emit('input', value);
|
||||
// TODO this does not trigger the forms dirty flag
|
||||
},
|
||||
|
||||
pick()
|
||||
{
|
||||
if (this.disabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let options = _extend({
|
||||
title: '@iconpicker.title',
|
||||
closeLabel: '@ui.close',
|
||||
component: PickMediaOverlay,
|
||||
model: this.value,
|
||||
theme: 'dark',
|
||||
}, typeof this.config === 'object' ? this.config : {});
|
||||
|
||||
return Overlay.open(options).then(value =>
|
||||
{
|
||||
this.onChange(value);
|
||||
//this.$refs.input.value = value;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<ui-form v-if="!loading" ref="form" class="ui-mediapicker-overlay" v-slot="form">
|
||||
<h2 class="ui-headline" v-localize="'@media.name'"></h2>
|
||||
|
||||
<!--<div class="app-confirm-buttons">
|
||||
<ui-button v-if="!disabled" type="light" :submit="true" :state="form.state" label="@ui.save"></ui-button>
|
||||
<ui-button type="light" :label="config.closeLabel" :disabled="loading" @click="config.close"></ui-button>
|
||||
</div>-->
|
||||
</ui-form>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { debounce as _debounce, filter as _filter } from 'underscore';
|
||||
|
||||
export default {
|
||||
|
||||
props: {
|
||||
model: String,
|
||||
config: Object
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
colors: [ 'default', 'gray', 'blue-gray', 'blue', 'teal', 'green', 'lime', 'yellow', 'orange', 'red', 'purple', 'brown' ],
|
||||
icon: null,
|
||||
color: null,
|
||||
query: '',
|
||||
items: []
|
||||
}),
|
||||
|
||||
watch: {
|
||||
model()
|
||||
{
|
||||
this.init();
|
||||
},
|
||||
query()
|
||||
{
|
||||
this.debouncedSearch();
|
||||
}
|
||||
},
|
||||
|
||||
created()
|
||||
{
|
||||
this.debouncedSearch = _debounce(this.search, 100);
|
||||
this.items = this.config.items;
|
||||
this.init();
|
||||
},
|
||||
|
||||
mounted()
|
||||
{
|
||||
let $selected = this.$el.querySelector('.ui-iconpicker-overlay-item.is-active');
|
||||
|
||||
if ($selected)
|
||||
{
|
||||
let $scrollable = this.$el.querySelector('content');
|
||||
const offset = $selected.offsetTop - $scrollable.clientHeight * 0.5 - 30;
|
||||
$scrollable.scrollTop = offset < 0 ? 0 : offset;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
confirm()
|
||||
{
|
||||
const result = (this.icon || '') + ' ' + (this.color || '').trim();
|
||||
this.config.confirm(result);
|
||||
},
|
||||
|
||||
select(item)
|
||||
{
|
||||
this.icon = item;
|
||||
this.confirm();
|
||||
},
|
||||
|
||||
selectColor(color)
|
||||
{
|
||||
this.color = color === 'default' ? null : 'color-' + color;
|
||||
},
|
||||
|
||||
init()
|
||||
{
|
||||
if (!this.model)
|
||||
{
|
||||
this.icon = null;
|
||||
this.color = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
const parts = this.model.split(' ');
|
||||
this.icon = parts[0];
|
||||
this.color = parts.length > 1 ? parts[1] : null;
|
||||
}
|
||||
},
|
||||
|
||||
search()
|
||||
{
|
||||
const query = this.query;
|
||||
|
||||
if (!query)
|
||||
{
|
||||
this.items = this.config.items;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.items = _filter(this.config.items, function (item)
|
||||
{
|
||||
return item.toLowerCase().indexOf(query) > -1;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-iconpicker-overlay content
|
||||
{
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.ui-iconpicker-overlay-items
|
||||
{
|
||||
display: grid;
|
||||
grid-gap: 0;
|
||||
grid-template-columns: repeat(auto-fill, 61px);
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.ui-iconpicker-overlay-item
|
||||
{
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
height: 60px;
|
||||
border-radius: var(--radius);
|
||||
/*border: 2px solid transparent;*/
|
||||
|
||||
&:hover, &.is-active
|
||||
{
|
||||
background: var(--color-box);
|
||||
box-shadow: 0 0 20px var(--color-shadow);
|
||||
}
|
||||
|
||||
&.is-active
|
||||
{
|
||||
//color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-iconpicker-overlay-search
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ui-iconpicker-overlay-colors
|
||||
{
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 0 20px;
|
||||
|
||||
i
|
||||
{
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&.is-active
|
||||
{
|
||||
transform: scale(1.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui-iconpicker-overlay-line
|
||||
{
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
</ui-property>
|
||||
<ui-property label="@user.fields.avatar" description="@user.fields.avatar_text" :required="true">
|
||||
<ui-media :config="avatarConfig" v-model="model.avatarId" :disabled="disabled" />
|
||||
<ui-mediapicker :config="avatarConfig" v-model="model.avatarId" :disabled="disabled" />
|
||||
</ui-property>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -297,8 +297,8 @@
|
||||
},
|
||||
|
||||
"mediapicker": {
|
||||
"select_text": "Select",
|
||||
"select_description": "from library",
|
||||
"select_text": "Add media",
|
||||
"select_description": "Upload or select",
|
||||
"upload_text": "Upload",
|
||||
"upload_description": "Upload a new file"
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace zero.Web
|
||||
public ZeroMiddleware(RequestDelegate next, IZeroOptions options)
|
||||
{
|
||||
Next = next;
|
||||
Options = options;
|
||||
Options = options;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user