Fix deep-selectors
This commit is contained in:
parent
4477b7c5ed
commit
4b55f8952c
|
|
@ -3,36 +3,18 @@
|
||||||
:class="{ 'hideable-element--greyed-out': hidden }"
|
:class="{ 'hideable-element--greyed-out': hidden }"
|
||||||
class="content-block__container hideable-element content-list__parent"
|
class="content-block__container hideable-element content-list__parent"
|
||||||
>
|
>
|
||||||
<div
|
<div :class="specialClass" :style="instrumentStyle" class="content-block" data-cy="content-block">
|
||||||
:class="specialClass"
|
<div class="block-actions" v-if="canEditModule && !isInstrumentBlock">
|
||||||
:style="instrumentStyle"
|
<user-widget v-bind="me" class="block-actions__user-widget content-block__user-widget" v-if="isMine" />
|
||||||
class="content-block"
|
|
||||||
data-cy="content-block"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="block-actions"
|
|
||||||
v-if="canEditModule && !isInstrumentBlock"
|
|
||||||
>
|
|
||||||
<user-widget
|
|
||||||
v-bind="me"
|
|
||||||
class="block-actions__user-widget content-block__user-widget"
|
|
||||||
v-if="isMine"
|
|
||||||
/>
|
|
||||||
<more-options-widget>
|
<more-options-widget>
|
||||||
<li
|
<li class="popover-links__link" v-if="!isInstrumentBlock">
|
||||||
class="popover-links__link"
|
|
||||||
v-if="!isInstrumentBlock"
|
|
||||||
>
|
|
||||||
<popover-link
|
<popover-link
|
||||||
data-cy="duplicate-content-block-link"
|
data-cy="duplicate-content-block-link"
|
||||||
text="Duplizieren"
|
text="Duplizieren"
|
||||||
@link-action="duplicateContentBlock(contentBlock)"
|
@link-action="duplicateContentBlock(contentBlock)"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li class="popover-links__link" v-if="isMine">
|
||||||
class="popover-links__link"
|
|
||||||
v-if="isMine"
|
|
||||||
>
|
|
||||||
<popover-link
|
<popover-link
|
||||||
data-cy="delete-content-block-link"
|
data-cy="delete-content-block-link"
|
||||||
text="Löschen"
|
text="Löschen"
|
||||||
|
|
@ -40,22 +22,13 @@
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li class="popover-links__link" v-if="isMine">
|
||||||
class="popover-links__link"
|
<popover-link text="Bearbeiten" @link-action="editContentBlock(contentBlock)" />
|
||||||
v-if="isMine"
|
|
||||||
>
|
|
||||||
<popover-link
|
|
||||||
text="Bearbeiten"
|
|
||||||
@link-action="editContentBlock(contentBlock)"
|
|
||||||
/>
|
|
||||||
</li>
|
</li>
|
||||||
</more-options-widget>
|
</more-options-widget>
|
||||||
</div>
|
</div>
|
||||||
<div class="content-block__visibility">
|
<div class="content-block__visibility">
|
||||||
<visibility-action
|
<visibility-action :block="contentBlock" v-if="canEditModule" />
|
||||||
:block="contentBlock"
|
|
||||||
v-if="canEditModule"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3
|
<h3
|
||||||
|
|
@ -66,10 +39,7 @@
|
||||||
>
|
>
|
||||||
{{ instrumentLabel }}
|
{{ instrumentLabel }}
|
||||||
</h3>
|
</h3>
|
||||||
<h4
|
<h4 class="content-block__title" v-if="!contentBlock.indent">
|
||||||
class="content-block__title"
|
|
||||||
v-if="!contentBlock.indent"
|
|
||||||
>
|
|
||||||
{{ contentBlock.title }}
|
{{ contentBlock.title }}
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
|
|
@ -85,10 +55,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<add-content-button
|
<add-content-button :where="{ after: contentBlock }" v-if="canEditModule" />
|
||||||
:where="{after: contentBlock}"
|
|
||||||
v-if="canEditModule"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -112,8 +79,9 @@
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
import { instrumentCategory } from '@/helpers/instrumentType';
|
import { instrumentCategory } from '@/helpers/instrumentType';
|
||||||
|
|
||||||
const ContentComponent = defineAsyncComponent(() => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/ContentComponent'));
|
const ContentComponent = defineAsyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ContentComponent')
|
||||||
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ContentBlock',
|
name: 'ContentBlock',
|
||||||
|
|
@ -157,14 +125,15 @@
|
||||||
instrumentStyle() {
|
instrumentStyle() {
|
||||||
if (this.isInstrumentBlock) {
|
if (this.isInstrumentBlock) {
|
||||||
return {
|
return {
|
||||||
backgroundColor: this.contentBlock.instrumentCategory.background
|
backgroundColor: this.contentBlock.instrumentCategory.background,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
instrumentLabel() {
|
instrumentLabel() {
|
||||||
const contentType = this.contentBlock.type.toLowerCase();
|
const contentType = this.contentBlock.type.toLowerCase();
|
||||||
if (contentType.startsWith('base')) { // all legacy instruments start with `base`
|
if (contentType.startsWith('base')) {
|
||||||
|
// all legacy instruments start with `base`
|
||||||
return instrumentCategory(contentType);
|
return instrumentCategory(contentType);
|
||||||
}
|
}
|
||||||
if (this.isInstrumentBlock) {
|
if (this.isInstrumentBlock) {
|
||||||
|
|
@ -176,7 +145,7 @@
|
||||||
instrumentLabelStyle() {
|
instrumentLabelStyle() {
|
||||||
if (this.isInstrumentBlock) {
|
if (this.isInstrumentBlock) {
|
||||||
return {
|
return {
|
||||||
color: this.contentBlock.instrumentCategory.foreground
|
color: this.contentBlock.instrumentCategory.foreground,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -207,7 +176,8 @@
|
||||||
// collect content_list_items
|
// collect content_list_items
|
||||||
if (content.type === 'content_list_item') {
|
if (content.type === 'content_list_item') {
|
||||||
contentList = [...contentList, content];
|
contentList = [...contentList, content];
|
||||||
if (index === this.contentBlock.contents.length - 1) { // content is last element of contents array
|
if (index === this.contentBlock.contents.length - 1) {
|
||||||
|
// content is last element of contents array
|
||||||
let updatedContent = [...newContents, ...this.createContentListOrBlocks(contentList)];
|
let updatedContent = [...newContents, ...this.createContentListOrBlocks(contentList)];
|
||||||
return updatedContent;
|
return updatedContent;
|
||||||
}
|
}
|
||||||
|
|
@ -249,14 +219,21 @@
|
||||||
id,
|
id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update(store, {data: {duplicateContentBlock: {contentBlock}}}) {
|
update(
|
||||||
|
store,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
duplicateContentBlock: { contentBlock },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
) {
|
||||||
if (contentBlock) {
|
if (contentBlock) {
|
||||||
const query = CHAPTER_QUERY;
|
const query = CHAPTER_QUERY;
|
||||||
const variables = {
|
const variables = {
|
||||||
id: parent.id,
|
id: parent.id,
|
||||||
};
|
};
|
||||||
const { chapter } = store.readQuery({ query, variables });
|
const { chapter } = store.readQuery({ query, variables });
|
||||||
const index = chapter.contentBlocks.findIndex(contentBlock => contentBlock.id === id);
|
const index = chapter.contentBlocks.findIndex((contentBlock) => contentBlock.id === id);
|
||||||
const contentBlocks = insertAtIndex(chapter.contentBlocks, index, contentBlock);
|
const contentBlocks = insertAtIndex(chapter.contentBlocks, index, contentBlock);
|
||||||
const data = {
|
const data = {
|
||||||
chapter: {
|
chapter: {
|
||||||
|
|
@ -268,7 +245,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
editContentBlock(contentBlock) {
|
editContentBlock(contentBlock) {
|
||||||
const route = {
|
const route = {
|
||||||
|
|
@ -280,7 +256,9 @@
|
||||||
this.$router.push(route);
|
this.$router.push(route);
|
||||||
},
|
},
|
||||||
deleteContentBlock(contentBlock) {
|
deleteContentBlock(contentBlock) {
|
||||||
this.$modal.open('confirm').then(() => {
|
this.$modal
|
||||||
|
.open('confirm')
|
||||||
|
.then(() => {
|
||||||
this.doDeleteContentBlock(contentBlock);
|
this.doDeleteContentBlock(contentBlock);
|
||||||
})
|
})
|
||||||
.catch();
|
.catch();
|
||||||
|
|
@ -295,14 +273,21 @@
|
||||||
id,
|
id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update(store, {data: {deleteContentBlock: {success}}}) {
|
update(
|
||||||
|
store,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
deleteContentBlock: { success },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
) {
|
||||||
if (success) {
|
if (success) {
|
||||||
const query = CHAPTER_QUERY;
|
const query = CHAPTER_QUERY;
|
||||||
const variables = {
|
const variables = {
|
||||||
id: parent.id,
|
id: parent.id,
|
||||||
};
|
};
|
||||||
const { chapter } = store.readQuery({ query, variables });
|
const { chapter } = store.readQuery({ query, variables });
|
||||||
const index = chapter.contentBlocks.findIndex(contentBlock => contentBlock.id === id);
|
const index = chapter.contentBlocks.findIndex((contentBlock) => contentBlock.id === id);
|
||||||
const contentBlocks = removeAtIndex(chapter.contentBlocks, index);
|
const contentBlocks = removeAtIndex(chapter.contentBlocks, index);
|
||||||
const data = {
|
const data = {
|
||||||
chapter: {
|
chapter: {
|
||||||
|
|
@ -316,18 +301,20 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
createContentListOrBlocks(contentList) {
|
createContentListOrBlocks(contentList) {
|
||||||
return [{
|
return [
|
||||||
|
{
|
||||||
type: 'content_list',
|
type: 'content_list',
|
||||||
contents: contentList,
|
contents: contentList,
|
||||||
id: contentList[0].id,
|
id: contentList[0].id,
|
||||||
}];
|
},
|
||||||
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "~styles/helpers";
|
@import '~styles/helpers';
|
||||||
|
|
||||||
.content-block {
|
.content-block {
|
||||||
margin-bottom: $section-spacing;
|
margin-bottom: $section-spacing;
|
||||||
|
|
@ -398,7 +385,7 @@
|
||||||
@include content-box-base;
|
@include content-box-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ p {
|
:deep(p) {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
|
@ -407,7 +394,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .text-block {
|
:deep(.text-block) {
|
||||||
ul {
|
ul {
|
||||||
@include list-parent;
|
@include list-parent;
|
||||||
}
|
}
|
||||||
|
|
@ -417,6 +404,5 @@
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<div
|
<div class="solution" data-cy="solution">
|
||||||
class="solution"
|
<a class="solution__toggle" data-cy="show-solution" @click="toggle"
|
||||||
data-cy="solution"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="solution__toggle"
|
|
||||||
data-cy="show-solution"
|
|
||||||
@click="toggle"
|
|
||||||
>Lösung
|
>Lösung
|
||||||
<template v-if="!visible">anzeigen</template>
|
<template v-if="!visible">anzeigen</template>
|
||||||
<template v-else>ausblenden</template>
|
<template v-else>ausblenden</template>
|
||||||
</a>
|
</a>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div
|
<div class="solution__hidden fade" v-if="visible">
|
||||||
class="solution__hidden fade"
|
<p class="solution__text solution-text" data-cy="solution-text" v-html="sanitizedText" />
|
||||||
v-if="visible"
|
<cms-document-block :solution="true" class="solution__document" :value="value.document" v-if="value.document" />
|
||||||
>
|
|
||||||
<p
|
|
||||||
class="solution__text solution-text"
|
|
||||||
data-cy="solution-text"
|
|
||||||
|
|
||||||
v-html="sanitizedText"
|
|
||||||
/>
|
|
||||||
<cms-document-block
|
|
||||||
:solution="true"
|
|
||||||
class="solution__document"
|
|
||||||
:value="value.document"
|
|
||||||
v-if="value.document"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -63,7 +44,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "~styles/helpers";
|
@import '~styles/helpers';
|
||||||
|
|
||||||
.solution {
|
.solution {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -86,12 +67,12 @@
|
||||||
font-size: toRem(18px);
|
font-size: toRem(18px);
|
||||||
color: $color-silver-dark;
|
color: $color-silver-dark;
|
||||||
|
|
||||||
/deep/ p {
|
:deep(p) {
|
||||||
font-size: toRem(18px);
|
font-size: toRem(18px);
|
||||||
color: $color-silver-dark;
|
color: $color-silver-dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ ul {
|
:deep(ul) {
|
||||||
padding-left: $medium-spacing;
|
padding-left: $medium-spacing;
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
|
|
@ -104,7 +85,7 @@
|
||||||
|
|
||||||
.fade-enter-active,
|
.fade-enter-active,
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
transition: opacity .3s;
|
transition: opacity 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter-from,
|
.fade-enter-from,
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<div
|
<div :data-scrollto="value.id" class="assignment">
|
||||||
:data-scrollto="value.id"
|
<p class="assignment__main-text" data-cy="assignment-main-text" v-html="assignment.assignment" />
|
||||||
class="assignment"
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
class="assignment__main-text"
|
|
||||||
data-cy="assignment-main-text"
|
|
||||||
v-html="assignment.assignment"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<solution
|
<solution :value="solution" v-if="assignment.solution" />
|
||||||
:value="solution"
|
|
||||||
v-if="assignment.solution"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template v-if="isStudent">
|
<template v-if="isStudent">
|
||||||
<submission-form
|
<submission-form
|
||||||
|
|
@ -33,24 +23,13 @@
|
||||||
@spellcheck="spellcheck"
|
@spellcheck="spellcheck"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<spell-check
|
<spell-check :corrections="corrections" :text="submission.text" />
|
||||||
:corrections="corrections"
|
|
||||||
:text="submission.text"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p
|
<p class="assignment__feedback" v-if="assignment.submission.submissionFeedback" v-html="feedbackText" />
|
||||||
class="assignment__feedback"
|
|
||||||
v-if="assignment.submission.submissionFeedback"
|
|
||||||
v-html="feedbackText"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!isStudent">
|
<template v-if="!isStudent">
|
||||||
<router-link
|
<router-link :to="{ name: 'submissions', params: { id: assignment.id } }" class="button button--primary">
|
||||||
:to="{name: 'submissions', params: { id: assignment.id }}"
|
Zu den Ergebnissen
|
||||||
class="button button--primary"
|
|
||||||
>
|
|
||||||
Zu den
|
|
||||||
Ergebnissen
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -68,9 +47,15 @@
|
||||||
import { sanitize } from '@/helpers/text';
|
import { sanitize } from '@/helpers/text';
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
|
|
||||||
const SubmissionForm = defineAsyncComponent(() => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/assignment/SubmissionForm'));
|
const SubmissionForm = defineAsyncComponent(() =>
|
||||||
const Solution = defineAsyncComponent(() => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/Solution'));
|
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/assignment/SubmissionForm')
|
||||||
const SpellCheck = defineAsyncComponent(() => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/assignment/SpellCheck'));
|
);
|
||||||
|
const Solution = defineAsyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/Solution')
|
||||||
|
);
|
||||||
|
const SpellCheck = defineAsyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/assignment/SpellCheck')
|
||||||
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['value'],
|
props: ['value'],
|
||||||
|
|
@ -127,7 +112,8 @@
|
||||||
...mapActions(['scrollToAssignmentReady']),
|
...mapActions(['scrollToAssignmentReady']),
|
||||||
_save: debounce(function (submission) {
|
_save: debounce(function (submission) {
|
||||||
this.saving++;
|
this.saving++;
|
||||||
this.$apollo.mutate({
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
mutation: UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS,
|
mutation: UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS,
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -138,7 +124,14 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update(store, {data: {updateAssignment: {successful, updatedAssignment}}}) {
|
update(
|
||||||
|
store,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
updateAssignment: { successful, updatedAssignment },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
if (successful) {
|
if (successful) {
|
||||||
const query = ASSIGNMENT_QUERY;
|
const query = ASSIGNMENT_QUERY;
|
||||||
|
|
@ -149,7 +142,7 @@
|
||||||
submission,
|
submission,
|
||||||
});
|
});
|
||||||
const data = {
|
const data = {
|
||||||
assignment
|
assignment,
|
||||||
};
|
};
|
||||||
store.writeQuery({ query, variables, data });
|
store.writeQuery({ query, variables, data });
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +151,8 @@
|
||||||
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
|
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
this.saving--;
|
this.saving--;
|
||||||
if (this.saving === 0) {
|
if (this.saving === 0) {
|
||||||
this.unsaved = false;
|
this.unsaved = false;
|
||||||
|
|
@ -222,7 +216,8 @@
|
||||||
spellcheck() {
|
spellcheck() {
|
||||||
let self = this;
|
let self = this;
|
||||||
this.spellcheckLoading = true;
|
this.spellcheckLoading = true;
|
||||||
this.$apollo.mutate({
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
mutation: SPELL_CHECK_MUTATION,
|
mutation: SPELL_CHECK_MUTATION,
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -230,10 +225,18 @@
|
||||||
text: this.assignment.submission.text,
|
text: this.assignment.submission.text,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update(store, {data: {spellCheck: {results}}}) {
|
update(
|
||||||
|
store,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
spellCheck: { results },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
) {
|
||||||
self.corrections = results;
|
self.corrections = results;
|
||||||
},
|
},
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
this.spellcheckLoading = false;
|
this.spellcheckLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -278,11 +281,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__main-text {
|
&__main-text {
|
||||||
/deep/ ul{
|
:deep(ul) {
|
||||||
@include list-parent
|
@include list-parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ li {
|
:deep(li) {
|
||||||
@include list-child;
|
@include list-child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -313,7 +316,5 @@
|
||||||
&__feedback {
|
&__feedback {
|
||||||
@include regular-text;
|
@include regular-text;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="tip-tap">
|
<div class="tip-tap">
|
||||||
<editor-content
|
<editor-content class="tip-tap__editor-wrapper" :editor="editor" />
|
||||||
class="tip-tap__editor-wrapper"
|
|
||||||
:editor="editor"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<toggle
|
<toggle :bordered="false" :checked="isList" label="Als Liste formatieren" @input="toggleList" />
|
||||||
:bordered="false"
|
|
||||||
:checked="isList"
|
|
||||||
label="Als Liste formatieren"
|
|
||||||
@input="toggleList"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import {Editor, EditorContent} from "@tiptap/vue-3";
|
import { Editor, EditorContent } from '@tiptap/vue-3';
|
||||||
import Document from '@tiptap/extension-document';
|
import Document from '@tiptap/extension-document';
|
||||||
import Paragraph from '@tiptap/extension-paragraph';
|
import Paragraph from '@tiptap/extension-paragraph';
|
||||||
import Text from '@tiptap/extension-text';
|
import Text from '@tiptap/extension-text';
|
||||||
import BulletList from '@tiptap/extension-bullet-list';
|
import BulletList from '@tiptap/extension-bullet-list';
|
||||||
import ListItem from '@tiptap/extension-list-item';
|
import ListItem from '@tiptap/extension-list-item';
|
||||||
import Toggle from "@/components/ui/Toggle.vue";
|
import Toggle from '@/components/ui/Toggle.vue';
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
editor: Editor | undefined;
|
editor: Editor | undefined;
|
||||||
|
|
@ -43,7 +35,7 @@
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Toggle,
|
Toggle,
|
||||||
EditorContent
|
EditorContent,
|
||||||
},
|
},
|
||||||
|
|
||||||
data(): Data {
|
data(): Data {
|
||||||
|
|
@ -58,7 +50,7 @@
|
||||||
},
|
},
|
||||||
text(): string {
|
text(): string {
|
||||||
return this.value?.text || '';
|
return this.value?.text || '';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -71,29 +63,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.commands.setContent(text, false);
|
editor.commands.setContent(text, false);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.editor = new Editor({
|
this.editor = new Editor({
|
||||||
editorProps: {
|
editorProps: {
|
||||||
attributes: {
|
attributes: {
|
||||||
class: 'tip-tap__editor'
|
class: 'tip-tap__editor',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
content: this.text,
|
content: this.text,
|
||||||
extensions: [
|
extensions: [Document, Paragraph, Text, BulletList, ListItem],
|
||||||
Document,
|
|
||||||
Paragraph,
|
|
||||||
Text,
|
|
||||||
BulletList,
|
|
||||||
ListItem
|
|
||||||
],
|
|
||||||
onUpdate: () => {
|
onUpdate: () => {
|
||||||
const text = (this.editor as Editor).getHTML();
|
const text = (this.editor as Editor).getHTML();
|
||||||
this.$emit('input', text);
|
this.$emit('input', text);
|
||||||
this.$emit('change-text', text);
|
this.$emit('change-text', text);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -106,42 +92,39 @@
|
||||||
const editor = this.editor as Editor;
|
const editor = this.editor as Editor;
|
||||||
editor.chain().selectAll().toggleBulletList().run();
|
editor.chain().selectAll().toggleBulletList().run();
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '~styles/helpers';
|
@import '~styles/helpers';
|
||||||
|
|
||||||
|
|
||||||
.tip-tap {
|
.tip-tap {
|
||||||
|
|
||||||
&__editor-wrapper {
|
&__editor-wrapper {
|
||||||
margin-bottom: $medium-spacing;
|
margin-bottom: $medium-spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ &__editor {
|
:deep(.tip-tap__editor) {
|
||||||
@include inputstyle;
|
@include inputstyle;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ ul {
|
:deep(ul) {
|
||||||
padding-left: $medium-spacing;
|
padding-left: $medium-spacing;
|
||||||
list-style: initial;
|
list-style: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ li {
|
:deep(li) {
|
||||||
@include inputfont;
|
@include inputfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ div {
|
:deep(div) {
|
||||||
@include inputfont;
|
@include inputfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ p {
|
:deep(p) {
|
||||||
@include inputfont;
|
@include inputfont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,7 @@
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="activity-entry__link" @click="$emit('link')">
|
||||||
class="activity-entry__link"
|
|
||||||
@click="$emit('link')"
|
|
||||||
>
|
|
||||||
<chevron-right class="activity-entry__icon" />
|
<chevron-right class="activity-entry__icon" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,20 +15,22 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
const ChevronRight = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */'@/components/icons/ChevronRight'));
|
const ChevronRight = defineAsyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "icons" */ '@/components/icons/ChevronRight')
|
||||||
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['title'],
|
props: ['title'],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
ChevronRight
|
ChevronRight,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import '@/styles/_variables.scss';
|
||||||
@import "@/styles/_mixins.scss";
|
@import '@/styles/_mixins.scss';
|
||||||
|
|
||||||
.activity-entry {
|
.activity-entry {
|
||||||
padding: $small-spacing 0;
|
padding: $small-spacing 0;
|
||||||
|
|
@ -63,7 +62,7 @@
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ p {
|
:deep(p) {
|
||||||
@include regular-text;
|
@include regular-text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,46 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="simple-file-upload">
|
<div class="simple-file-upload">
|
||||||
<component
|
<component :is="button" @click="clickUploadCare" />
|
||||||
:is="button"
|
|
||||||
@click="clickUploadCare"
|
|
||||||
/>
|
|
||||||
<simple-file-upload-hidden-input @link-change-url="$emit('link-change-url', $event)" />
|
<simple-file-upload-hidden-input @link-change-url="$emit('link-change-url', $event)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
const SimpleFileUploadHiddenInput = defineAsyncComponent(() => import('@/components/ui/file-upload/SimpleFileUploadHiddenInput'));
|
const SimpleFileUploadHiddenInput = defineAsyncComponent(() =>
|
||||||
|
import('@/components/ui/file-upload/SimpleFileUploadHiddenInput')
|
||||||
|
);
|
||||||
const SimpleFileUploadIcon = defineAsyncComponent(() => import('@/components/ui/file-upload/SimpleFileUploadIcon'));
|
const SimpleFileUploadIcon = defineAsyncComponent(() => import('@/components/ui/file-upload/SimpleFileUploadIcon'));
|
||||||
const SimpleFileUploadIconAndText = defineAsyncComponent(() => import('@/components/ui/file-upload/SimpleFileUploadIconAndText'));
|
const SimpleFileUploadIconAndText = defineAsyncComponent(() =>
|
||||||
const DocumentIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */'@/components/icons/DocumentIcon'));
|
import('@/components/ui/file-upload/SimpleFileUploadIconAndText')
|
||||||
|
);
|
||||||
|
const DocumentIcon = defineAsyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "icons" */ '@/components/icons/DocumentIcon')
|
||||||
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
withText: {
|
withText: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
SimpleFileUploadHiddenInput,
|
SimpleFileUploadHiddenInput,
|
||||||
DocumentIcon,
|
DocumentIcon,
|
||||||
SimpleFileUploadIcon,
|
SimpleFileUploadIcon,
|
||||||
SimpleFileUploadIconAndText
|
SimpleFileUploadIconAndText,
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
button() {
|
button() {
|
||||||
return this.withText ? 'simple-file-upload-icon-and-text' : 'simple-file-upload-icon';
|
return this.withText ? 'simple-file-upload-icon-and-text' : 'simple-file-upload-icon';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -45,13 +48,13 @@
|
||||||
// workaround for styling the uploadcare widget
|
// workaround for styling the uploadcare widget
|
||||||
let button = this.$el.querySelector('.uploadcare--widget__button');
|
let button = this.$el.querySelector('.uploadcare--widget__button');
|
||||||
button.click();
|
button.click();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "~styles/_helpers";
|
@import '~styles/_helpers';
|
||||||
|
|
||||||
.simple-file-upload {
|
.simple-file-upload {
|
||||||
height: 25px;
|
height: 25px;
|
||||||
|
|
@ -66,7 +69,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .uploadcare--widget {
|
:deep(.uploadcare--widget) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="simple-file-upload">
|
<div class="simple-file-upload">
|
||||||
<button-with-icon-and-text
|
<button-with-icon-and-text icon="document-icon" text="Dokument hochladen" v-if="!value" @click="clickUploadCare" />
|
||||||
icon="document-icon"
|
|
||||||
text="Dokument hochladen"
|
|
||||||
v-if="!value"
|
|
||||||
@click="clickUploadCare"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<simple-file-upload-hidden-input @link-change-url="$emit('link-change-url', $event)" />
|
<simple-file-upload-hidden-input @link-change-url="$emit('link-change-url', $event)" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -13,7 +8,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
const SimpleFileUploadHiddenInput = defineAsyncComponent(() => import('@/components/ui/file-upload/SimpleFileUploadHiddenInput'));
|
const SimpleFileUploadHiddenInput = defineAsyncComponent(() =>
|
||||||
|
import('@/components/ui/file-upload/SimpleFileUploadHiddenInput')
|
||||||
|
);
|
||||||
const ButtonWithIconAndText = defineAsyncComponent(() => import('@/components/ui/ButtonWithIconAndText'));
|
const ButtonWithIconAndText = defineAsyncComponent(() => import('@/components/ui/ButtonWithIconAndText'));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -35,7 +32,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "~styles/_helpers";
|
@import '~styles/_helpers';
|
||||||
|
|
||||||
.simple-file-upload {
|
.simple-file-upload {
|
||||||
width: 25px;
|
width: 25px;
|
||||||
|
|
@ -55,7 +52,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .uploadcare--widget {
|
:deep(.uploadcare--widget) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="instrument">
|
<div class="instrument">
|
||||||
<h1
|
<h1 class="instrument__title" data-cy="instrument-title">
|
||||||
class="instrument__title"
|
|
||||||
data-cy="instrument-title"
|
|
||||||
>
|
|
||||||
{{ instrument.title }}
|
{{ instrument.title }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<div
|
<div class="instrument__intro intro" data-cy="instrument-intro" v-html="instrument.intro" />
|
||||||
class="instrument__intro intro"
|
|
||||||
data-cy="instrument-intro"
|
|
||||||
v-html="instrument.intro"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<content-component
|
<content-component
|
||||||
:component="component"
|
:component="component"
|
||||||
|
|
@ -30,7 +23,9 @@
|
||||||
import INSTRUMENT_QUERY from '@/graphql/gql/queries/instrumentQuery.gql';
|
import INSTRUMENT_QUERY from '@/graphql/gql/queries/instrumentQuery.gql';
|
||||||
|
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
const ContentComponent = defineAsyncComponent(() => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/ContentComponent'));
|
const ContentComponent = defineAsyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ContentComponent')
|
||||||
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
apollo: {
|
apollo: {
|
||||||
|
|
@ -38,26 +33,26 @@
|
||||||
return {
|
return {
|
||||||
query: INSTRUMENT_QUERY,
|
query: INSTRUMENT_QUERY,
|
||||||
variables: {
|
variables: {
|
||||||
slug: this.$route.params.slug
|
slug: this.$route.params.slug,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
ContentComponent
|
ContentComponent,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
instrument: {}
|
instrument: {},
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "~styles/helpers";
|
@import '~styles/helpers';
|
||||||
|
|
||||||
.instrument {
|
.instrument {
|
||||||
&__title {
|
&__title {
|
||||||
|
|
@ -66,7 +61,7 @@
|
||||||
line-height: $default-heading-line-height;
|
line-height: $default-heading-line-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
& /deep/ {
|
& :deep() {
|
||||||
& p {
|
& p {
|
||||||
margin-bottom: $large-spacing;
|
margin-bottom: $large-spacing;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue