Skip to content
Snippets Groups Projects
CoursewareToolbar.vue 7.76 KiB
Newer Older
<template>
    <div class="cw-toolbar-wrapper">
        <div id="cw-toolbar" class="cw-toolbar" :style="toolbarStyle">
Ron Lucke's avatar
Ron Lucke committed
            <div v-if="showTools" class="cw-toolbar-tools" :class="{ unfold: unfold, hd: isHd, wqhd: isWqhd }">
                <div class="cw-toolbar-button-wrapper">
                    <button
                        class="cw-toolbar-button"
Ron Lucke's avatar
Ron Lucke committed
                        :class="{ active: activeTool === 'blockAdder' }"
                        :title="$gettext('Blöcke hinzufügen')"
                        @click="activateTool('blockAdder')"
                    >
                        {{ $gettext('Blöcke') }}
                    </button>
                    <button
                        class="cw-toolbar-button"
Ron Lucke's avatar
Ron Lucke committed
                        :class="{ active: activeTool === 'containerAdder' }"
                        :title="$gettext('Abschnitte hinzufügen')"
                        @click="activateTool('containerAdder')"
                    >
                        {{ $gettext('Abschnitte') }}
                    </button>
                    <button
                        class="cw-toolbar-button"
Ron Lucke's avatar
Ron Lucke committed
                        :class="{ active: activeTool === 'clipboard' }"
                        :title="$gettext('Block Merkliste')"
                        @click="activateTool('clipboard')"
                    >
                        {{ $gettext('Merkliste') }}
                    </button>
                    <button
Ron Lucke's avatar
Ron Lucke committed
                        class="cw-toolbar-button cw-toolbar-button-toggle"
                        :title="$gettext('Werkzeugleiste einklappen')"
Ron Lucke's avatar
Ron Lucke committed
                        @click="toggleToolbarActive"
Ron Lucke's avatar
Ron Lucke committed
                    >
                        <studip-icon shape="arr_2right" :size="24" />
                    </button>
                </div>
                <courseware-toolbar-blocks v-if="activeTool === 'blockAdder'" />
                <courseware-toolbar-containers v-if="activeTool === 'containerAdder'" />
                <courseware-toolbar-clipboard v-if="activeTool === 'clipboard'" />
            </div>
Ron Lucke's avatar
Ron Lucke committed
            <div v-else class="cw-toolbar-folded-wrapper">
                <button
                    class="cw-toolbar-button"
                    :title="$gettext('Werkzeugleiste ausklappen')"
                    @click="toggleToolbarActive"
                >
                    <studip-icon shape="arr_2left" :size="24" />
                </button>
                <button
                    class="cw-toolbar-button"
                    :title="
                        hideEditLayout
                            ? $gettext('Bearbeitungselemente anzeigen')
                            : $gettext('Bearbeitungselemente ausblenden')
                    "
                    @click="toggleHideEditLayout"
                >
                    <studip-icon :shape="hideEditLayout ? 'visibility-checked' : 'visibility-invisible'" :size="24" />
                </button>
            </div>
            <div class="cw-toolbar-spacer-right"></div>
        </div>
    </div>
</template>

<script>
import CoursewareToolbarBlocks from './CoursewareToolbarBlocks.vue';
import CoursewareToolbarContainers from './CoursewareToolbarContainers.vue';
import CoursewareToolbarClipboard from './CoursewareToolbarClipboard.vue';
Ron Lucke's avatar
Ron Lucke committed
import containerMixin from '@/vue/mixins/courseware/container.js';
import { mapActions, mapGetters } from 'vuex';

