From 33d14c3abc8e861efdb9b8e6bf619b3af1d75b3e Mon Sep 17 00:00:00 2001 From: Ron Lucke Date: Wed, 12 Mar 2025 16:05:41 +0100 Subject: add qr code to link block --- lib/models/Courseware/BlockTypes/Link.json | 9 ++ lib/models/Courseware/BlockTypes/Link.php | 6 +- package.json | 1 + .../stylesheets/scss/courseware/blocks/link.scss | 10 +- .../courseware/blocks/CoursewareLinkBlock.vue | 127 +++++++++++++++++---- 5 files changed, 129 insertions(+), 24 deletions(-) diff --git a/lib/models/Courseware/BlockTypes/Link.json b/lib/models/Courseware/BlockTypes/Link.json index 351983f..8fdd124 100644 --- a/lib/models/Courseware/BlockTypes/Link.json +++ b/lib/models/Courseware/BlockTypes/Link.json @@ -16,6 +16,15 @@ }, "title": { "type": "string" + }, + "qr-enabled": { + "type": "boolean" + }, + "qr-level": { + "type": "string" + }, + "qr-size": { + "type": "string" } }, "required": [ diff --git a/lib/models/Courseware/BlockTypes/Link.php b/lib/models/Courseware/BlockTypes/Link.php index 8e14079..9cf17f5 100644 --- a/lib/models/Courseware/BlockTypes/Link.php +++ b/lib/models/Courseware/BlockTypes/Link.php @@ -35,6 +35,9 @@ class Link extends BlockType 'unit-target' => '', 'url' => '', 'title' => '', + 'qr-enabled' => false, + 'qr-level' => 'L', + 'qr-size' => 180, ]; } @@ -76,7 +79,8 @@ class Link extends BlockType _('Hyperlink'), _('Quellenangabe'), _('Linkliste'), - _('Linksammlung') + _('Linksammlung'), + _('QR-Code'), ]; } } diff --git a/package.json b/package.json index e52d011..367c5ac 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "postcss": "^8.4.49", "postcss-loader": "^8.1.1", "postcss-scss": "^4.0.4", + "qrcode.vue": "3.6.0", "raw-loader": "^4.0.2", "sanitize-html": "^2.7.0", "sass": "^1.29.0", diff --git a/resources/assets/stylesheets/scss/courseware/blocks/link.scss b/resources/assets/stylesheets/scss/courseware/blocks/link.scss index bfa286d..7d342bb 100644 --- a/resources/assets/stylesheets/scss/courseware/blocks/link.scss +++ b/resources/assets/stylesheets/scss/courseware/blocks/link.scss @@ -103,6 +103,14 @@ } } - } + } + } + + .cw-link-qr-code { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + margin: 10px 0; } } diff --git a/resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue b/resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue index 78d17dc..5b1fe1c 100644 --- a/resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue @@ -11,20 +11,49 @@ > @@ -98,12 +162,14 @@ import StudipIdentImage from './../../StudipIdentImage.vue'; import BlockComponents from './block-components.js'; import blockMixin from '@/vue/mixins/courseware/block.js'; import colorMixin from '@/vue/mixins/courseware/colors.js'; +import QrcodeVue from 'qrcode.vue'; import { mapActions, mapGetters } from 'vuex'; +import { $gettext } from '../../../../assets/javascripts/lib/gettext'; export default { name: 'courseware-link-block', mixins: [blockMixin, colorMixin], - components: Object.assign(BlockComponents, { StudipIdentImage }), + components: { ...BlockComponents, StudipIdentImage, QrcodeVue }, props: { block: Object, canEdit: Boolean, @@ -116,6 +182,9 @@ export default { currentUnitTarget: '', currentUrl: '', currentTitle: '', + currentQREnabled: false, + currentQRLevel: '', + currentQRSize: '', identimage: '', }; }, @@ -142,6 +211,15 @@ export default { title() { return this.block?.attributes?.payload?.title; }, + qrEnabled() { + return this.block?.attributes?.payload?.['qr-enabled']; + }, + qrLevel() { + return this.block?.attributes?.payload?.['qr-level']; + }, + qrSize() { + return this.block?.attributes?.payload?.['qr-size']; + }, units() { const allUnits = this.courseUnits; const units = allUnits.filter((unit) => unit.id !== this.context.unit); @@ -156,9 +234,8 @@ export default { return this.currentType === 'unit' ? this.getUnitData(this.unitById({ id: this.currentUnitTarget })) : null; }, headerImageUrl() { - const headerUrl = this.rootElement(this.unitById({ id: this.currentUnitTarget }))?.relationships?.image?.meta?.[ - 'download-url' - ]; + const headerUrl = this.rootElement(this.unitById({ id: this.currentUnitTarget }))?.relationships?.image + ?.meta?.['download-url']; return headerUrl ? headerUrl : null; }, previewImageStyle() { @@ -194,6 +271,9 @@ export default { this.currentUrl = this.url; this.fixUrl(); this.currentTitle = this.title; + this.currentQREnabled = this.qrEnabled; + this.currentQRLevel = this.qrLevel; + this.currentQRSize = this.qrSize; }, fixUrl() { @@ -249,8 +329,11 @@ export default { target: this.currentTarget, 'unit-target': this.currentUnitTarget, url: this.currentUrl, - title: this.currentTitle - } + title: this.currentTitle, + 'qr-enabled': this.currentQREnabled, + 'qr-level': this.currentQRLevel, + 'qr-size': this.currentQRSize, + }, }; this.updateBlock({ @@ -284,7 +367,7 @@ export default { }); } }, - } + }, };