Show and disable content element actions based on context
This commit is contained in:
parent
ec5d942f5d
commit
3d57f42821
|
|
@ -9,3 +9,9 @@ export interface ContentBlock {
|
|||
isAssignment: boolean;
|
||||
type: types;
|
||||
}
|
||||
|
||||
export interface ActionOptions {
|
||||
up?: boolean,
|
||||
down?: boolean,
|
||||
extended?: boolean
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
<add-content-link
|
||||
@click="addBlock(-1)"
|
||||
/>
|
||||
|
||||
<!-- Loop for outer contents layer -->
|
||||
<div
|
||||
class="content-list content-list--creator content-block-form__segment"
|
||||
|
|
@ -45,6 +46,7 @@
|
|||
>
|
||||
<content-element-actions
|
||||
class="content-block-form__actions"
|
||||
:actions="{extended: true, up: outer>0, down: outer<localContentBlock.contents.length }"
|
||||
@remove="remove(outer)"
|
||||
@move-up="up(outer)"
|
||||
@move-down="down(outer)"
|
||||
|
|
@ -61,8 +63,11 @@
|
|||
:key="content.id"
|
||||
>
|
||||
<content-element
|
||||
:first-element="index===0"
|
||||
:last-element="index===block.contents.length-1"
|
||||
:element="content"
|
||||
class="content-block-form__segment"
|
||||
:top-level="false"
|
||||
@update="update(index, $event, outer)"
|
||||
@remove="remove(outer, index, $event)"
|
||||
@up="up(outer, index)"
|
||||
|
|
@ -78,10 +83,14 @@
|
|||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<!-- If the block is a single element -->
|
||||
<content-element
|
||||
:element="block"
|
||||
class="content-block-form__segment"
|
||||
:top-level="true"
|
||||
:first-element="outer===0"
|
||||
:last-element="outer===localContentBlock.contents.length-1"
|
||||
v-else
|
||||
@update="update(outer, $event)"
|
||||
@remove="remove(outer, undefined, $event)"
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
@change-type="changeType"
|
||||
@remove="$emit('remove', false)"
|
||||
/>
|
||||
|
||||
<!-- Content Forms -->
|
||||
<content-form-section
|
||||
:title="title"
|
||||
:has-actions="true"
|
||||
:actions="actions"
|
||||
v-else
|
||||
@top="$emit('top')"
|
||||
@up="$emit('up')"
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
<script>
|
||||
import ContentFormSection from '@/components/content-block-form/ContentFormSection';
|
||||
import ContentElementActions from '@/components/content-block-form/ContentElementActions';
|
||||
|
||||
const TrashIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/TrashIcon');
|
||||
const ContentBlockElementChooserWidget = () => import(/* webpackChunkName: "content-forms" */'@/components/content-forms/ContentBlockElementChooserWidget');
|
||||
const LinkForm = () => import(/* webpackChunkName: "content-forms" */'@/components/content-forms/LinkForm');
|
||||
|
|
@ -60,8 +62,21 @@
|
|||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
default: null,
|
||||
},
|
||||
// is this element at the top level, or is it nested? we assume top level
|
||||
topLevel: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
firstElement: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
lastElement: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
components: {
|
||||
|
|
@ -75,10 +90,17 @@
|
|||
DocumentForm,
|
||||
AssignmentForm,
|
||||
TextForm,
|
||||
SubtitleForm
|
||||
SubtitleForm,
|
||||
},
|
||||
|
||||
computed: {
|
||||
actions() {
|
||||
return {
|
||||
up: !this.firstElement,
|
||||
down: !this.lastElement,
|
||||
extended: this.topLevel,
|
||||
};
|
||||
},
|
||||
isChooser() {
|
||||
return this.component === CHOOSER;
|
||||
},
|
||||
|
|
@ -93,7 +115,7 @@
|
|||
},
|
||||
icon() {
|
||||
return this.type.icon;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -103,49 +125,49 @@
|
|||
return {
|
||||
component: 'subtitle-form',
|
||||
title: 'Untertitel',
|
||||
icon: 'title-icon'
|
||||
icon: 'title-icon',
|
||||
};
|
||||
case 'link_block':
|
||||
return {
|
||||
component: 'link-form',
|
||||
title: 'Link',
|
||||
icon: 'link-icon'
|
||||
icon: 'link-icon',
|
||||
};
|
||||
case 'video_block':
|
||||
return {
|
||||
component: 'video-form',
|
||||
title: 'Video',
|
||||
icon: 'video-icon'
|
||||
icon: 'video-icon',
|
||||
};
|
||||
case 'image_url_block':
|
||||
return {
|
||||
component: 'image-form',
|
||||
title: 'Bild',
|
||||
icon: 'image-icon'
|
||||
icon: 'image-icon',
|
||||
};
|
||||
case 'text_block':
|
||||
return {
|
||||
component: 'text-form',
|
||||
title: 'Text',
|
||||
icon: 'text-icon'
|
||||
icon: 'text-icon',
|
||||
};
|
||||
case 'assignment':
|
||||
return {
|
||||
component: 'assignment-form',
|
||||
title: 'Aufgabe & Ergebnis',
|
||||
icon: 'speech-bubble-icon'
|
||||
icon: 'speech-bubble-icon',
|
||||
};
|
||||
case 'document_block':
|
||||
return {
|
||||
component: 'document-form',
|
||||
title: 'Dokument',
|
||||
icon: 'document-icon'
|
||||
icon: 'document-icon',
|
||||
};
|
||||
}
|
||||
return {
|
||||
component: CHOOSER,
|
||||
title: '',
|
||||
icon: ''
|
||||
icon: '',
|
||||
};
|
||||
},
|
||||
_updateProperty(value, key) {
|
||||
|
|
@ -231,7 +253,7 @@
|
|||
if (convertToList) {
|
||||
el = {
|
||||
type: 'content_list_item',
|
||||
contents: [el]
|
||||
contents: [el],
|
||||
};
|
||||
}
|
||||
this.update(el);
|
||||
|
|
@ -242,7 +264,7 @@
|
|||
switchToDocument(value) {
|
||||
this.changeType('document_block', value);
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,14 @@
|
|||
:large="true"
|
||||
icon="arrow-thin-top"
|
||||
text="Ganz nach oben verschieben"
|
||||
:disabled="!actions.up"
|
||||
v-if="actions.extended"
|
||||
@click="emitAndClose('move-top')"
|
||||
/>
|
||||
<button-with-icon-and-text
|
||||
class="content-element-actions__button"
|
||||
:large="true"
|
||||
:disabled="!actions.up"
|
||||
icon="arrow-thin-up"
|
||||
text="Nach oben verschieben"
|
||||
@click="emitAndClose('move-up')"
|
||||
|
|
@ -30,6 +33,7 @@
|
|||
<button-with-icon-and-text
|
||||
class="content-element-actions__button"
|
||||
:large="true"
|
||||
:disabled="!actions.down"
|
||||
icon="arrow-thin-down"
|
||||
text="Nach unten verschieben"
|
||||
@click="emitAndClose('move-down')"
|
||||
|
|
@ -37,8 +41,10 @@
|
|||
<button-with-icon-and-text
|
||||
class="content-element-actions__button"
|
||||
:large="true"
|
||||
:disabled="!actions.down"
|
||||
icon="arrow-thin-bottom"
|
||||
text="Ganz nach unten verschieben"
|
||||
v-if="actions.extended"
|
||||
@click="emitAndClose('move-bottom')"
|
||||
/>
|
||||
</section>
|
||||
|
|
@ -56,20 +62,31 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetPopover from '@/components/ui/WidgetPopover';
|
||||
import Ellipses from '@/components/icons/Ellipses';
|
||||
import ButtonWithIconAndText from '@/components/ui/ButtonWithIconAndText';
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import WidgetPopover from '@/components/ui/WidgetPopover.vue';
|
||||
import Ellipses from '@/components/icons/Ellipses.vue';
|
||||
import ButtonWithIconAndText from '@/components/ui/ButtonWithIconAndText.vue';
|
||||
import {ActionOptions} from "@/@types";
|
||||
|
||||
export default {
|
||||
interface Data {
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
actions: {
|
||||
type: Object as () => ActionOptions
|
||||
},
|
||||
},
|
||||
components: {ButtonWithIconAndText, Ellipses, WidgetPopover},
|
||||
|
||||
data: () => ({
|
||||
data: (): Data => ({
|
||||
show: false,
|
||||
}),
|
||||
|
||||
methods: {
|
||||
toggle(show) {
|
||||
toggle(show: boolean) {
|
||||
this.show = show;
|
||||
},
|
||||
close() {
|
||||
|
|
@ -91,12 +108,12 @@
|
|||
this.$emit('move-bottom');
|
||||
this.close();
|
||||
},
|
||||
emitAndClose(event) {
|
||||
emitAndClose(event: string) {
|
||||
this.$emit(event);
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
<content-element-actions
|
||||
class="content-form-section__actions"
|
||||
v-if="hasActions"
|
||||
:actions="actions"
|
||||
v-if="actions"
|
||||
@remove="$emit('remove')"
|
||||
@move-top="$emit('top')"
|
||||
@move-up="$emit('up')"
|
||||
|
|
@ -22,9 +23,11 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import formElementIcons from '@/components/ui/form-element-icons';
|
||||
import ContentElementActions from '@/components/content-block-form/ContentElementActions';
|
||||
<script lang="ts">
|
||||
import formElementIcons from '@/components/ui/form-element-icons.js';
|
||||
import ContentElementActions from '@/components/content-block-form/ContentElementActions.vue';
|
||||
import {ActionOptions} from "@/@types";
|
||||
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
|
@ -36,9 +39,9 @@
|
|||
type: String,
|
||||
default: ''
|
||||
},
|
||||
hasActions: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
actions: {
|
||||
type: Object as () => ActionOptions,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<a
|
||||
:class="[ 'button-with-icon-and-text', {'button-with-icon-and-text--large': large}]"
|
||||
<button
|
||||
:class="['button', 'button-with-icon-and-text', {'button-with-icon-and-text--large': large}]"
|
||||
:disabled="disabled"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<component
|
||||
|
|
@ -8,7 +9,7 @@
|
|||
:is="icon"
|
||||
/>
|
||||
<span class="button-with-icon-and-text__text">{{ text }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -27,6 +28,10 @@
|
|||
large: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -43,6 +48,13 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
|
||||
&:disabled {
|
||||
background-color: transparent;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 24px;
|
||||
|
|
|
|||
Loading…
Reference in New Issue