diff options
| author | Ron Lucke <lucke@elan-ev.de> | 2023-11-08 07:53:25 +0000 |
|---|---|---|
| committer | Ron Lucke <lucke@elan-ev.de> | 2023-11-08 07:53:25 +0000 |
| commit | 1d51328ba0e823d872211e10b33ba87fcd677a23 (patch) | |
| tree | 2c0f9d8034eb48aefc55d65d54732152854e30e2 /resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue | |
| parent | b74f289044a09b36d5ad7fed2cb0e83a35c9b9da (diff) | |
TIC 3361 - Courseware CSS aufteilen
Closes #3361
Merge request studip/studip!2293
Diffstat (limited to 'resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue')
| -rw-r--r-- | resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue | 809 |
1 files changed, 809 insertions, 0 deletions
diff --git a/resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue new file mode 100644 index 0000000..7f7b10c --- /dev/null +++ b/resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue @@ -0,0 +1,809 @@ +<template> + <div class="cw-block cw-block-document"> + <courseware-default-block + :block="block" + :canEdit="canEdit" + :isTeacher="isTeacher" + :preview="false" + @showEdit="initCurrentData" + @storeEdit="storeBlock" + @closeEdit="initCurrentData" + > + <template #content> + <div class="cw-pdf-main-container"> + <template v-if="hasFile"> + <div v-if="currentTitle !== ''" class="cw-block-title"> + {{ currentTitle }} + </div> + <div class="cw-pdf-toolbar"> + <div class="cw-pdf-toolbar-left"> + <div class="cw-pdf-toc"> + <button + class="undecorated" + :class="{ active: pdfTOCDisplay }" + :title="$gettext('Inhaltsverzeichnis')" + :aria-pressed="pdfTOCDisplay ? 'true' : 'false'" + @click="toggleTOCViewer" + > + <studip-icon + shape="table-of-contents" + :role=" + pdfTOC.length === 0 + ? 'inactive' + : pdfTOCDisplay + ? 'info_alt' + : 'clickable' + " + :size="18" + class="text-bottom" + /> + </button> + </div> + <div class="cw-pdf-search-toggle-btn"> + <button + class="undecorated" + :class="{ active: showPdfSearchBox }" + :title="$gettext('Suche')" + :aria-pressed="showPdfSearchBox ? 'true' : 'false'" + @click="togglePdfSearchBox" + > + <studip-icon + shape="search" + :role="showPdfSearchBox ? 'info_alt' : 'clickable'" + :size="18" + class="text-bottom" + /> + </button> + </div> + <div class="cw-pdf-search-box" v-show="showPdfSearchBox"> + <input + ref="pdfSearchInput" + type="text" + v-model="pdfSearch" + @change="doSearchInPdf" + /> + <div class="cw-pdf-search-navs" v-if="pdfSearchFoundNums > 1"> + <button class="undecorated" @click="prevPdfSearch" :title="$gettext('Letzte')"> + <studip-icon + shape="arr_1left" + :role="pdfSearchFoundSelectedIndex === 0 ? 'inactive' : 'clickable'" + :size="18" + class="text-bottom" + /> + </button> + <button class="undecorated" @click="nextPdfSearch" :title="$gettext('Nächste')"> + <studip-icon + shape="arr_1right" + :role=" + pdfSearchFoundSelectedIndex === pdfSearchFoundNums - 1 + ? 'inactive' + : 'clickable' + " + :size="18" + class="text-bottom" + /> + </button> + </div> + <span class="cw-pdf-search-num" v-if="pdfSearchFoundNums > 0"> + {{ pdfSearchFoundSelectedIndex + 1 }} / {{ pdfSearchFoundNums }} + {{ $gettext('Treffer') }} + </span> + </div> + <div class="cw-pdf-page-nav"> + <button + class="undecorated" + @click="prevPage" + :title="$gettext('Eine Seite zurück')" + > + <studip-icon + shape="arr_1up" + :role="pageNum - 1 === 0 ? 'inactive' : 'clickable'" + :size="18" + class="text-bottom" + /> + </button> + <button class="undecorated" @click="nextPage" :title="$gettext('Eine Seite vor')"> + <studip-icon + shape="arr_1down" + :role="pageNum === pageCount ? 'inactive' : 'clickable'" + :size="18" + class="text-bottom" + /> + </button> + <input + type="text" + ref="pageNumInput" + class="cw-pdf-page-num" + :aria-label="$gettext('Seite')" + :value="pageNum" + @change="updatePageNum" + /> + <span> {{ $gettext('von') }} {{ pageCount }} </span> + </div> + </div> + <div class="cw-pdf-toolbar-middle"> + <div class="cw-pdf-zoom-buttons"> + <button class="undecorated" @click="zoomIn" :title="$gettext('Vergrößern')"> + <studip-icon shape="add" :size="18" class="text-bottom" /> + </button> + <button class="undecorated" @click="zoomOut" :title="$gettext('Verkleinern')"> + <studip-icon shape="remove" :size="18" class="text-bottom" /> + </button> + <select v-model="currentScale" :aria-label="$gettext('Zoom')" @change="updateZoom"> + <option v-show="false" :value="currentScale">{{ formattedZoom }}%</option> + <option v-for="(value, index) in scaleValues" :key="index" :value="value"> + {{ value * 100 }}% + </option> + </select> + </div> + <div class="cw-pdf-rotate"> + <button class="undecorated" @click="doRotatePdf" :title="$gettext('Drehen')"> + <studip-icon shape="rotate-right" :size="18" class="text-bottom" /> + </button> + </div> + </div> + <div class="cw-pdf-toolbar-right"> + <div class="cw-pdf-handtool"> + <button + class="undecorated" + :class="{ active: pdfHandTool }" + :title="$gettext('Hand-Werkzeug')" + :aria-pressed="pdfHandTool ? 'true' : 'false'" + @click="toggleHandTool" + > + <studip-icon + shape="hand" + :role="pdfHandTool ? 'info_alt' : 'clickable'" + :size="18" + class="text-bottom" + /> + </button> + </div> + <div class="cw-pdf-download"> + <a + v-if="downloadable === 'true'" + :href="currentUrl" + download + :title="$gettext('Speichern')" + > + <studip-icon shape="download" :size="18" class="text-bottom" /> + </a> + </div> + </div> + </div> + <div class="cw-pdf-outer-container" ref="outerContainer"> + <div class="cw-pdf-content"> + <span class="sr-only" aria-live="polite">{{ srMessage }}</span> + <div class="cw-pdf-sidebar" v-show="pdfTOCDisplay"> + <ul class="cw-pdf-toc-list"> + <CoursewarePDFTableOfContent + v-for="(item, index) in pdfTOC" + :item="item" + :key="index" + @tocPageNav="tocPageNav" + /> + </ul> + </div> + <div + ref="container" + class="cw-pdf-viewer-container" + :class="{ + 'hand-cursor-grab': pdfHandTool, + grabbing: pdfGrabbing, + 'has-error': pdfError, + }" + v-dragscroll="pdfHandTool" + @mousedown="handleMouseDown" + @mouseup="handleMouseUp" + > + <div class="pdfViewer" /> + </div> + </div> + <div v-show="pdfError" class="cw-pdf-error-page"> + <courseware-companion-box + mood="sad" + :msgCompanion="$gettext('Es gab einen Fehler. Bitte versuchen Sie es erneut!')" + > + </courseware-companion-box> + </div> + <div ref="fakeContainer" class="cw-pdf-viewer-fake-container"> + <div class="pdfViewer" /> + </div> + </div> + </template> + </div> + </template> + <template v-if="canEdit" #edit> + <form class="default" @submit.prevent=""> + <label> + {{ $gettext('Überschrift') }} + <input type="text" v-model="currentTitle" /> + </label> + <label> + {{ $gettext('Datei') }} + <courseware-file-chooser + v-model="currentFileId" + :isDocument="true" + @selectFile="updateCurrentFile" + /> + </label> + <label> + {{ $gettext('Download-Icon anzeigen') }} + <select v-model="currentDownloadable"> + <option value="true">{{ $gettext('Ja') }}</option> + <option value="false">{{ $gettext('Nein') }}</option> + </select> + </label> + <label> + {{ $gettext('Dateityp') }} + <select v-model="currentDocType"> + <option value="pdf">PDF</option> + </select> + </label> + </form> + </template> + <template #info> + <p>{{ $gettext('Informationen zum Dokument-Block') }}</p> + </template> + </courseware-default-block> + </div> +</template> + +<script> +import BlockComponents from './block-components.js'; +import blockMixin from '@/vue/mixins/courseware/block.js'; +import CoursewarePDFTableOfContent from './CoursewarePDFTableOfContent.vue'; +import { getDocument } from 'pdfjs-dist'; +import { + DefaultAnnotationLayerFactory, + DefaultTextLayerFactory, + DefaultXfaLayerFactory, + DefaultStructTreeLayerFactory, + PDFFindController, + PDFLinkService, + PDFPageView, + PDFViewer, + EventBus, +} from 'pdfjs-dist/web/pdf_viewer.js'; +// pdfjsWorker must be imported! +import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; +import { dragscroll } from 'vue-dragscroll'; + +import { mapActions } from 'vuex'; +import 'pdfjs-dist/web/pdf_viewer.css'; + +export default { + name: 'courseware-document-block', + mixins: [blockMixin], + components: Object.assign(BlockComponents, { CoursewarePDFTableOfContent }), + directives: { + dragscroll, + }, + props: { + block: Object, + canEdit: Boolean, + isTeacher: Boolean, + }, + data() { + return { + currentTitle: '', + currentFileId: '', + currentFile: {}, + currentDownloadable: '', + currentDocType: '', + + pdfError: false, + pdfBasePage: null, + pdfPage: null, + pdfTextContent: null, + pdfHandTool: false, + pdfGrabbing: false, + pdfTextLayer: null, + pdfAnnotationLayer: null, + pdfAnnotation: false, + pdfRotate: 0, + PdfViewer: null, + pdfEventBus: null, + pdfLinkService: null, + pdfFindController: null, + pdfDoc: null, + pdfLoadingTask: null, + pdfSearch: '', + pdfSearchMatchesMapping: [], + pdfSearchFoundNums: 0, + pdfSearchFoundSelectedIndex: 0, + pdfSearchHighlightedList: [], + showPdfSearchBox: false, + pdfTOC: [], + pdfTOCDisplay: false, + pageNum: 1, + pageCount: 0, + scale: 1, + currentScale: 1, + scaleValues: [0.5, 1, 1.5, 2, 3, 4], + file: null, + + srMessage: '', + }; + }, + computed: { + title() { + return this.block?.attributes?.payload?.title; + }, + fileDownloadable() { + return this.currentDownloadable === 'true'; + }, + downloadable() { + return this.block?.attributes?.payload?.downloadable ?? 'true'; + }, + fileId() { + return this.block?.attributes?.payload?.file_id; + }, + docType() { + return this.block?.attributes?.payload?.doc_type; + }, + currentUrl() { + if (this.currentFile?.meta) { + return this.currentFile.meta['download-url']; + } else { + return ''; + } + }, + hasFile() { + return this.currentFileId !== ''; + }, + formattedZoom() { + return Number.parseInt(this.scale * 100, 10); + }, + }, + watch: { + scale(newValue) { + let overflow = newValue > 1 ? 'auto' : 'hidden'; + let container = this.$refs.container; + container.style.overflow = overflow; + this.currentScale = newValue; + }, + pageNum(newValue) { + this.resetPdfViewer(); + }, + showPdfSearchBox() { + this.resetPdfSearch(); + }, + }, + mounted() { + this.loadFileRefs(this.block.id).then((response) => { + this.file = response[0]; + this.currentFile = this.file; + this.initPdfTask(); + }); + this.initCurrentData(); + }, + methods: { + ...mapActions({ + updateBlock: 'updateBlockInContainer', + loadFileRefs: 'loadFileRefs', + companionWarning: 'companionWarning', + }), + initCurrentData() { + this.currentTitle = this.title; + this.currentDownloadable = this.downloadable; + this.currentFileId = this.fileId; + this.currentDocType = this.docType; + }, + updateCurrentFile(file) { + this.currentFile = file; + this.currentFileId = file.id; + }, + initPdfTask() { + if (this.currentUrl) { + let view = this; + view.pdfEventBus = new EventBus(); + view.pdfLoadingTask = getDocument(this.currentUrl).promise; + view.pdfLoadingTask.__PDFDocumentLoadingTask = true; + // Link Service + view.pdfLinkService = new PDFLinkService({ + eventBus: view.pdfEventBus, + }); + // Find Controller + view.pdfFindController = new PDFFindController({ + eventBus: view.pdfEventBus, + linkService: view.pdfLinkService, + }); + // Annotation Layer + view.pdfAnnotationLayer = new DefaultAnnotationLayerFactory(); + // Text Layer + view.pdfTextLayer = new DefaultTextLayerFactory(); + // Load Pdf Document + view.loadPdfDocument(); + + // Handle search results. + view.pdfEventBus.on('updatetextlayermatches', ({ source, pageIndex }) => { + if (view.pdfViewer.pdfPage._pageIndex == pageIndex) { + setTimeout(() => { + view.handleSearchMatches(); + }, 260); + } + }); + } + }, + loadPdfDocument() { + if (this.pdfLoadingTask) { + let view = this; + view.pdfLoadingTask.then((pdfDocument) => { + view.pdfDoc = pdfDocument; + view.pageCount = pdfDocument.numPages; + // get table of contents if any. + view.loadPdfTOC(); + // Rendering PDF viewer + view.loadPdfViewer(); + view.pdfLinkService.setDocument(view.pdfDoc, null); + view.pdfFindController.setDocument(view.pdfDoc); + }); + } + }, + loadPdfTOC() { + if (this.pdfDoc) { + let view = this; + view.pdfTOC = []; + // Get the tree outline + view.pdfDoc.getOutline().then((outline) => { + if (outline) { + view.pdfTOC = outline; + } + }); + } + }, + loadPdfViewer() { + if (this.pdfDoc) { + let view = this; + this.pdfError = false; + let container = this.$refs.container; + let outerContainer = this.$refs.outerContainer; + let fakeContainer = this.$refs.fakeContainer; + this.pdfDoc + .getPage(parseInt(view.pageNum)) + .then((pdfPage) => { + view.pdfPage = pdfPage; + // Creating the page view with default parameters. + let defaultViewport = pdfPage.getViewport({ + scale: 1.35, + }); + + view.pdfBasePage = new PDFViewer({ + container: fakeContainer, + eventBus: view.pdfEventBus, + findController: view.pdfFindController, + }); + + let pdfPageViewOptions = { + container: container, + id: view.pageNum, + scale: view.scale, + defaultViewport: defaultViewport, + eventBus: view.pdfEventBus, + findController: view.pdfFindController, + textHighlighterFactory: view.pdfBasePage, + xfaLayerFactory: view.pdfDoc.isPureXfa ? new DefaultXfaLayerFactory() : null, + structTreeLayerFactory: new DefaultStructTreeLayerFactory(), + }; + if (view.pdfHandTool === false) { + pdfPageViewOptions.textLayerFactory = view.pdfTextLayer; + pdfPageViewOptions.annotationLayerFactory = view.pdfAnnotationLayer; + } else { + pdfPageViewOptions.textLayerMode = 0; + pdfPageViewOptions.annotationMode = 0; + } + // Force annotation to be disabled. + if (!this.pdfAnnotation && pdfPageViewOptions?.annotationLayerFactory) { + pdfPageViewOptions.annotationLayerFactory = null; + pdfPageViewOptions.annotationMode = 0; + } + view.pdfViewer = new PDFPageView(pdfPageViewOptions); + // Associates the actual page with the view, and drawing it + view.pdfViewer.setPdfPage(view.pdfPage); + // Set LinkService viewer + view.pdfLinkService.setViewer(view.pdfViewer); + // Set outer container height + outerContainer.style.height = container.offsetHeight + 'px'; + view.renderPage(); + }) + .catch((err) => { + console.log(err); + outerContainer.style.minHeight = '350px'; + view.pdfError = true; + }); + } + }, + renderPage() { + if (this.pdfViewer) { + this.updatePdfViewer(); + this.pdfViewer.draw(); + if (!this.pdfHandTool) { + this.pdfViewer.textLayer.findController = this.pdfFindController; + } + if (this.pdfPage) { + this.pdfPage.getTextContent().then((textContent) => { + this.pdfTextContent = textContent; + }); + } + if (this.pdfSearchMatchesMapping.length) { + this.pdfSearchDisplayHandler(); + } + } + }, + resetPdfViewer() { + this.pdfViewer.destroy(); + let container = this.$refs.container; + while (!container.lastChild.classList.contains('pdfViewer')) { + container.removeChild(container.lastChild); + } + this.loadPdfViewer(); + }, + updatePdfViewer(resetScale = false) { + let updateArgs = { + scale: resetScale ? 1 : this.scale, + rotation: this.pdfRotate, + }; + this.pdfViewer.update(updateArgs); + }, + prevPage() { + if (this.pageNum <= 1) { + return; + } + this.pageNum--; + }, + nextPage() { + if (this.pageNum >= this.pdfDoc.numPages) { + return; + } + this.pageNum++; + }, + goToPage(page) { + const pageNum = Number.parseInt(page, 10); + if (pageNum < 1 || pageNum > this.pdfDoc.numPages) { + return; + } + this.pageNum = pageNum; + }, + tocPageNav(dest) { + let view = this; + let destObj = dest.find( + (ref) => + typeof ref === 'object' && + ref !== null && + Number.isInteger(ref.num) && + ref.num >= 0 && + Number.isInteger(ref.gen) && + ref.gen >= 0 + ); + if (destObj) { + view.pdfDoc.getPageIndex(destObj).then((pageIndex) => { + view.goToPage(pageIndex + 1); + }); + } + }, + updatePageNum() { + let pageNumInput = this.$refs.pageNumInput; + let value = Number.parseInt(pageNumInput.value, 10); + if (Number.isInteger(value) && value > 0 && value <= Number.parseInt(this.pageCount, 10)) { + this.pageNum = value; + } else { + pageNumInput.value = this.pageNum; + } + }, + doRotatePdf() { + let rotationDegs = [0, 90, 180, 270, 360]; + let index = rotationDegs.indexOf(this.pdfRotate); + let nextIndex = index + 1 >= rotationDegs.length ? 0 : index + 1; + let nextDeg = rotationDegs[nextIndex]; + this.pdfRotate = nextDeg; + this.renderPage(); + this.updateSrMessage(this.$gettext('gedreht')); + }, + zoomIn() { + this.scale = this.scale < 4 ? (this.scale * 10 + 1) / 10 : this.scale; + this.renderPage(); + this.updateSrMessage(this.$gettext('vergrößert')); + }, + zoomOut() { + this.scale = this.scale > 0.1 ? (this.scale * 10 - 1) / 10 : this.scale; + this.renderPage(); + this.updateSrMessage(this.$gettext('verkleinert')); + }, + updateZoom(e) { + const value = e.target.value; + if (this.scale === value) { + return; + } + this.scale = value; + this.renderPage(); + this.updateSrMessage(this.$gettext('Zoom Stufe ausgweählt')); + }, + toggleHandTool() { + this.pdfHandTool = !this.pdfHandTool; + this.resetPdfViewer(); + this.showPdfSearchBox = false; + }, + handleHandToolDisplay(event) { + this.pdfGrabbing = event.type === 'mousedown'; + }, + handleMouseDown(e) { + this.handleHandToolDisplay(e); + }, + handleMouseUp(e) { + this.handleHandToolDisplay(e); + }, + togglePdfSearchBox() { + this.showPdfSearchBox = this.pdfHandTool ? false : !this.showPdfSearchBox; + if (this.showPdfSearchBox) { + this.$nextTick(() => { + this.$refs.pdfSearchInput.focus(); + }); + } + }, + handleSearchMatches() { + let view = this; + let allMatches = view.pdfFindController.pageMatches; + let totalMatches = 0; + let searchSelectIndex = 0; + let matchesPageCount = 0; + view.pdfSearchMatchesMapping = []; + for (let pageIndex = 0; pageIndex < view.pageCount; pageIndex++) { + let pageNum = pageIndex + 1; + let pageMatches = allMatches[pageIndex]; + totalMatches += pageMatches.length; + if (pageMatches.length) { + matchesPageCount++; + } + for (let i in pageMatches) { + let matchIndex = parseInt(i, 10); + let mappingObj = { + selectIndex: searchSelectIndex, + matchIndex: matchIndex, + pageNum: pageNum, + }; + view.pdfSearchMatchesMapping.push(mappingObj); + searchSelectIndex++; + } + } + // Find next match if there the current page has nothing. + if ( + view.pdfSearchFoundSelectedIndex === 0 && + view.pdfViewer.pdfPage._pageIndex > 0 && + matchesPageCount > 0 + ) { + let nextMapped = view.pdfSearchMatchesMapping.filter( + (map) => map.pageNum >= view.pdfViewer.pdfPage._pageIndex + 1 + ); + if (nextMapped.length) { + view.pdfSearchFoundSelectedIndex = nextMapped[0].selectIndex; + } + } + view.pdfSearchFoundNums = totalMatches; + view.pdfSearchDisplayHandler(); + }, + doSearchInPdf() { + let findObj = { + type: '', + query: this.pdfSearch, + phraseSearch: true, + caseSensitive: false, + entireWord: true, + highlightAll: true, + findPrevious: false, + matchDiacritics: false, + }; + this.pdfEventBus.dispatch('find', findObj); + }, + prevPdfSearch() { + if (this.pdfSearchFoundSelectedIndex === 0) { + return; + } + this.pdfSearchFoundSelectedIndex--; + this.pdfSearchDisplayHandler(); + }, + nextPdfSearch() { + if (this.pdfSearchFoundSelectedIndex === this.pdfSearchFoundNums - 1) { + return; + } + this.pdfSearchFoundSelectedIndex++; + this.pdfSearchDisplayHandler(); + }, + pdfSearchDisplayHandler() { + // Go to page based on selected index. + let pageMatches = this.pdfSearchMatchesMapping.filter( + (map) => map.selectIndex === this.pdfSearchFoundSelectedIndex + ); + if (pageMatches.length) { + let matchObj = pageMatches[0]; + // A timeout of > 250ms is needed when page is changed! + let highlightRenderTimeout = 0; + if (matchObj.pageNum !== this.pageNum) { + this.goToPage(matchObj.pageNum); + highlightRenderTimeout = 260; + } + setTimeout(() => { + this.setPdfSearchHighlighted(); + this.scrollToSearchFounds(matchObj.matchIndex); + }, highlightRenderTimeout); + } + }, + scrollToSearchFounds(matchIndex) { + if (this.pdfSearchHighlightedList?.length) { + let selectedSpan = this.pdfSearchHighlightedList[matchIndex]; + if (selectedSpan) { + selectedSpan.classList.add('selected'); + selectedSpan.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + } + }, + setPdfSearchHighlighted() { + if (this.pdfViewer?.textLayer?.textDivs) { + let textDivs = this.pdfViewer.textLayer.textDivs; + let highlightedSpans = []; + for (let textSpan of textDivs) { + if (textSpan?.children) { + let children = [...textSpan.children]; + for (let child of children) { + if (child.nodeName == 'SPAN' && child.classList.contains('highlight')) { + child.classList.remove('selected'); + highlightedSpans.push(child); + } + } + } + } + // Sort the array based on the top of the span. + highlightedSpans.sort((current, next) => { + let currentTop = parseInt(current.parentNode.style.top, 10); + let nextTop = parseInt(next.parentNode.style.top, 10); + return currentTop > nextTop; + }); + this.pdfSearchHighlightedList = highlightedSpans; + } + }, + resetPdfSearch() { + this.pdfSearch = ''; + this.pdfSearchFoundNums = 0; + this.pdfSearchFoundSelectedIndex = 0; + this.pdfSearchHighlightedList = []; + this.pdfSearchMatchesMapping = []; + this.doSearchInPdf(); + }, + toggleTOCViewer() { + if (this.pdfTOC.length) { + this.pdfTOCDisplay = !this.pdfTOCDisplay; + } else { + this.pdfTOCDisplay = false; + } + }, + storeBlock() { + if (this.currentFile === undefined) { + this.companionWarning({ + info: this.$gettext('Bitte wählen Sie eine Datei aus.'), + }); + return false; + } else { + let attributes = {}; + attributes.payload = {}; + attributes.payload.title = this.currentTitle; + attributes.payload.file_id = this.currentFile.id; + attributes.payload.downloadable = this.currentDownloadable.toString(); + attributes.payload.doc_type = this.currentDocType; + + this.updateBlock({ + attributes: attributes, + blockId: this.block.id, + containerId: this.block.relationships.container.data.id, + }); + } + }, + updateSrMessage(message) { + this.srMessage = ''; + this.srMessage = message; + }, + }, +}; +</script> +<style scoped lang="scss"> +@import '../../../../assets/stylesheets/scss/courseware/blocks/document.scss'; +</style>
\ No newline at end of file |
