Merged in feature/documents-in-solutions (pull request #117)

Feature/documents in solutions

Resolves MS-543 

Approved-by: Lorenz Padberg
This commit is contained in:
Ramon Wenger 2022-09-13 14:42:43 +00:00
commit 76ee8bc8a8
7 changed files with 102 additions and 30 deletions

View File

@ -1,5 +1,8 @@
<template> <template>
<div class="cms-document-block"> <div
:class="{'cms-document-block--solution': solution}"
class="cms-document-block"
>
<document-icon class="cms-document-block__icon" /> <document-icon class="cms-document-block__icon" />
<a <a
:href="value.url" :href="value.url"
@ -15,6 +18,10 @@
export default { export default {
props: { props: {
value: Object, value: Object,
solution: {
type: Boolean,
default: false,
},
}, },
components: { components: {
@ -37,8 +44,23 @@
height: 30px; height: 30px;
} }
&__link { &__link {
text-decoration: underline; text-decoration: underline;
} }
$parent: &;
&--solution {
margin-bottom: $small-spacing;
#{$parent}__link {
color: $color-silver-dark;
}
#{$parent}__icon {
fill: $color-silver-dark;
}
}
} }
</style> </style>

View File

@ -5,7 +5,7 @@
> >
<bulb-icon class="instruction__icon" /> <bulb-icon class="instruction__icon" />
<a <a
:href="value.url" :href="url"
class="instruction__link" class="instruction__link"
>{{ text }}</a> >{{ text }}</a>
</div> </div>
@ -27,6 +27,9 @@
computed: { computed: {
text() { text() {
return this.value.text ? this.value.text : 'Anweisungen'; return this.value.text ? this.value.text : 'Anweisungen';
},
url() {
return this.value.document ? this.value.document.url : this.value.url;
} }
} }
}; };

View File