export default {
    name: 'courseware-toolbar',
Ron Lucke's avatar
Ron Lucke committed
    mixins: [containerMixin],
    components: {
        CoursewareToolbarBlocks,
        CoursewareToolbarContainers,
Ron Lucke's avatar
Ron Lucke committed
        CoursewareToolbarClipboard,
    },
    data() {
        return {
            unfold: true,
            showTools: true,
            toolbarTop: 0,
            activeTool: 'blockAdder',

            windowWidth: window.outerWidth,
Ron Lucke's avatar
Ron Lucke committed
            windowInnerHeight: window.innerHeight,
        };
    },
    computed: {
Ron Lucke's avatar
Ron Lucke committed
        ...mapGetters({
            relatedContainers: 'courseware-containers/related',
            structuralElementById: 'courseware-structural-elements/byId',
Ron Lucke's avatar
Ron Lucke committed
            toolbarActive: 'toolbarActive',
Ron Lucke's avatar
Ron Lucke committed
            hideEditLayout: 'hideEditLayout',
Ron Lucke's avatar
Ron Lucke committed
        }),
        toolbarStyle() {
            const scrollTopStyles = window.getComputedStyle(document.getElementById('scroll-to-top'));
Ron Lucke's avatar
Ron Lucke committed
            const scrollTopHeight =
                parseInt(scrollTopStyles['height'], 10) +
                parseInt(scrollTopStyles['padding-top'], 10) +
                parseInt(scrollTopStyles['padding-bottom'], 10) +
                parseInt(scrollTopStyles['margin-bottom'], 10);
            let height = parseInt(
Ron Lucke's avatar
Ron Lucke committed
                Math.min(this.windowInnerHeight * 0.9, this.windowInnerHeight - this.toolbarTop - scrollTopHeight)
            );

            return {
                height: height + 'px',
                minHeight: height + 'px',
                top: this.toolbarTop + 'px',
            };
        },
Ron Lucke's avatar
Ron Lucke committed
        containers() {
            return this.relatedContainers({
Ron Lucke's avatar
Ron Lucke committed
                parent: this.structuralElementById({ id: this.$route.params.id }),
                relationship: 'containers',
Ron Lucke's avatar
Ron Lucke committed
            });
        },
        toolbarHeader() {
            let header = '';
            if (this.activeTool === 'blockAdder') {
                header = this.$gettext('Block hinzufügen');
            }
            if (this.activeTool === 'containerAdder') {
                header = this.$gettext('Abschnitt hinzufügen');
            }

            return header;
        },
        isHd() {
            return this.windowWidth >= 1920;
        },
        isWqhd() {
            return this.windowWidth >= 2560;
        },
    },
    methods: {
Ron Lucke's avatar
Ron Lucke committed
        ...mapActions({
            toggleToolbarActive: 'toggleToolbarActive',
Ron Lucke's avatar
Ron Lucke committed
            toggleHideEditLayout: 'toggleHideEditLayout',
Ron Lucke's avatar
Ron Lucke committed
        }),
        activateTool(tool) {
            this.activeTool = tool;
        },
        updateToolbarTop() {
            const responsiveContentbar = document.getElementById('responsive-contentbar');
            if (responsiveContentbar) {
Ron Lucke's avatar
Ron Lucke committed
                const contentbarRect = responsiveContentbar.getBoundingClientRect();
                this.toolbarTop = contentbarRect.bottom + 25;
                return;
            }

            const ribbon = document.getElementById('cw-ribbon') ?? document.getElementById('contentbar');
            if (ribbon) {
                const contentbarRect = ribbon.getBoundingClientRect();
Ron Lucke's avatar
Ron Lucke committed
                if (ribbon.classList.contains('cw-ribbon-sticky')) {
                    this.toolbarTop = contentbarRect.bottom + 16;
                } else {
                    this.toolbarTop = contentbarRect.bottom + 15;
                }
            }
        },
        onResize() {
            this.windowWidth = window.outerWidth;
            this.windowInnerHeight = window.innerHeight;
Ron Lucke's avatar
Ron Lucke committed
        },
    },
    mounted() {
        this.updateToolbarTop();
        this.$nextTick(() => {
            window.addEventListener('scroll', this.updateToolbarTop);
            window.addEventListener('resize', this.onResize);
        });
Ron Lucke's avatar
Ron Lucke committed
        this.resetAdderStorage();
Ron Lucke's avatar
Ron Lucke committed
    beforeDestroy() {
        window.removeEventListener('scroll', this.updateToolbarTop);
Ron Lucke's avatar
Ron Lucke committed
        window.removeEventListener('resize', this.onResize);
Ron Lucke's avatar
Ron Lucke committed
        containers(newValue, oldValue) {
            if (newValue) {
Ron Lucke's avatar
Ron Lucke committed
                this.resetAdderStorage();
            }
        },
Ron Lucke's avatar
Ron Lucke committed
        toolbarActive(newState, oldState) {
            let view = this;
            if (newState) {
                this.showTools = true;
                setTimeout(() => {
                    view.unfold = true;
                }, 10);
            } else {
                this.unfold = false;
                setTimeout(() => {
Ron Lucke's avatar
Ron Lucke committed
                    if (!view.toolbarActive) {
                        view.showTools = false;
                    }
                }, 600);
            }
        },
    },
};
</script>