Merge branch 'feature/vite-vue3' into develop

This commit is contained in:
Ramon Wenger 2023-05-08 16:14:06 +02:00
commit a25296d3d3
255 changed files with 2155 additions and 1209 deletions

View File

@ -1,10 +0,0 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: {
'postcss-import': {},
'postcss-url': {},
// to edit target browsers: use "browserslist" field in package.json
autoprefixer: {},
},
};

7
client/.postcssrc.json Normal file
View File

@ -0,0 +1,7 @@
{
"plugins": {
"postcss-import": {},
"postcss-url": {},
"autoprefixer": {}
}
}

View File

@ -1,45 +0,0 @@
'use strict';
require('./check-versions')();
process.env.NODE_ENV = 'production';
const ora = require('ora');
const rm = require('rimraf');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');
const spinner = ora('building for production...');
spinner.start();
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), (err) => {
if (err) throw err;
webpack(webpackConfig, (err, stats) => {
spinner.succeed();
if (err) throw err;
process.stdout.write(
stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false,
}) + '\n\n'
);
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'));
process.exit(1);
}
console.log(chalk.cyan(' Build complete.\n'));
console.log(
chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
" Opening index.html over file:// won't work.\n"
)
);
});
});

View File

@ -1,53 +0,0 @@
'use strict';
const chalk = require('chalk');
const semver = require('semver');
const packageConfig = require('../package.json');
const shell = require('shelljs');
function exec(cmd) {
return require('child_process').execSync(cmd).toString().trim();
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node,
},
];
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm,
});
}
module.exports = function () {
const warnings = [];
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i];
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(
mod.name + ': ' + chalk.red(mod.currentVersion) + ' should be ' + chalk.green(mod.versionRequirement)
);
}
}
if (warnings.length) {
console.log('');
console.log(chalk.yellow('To use this template, you must update following to modules:'));
console.log();
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i];
console.log(' ' + warning);
}
console.log();
process.exit(1);
}
};

View File

@ -3,7 +3,7 @@ const path = require('path');
const config = require('../config'); const config = require('../config');
const packageConfig = require('../package.json'); const packageConfig = require('../package.json');
const isDev = process.env.NODE_ENV !== 'production'; const isDev = import.meta.env.MODE !== 'production';
const assetsPath = (_path) => { const assetsPath = (_path) => {
const assetsSubDirectory = isDev ? config.dev.assetsSubDirectory : config.build.assetsSubDirectory; const assetsSubDirectory = isDev ? config.dev.assetsSubDirectory : config.build.assetsSubDirectory;

View File

@ -1,17 +1,7 @@
'use strict'; const config = {
module.exports = {
/*
* ENV variables used in JS code need to be stringyfied, as they will be replaced in the code, and JS needs quotes
* around strings
*/
VUE_APP_ENABLE_SPELLCHECK: !!process.env.TASKBASE_BASEURL,
/*
* Vars used in HTML templates don't need to be stringyfied, as HTML does not need them to have quotes
*/
// vvvv HTML PROPERTIES FROM HERE, NOT STRINGIFIED vvvv
VUE_APP_FAVICON_32: 'https://skillbox-my-detailhandel-dha-prod.s3.eu-central-1.amazonaws.com/myDHA-favicon.png', VUE_APP_FAVICON_32: 'https://skillbox-my-detailhandel-dha-prod.s3.eu-central-1.amazonaws.com/myDHA-favicon.png',
VUE_APP_FAVICON_16: 'https://skillbox-my-detailhandel-dha-prod.s3.eu-central-1.amazonaws.com/myDHA-favicon.png', VUE_APP_FAVICON_16: 'https://skillbox-my-detailhandel-dha-prod.s3.eu-central-1.amazonaws.com/myDHA-favicon.png',
VUE_APP_TITLE: 'myDHA', VUE_APP_TITLE: 'myDHA',
// ^^^^ HTML PROPERTIES TO HERE, NOT STRINGIFIED ^^^^
}; };
export default config;

View File

@ -1,17 +1,7 @@
'use strict'; const config = {
module.exports = {
/*
* ENV variables used in JS code need to be stringyfied, as they will be replaced in the code, and JS needs quotes
* around strings
*/
VUE_APP_ENABLE_SPELLCHECK: !!process.env.TASKBASE_BASEURL,
/*
* Vars used in HTML templates don't need to be stringyfied, as HTML does not need them to have quotes
*/
// vvvv HTML PROPERTIES FROM HERE, NOT STRINGIFIED vvvv
VUE_APP_FAVICON_32: 'https://skillbox-my-detailhandel-dhf-prod.s3.eu-central-1.amazonaws.com/myDHF-favicon.png', VUE_APP_FAVICON_32: 'https://skillbox-my-detailhandel-dhf-prod.s3.eu-central-1.amazonaws.com/myDHF-favicon.png',
VUE_APP_FAVICON_16: 'https://skillbox-my-detailhandel-dhf-prod.s3.eu-central-1.amazonaws.com/myDHF-favicon.png', VUE_APP_FAVICON_16: 'https://skillbox-my-detailhandel-dhf-prod.s3.eu-central-1.amazonaws.com/myDHF-favicon.png',
VUE_APP_TITLE: 'myDHF', VUE_APP_TITLE: 'myDHF',
// ^^^^ HTML PROPERTIES TO HERE, NOT STRINGIFIED ^^^^
}; };
export default config;

View File

@ -1,17 +1,7 @@
'use strict'; const config = {
module.exports = {
/*
* ENV variables used in JS code need to be stringyfied, as they will be replaced in the code, and JS needs quotes
* around strings
*/
VUE_APP_ENABLE_SPELLCHECK: !!process.env.TASKBASE_BASEURL,
/*
* Vars used in HTML templates don't need to be stringyfied, as HTML does not need them to have quotes
*/
// vvvv HTML PROPERTIES FROM HERE, NOT STRINGIFIED vvvv
VUE_APP_FAVICON_32: 'https://skillbox-my-kv-prod.s3-eu-west-1.amazonaws.com/mykv-favicon.png', VUE_APP_FAVICON_32: 'https://skillbox-my-kv-prod.s3-eu-west-1.amazonaws.com/mykv-favicon.png',
VUE_APP_FAVICON_16: 'https://skillbox-my-kv-prod.s3-eu-west-1.amazonaws.com/mykv-favicon.png', VUE_APP_FAVICON_16: 'https://skillbox-my-kv-prod.s3-eu-west-1.amazonaws.com/mykv-favicon.png',
VUE_APP_TITLE: 'myKV', VUE_APP_TITLE: 'myKV',
// ^^^^ HTML PROPERTIES TO HERE, NOT STRINGIFIED ^^^^
}; };
export default config;

View File

@ -1,43 +0,0 @@
'use strict';
const { merge } = require('webpack-merge');
const values = {
NODE_ENV: '"production"',
HEP_URL: JSON.stringify(process.env.HEP_URL),
MATOMO_HOST: JSON.stringify(process.env.MATOMO_HOST),
MATOMO_SITE_ID: JSON.stringify(process.env.MATOMO_SITE_ID),
LOGOUT_REDIRECT_URL: JSON.stringify(process.env.LOGOUT_REDIRECT_URL),
VUE_APP_FLAVOR: JSON.stringify(process.env.APP_FLAVOR),
SENTRY_DSN: JSON.stringify(process.env.SENTRY_JAVASCRIPT_DSN),
SENTRY_ENVIRONMENT: JSON.stringify(process.env.SENTRY_ENV),
/*
* ENV variables used in JS code need to be stringyfied, as they will be replaced (in place) in the code,
* and JS needs quotes around strings
* see https://cli.vuejs.org/guide/mode-and-env.html#using-env-variables-in-client-side-code
*/
VUE_APP_ENABLE_SPELLCHECK: !!process.env.TASKBASE_BASEURL,
/*
* Vars used in HTML templates don't need to be stringyfied, as HTML does not need them to have quotes
*/
// vvvv HTML PROPERTIES FROM HERE, NOT STRINGIFIED vvvv
VUE_APP_FAVICON_32: '/static/favicon-32x32.png',
VUE_APP_FAVICON_16: '/static/favicon-16x16.png',
VUE_APP_TITLE: 'mySkillbox',
// ^^^^ HTML PROPERTIES TO HERE, NOT STRINGIFIED ^^^^
};
switch (process.env.APP_FLAVOR) {
case 'my-kv':
module.exports = merge(values, require('./prod-my-kv.env.js'));
break;
case 'my-dhf':
module.exports = merge(values, require('./prod-dhf.env.js'));
break;
case 'my-dha':
module.exports = merge(values, require('./prod-dha.env.js'));
break;
default:
// we are on the skillbox APP_FLAVOR
module.exports = values;
}

View File

@ -37,11 +37,7 @@ export default defineConfig({
component: { component: {
devServer: { devServer: {
framework: 'vue', framework: 'vue',
bundler: 'webpack', bundler: 'vite',
webpackConfig: async () => {
const webpackConfig = await require('./build/webpack.dev.conf');
return webpackConfig;
},
}, },
}, },
}); });

View File