@ -13,22 +13,34 @@
<template v-else>ausblenden</template> <template v-else>ausblenden</template>
</a> </a>
<transition name="fade"> <transition name="fade">
<p <div
class="solution__text solution-text fade" class="solution__hidden fade"
data-cy="solution-text"
v-if="visible" v-if="visible"
v-html="sanitizedText" >
/> <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>
</transition> </transition>
</div> </div>
</template> </template>
<script> <script>
import {sanitizeAsHtml} from '@/helpers/text'; import {sanitizeAsHtml} from '@/helpers/text';
import CmsDocumentBlock from '@/components/content-blocks/CmsDocumentBlock';
export default { export default {
props: ['value'], props: ['value'],
components: {CmsDocumentBlock},
data() { data() {
return { return {

View File

@ -17,12 +17,30 @@ from surveys.models import Survey
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# todo: replace this with the newer method from https://wagtail.org/blog/graphql-with-streamfield/
class GenericStreamFieldType(Scalar): class GenericStreamFieldType(Scalar):
@staticmethod @staticmethod
def serialize(stream_value): def serialize(stream_value):
raw_data = stream_value.raw_data raw_data = stream_value.raw_data
return list(augment_fields(raw_data)) return list(augment_fields(raw_data))
def get_document_json(document_id):
try:
document = CustomDocument.objects.get(id=document_id)
value = {
'value': document_id,
'id': document.id,
'file_name': document.filename,
'file_extension': document.file_extension,
'url': document.url,
'title': document.title,
'display_text': document.display_text
}
return value
except CustomDocument.DoesNotExist:
logger.error('CustomDocument {} does not exist'.format(document_id))
return None
def augment_fields(raw_data): def augment_fields(raw_data):
for data in raw_data: for data in raw_data:
@ -88,21 +106,20 @@ def augment_fields(raw_data):
data['value'] = augment_fields(item_data) data['value'] = augment_fields(item_data)
if _type == 'cms_document_block': if _type == 'cms_document_block':
try: _value = data['value']
_value = data['value'] value = get_document_json(_value)
document = CustomDocument.objects.get(id=_value) if value is not None:
value = {
'value': _value,
'id': document.id,
'file_name': document.filename,
'file_extension': document.file_extension,
'url': document.url,
'title': document.title,
'display_text': document.display_text
}
data['value'] = value data['value'] = value
except CustomDocument.DoesNotExist: if _type == 'solution' or _type == 'instruction':
logger.error('CustomDocument {} does not exist'.format(_value)) _value = data['value']
document_id = _value.get('document')
if document_id is not None:
document = get_document_json(document_id)
if document is not None:
_value['document'] = document
data['value'] = _value
return raw_data return raw_data

View File

@ -2,10 +2,10 @@ from django.db import models
from django.utils.text import slugify from django.utils.text import slugify
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
from wagtail.core.fields import RichTextField, StreamField from wagtail.core.fields import RichTextField, StreamField
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
from books.blocks import DocumentBlock, GeniallyBlock, InfogramBlock, InstrumentTextBlock, LinkBlock, SectionTitleBlock, \ from books.blocks import CMSDocumentBlock, DocumentBlock, GeniallyBlock, InfogramBlock, InstrumentTextBlock, LinkBlock, \
SectionTitleBlock, \
SubtitleBlock, ThinglinkBlock, VideoBlock SubtitleBlock, ThinglinkBlock, VideoBlock
from core.constants import DEFAULT_RICH_TEXT_FEATURES from core.constants import DEFAULT_RICH_TEXT_FEATURES
from core.wagtail_utils import StrictHierarchyPage from core.wagtail_utils import StrictHierarchyPage
@ -53,7 +53,7 @@ class BasicKnowledge(StrictHierarchyPage):
('genially_block', GeniallyBlock()), ('genially_block', GeniallyBlock()),
('thinglink_block', ThinglinkBlock()), ('thinglink_block', ThinglinkBlock()),
('subtitle', SubtitleBlock()), ('subtitle', SubtitleBlock()),
('cms_document_block', DocumentChooserBlock()), ('cms_document_block', CMSDocumentBlock()),
], null=True, blank=True) ], null=True, blank=True)
new_type = models.ForeignKey(InstrumentType, null=True, on_delete=models.PROTECT, related_name='instruments') new_type = models.ForeignKey(InstrumentType, null=True, on_delete=models.PROTECT, related_name='instruments')

View File

@ -1,4 +1,5 @@
from wagtail.core import blocks from wagtail.core import blocks
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.snippets.blocks import SnippetChooserBlock from wagtail.snippets.blocks import SnippetChooserBlock
from assignments.models import Assignment from assignments.models import Assignment
@ -6,6 +7,11 @@ from core.constants import DEFAULT_RICH_TEXT_FEATURES, INSTRUMENTS_RICH_TEXT_FEA
from surveys.models import Survey from surveys.models import Survey
class CMSDocumentBlock(DocumentChooserBlock):
class Meta:
label = 'CMS Document'
# link_block # link_block
class LinkBlock(blocks.StructBlock): class LinkBlock(blocks.StructBlock):
class Meta: class Meta:
@ -23,6 +29,14 @@ class TextBlock(blocks.StructBlock):
text = blocks.RichTextBlock(features=DEFAULT_RICH_TEXT_FEATURES) text = blocks.RichTextBlock(features=DEFAULT_RICH_TEXT_FEATURES)
class SolutionBlock(blocks.StructBlock):
class Meta:
icon = 'tick'
text = blocks.RichTextBlock(features=DEFAULT_RICH_TEXT_FEATURES)
document = CMSDocumentBlock(required=False)
# 'basic_knowledge' # 'basic_knowledge'
class BasicKnowledgeBlock(blocks.StructBlock): class BasicKnowledgeBlock(blocks.StructBlock):
class Meta: class Meta:
@ -113,8 +127,10 @@ class InstructionBlock(blocks.StructBlock):
class Meta: class Meta:
icon = 'help' icon = 'help'
url = blocks.URLBlock() url = blocks.URLBlock(required=False)
text = blocks.TextBlock(required=False) text = blocks.TextBlock(required=False)
document = DocumentChooserBlock(required=False)
# 'text_block' 'task' 'basic_knowledge' 'student_entry' 'image_block' # 'text_block' 'task' 'basic_knowledge' 'student_entry' 'image_block'
# #

View File

@ -4,11 +4,11 @@ from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList, StreamFieldPanel from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList, StreamFieldPanel
from wagtail.core.blocks import StreamBlock from wagtail.core.blocks import StreamBlock
from wagtail.core.fields import StreamField from wagtail.core.fields import StreamField
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
from core.wagtail_utils import get_default_settings from core.wagtail_utils import get_default_settings
from books.blocks import TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, DocumentBlock, \ from books.blocks import CMSDocumentBlock, SolutionBlock, TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, \
DocumentBlock, \
ImageUrlBlock, AssignmentBlock, InfogramBlock, GeniallyBlock, SubtitleBlock, SurveyBlock, ModuleRoomSlugBlock, \ ImageUrlBlock, AssignmentBlock, InfogramBlock, GeniallyBlock, SubtitleBlock, SurveyBlock, ModuleRoomSlugBlock, \
ThinglinkBlock, InstructionBlock ThinglinkBlock, InstructionBlock
from books.utils import get_type_and_value from books.utils import get_type_and_value
@ -56,7 +56,8 @@ class ContentBlock(StrictHierarchyPage):
('image_block', ImageChooserBlock()), ('image_block', ImageChooserBlock()),
('image_url_block', ImageUrlBlock()), ('image_url_block', ImageUrlBlock()),
('link_block', LinkBlock()), ('link_block', LinkBlock()),
('solution', TextBlock(icon='tick')), # ('solution', TextBlock(icon='tick')),
('solution', SolutionBlock()),
('video_block', VideoBlock()), ('video_block', VideoBlock()),
('document_block', DocumentBlock()), ('document_block', DocumentBlock()),
('infogram_block', InfogramBlock()), ('infogram_block', InfogramBlock()),
@ -65,7 +66,8 @@ class ContentBlock(StrictHierarchyPage):
('subtitle', SubtitleBlock()), ('subtitle', SubtitleBlock()),
('instruction', InstructionBlock()), ('instruction', InstructionBlock()),
('module_room_slug', ModuleRoomSlugBlock()), ('module_room_slug', ModuleRoomSlugBlock()),
('cms_document_block', DocumentChooserBlock()) # ('cms_document_block', DocumentChooserBlock(label='CMS Document'))
('cms_document_block', CMSDocumentBlock())
] ]
content_list_item = StreamBlock(content_blocks) content_list_item = StreamBlock(content_blocks)