Show and disable content element actions based on context

This commit is contained in:
Ramon Wenger 2022-02-28 14:02:53 +01:00
parent ec5d942f5d
commit 3d57f42821
6 changed files with 103 additions and 34 deletions

View File

@ -9,3 +9,9 @@ export interface ContentBlock {
isAssignment: boolean;
type: types;
}
export interface ActionOptions {
up?: boolean,
down?: boolean,
extended?: boolean
}

View File

@ -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)"

View File

@ -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>

View File

@ -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">

View File

@ -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: {

View File

@ -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;