@ -245,7 +245,8 @@ describe('Snapshot', () => {
cy.visit('module/miteinander-reden/snapshots'); cy.visit('module/miteinander-reden/snapshots');
cy.getByDataCy('snapshot-link').should('have.text', 'Old Title'); cy.getByDataCy('snapshot-link').should('have.text', 'Old Title');
cy.getByDataCy('rename-snapshot-button').click(); cy.getByDataCy('rename-snapshot-button').click();
cy.getByDataCy('edit-name-input').clear().type(newTitle); cy.getByDataCy('edit-name-input').clear();
cy.getByDataCy('edit-name-input').type(newTitle);
cy.getByDataCy('modal-save-button').click(); cy.getByDataCy('modal-save-button').click();
cy.getByDataCy('snapshot-link').should('have.text', 'New Title'); cy.getByDataCy('snapshot-link').should('have.text', 'New Title');
waitNTimes(5); waitNTimes(5);

View File

@ -1,12 +1,12 @@
import { getMinimalMe } from '../../../support/helpers'; import { getMinimalMe } from '../../../support/helpers'
describe('The Room Page (Teacher)', () => { describe('The Room Page (Teacher)', () => {
const MeQuery = getMinimalMe(); const MeQuery = getMinimalMe()
const selectedClass = MeQuery.me.selectedClass; const selectedClass = MeQuery.me.selectedClass
const entryText = 'something should be here'; const entryText = 'something should be here'
const entryTitle = 'some title'; const entryTitle = 'some title'
const slug = 'ein-historisches-festival'; const slug = 'ein-historisches-festival'
const id = btoa('RoomNode:1'); const id = btoa('RoomNode:1')
const room = { const room = {
id, id,
slug, slug,
@ -15,11 +15,11 @@ describe('The Room Page (Teacher)', () => {
roomEntries: { roomEntries: {
edges: [], edges: [],
}, },
}; }
const RoomEntriesQuery = { const RoomEntriesQuery = {
room, room,
}; }
const operations = { const operations = {
MeQuery, MeQuery,
@ -46,38 +46,42 @@ describe('The Room Page (Teacher)', () => {
errors: [], errors: [],
}, },
}, },
}; }
const checkRadioButton = () => { const checkRadioButton = () => {
cy.get('.base-input-container__input:checked + .base-input-container__radiobutton svg').should('have.length', 1); cy.get(
}; '.base-input-container__input:checked + .base-input-container__radiobutton svg'
).should('have.length', 1)
}
beforeEach(() => { beforeEach(() => {
cy.setup(); cy.setup()
}); })
it('displays new room entry with author name', () => { it('displays new room entry with author name', () => {
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('add-room-entry-button').click(); cy.getByDataCy('add-room-entry-button').click()
cy.getByDataCy('add-content-link').first().click(); cy.getByDataCy('add-content-link').first().click()
cy.getByDataCy('choose-text-widget').click(); cy.getByDataCy('choose-text-widget').click()
cy.getByDataCy('input-with-label-input').type(entryTitle); cy.getByDataCy('input-with-label-input').type(entryTitle)
cy.get('.tip-tap__editor').type(entryText); cy.get('.tip-tap__editor').type(entryText)
cy.getByDataCy('save-button').click(); cy.getByDataCy('save-button').click()
cy.get('.room-entry__content:first').should('contain', entryText).should('contain', 'Rachel Green'); cy.get('.room-entry__content:first')
}); .should('contain', entryText)
.should('contain', 'Rachel Green')
})
// todo: re-enable once cypress can do it correctly // todo: re-enable once cypress can do it correctly
it.skip('changes visibility of a room', () => { it.skip('changes visibility of a room', () => {
const MeQuery = getMinimalMe({ const MeQuery = getMinimalMe({
isTeacher: true, isTeacher: true,
}); })
const operations = { const operations = {
MeQuery, MeQuery,
RoomEntriesQuery, RoomEntriesQuery,
@ -90,61 +94,72 @@ describe('The Room Page (Teacher)', () => {
}, },
}, },
}, },
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-visibility-status').should('contain', 'alle Lernenden'); cy.getByDataCy('room-visibility-status').should('contain', 'alle Lernenden')
cy.getByDataCy('toggle-more-actions-menu').click(); cy.getByDataCy('toggle-more-actions-menu').click()
cy.getByDataCy('change-visibility').click(); cy.getByDataCy('change-visibility').click()
cy.getByDataCy('modal-title').should('contain', 'Sichtbarkeit anpassen'); cy.getByDataCy('modal-title').should('contain', 'Sichtbarkeit anpassen')
cy.get('.change-visibility__radio').should('have.length', 2); cy.get('.change-visibility__radio').should('have.length', 2)
cy.get('.change-visibility__radio--selected').should('have.length', 1); cy.get('.change-visibility__radio--selected').should('have.length', 1)
checkRadioButton(); checkRadioButton()
cy.get('.change-visibility__radio--selected').should('have.length', 1).should('contain', 'alle Lernenden'); cy.get('.change-visibility__radio--selected')
checkRadioButton(); .should('have.length', 1)
cy.getByDataCy('select-option').eq(0).click(); .should('contain', 'alle Lernenden')
cy.get('.change-visibility__radio--selected').should('have.length', 1); checkRadioButton()
checkRadioButton(); cy.getByDataCy('select-option').eq(0).click()
cy.getByDataCy('select-option').eq(1).click(); cy.get('.change-visibility__radio--selected').should('have.length', 1)
cy.getByDataCy('select-option').eq(1).click(); checkRadioButton()
cy.get('.change-visibility__radio--selected').should('have.length', 1).should('contain', 'eigenen Beiträge'); cy.getByDataCy('select-option').eq(1).click()
checkRadioButton(); cy.getByDataCy('select-option').eq(1).click()
cy.getByDataCy('modal-save-button').click(); cy.get('.change-visibility__radio--selected')
cy.getByDataCy('room-visibility-status').should('contain', 'eigenen Beiträge'); .should('have.length', 1)
cy.getByDataCy('toggle-more-actions-menu').click(); .should('contain', 'eigenen Beiträge')
cy.getByDataCy('change-visibility').click(); checkRadioButton()
cy.getByDataCy('modal-title').should('contain', 'Sichtbarkeit anpassen'); cy.getByDataCy('modal-save-button').click()
cy.get('.change-visibility__radio--selected').should('have.length', 1).should('contain', 'eigenen Beiträge'); cy.getByDataCy('room-visibility-status').should(
checkRadioButton(); 'contain',
}); 'eigenen Beiträge'
)
cy.getByDataCy('toggle-more-actions-menu').click()
cy.getByDataCy('change-visibility').click()
cy.getByDataCy('modal-title').should('contain', 'Sichtbarkeit anpassen')
cy.get('.change-visibility__radio--selected')
.should('have.length', 1)
.should('contain', 'eigenen Beiträge')
checkRadioButton()
})
it('deletes the room and goes back to the overview', () => { it('deletes the room and goes back to the overview', () => {
const MeQuery = getMinimalMe(); const MeQuery = getMinimalMe()
const schoolClass = MeQuery.me.selectedClass; const schoolClass = MeQuery.me.selectedClass
const roomToDelete = { const roomToDelete = {
id: btoa('RoomNode:room-to-delete'), id: window.btoa('RoomNode:room-to-delete'),
title: 'Delete Me',
schoolClass, schoolClass,
slug: 'delete-me', slug: 'delete-me',
roomEntries: { roomEntries: {
edges: [], edges: [],
}, },
}; }
const otherRoom = { const otherRoom = {
id: btoa('RoomNode:otherRoom'), id: window.btoa('RoomNode:otherRoom'),
slug: 'other-slug', slug: 'other-slug',
title: 'Other Room',
schoolClass, schoolClass,
}; }
let rooms = [roomToDelete, otherRoom]; let rooms = [roomToDelete, otherRoom]
const operations = { const operations = {
MeQuery, MeQuery,
RoomsQuery() { RoomsQuery() {
return { return {
rooms, rooms,
}; }
}, },
RoomEntriesQuery: { RoomEntriesQuery: {
room: roomToDelete, room: roomToDelete,
@ -154,31 +169,32 @@ describe('The Room Page (Teacher)', () => {
success: true, success: true,
}, },
}, },
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/rooms`); cy.visit(`/rooms`)
cy.getByDataCy('room-widget').should('have.length', 2); cy.getByDataCy('room-widget').should('have.length', 2)
cy.getByDataCy('room-widget').first().click(); cy.getByDataCy('room-widget').first().click()
cy.getByDataCy('toggle-more-actions-menu').click(); cy.getByDataCy('room-title').should('contain', 'Delete Me')
cy.getByDataCy('toggle-more-actions-menu').click()
cy.getByDataCy('delete-room').within(() => { cy.getByDataCy('delete-room').within(() => {
cy.get('a').click(); cy.get('a').click()
}); })
cy.getByDataCy('modal-save-button').click(); cy.getByDataCy('modal-save-button').click()
cy.url().should('include', 'rooms'); cy.url().should('include', 'rooms')
cy.getByDataCy('room-widget').should('have.length', 1); cy.getByDataCy('room-widget').should('have.length', 1)
}); })
it('changes class while on room page', () => { it('changes class while on room page', () => {
const { me } = MeQuery; const { me } = MeQuery
const otherClass = { const otherClass = {
id: btoa('SchoolClassNode:34'), id: window.btoa('SchoolClassNode:34'),
name: 'Other Class', name: 'Other Class',
readOnly: false, readOnly: false,
}; }
let selectedClass = me.selectedClass; let selectedClass = me.selectedClass
const operations = { const operations = {
MeQuery: () => { MeQuery: () => {
return { return {
@ -187,16 +203,16 @@ describe('The Room Page (Teacher)', () => {
schoolClasses: [...me.schoolClasses, otherClass], schoolClasses: [...me.schoolClasses, otherClass],
selectedClass, selectedClass,
}, },
}; }
}, },
RoomEntriesQuery, RoomEntriesQuery,
UpdateSettings() { UpdateSettings() {
selectedClass = otherClass; selectedClass = otherClass
return { return {
updateSettings: { updateSettings: {
success: true, success: true,
}, },
}; }
}, },
ModuleDetailsQuery: {}, ModuleDetailsQuery: {},
MySchoolClassQuery: () => { MySchoolClassQuery: () => {
@ -204,32 +220,32 @@ describe('The Room Page (Teacher)', () => {
me: { me: {
selectedClass, selectedClass,
}, },
}; }
}, },
RoomsQuery: { RoomsQuery: {
rooms: [], rooms: [],
}, },
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-title').should('contain', 'A Room'); cy.getByDataCy('room-title').should('contain', 'A Room')
cy.selectClass('Other Class'); cy.selectClass('Other Class')
cy.url().should('include', 'rooms'); cy.url().should('include', 'rooms')
cy.getByDataCy('current-class-name').should('contain', 'Other Class'); cy.getByDataCy('current-class-name').should('contain', 'Other Class')
}); })
}); })
describe('The Room Page (student)', () => { describe('The Room Page (student)', () => {
const slug = 'ein-historisches-festival'; const slug = 'ein-historisches-festival'
const MeQuery = getMinimalMe({ isTeacher: false }); const MeQuery = getMinimalMe({ isTeacher: false })
const { me } = MeQuery; const { me } = MeQuery
const id = atob(me.id).split(':')[1]; const id = atob(me.id).split(':')[1]
const authorId = btoa(`PublicUserNode:${id}`); const authorId = btoa(`PublicUserNode:${id}`)
const entrySlug = 'entry-slug'; const entrySlug = 'entry-slug'
const { selectedClass } = me; const { selectedClass } = me
const roomEntry = { const roomEntry = {
id: 'entry-id', id: 'entry-id',
slug: entrySlug, slug: entrySlug,
@ -250,7 +266,7 @@ describe('The Room Page (student)', () => {
lastName: 'Was Heiri', lastName: 'Was Heiri',
avatarUrl: '', avatarUrl: '',
}, },
}; }
const room = { const room = {
id, id,
slug, slug,
@ -263,55 +279,58 @@ describe('The Room Page (student)', () => {
}, },
], ],
}, },
}; }
const RoomEntriesQuery = { const RoomEntriesQuery = {
room, room,
}; }
beforeEach(() => { beforeEach(() => {
cy.setup(); cy.setup()
}); })
it('room actions should not exist for student', () => { it('room actions should not exist for student', () => {
const operations = { const operations = {
MeQuery: getMinimalMe({ isTeacher: false }), MeQuery: getMinimalMe({ isTeacher: false }),
RoomEntriesQuery, RoomEntriesQuery,
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-title').should('exist'); cy.getByDataCy('room-title').should('exist')
cy.getByDataCy('room-actions').should('not.exist'); cy.getByDataCy('room-actions').should('not.exist')
}); })
it('creates a room entry', () => { it('creates a room entry', () => {
const MeQuery = getMinimalMe({ isTeacher: false }); const MeQuery = getMinimalMe({ isTeacher: false })
const room = { const room = {
id: 'some-room', id: 'some-room',
roomEntries: { roomEntries: {
edges: [], edges: [],
}, },
}; }
const operations = { const operations = {
MeQuery, MeQuery,
RoomEntriesQuery: { RoomEntriesQuery: {
room, room,
}, },
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('add-room-entry-button').click(); cy.getByDataCy('add-room-entry-button').click()
cy.getByDataCy('content-form-section-title').should('have.text', 'Titel (Pflichtfeld)'); cy.getByDataCy('content-form-section-title').should(
}); 'have.text',
'Titel (Pflichtfeld)'
)
})
it('edits own room entry', () => { it('edits own room entry', () => {
const room = { const room = {
@ -325,7 +344,7 @@ describe('The Room Page (student)', () => {
}, },
], ],
}, },
}; }
const operations = { const operations = {
MeQuery: MeQuery, MeQuery: MeQuery,
RoomEntriesQuery: { RoomEntriesQuery: {
@ -334,15 +353,15 @@ describe('The Room Page (student)', () => {
RoomEntryQuery: { RoomEntryQuery: {
roomEntry, roomEntry,
}, },
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-entry-actions').click(); cy.getByDataCy('room-entry-actions').click()
cy.getByDataCy('edit-room-entry').click(); cy.getByDataCy('edit-room-entry').click()
cy.location('pathname').should('include', entrySlug); cy.location('pathname').should('include', entrySlug)
}); })
it('deletes room entry', () => { it('deletes room entry', () => {
const DeleteRoomEntry = { const DeleteRoomEntry = {
@ -351,57 +370,57 @@ describe('The Room Page (student)', () => {
errors: null, errors: null,
roomSlug: slug, roomSlug: slug,
}, },
}; }
const operations = { const operations = {
MeQuery, MeQuery,
RoomEntriesQuery, RoomEntriesQuery,
DeleteRoomEntry, DeleteRoomEntry,
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-entry').should('have.length', 1); cy.getByDataCy('room-entry').should('have.length', 1)
cy.getByDataCy('room-entry-actions').click(); cy.getByDataCy('room-entry-actions').click()
cy.getByDataCy('delete-room-entry').click(); cy.getByDataCy('delete-room-entry').click()
cy.getByDataCy('delete-room-entry').should('not.exist'); cy.getByDataCy('delete-room-entry').should('not.exist')
cy.getByDataCy('modal-save-button').click(); cy.getByDataCy('modal-save-button').click()
cy.getByDataCy('room-entry').should('have.length', 0); cy.getByDataCy('room-entry').should('have.length', 0)
}); })
it('shows room entries with comment count', () => { it('shows room entries with comment count', () => {
const operations = { const operations = {
MeQuery, MeQuery,
RoomEntriesQuery, RoomEntriesQuery,
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-entry') cy.getByDataCy('room-entry')
.should('have.length', 1) .should('have.length', 1)
.within(() => { .within(() => {
cy.getByDataCy('entry-count').should('contain.text', '2'); cy.getByDataCy('entry-count').should('contain.text', '2')
}); })
}); })
it('does not show actions on mobile', () => { it('does not show actions on mobile', () => {
const operations = { const operations = {
MeQuery, MeQuery,
RoomEntriesQuery, RoomEntriesQuery,
}; }
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); })
cy.viewport('iphone-8'); cy.viewport('iphone-8')
cy.visit(`/room/${slug}`); cy.visit(`/room/${slug}`)
cy.getByDataCy('room-actions').should('not.exist'); cy.getByDataCy('room-actions').should('not.exist')
cy.getByDataCy('room-entry').should('have.length', 1); cy.getByDataCy('room-entry').should('have.length', 1)
cy.getByDataCy('room-entry-actions').should('not.be.visible'); cy.getByDataCy('room-entry-actions').should('not.be.visible')
}); })
}); })

View File

@ -4,17 +4,15 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" /> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<title> <title>_APP_TITLE_</title>
<%= htmlWebpackPlugin.options.VUE_APP_TITLE %>
</title>
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet" type="text/css" /> <link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,800" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,800" rel="stylesheet" />
<link href="https://use.typekit.net/tck7ptw.css" rel="stylesheet" /> <link href="https://use.typekit.net/tck7ptw.css" rel="stylesheet" />
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="<%- htmlWebpackPlugin.options.VUE_APP_FAVICON_32 %>" /> <link rel="icon" type="image/png" sizes="32x32" href="_FAVICON_32_" />
<link rel="icon" type="image/png" sizes="16x16" href="<%- htmlWebpackPlugin.options.VUE_APP_FAVICON_16 %>" /> <link rel="icon" type="image/png" sizes="16x16" href="_FAVICON_16_" />
<link rel="manifest" href="/static/site.webmanifest" /> <link rel="manifest" href="/static/site.webmanifest" />
<link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5" /> <link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#da532c" /> <meta name="msapplication-TileColor" content="#da532c" />
@ -37,10 +35,8 @@
</head> </head>
<body> <body>
<div id="app"> <div id="app"></div>
<div class="center"></div> <script type="module" src="/src/main.ts"></script>
</div>
<!-- built files will be auto injected -->
</body> </body>
</html> </html>

992
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,11 @@
}, },
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "webpack serve --progress --config build/webpack.dev.conf.js",
"analyze": "webpack --profile --json --config build/webpack.dev.conf.js > dist/stats.json && webpack-bundle-analyzer dist/stats.json",
"start": ". ../server/.env && npm run dev", "start": ". ../server/.env && npm run dev",
"lint": "eslint --ext .js,.vue,.ts src", "lint": "eslint --ext .js,.vue,.ts src",
"fix-lint": "eslint --ext .js,.vue,.ts --fix src", "fix-lint": "eslint --ext .js,.vue,.ts --fix src",
"build": "node build/build.js", "build": "vite build",
"dev": "vite",
"open:cypress:e2e": "npm run cypress:e2e:open", "open:cypress:e2e": "npm run cypress:e2e:open",
"open:cypress:frontend": "npm run cypress:frontend:open", "open:cypress:frontend": "npm run cypress:frontend:open",
"test:cypress:e2e": "npm run cypress:e2e:test", "test:cypress:e2e": "npm run cypress:e2e:test",
@ -43,6 +42,7 @@
"@graphql-tools/jest-transform": "^1.2.2", "@graphql-tools/jest-transform": "^1.2.2",
"@graphql-tools/mock": "^8.6.5", "@graphql-tools/mock": "^8.6.5",
"@graphql-tools/schema": "^8.3.7", "@graphql-tools/schema": "^8.3.7",
"@rollup/plugin-graphql": "^1.1.0",
"@sentry/vue": "^7.45.0", "@sentry/vue": "^7.45.0",
"@sentry/webpack-plugin": "^1.20.0", "@sentry/webpack-plugin": "^1.20.0",
"@tiptap/core": "^2.0.0-beta.174", "@tiptap/core": "^2.0.0-beta.174",
@ -54,6 +54,7 @@
"@tiptap/vue-3": "^2.0.0-beta.90", "@tiptap/vue-3": "^2.0.0-beta.90",
"@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0", "@typescript-eslint/parser": "^5.10.0",
"@vitejs/plugin-vue": "^3.0.3",
"@vue/apollo-composable": "^4.0.0-beta.1", "@vue/apollo-composable": "^4.0.0-beta.1",
"@vue/apollo-option": "^4.0.0-alpha.16", "@vue/apollo-option": "^4.0.0-alpha.16",
"@vue/compat": "3.2.30", "@vue/compat": "3.2.30",
@ -107,17 +108,19 @@
"semver": "^5.3.0", "semver": "^5.3.0",
"shelljs": "^0.8.5", "shelljs": "^0.8.5",
"survey-knockout": "^1.9.41", "survey-knockout": "^1.9.41",
"typescript": "^4.6.4",
"ts-loader": "^8.3.0", "ts-loader": "^8.3.0",
"typescript": "^4.5.4",
"uploadcare-widget": "^3.6.0", "uploadcare-widget": "^3.6.0",
"url-loader": "^4.1.1", "url-loader": "^4.1.1",
"vee-validate": "^4.5.10", "vee-validate": "^4.5.10",
"vite": "^3.1.0",
"vue": "3.2.30", "vue": "3.2.30",
"vue-loader": "^16.8.3", "vue-loader": "^16.8.3",
"vue-matomo": "^4.2.0", "vue-matomo": "^4.2.0",
"vue-router": "^4.0.14", "vue-router": "^4.0.14",
"vue-scrollto": "^2.20.0", "vue-scrollto": "^2.20.0",
"vue-style-loader": "^3.0.1", "vue-style-loader": "^3.0.1",
"vue-tsc": "^0.40.4",
"vue-vimeo-player": "^1.1.2", "vue-vimeo-player": "^1.1.2",
"vuex": "4.0.1", "vuex": "4.0.1",
"webpack": "^5.67.0", "webpack": "^5.67.0",

View File

@ -21,52 +21,52 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import ScrollUp from '@/components/ScrollUp'; import ScrollUp from '@/components/ScrollUp.vue';
import ReadOnlyBanner from '@/components/ReadOnlyBanner'; import ReadOnlyBanner from '@/components/ReadOnlyBanner.vue';
import modals from '@/components/modals'; import modals from '@/components/modals';
const NewContentBlockWizard = defineAsyncComponent(() => const NewContentBlockWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-block-form/NewContentBlockWizard') import('@/components/content-block-form/NewContentBlockWizard.vue')
); );
const EditContentBlockWizard = defineAsyncComponent(() => const EditContentBlockWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-block-form/EditContentBlockWizard') import('@/components/content-block-form/EditContentBlockWizard.vue')
); );
const EditRoomEntryWizard = defineAsyncComponent(() => const EditRoomEntryWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/rooms/room-entries/EditRoomEntryWizard') import('@/components/rooms/room-entries/EditRoomEntryWizard.vue')
); );
const NewProjectEntryWizard = defineAsyncComponent(() => const NewProjectEntryWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/portfolio/NewProjectEntryWizard') import('@/components/portfolio/NewProjectEntryWizard.vue')
); );
const EditProjectEntryWizard = defineAsyncComponent(() => const EditProjectEntryWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/portfolio/EditProjectEntryWizard') import('@/components/portfolio/EditProjectEntryWizard.vue')
); );
const NewObjectiveWizard = defineAsyncComponent(() => const NewObjectiveWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/objective-groups/NewObjectiveWizard') import('@/components/objective-groups/NewObjectiveWizard.vue')
); );
const NewNoteWizard = defineAsyncComponent(() => const NewNoteWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/notes/NewNoteWizard') import('@/components/notes/NewNoteWizard.vue')
); );
const EditNoteWizard = defineAsyncComponent(() => const EditNoteWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/notes/EditNoteWizard') import('@/components/notes/EditNoteWizard.vue')
); );
const EditClassNameWizard = defineAsyncComponent(() => const EditClassNameWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/school-class/EditClassNameWizard') import('@/components/school-class/EditClassNameWizard.vue')
); );
const EditTeamNameWizard = defineAsyncComponent(() => const EditTeamNameWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/profile/EditTeamNameWizard') import('@/components/profile/EditTeamNameWizard.vue')
); );
const EditSnapshotTitleWizard = defineAsyncComponent(() => const EditSnapshotTitleWizard = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/snapshots/EditSnapshotTitleWizard') import('@/components/snapshots/EditSnapshotTitleWizard.vue')
); );
const DefaultLayout = defineAsyncComponent(() => import(/* webpackChunkName: "layouts" */ '@/layouts/DefaultLayout')); const DefaultLayout = defineAsyncComponent(() => import('@/layouts/DefaultLayout.vue'));
const SimpleLayout = defineAsyncComponent(() => import(/* webpackChunkName: "layouts" */ '@/layouts/SimpleLayout')); const SimpleLayout = defineAsyncComponent(() => import('@/layouts/SimpleLayout.vue'));
const FullScreenLayout = defineAsyncComponent(() => const FullScreenLayout = defineAsyncComponent(() =>
import(/* webpackChunkName: "layouts" */ '@/layouts/FullScreenLayout') import('@/layouts/FullScreenLayout.vue')
); );
const PublicLayout = defineAsyncComponent(() => import(/* webpackChunkName: "layouts" */ '@/layouts/PublicLayout')); const PublicLayout = defineAsyncComponent(() => import('@/layouts/PublicLayout.vue'));
const BlankLayout = defineAsyncComponent(() => import(/* webpackChunkName: "layouts" */ '@/layouts/BlankLayout')); const BlankLayout = defineAsyncComponent(() => import('@/layouts/BlankLayout.vue'));
const SplitLayout = defineAsyncComponent(() => import(/* webpackChunkName: "layouts" */ '@/layouts/SplitLayout')); const SplitLayout = defineAsyncComponent(() => import('@/layouts/SplitLayout.vue'));
export default { export default {
name: 'App', name: 'App',
@ -110,7 +110,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
body { body {
overflow-y: auto; overflow-y: auto;

View File

@ -13,7 +13,7 @@
import { CREATE_CONTENT_BLOCK_AFTER_PAGE, CREATE_CONTENT_BLOCK_UNDER_PARENT_PAGE } from '@/router/module.names'; import { CREATE_CONTENT_BLOCK_AFTER_PAGE, CREATE_CONTENT_BLOCK_UNDER_PARENT_PAGE } from '@/router/module.names';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const AddPointer = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/AddPointer')); const AddPointer = defineAsyncComponent(() => import('@/components/icons/AddPointer.vue'));
export default { export default {
props: { props: {
@ -76,7 +76,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.add-content { .add-content {
display: none; display: none;

View File

@ -9,7 +9,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const AddIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/AddIcon')); const AddIcon = defineAsyncComponent(() => import('@/components/icons/AddIcon.vue'));
export default { export default {
props: ['index'], props: ['index'],

View File

@ -53,7 +53,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.add-widget { .add-widget {
display: none; display: none;

View File

@ -58,7 +58,7 @@
</template> </template>
<script> <script>
import StudentSubmission from '@/components/StudentSubmission'; import StudentSubmission from '@/components/StudentSubmission.vue';
import { meQuery } from '@/graphql/queries'; import { meQuery } from '@/graphql/queries';
@ -105,7 +105,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.assignment-with-submissions { .assignment-with-submissions {
&__title { &__title {

View File

@ -15,7 +15,7 @@ import { PROJECTS_PAGE } from '@/router/portfolio.names';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const ChevronLeft = defineAsyncComponent(() => const ChevronLeft = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/ChevronLeft') import('@/components/icons/ChevronLeft.vue')
); );
export default { export default {
@ -70,7 +70,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.back-link { .back-link {
@include regular-text; @include regular-text;

View File

@ -232,7 +232,7 @@ const textHidden = (type: string) => {
<style lang="scss"> <style lang="scss">
/* todo: re-add `scoped`, same as in ContentBlock.vue */ /* todo: re-add `scoped`, same as in ContentBlock.vue */
@import '~styles/helpers'; @import 'styles/helpers';
.chapter { .chapter {
position: relative; position: relative;

View File

@ -23,7 +23,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Tick = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Tick')); const Tick = defineAsyncComponent(() => import('@/components/icons/Tick.vue'));
export default { export default {
props: ['selectedColor'], props: ['selectedColor'],

View File

@ -357,7 +357,7 @@ const root = computed(() => {
<style lang="scss"> <style lang="scss">
/* todo: re-add `scoped` after switch to vite or this bug is fixed: https://github.com/vuejs/vue-loader/issues/1915 */ /* todo: re-add `scoped` after switch to vite or this bug is fixed: https://github.com/vuejs/vue-loader/issues/1915 */
@import '~styles/helpers'; @import 'styles/helpers';
.content-block { .content-block {
margin-bottom: $section-spacing; margin-bottom: $section-spacing;

View File

@ -37,7 +37,7 @@ const copyLink = () => {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.copy-link { .copy-link {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;

View File

@ -12,7 +12,7 @@
</template> </template>
<script> <script>
import Modal from '@/components/Modal'; import Modal from '@/components/Modal.vue';
export default { export default {
components: { components: {

View File

@ -8,13 +8,13 @@
</template> </template>
<script> <script>
import Modal from '@/components/Modal'; import Modal from '@/components/Modal.vue';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const InfogramBlock = defineAsyncComponent(() => const InfogramBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/InfogramBlock') import('@/components/content-blocks/InfogramBlock.vue')
); );
const GeniallyBlock = defineAsyncComponent(() => const GeniallyBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/GeniallyBlock') import('@/components/content-blocks/GeniallyBlock.vue')
); );
export default { export default {

View File

@ -18,7 +18,7 @@
</template> </template>
<script> <script>
import Modal from '@/components/Modal'; import Modal from '@/components/Modal.vue';
export default { export default {
components: { components: {

View File

@ -28,13 +28,13 @@
<script> <script>
import ContentNavigation from '@/components/book-navigation/ContentNavigation.vue'; import ContentNavigation from '@/components/book-navigation/ContentNavigation.vue';
import UserWidget from '@/components/UserWidget.vue'; import UserWidget from '@/components/UserWidget.vue';
import CurrentClass from '@/components/school-class/CurrentClass'; import CurrentClass from '@/components/school-class/CurrentClass.vue';
import openSidebar from '@/mixins/open-sidebar'; import openSidebar from '@/mixins/open-sidebar';
import me from '@/mixins/me'; import me from '@/mixins/me';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Hamburger = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Hamburger')); const Hamburger = defineAsyncComponent(() => import('@/components/icons/Hamburger.vue'));
export default { export default {
mixins: [openSidebar, me], mixins: [openSidebar, me],
@ -49,7 +49,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.header-bar { .header-bar {
display: flex; display: flex;

View File

@ -11,7 +11,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const InfoIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/InfoIcon')); const InfoIcon = defineAsyncComponent(() => import('@/components/icons/InfoIcon.vue'));
export default { export default {
props: ['text'], props: ['text'],

View File

@ -16,7 +16,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const LoadingIcon = defineAsyncComponent(() => const LoadingIcon = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/LoadingIcon') import('@/components/icons/LoadingIcon.vue')
); );
export default { export default {
@ -41,7 +41,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.loading-button { .loading-button {
height: 52px; height: 52px;

View File

@ -19,14 +19,14 @@
</template> </template>
<script> <script>
import UserWidget from '@/components/UserWidget'; import UserWidget from '@/components/UserWidget.vue';
import me from '@/mixins/me'; import me from '@/mixins/me';
import openSidebar from '@/mixins/open-sidebar'; import openSidebar from '@/mixins/open-sidebar';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Logo = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Logo')); const Logo = defineAsyncComponent(() => import('@/components/icons/Logo.vue'));
const Hamburger = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Hamburger')); const Hamburger = defineAsyncComponent(() => import('@/components/icons/Hamburger.vue'));
export default { export default {
mixins: [me, openSidebar], mixins: [me, openSidebar],
@ -46,7 +46,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.mobile-header { .mobile-header {
justify-content: space-between; justify-content: space-between;

View File

@ -36,7 +36,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Cross = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/CrossIcon')); const Cross = defineAsyncComponent(() => import('@/components/icons/CrossIcon.vue'));
export default { export default {
props: { props: {

View File

@ -1,24 +1,25 @@
<template> <template>
<div class="modal-input"> <div class="modal-input">
<input <input :placeholder="placeholder" :class="{ 'skillbox-input--error': error }" :value="value"
:placeholder="placeholder" class="modal-input__inputfield skillbox-input" @input="input" />
:class="{ 'skillbox-input--error': error }" <div class="modal-input__error" v-if="error">
:value="value"
class="modal-input__inputfield skillbox-input"
@input="$emit('input', $event.target.value)"
/>
<div
class="modal-input__error"
v-if="error"
>
Für Inhaltsblöcke muss zwingend ein Titel erfasst werden. Für Inhaltsblöcke muss zwingend ein Titel erfasst werden.
</div> </div>
</div> </div>
</template> </template>
<script> <script setup lang="ts">
export default { defineProps<{
props: ['value', 'error', 'placeholder'], value: any;
error: any;
placeholder: any;
}>();
const emit = defineEmits(['input']);
const input = (e: Event) => {
const value = (e.target as HTMLInputElement).value;
emit('input', value);
}; };
</script> </script>

View File

@ -18,7 +18,7 @@
</template> </template>
<script> <script>
import WidgetPopover from '@/components/ui/WidgetPopover'; import WidgetPopover from '@/components/ui/WidgetPopover.vue';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Ellipses = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Ellipses.vue')); const Ellipses = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Ellipses.vue'));
@ -38,7 +38,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.more-options { .more-options {
display: flex; display: flex;

View File

@ -9,7 +9,7 @@
</template> </template>
<script> <script>
import BaseInput from '@/components/ui/BaseInput'; import BaseInput from '@/components/ui/BaseInput.vue';
export default { export default {
props: { props: {

View File

@ -81,7 +81,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.read-only-banner { .read-only-banner {
background-color: $color-brand-light; background-color: $color-brand-light;

View File

@ -12,7 +12,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const ArrowUp = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/ArrowUp')); const ArrowUp = defineAsyncComponent(() => import('@/components/icons/ArrowUp.vue'));
export default { export default {
components: { components: {

View File

@ -30,7 +30,7 @@
</template> </template>
<script> <script>
import StudentSubmissionDocument from '@/components/StudentSubmissionDocument'; import StudentSubmissionDocument from '@/components/StudentSubmissionDocument.vue';
export default { export default {
props: ['submission'], props: ['submission'],
@ -70,7 +70,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.student-submission { .student-submission {
@include table-row; @include table-row;

View File

@ -13,7 +13,7 @@
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
import filenameFromUrl from '@/helpers/urls'; import filenameFromUrl from '@/helpers/urls';
const DocumentIcon = defineAsyncComponent(() => const DocumentIcon = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/DocumentIcon') import('@/components/icons/DocumentIcon.vue')
); );
export default { export default {

View File

@ -13,7 +13,7 @@
</template> </template>
<script> <script>
import Avatar from '@/components/profile/Avatar'; import Avatar from '@/components/profile/Avatar.vue';
export default { export default {
props: ['firstName', 'lastName', 'avatarUrl', 'date'], props: ['firstName', 'lastName', 'avatarUrl', 'date'],

View File

@ -17,7 +17,7 @@
</template> </template>
<script> <script>
import Avatar from '@/components/profile/Avatar'; import Avatar from '@/components/profile/Avatar.vue';
export default { export default {
props: { props: {
@ -40,7 +40,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.user-widget { .user-widget {
color: $color-silver-dark; color: $color-silver-dark;

View File

@ -95,13 +95,13 @@
</template> </template>
<script> <script>
import TopicNavigation from '@/components/book-navigation/TopicNavigation'; import TopicNavigation from '@/components/book-navigation/TopicNavigation.vue';
import sidebarMixin from '@/mixins/sidebar'; import sidebarMixin from '@/mixins/sidebar';
import meMixin from '@/mixins/me'; import meMixin from '@/mixins/me';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Logo = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/Logo')); const Logo = defineAsyncComponent(() => import('@/components/icons/Logo.vue'));
export default { export default {
props: { props: {

View File

@ -20,12 +20,12 @@
</template> </template>
<script> <script>
import ContentNavigation from '@/components/book-navigation/ContentNavigation'; import ContentNavigation from '@/components/book-navigation/ContentNavigation.vue';
import sidebarMixin from '@/mixins/sidebar'; import sidebarMixin from '@/mixins/sidebar';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Cross = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/CrossIcon')); const Cross = defineAsyncComponent(() => import('@/components/icons/CrossIcon.vue'));
export default { export default {
mixins: [sidebarMixin], mixins: [sidebarMixin],

View File

@ -24,9 +24,9 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const ChevronDown = defineAsyncComponent(() => const ChevronDown = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/ChevronDown') import('@/components/icons/ChevronDown.vue')
); );
const ChevronUp = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/ChevronUp')); const ChevronUp = defineAsyncComponent(() => import('@/components/icons/ChevronUp.vue'));
export default { export default {
props: ['title'], props: ['title'],

View File

@ -56,7 +56,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.topic-navigation { .topic-navigation {
display: flex; display: flex;

View File

@ -2,20 +2,23 @@
<a <a
class="add-content-link" class="add-content-link"
data-cy="add-content-link" data-cy="add-content-link"
@click="$emit('click')" @click="click"
><plus-icon class="add-content-link__icon" /> <span class="add-content-link__text">Inhalt hinzufügen</span></a ><plus-icon class="add-content-link__icon" /> <span class="add-content-link__text">Inhalt hinzufügen</span></a
> >
</template> </template>
<script> <script setup lang="ts">
import PlusIcon from '@/components/icons/PlusIcon'; import PlusIcon from '@/components/icons/PlusIcon.vue';
export default {
components: { PlusIcon }, const emit = defineEmits(['click']);
};
const click = () => {
emit('click');
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
$color: $color-silver-dark; $color: $color-silver-dark;
$icon-size: 14px; $icon-size: 14px;

View File

@ -333,7 +333,7 @@ export default defineComponent({
</script> </script>
<style lang="scss"> <style lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
// override parent page properties // override parent page properties
.layout--no-scroll { .layout--no-scroll {
padding-bottom: 20px; padding-bottom: 20px;
@ -351,7 +351,7 @@ export default defineComponent({
</style> </style>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.content-block-form { .content-block-form {
max-width: 100%; max-width: 100%;

View File

@ -39,62 +39,62 @@
</template> </template>
<script> <script>
import ContentFormSection from '@/components/content-block-form/ContentFormSection'; import ContentFormSection from '@/components/content-block-form/ContentFormSection.vue';
import ContentElementActions from '@/components/content-block-form/ContentElementActions'; import ContentElementActions from '@/components/content-block-form/ContentElementActions.vue';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const TrashIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/TrashIcon')); const TrashIcon = defineAsyncComponent(() => import('@/components/icons/TrashIcon.vue'));
const ContentBlockElementChooserWidget = defineAsyncComponent(() => const ContentBlockElementChooserWidget = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/ContentBlockElementChooserWidget') import('@/components/content-forms/ContentBlockElementChooserWidget.vue')
); );
const LinkForm = defineAsyncComponent(() => const LinkForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/LinkForm') import('@/components/content-forms/LinkForm.vue')
); );
const VideoForm = defineAsyncComponent(() => const VideoForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/VideoForm') import('@/components/content-forms/VideoForm.vue')
); );
const ImageForm = defineAsyncComponent(() => const ImageForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/ImageForm') import('@/components/content-forms/ImageForm.vue')
); );
const DocumentForm = defineAsyncComponent(() => const DocumentForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/DocumentForm') import('@/components/content-forms/DocumentForm.vue')
); );
const AssignmentForm = defineAsyncComponent(() => const AssignmentForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/AssignmentForm') import('@/components/content-forms/AssignmentForm.vue')
); );
const TextForm = defineAsyncComponent(() => const TextForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/TipTap.vue') import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/TipTap.vue')
); );
const SubtitleForm = defineAsyncComponent(() => const SubtitleForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/SubtitleForm') import('@/components/content-forms/SubtitleForm.vue')
); );
// readonly blocks // readonly blocks
const Assignment = defineAsyncComponent(() => const Assignment = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/assignment/Assignment') import('@/components/content-blocks/assignment/Assignment.vue')
); );
const SurveyBlock = defineAsyncComponent(() => const SurveyBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/SurveyBlock') import('@/components/content-blocks/SurveyBlock.vue')
); );
const Solution = defineAsyncComponent(() => const Solution = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/Solution') import('@/components/content-blocks/Solution.vue')
); );
const ImageBlock = defineAsyncComponent(() => const ImageBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/ImageBlock') import('@/components/content-blocks/ImageBlock.vue')
); );
const Instruction = defineAsyncComponent(() => const Instruction = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/Instruction') import('@/components/content-blocks/Instruction.vue')
); );
const ModuleRoomSlug = defineAsyncComponent(() => const ModuleRoomSlug = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/ModuleRoomSlug') import('@/components/content-blocks/ModuleRoomSlug.vue')
); );
const CmsDocumentBlock = defineAsyncComponent(() => const CmsDocumentBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/CmsDocumentBlock') import('@/components/content-blocks/CmsDocumentBlock.vue')
); );
const ThinglinkBlock = defineAsyncComponent(() => const ThinglinkBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/ThinglinkBlock') import('@/components/content-blocks/ThinglinkBlock.vue')
); );
const InfogramBlock = defineAsyncComponent(() => const InfogramBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-blocks/InfogramBlock') import('@/components/content-blocks/InfogramBlock.vue')
); );
const CHOOSER = 'content-block-element-chooser-widget'; const CHOOSER = 'content-block-element-chooser-widget';
@ -362,7 +362,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.content-element { .content-element {
display: flex; display: flex;

View File

@ -117,7 +117,7 @@ export default defineComponent({
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.content-element-actions { .content-element-actions {
position: relative; position: relative;

View File

@ -57,7 +57,7 @@ export default defineComponent({
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.content-form-section { .content-form-section {
@include default-box-shadow; @include default-box-shadow;

View File

@ -65,17 +65,17 @@ import { defineAsyncComponent } from 'vue';
import { meQuery } from '@/graphql/queries'; import { meQuery } from '@/graphql/queries';
const ModalInput = defineAsyncComponent(() => const ModalInput = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/ModalInput') import('@/components/ModalInput.vue')
); );
const AddContentElement = defineAsyncComponent(() => const AddContentElement = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/AddContentElement') import('@/components/AddContentElement.vue')
); );
const ContentElement = defineAsyncComponent(() => const ContentElement = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-forms" */ '@/components/content-block-form/ContentElement') import('@/components/content-block-form/ContentElement.vue')
); );
const Modal = defineAsyncComponent(() => import('@/components/Modal')); const Modal = defineAsyncComponent(() => import('@/components/Modal.vue'));
const Checkbox = defineAsyncComponent(() => import('@/components/ui/Checkbox')); const Checkbox = defineAsyncComponent(() => import('@/components/ui/Checkbox.vue'));
export default { export default {
props: { props: {
@ -164,7 +164,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.contents-form { .contents-form {
/* top level does not exist, because of the modal */ /* top level does not exist, because of the modal */

View File

@ -8,7 +8,7 @@
</template> </template>
<script> <script>
import ContentsForm from '@/components/content-block-form/ContentsForm'; import ContentsForm from '@/components/content-block-form/ContentsForm.vue';
import { store } from '@/store'; import { store } from '@/store';

View File

@ -9,7 +9,7 @@
</template> </template>
<script> <script>
import ContentsForm from '@/components/content-block-form/ContentsForm'; import ContentsForm from '@/components/content-block-form/ContentsForm.vue';
import NEW_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/addContentBlock.gql'; import NEW_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/addContentBlock.gql';
import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql'; import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql';

View File

@ -17,7 +17,7 @@
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const DocumentIcon = defineAsyncComponent(() => const DocumentIcon = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/DocumentIcon') import('@/components/icons/DocumentIcon.vue')
); );
export default { export default {
@ -36,7 +36,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.cms-document-block { .cms-document-block {
display: grid; display: grid;

View File

@ -26,64 +26,64 @@ import { constructContentComponentBookmarkMutation } from '@/helpers/update-cont
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const TextBlock = defineAsyncComponent(() => const TextBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/TextBlock') import('@/components/content-blocks/TextBlock.vue')
); );
const InstrumentWidget = defineAsyncComponent(() => const InstrumentWidget = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/InstrumentWidget') import('@/components/content-blocks/InstrumentWidget.vue')
); );
const ImageBlock = defineAsyncComponent(() => const ImageBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ImageBlock') import('@/components/content-blocks/ImageBlock.vue')
); );
const ImageUrlBlock = defineAsyncComponent(() => const ImageUrlBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ImageUrlBlock') import('@/components/content-blocks/ImageUrlBlock.vue')
); );
const VideoBlock = defineAsyncComponent(() => const VideoBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/VideoBlock') import('@/components/content-blocks/VideoBlock.vue')
); );
const LinkBlock = defineAsyncComponent(() => const LinkBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/LinkBlock') import('@/components/content-blocks/LinkBlock.vue')
); );
const DocumentBlock = defineAsyncComponent(() => const DocumentBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/DocumentBlock') import('@/components/content-blocks/DocumentBlock.vue')
); );
const CmsDocumentBlock = defineAsyncComponent(() => const CmsDocumentBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/CmsDocumentBlock') import('@/components/content-blocks/CmsDocumentBlock.vue')
); );
const InfogramBlock = defineAsyncComponent(() => const InfogramBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/InfogramBlock') import('@/components/content-blocks/InfogramBlock.vue')
); );
const ThinglinkBlock = defineAsyncComponent(() => const ThinglinkBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ThinglinkBlock') import('@/components/content-blocks/ThinglinkBlock.vue')
); );
const GeniallyBlock = defineAsyncComponent(() => const GeniallyBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/GeniallyBlock') import('@/components/content-blocks/GeniallyBlock.vue')
); );
const SubtitleBlock = defineAsyncComponent(() => const SubtitleBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/SubtitleBlock') import('@/components/content-blocks/SubtitleBlock.vue')
); );
const SectionTitleBlock = defineAsyncComponent(() => const SectionTitleBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/SectionTitleBlock') import('@/components/content-blocks/SectionTitleBlock.vue')
); );
const ContentListBlock = defineAsyncComponent(() => const ContentListBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ContentListBlock') import('@/components/content-blocks/ContentListBlock.vue')
); );
const ModuleRoomSlug = defineAsyncComponent(() => const ModuleRoomSlug = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/ModuleRoomSlug') import('@/components/content-blocks/ModuleRoomSlug.vue')
); );
const Assignment = defineAsyncComponent(() => const Assignment = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/assignment/Assignment') import('@/components/content-blocks/assignment/Assignment.vue')
); );
const Survey = defineAsyncComponent(() => const Survey = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/SurveyBlock') import('@/components/content-blocks/SurveyBlock.vue')
); );
const Solution = defineAsyncComponent(() => const Solution = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/Solution') import('@/components/content-blocks/Solution.vue')
); );
const Instruction = defineAsyncComponent(() => const Instruction = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/Instruction') import('@/components/content-blocks/Instruction.vue')
); );
const BookmarkActions = defineAsyncComponent(() => const BookmarkActions = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/notes/BookmarkActions') import('@/components/notes/BookmarkActions.vue')
); );
export default { export default {
@ -181,7 +181,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~styles/helpers'; @import 'styles/helpers';
.content-component { .content-component {
position: relative; position: relative;

View File

@ -11,8 +11,8 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const ContentList = defineAsyncComponent(() => import('@/components/content-blocks/ContentList')); const ContentList = defineAsyncComponent(() => import('@/components/content-blocks/ContentList.vue'));
const ContentBlock = defineAsyncComponent(() => import('@/components/ContentBlock')); const ContentBlock = defineAsyncComponent(() => import('@/components/ContentBlock.vue'));
export default { export default {
name: 'ContentBlockList', name: 'ContentBlockList',

View File

@ -20,9 +20,9 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const DocumentIcon = defineAsyncComponent(() => const DocumentIcon = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/DocumentIcon') import('@/components/icons/DocumentIcon.vue')
); );
const TrashIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/TrashIcon')); const TrashIcon = defineAsyncComponent(() => import('@/components/icons/TrashIcon.vue'));
export default { export default {
props: { props: {
@ -48,7 +48,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.document-block { .document-block {
display: grid; display: grid;

View File

@ -19,7 +19,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.image-block { .image-block {
width: 100%; width: 100%;

View File

@ -15,7 +15,7 @@
<script> <script>
import me from '@/mixins/me'; import me from '@/mixins/me';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const BulbIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/BulbIcon')); const BulbIcon = defineAsyncComponent(() => import('@/components/icons/BulbIcon.vue'));
export default { export default {
props: ['value'], props: ['value'],

View File

@ -25,7 +25,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/_variables.scss'; @import 'styles/_variables.scss';
.instrument-widget { .instrument-widget {
margin-bottom: $small-spacing; margin-bottom: $small-spacing;

View File

@ -15,7 +15,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const LinkIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/LinkIcon')); const LinkIcon = defineAsyncComponent(() => import('@/components/icons/LinkIcon.vue'));
export default { export default {
props: { props: {

View File

@ -35,7 +35,7 @@
<script> <script>
import { sanitizeAsHtml } from '@/helpers/text'; import { sanitizeAsHtml } from '@/helpers/text';
import CmsDocumentBlock from '@/components/content-blocks/CmsDocumentBlock'; import CmsDocumentBlock from '@/components/content-blocks/CmsDocumentBlock.vue';
export default { export default {
props: ['value'], props: ['value'],
@ -62,7 +62,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.solution { .solution {
display: grid; display: grid;

View File

@ -22,7 +22,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.subtitle { .subtitle {
padding-top: 1px; padding-top: 1px;

View File

@ -21,7 +21,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.text-block { .text-block {
margin-bottom: $medium-spacing; // if calc is not supported margin-bottom: $medium-spacing; // if calc is not supported

View File

@ -16,9 +16,9 @@
</template> </template>
<script> <script>
import YoutubeEmbed from '@/components/videos/YoutubeEmbed'; import YoutubeEmbed from '@/components/videos/YoutubeEmbed.vue';
import VimeoEmbed from '@/components/videos/VimeoEmbed'; import VimeoEmbed from '@/components/videos/VimeoEmbed.vue';
import SrfEmbed from '@/components/videos/SrfEmbed'; import SrfEmbed from '@/components/videos/SrfEmbed.vue';
import { isVimeoUrl, isYoutubeUrl, isSrfUrl } from '@/helpers/video'; import { isVimeoUrl, isYoutubeUrl, isSrfUrl } from '@/helpers/video';
export default { export default {

View File

@ -69,13 +69,13 @@ import { defineAsyncComponent } from 'vue';
import { matomoTrackEvent } from '@/helpers/matomo-client'; import { matomoTrackEvent } from '@/helpers/matomo-client';
const SubmissionForm = defineAsyncComponent(() => const SubmissionForm = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/assignment/SubmissionForm.vue') import('@/components/content-blocks/assignment/SubmissionForm.vue')
); );
const Solution = defineAsyncComponent(() => const Solution = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/Solution.vue') import('@/components/content-blocks/Solution.vue')
); );
const SpellCheck = defineAsyncComponent(() => const SpellCheck = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/assignment/SpellCheck.vue') import('@/components/content-blocks/assignment/SpellCheck.vue')
); );
export default { export default {

View File

@ -26,10 +26,10 @@
import { newLineToParagraph } from '@/helpers/text'; import { newLineToParagraph } from '@/helpers/text';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const DocumentBlock = defineAsyncComponent(() => const DocumentBlock = defineAsyncComponent(() =>
import(/* webpackChunkName: "content-components" */ '@/components/content-blocks/DocumentBlock') import('@/components/content-blocks/DocumentBlock.vue')
); );
const InfoIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/InfoIcon')); const InfoIcon = defineAsyncComponent(() => import('@/components/icons/InfoIcon.vue'));
export default { export default {
props: { props: {
@ -61,7 +61,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.final-submission { .final-submission {
&__text { &__text {

View File

@ -88,7 +88,7 @@ const allowsDocuments = computed(() => {
return 'document' in props.userInput; return 'document' in props.userInput;
}); });
const showSpellcheckButton = computed(() => { const showSpellcheckButton = computed(() => {
return props.spellcheck && process.env.VUE_APP_ENABLE_SPELLCHECK; return props.spellcheck && import.meta.env.VUE_APP_ENABLE_SPELLCHECK;
}); });
const spellcheckText = computed(() => { const spellcheckText = computed(() => {
if (!props.spellcheckLoading) { if (!props.spellcheckLoading) {
@ -113,7 +113,7 @@ const changeDocumentUrl = (documentUrl: string) => {
<style lang="scss"> <style lang="scss">
// todo: use `scoped` once no longer on webpack // todo: use `scoped` once no longer on webpack
@import '~styles/helpers'; @import 'styles/helpers';
.submission-form-container { .submission-form-container {
@include form-with-border; @include form-with-border;

View File

@ -9,7 +9,7 @@
rows="1" rows="1"
class="submission-form__textarea" class="submission-form__textarea"
v-auto-grow v-auto-grow
@input="$emit('input', $event.target.value)" @input="input"
/> />
<div <div
class="submission-form__save-status submission-form__save-status--saved" class="submission-form__save-status submission-form__save-status--saved"
@ -26,34 +26,32 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const TickCircleIcon = defineAsyncComponent(() => const TickCircleIcon = defineAsyncComponent(() => import('@/components/icons/TickCircleIcon.vue'));
import(/* webpackChunkName: "icons" */ '@/components/icons/TickCircleIcon') const LoadingIcon = defineAsyncComponent(() => import('@/components/icons/LoadingIcon.vue'));
);
const LoadingIcon = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/LoadingIcon')
);
export default { interface Props {
props: { inputText: string;
inputText: String, saved: boolean;
saved: Boolean, readonly: boolean;
readonly: Boolean, placeholder: string;
placeholder: { }
type: String,
default: 'Ergebnis erfassen', withDefaults(defineProps<Props>(), {
}, placeholder: 'Ergebnis erfassen',
}, });
components: {
TickCircleIcon, const emit = defineEmits(['input']);
LoadingIcon,
}, const input = (e: Event) => {
const value = (e.target as HTMLInputElement).value;
emit('input', value);
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.submission-form { .submission-form {
display: flex; display: flex;

View File

@ -21,7 +21,7 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const InfoIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/InfoIcon')); const InfoIcon = defineAsyncComponent(() => import('@/components/icons/InfoIcon.vue'));
export default { export default {
props: ['value', 'index'], props: ['value', 'index'],
@ -32,7 +32,7 @@ export default {
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.assignment-form { .assignment-form {
display: grid; display: grid;

View File

@ -2,56 +2,64 @@
<div <div
:class="['chooser-element', subclass]" :class="['chooser-element', subclass]"
:data-cy="cy" :data-cy="cy"
@click="$emit('select')" @click="emit('select')"
> >
<component <component
class="chooser-element__icon" class="chooser-element__icon"
:is="icon" :is="realIcon"
/> />
<div class="chooser-element__title"> <div class="chooser-element__title">
{{ title }} {{ realTitle }}
</div> </div>
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import { computed } from 'vue';
interface Props {
type: string;
icon: string;
title: string;
}
const props = withDefaults(defineProps<Props>(), {
type: '',
});
const emit = defineEmits(['select']);
const defaultTitle = (type:string) => {
return type.replace(/^\w/, (c :string) => c.toUpperCase());
}
const defaultIcon = (type:string) => {
return `${type}-icon`;
}
const subclass =`chooser-element--${props.type}`;
const cy = `choose-${props.type}-widget`;
const realTitle = computed(() => {
return props.title || defaultTitle(props.type);
});
const realIcon = computed(() => {
return props.icon || defaultIcon(props.type);
});
</script>
<script lang="ts">
import formElementIcons from '@/components/ui/form-element-icons'; import formElementIcons from '@/components/ui/form-element-icons';
export default { export default {
props: {
type: {
type: String,
default: '',
},
icon: {
type: String,
default() {
return `${this.type}-icon`;
},
},
title: {
type: String,
default() {
return this.type.replace(/^\w/, (c) => c.toUpperCase());
},
},
},
components: { components: {
...formElementIcons, ...formElementIcons,
}, },
}
data() {
return {
subclass: `chooser-element--${this.type}`,
cy: `choose-${this.type}-widget`,
};
},
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.chooser-element { .chooser-element {
cursor: pointer; cursor: pointer;

View File

@ -39,11 +39,11 @@
</template> </template>
<script> <script>
import Checkbox from '@/components/ui/Checkbox'; import Checkbox from '@/components/ui/Checkbox.vue';
import formElementIcons from '@/components/ui/form-element-icons'; import formElementIcons from '@/components/ui/form-element-icons';
import CrossIcon from '@/components/icons/CrossIcon'; import CrossIcon from '@/components/icons/CrossIcon.vue';
import ChooserElement from '@/components/content-forms/ChooserElement'; import ChooserElement from '@/components/content-forms/ChooserElement.vue';
import { DEFAULT_FEATURE_SET } from '@/consts/features.consts'; import { DEFAULT_FEATURE_SET } from '@/consts/features.consts';
export default { export default {
@ -140,7 +140,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.content-block-element-chooser-widget { .content-block-element-chooser-widget {
display: -ms-grid; display: -ms-grid;

View File

@ -30,11 +30,11 @@
<script> <script>
import { uploadcare } from '@/helpers/uploadcare'; import { uploadcare } from '@/helpers/uploadcare';
import LoadingIcon from '@/components/icons/LoadingIcon'; import LoadingIcon from '@/components/icons/LoadingIcon.vue';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const DocumentIcon = defineAsyncComponent(() => const DocumentIcon = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/DocumentIcon') import('@/components/icons/DocumentIcon.vue')
); );
export default { export default {
@ -83,7 +83,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.document-form { .document-form {
&__uploaded { &__uploaded {

View File

@ -36,7 +36,7 @@
<script> <script>
import uploadcare from 'uploadcare-widget'; import uploadcare from 'uploadcare-widget';
import LoadingIcon from '@/components/icons/LoadingIcon'; import LoadingIcon from '@/components/icons/LoadingIcon.vue';
export default { export default {
props: ['value', 'index'], props: ['value', 'index'],
@ -99,7 +99,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.image-form { .image-form {
&__error { &__error {

View File

@ -23,7 +23,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.link-form { .link-form {
display: grid; display: grid;

View File

@ -12,7 +12,7 @@
</template> </template>
<script> <script>
import InputWithLabel from '@/components/ui/InputWithLabel'; import InputWithLabel from '@/components/ui/InputWithLabel.vue';
export default { export default {
props: { props: {
@ -39,7 +39,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.subtitle-form { .subtitle-form {
&__input { &__input {

View File

@ -35,7 +35,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.text-form { .text-form {
&__input { &__input {

View File

@ -12,8 +12,8 @@
</template> </template>
<script> <script>
import TextForm from '@/components/content-forms/TextForm'; import TextForm from '@/components/content-forms/TextForm.vue';
import HelpfulTooltip from '@/components/HelpfulTooltip'; import HelpfulTooltip from '@/components/HelpfulTooltip.vue';
export default { export default {
props: ['title', 'value', 'helpText'], props: ['title', 'value', 'helpText'],

View File

@ -105,7 +105,7 @@ export default defineComponent({
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.tip-tap { .tip-tap {
&__editor-wrapper { &__editor-wrapper {

View File

@ -44,12 +44,12 @@
</template> </template>
<script> <script>
import YoutubeEmbed from '@/components/videos/YoutubeEmbed'; import YoutubeEmbed from '@/components/videos/YoutubeEmbed.vue';
import VimeoEmbed from '@/components/videos/VimeoEmbed'; import VimeoEmbed from '@/components/videos/VimeoEmbed.vue';
import SrfEmbed from '@/components/videos/SrfEmbed'; import SrfEmbed from '@/components/videos/SrfEmbed.vue';
import { isVimeoUrl, isYoutubeUrl, isSrfUrl } from '@/helpers/video'; import { isVimeoUrl, isYoutubeUrl, isSrfUrl } from '@/helpers/video';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const InfoIcon = defineAsyncComponent(() => import(/* webpackChunkName: "icons" */ '@/components/icons/InfoIcon')); const InfoIcon = defineAsyncComponent(() => import('@/components/icons/InfoIcon.vue'));
export default { export default {
props: ['value', 'index'], props: ['value', 'index'],

View File

@ -24,7 +24,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/variables'; @import 'styles/variables';
.bookmark-icon { .bookmark-icon {
width: 24px; width: 24px;

View File

@ -37,5 +37,5 @@
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
</style> </style>

View File

@ -23,7 +23,7 @@
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql'; import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const ChevronRight = defineAsyncComponent(() => const ChevronRight = defineAsyncComponent(() =>
import(/* webpackChunkName: "icons" */ '@/components/icons/ChevronRight') import('@/components/icons/ChevronRight.vue')
); );
export default { export default {
@ -105,7 +105,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.filter-entry { .filter-entry {
display: flex; display: flex;

View File

@ -25,7 +25,7 @@
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FilterEntry from '@/components/instruments/FilterEntry'; import FilterEntry from '@/components/instruments/FilterEntry.vue';
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql'; import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql'; import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
@ -85,7 +85,7 @@ export default defineComponent({
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.filter-group { .filter-group {
border-bottom: 1px solid $color-silver; border-bottom: 1px solid $color-silver;

View File

@ -49,7 +49,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.instrument-entry { .instrument-entry {
padding: $medium-spacing; padding: $medium-spacing;

View File

@ -16,7 +16,7 @@
</template> </template>
<script> <script>
import FilterGroup from '@/components/instruments/FilterGroup'; import FilterGroup from '@/components/instruments/FilterGroup.vue';
import INSTRUMENT_CATEGORIES_QUERY from 'gql/queries/instrumentCategoriesQuery.gql'; import INSTRUMENT_CATEGORIES_QUERY from 'gql/queries/instrumentCategoriesQuery.gql';
@ -39,7 +39,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.instrument-filter { .instrument-filter {
display: none; display: none;

View File

@ -33,7 +33,7 @@
</template> </template>
<script> <script>
import Modal from '@/components/Modal'; import Modal from '@/components/Modal.vue';
export default { export default {
components: { components: {
@ -69,7 +69,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.confirm-dialog { .confirm-dialog {
&__heading { &__heading {

View File

@ -1,24 +1,24 @@
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
const Modal = defineAsyncComponent(() => import(/* webpackChunkName: "modals" */ '@/components/Modal')); const Modal = defineAsyncComponent(() => import('@/components/Modal.vue'));
const FullscreenImage = defineAsyncComponent(() => const FullscreenImage = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/FullscreenImage') import('@/components/FullscreenImage.vue')
); );
const FullscreenInfographic = defineAsyncComponent(() => const FullscreenInfographic = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/FullscreenInfographic') import('@/components/FullscreenInfographic.vue')
); );
const FullscreenVideo = defineAsyncComponent(() => const FullscreenVideo = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/FullscreenVideo') import('@/components/FullscreenVideo.vue')
); );
const DeactivatePerson = defineAsyncComponent(() => const DeactivatePerson = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/profile/DeactivatePerson') import('@/components/profile/DeactivatePerson.vue')
); );
const SnapshotCreated = defineAsyncComponent(() => const SnapshotCreated = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/modules/SnapshotCreated') import('@/components/modules/SnapshotCreated.vue')
); );
const ChangeVisibility = defineAsyncComponent(() => const ChangeVisibility = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/rooms/ChangeVisibility') import('@/components/rooms/ChangeVisibility.vue')
); );
const Confirm = defineAsyncComponent(() => import(/* webpackChunkName: "modals" */ '@/components/modals/Confirm')); const Confirm = defineAsyncComponent(() => import('@/components/modals/Confirm.vue'));
export default { export default {
Modal, Modal,

View File

@ -78,7 +78,7 @@
<script> <script>
import ObjectiveGroups from '@/components/objective-groups/ObjectiveGroups.vue'; import ObjectiveGroups from '@/components/objective-groups/ObjectiveGroups.vue';
import Chapter from '@/components/Chapter.vue'; import Chapter from '@/components/Chapter.vue';
import BookmarkActions from '@/components/notes/BookmarkActions'; import BookmarkActions from '@/components/notes/BookmarkActions.vue';
export default { export default {
props: { props: {
@ -121,7 +121,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.module { .module {
display: flex; display: flex;

View File

@ -29,12 +29,12 @@
</template> </template>
<script> <script>
import BackLink from '@/components/BackLink'; import BackLink from '@/components/BackLink.vue';
import { moduleQuery } from '@/graphql/queries'; import { moduleQuery } from '@/graphql/queries';
import ToggleEditing from '@/components/toggle-menu/ToggleEditing'; import ToggleEditing from '@/components/toggle-menu/ToggleEditing.vue';
import me from '@/mixins/me'; import me from '@/mixins/me';
import SnapshotMenu from '@/components/modules/SnapshotMenu'; import SnapshotMenu from '@/components/modules/SnapshotMenu.vue';
export default { export default {
apollo: { apollo: {
@ -129,7 +129,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
@mixin module-navigation-typography { @mixin module-navigation-typography {
font-family: $sans-serif-font-family; font-family: $sans-serif-font-family;

View File

@ -8,7 +8,7 @@
</template> </template>
<script> <script>
import BackLink from '@/components/BackLink'; import BackLink from '@/components/BackLink.vue';
import { moduleQuery } from '@/graphql/queries'; import { moduleQuery } from '@/graphql/queries';
import me from '@/mixins/me'; import me from '@/mixins/me';
@ -33,7 +33,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
@mixin module-navigation-typography { @mixin module-navigation-typography {
font-family: $sans-serif-font-family; font-family: $sans-serif-font-family;

View File

@ -43,7 +43,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.module-teaser { .module-teaser {
box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.12); box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.12);

View File

@ -32,7 +32,7 @@
</template> </template>
<script> <script>
import Modal from '@/components/Modal'; import Modal from '@/components/Modal.vue';
import { SNAPSHOT_LIST } from '@/router/module.names'; import { SNAPSHOT_LIST } from '@/router/module.names';
import dateformat from '@/helpers/date-format'; import dateformat from '@/helpers/date-format';
@ -71,7 +71,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.snapshot-created { .snapshot-created {
&__heading { &__heading {

View File

@ -50,7 +50,7 @@
<script> <script>
import dateformat from '@/helpers/date-format'; import dateformat from '@/helpers/date-format';
import Checkbox from '@/components/ui/Checkbox'; import Checkbox from '@/components/ui/Checkbox.vue';
import me from '@/mixins/me'; import me from '@/mixins/me';
@ -154,7 +154,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.snapshot-header { .snapshot-header {
&__subtitle { &__subtitle {

View File

@ -52,8 +52,8 @@ import UPDATE_SNAPSHOT_MUTATION from 'gql/mutations/snapshots/update.gql';
import DELETE_SNAPSHOT_MUTATION from 'gql/mutations/snapshots/delete.gql'; import DELETE_SNAPSHOT_MUTATION from 'gql/mutations/snapshots/delete.gql';
import SNAPSHOTS_QUERY from 'gql/queries/moduleSnapshots.gql'; import SNAPSHOTS_QUERY from 'gql/queries/moduleSnapshots.gql';
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import PenIcon from '@/components/icons/PenIcon'; import PenIcon from '@/components/icons/PenIcon.vue';
import TrashIcon from '@/components/icons/TrashIcon'; import TrashIcon from '@/components/icons/TrashIcon.vue';
import { removeAtIndex } from '@/graphql/immutable-operations'; import { removeAtIndex } from '@/graphql/immutable-operations';
import { matomoTrackEvent } from '@/helpers/matomo-client'; import { matomoTrackEvent } from '@/helpers/matomo-client';
@ -231,7 +231,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.snapshot-list-item { .snapshot-list-item {
display: flex; display: flex;

View File

@ -36,7 +36,7 @@
</template> </template>
<script> <script>
import WidgetPopover from '@/components/ui/WidgetPopover'; import WidgetPopover from '@/components/ui/WidgetPopover.vue';
import { SNAPSHOT_LIST } from '@/router/module.names'; import { SNAPSHOT_LIST } from '@/router/module.names';
import me from '@/mixins/me'; import me from '@/mixins/me';
@ -126,7 +126,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.snapshot-menu { .snapshot-menu {
position: relative; position: relative;

View File

@ -32,7 +32,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.snapshot-team-menu { .snapshot-team-menu {
display: flex; display: flex;

View File

@ -31,7 +31,7 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import 'styles/helpers';
.news-teaser { .news-teaser {
position: relative; position: relative;

View File

@ -10,7 +10,7 @@
</template> </template>
<script> <script>
import NewsTeaser from '@/components/news/NewsTeaser'; import NewsTeaser from '@/components/news/NewsTeaser.vue';
import news from '@/mixins/news'; import news from '@/mixins/news';

Some files were not shown because too many files have changed in this diff Show More