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 packageConfig = require('../package.json');
const isDev = process.env.NODE_ENV !== 'production';
const isDev = import.meta.env.MODE !== 'production';
const assetsPath = (_path) => {
const assetsSubDirectory = isDev ? config.dev.assetsSubDirectory : config.build.assetsSubDirectory;

View File

@ -1,17 +1,7 @@
'use strict';
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
const config = {
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_TITLE: 'myDHA',
// ^^^^ HTML PROPERTIES TO HERE, NOT STRINGIFIED ^^^^
};
export default config;

View File

@ -1,17 +1,7 @@
'use strict';
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
const config = {
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_TITLE: 'myDHF',
// ^^^^ HTML PROPERTIES TO HERE, NOT STRINGIFIED ^^^^
};
export default config;

View File

@ -1,17 +1,7 @@
'use strict';
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
const config = {
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_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: {
devServer: {
framework: 'vue',
bundler: 'webpack',
webpackConfig: async () => {
const webpackConfig = await require('./build/webpack.dev.conf');
return webpackConfig;
},
bundler: 'vite',
},
},
});

View File

@ -245,7 +245,8 @@ describe('Snapshot', () => {
cy.visit('module/miteinander-reden/snapshots');
cy.getByDataCy('snapshot-link').should('have.text', 'Old Title');
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('snapshot-link').should('have.text', 'New Title');
waitNTimes(5);

View File

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

View File

@ -4,17 +4,15 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<title>
<%= htmlWebpackPlugin.options.VUE_APP_TITLE %>
</title>
<title>_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=Montserrat:400,600,800" 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="icon" type="image/png" sizes="32x32" href="<%- htmlWebpackPlugin.options.VUE_APP_FAVICON_32 %>" />
<link rel="icon" type="image/png" sizes="16x16" href="<%- htmlWebpackPlugin.options.VUE_APP_FAVICON_16 %>" />
<link rel="icon" type="image/png" sizes="32x32" href="_FAVICON_32_" />
<link rel="icon" type="image/png" sizes="16x16" href="_FAVICON_16_" />
<link rel="manifest" href="/static/site.webmanifest" />
<link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#da532c" />
@ -37,10 +35,8 @@
</head>
<body>
<div id="app">
<div class="center"></div>
</div>
<!-- built files will be auto injected -->
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</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,
"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",
"lint": "eslint --ext .js,.vue,.ts 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:frontend": "npm run cypress:frontend:open",
"test:cypress:e2e": "npm run cypress:e2e:test",
@ -43,6 +42,7 @@
"@graphql-tools/jest-transform": "^1.2.2",
"@graphql-tools/mock": "^8.6.5",
"@graphql-tools/schema": "^8.3.7",
"@rollup/plugin-graphql": "^1.1.0",
"@sentry/vue": "^7.45.0",
"@sentry/webpack-plugin": "^1.20.0",
"@tiptap/core": "^2.0.0-beta.174",
@ -54,6 +54,7 @@
"@tiptap/vue-3": "^2.0.0-beta.90",
"@typescript-eslint/eslint-plugin": "^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-option": "^4.0.0-alpha.16",
"@vue/compat": "3.2.30",
@ -107,17 +108,19 @@
"semver": "^5.3.0",
"shelljs": "^0.8.5",
"survey-knockout": "^1.9.41",
"typescript": "^4.6.4",
"ts-loader": "^8.3.0",
"typescript": "^4.5.4",
"uploadcare-widget": "^3.6.0",
"url-loader": "^4.1.1",
"vee-validate": "^4.5.10",
"vite": "^3.1.0",
"vue": "3.2.30",
"vue-loader": "^16.8.3",
"vue-matomo": "^4.2.0",
"vue-router": "^4.0.14",
"vue-scrollto": "^2.20.0",
"vue-style-loader": "^3.0.1",
"vue-tsc": "^0.40.4",
"vue-vimeo-player": "^1.1.2",
"vuex": "4.0.1",
"webpack": "^5.67.0",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -357,7 +357,7 @@ const root = computed(() => {
<style lang="scss">
/* 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 {
margin-bottom: $section-spacing;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,9 +24,9 @@
<script>
import { defineAsyncComponent } from 'vue';
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 {
props: ['title'],

View File

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

View File

@ -2,20 +2,23 @@
<a
class="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
>
</template>
<script>
import PlusIcon from '@/components/icons/PlusIcon';
export default {
components: { PlusIcon },
};
<script setup lang="ts">
import PlusIcon from '@/components/icons/PlusIcon.vue';
const emit = defineEmits(['click']);
const click = () => {
emit('click');
}
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
$color: $color-silver-dark;
$icon-size: 14px;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@
</template>
<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 MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql';

View File

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

View File

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

View File

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

View File

@ -20,9 +20,9 @@
<script>
import { defineAsyncComponent } from 'vue';
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 {
props: {
@ -48,7 +48,7 @@ export default {
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
.document-block {
display: grid;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,10 +26,10 @@
import { newLineToParagraph } from '@/helpers/text';
import { defineAsyncComponent } from 'vue';
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 {
props: {
@ -61,7 +61,7 @@ export default {
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
.final-submission {
&__text {

View File

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

View File

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

View File

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

View File

@ -2,56 +2,64 @@
<div
:class="['chooser-element', subclass]"
:data-cy="cy"
@click="$emit('select')"
@click="emit('select')"
>
<component
class="chooser-element__icon"
:is="icon"
:is="realIcon"
/>
<div class="chooser-element__title">
{{ title }}
{{ realTitle }}
</div>
</div>
</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';
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: {
...formElementIcons,
},
data() {
return {
subclass: `chooser-element--${this.type}`,
cy: `choose-${this.type}-widget`,
};
},
};
}
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
.chooser-element {
cursor: pointer;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,7 @@
<script>
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 INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
@ -85,7 +85,7 @@ export default defineComponent({
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
.filter-group {
border-bottom: 1px solid $color-silver;

View File

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

View File

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

View File

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

View File

@ -1,24 +1,24 @@
import { defineAsyncComponent } from 'vue';
const Modal = defineAsyncComponent(() => import(/* webpackChunkName: "modals" */ '@/components/Modal'));
const Modal = defineAsyncComponent(() => import('@/components/Modal.vue'));
const FullscreenImage = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/FullscreenImage')
import('@/components/FullscreenImage.vue')
);
const FullscreenInfographic = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/FullscreenInfographic')
import('@/components/FullscreenInfographic.vue')
);
const FullscreenVideo = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/FullscreenVideo')
import('@/components/FullscreenVideo.vue')
);
const DeactivatePerson = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/profile/DeactivatePerson')
import('@/components/profile/DeactivatePerson.vue')
);
const SnapshotCreated = defineAsyncComponent(() =>
import(/* webpackChunkName: "modals" */ '@/components/modules/SnapshotCreated')
import('@/components/modules/SnapshotCreated.vue')
);
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 {
Modal,

View File

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

View File

@ -29,12 +29,12 @@
</template>
<script>
import BackLink from '@/components/BackLink';
import BackLink from '@/components/BackLink.vue';
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 SnapshotMenu from '@/components/modules/SnapshotMenu';
import SnapshotMenu from '@/components/modules/SnapshotMenu.vue';
export default {
apollo: {
@ -129,7 +129,7 @@ export default {
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
@mixin module-navigation-typography {
font-family: $sans-serif-font-family;

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@
<script>
import dateformat from '@/helpers/date-format';
import Checkbox from '@/components/ui/Checkbox';
import Checkbox from '@/components/ui/Checkbox.vue';
import me from '@/mixins/me';
@ -154,7 +154,7 @@ export default {
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
.snapshot-header {
&__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 SNAPSHOTS_QUERY from 'gql/queries/moduleSnapshots.gql';
import gql from 'graphql-tag';
import PenIcon from '@/components/icons/PenIcon';
import TrashIcon from '@/components/icons/TrashIcon';
import PenIcon from '@/components/icons/PenIcon.vue';
import TrashIcon from '@/components/icons/TrashIcon.vue';
import { removeAtIndex } from '@/graphql/immutable-operations';
import { matomoTrackEvent } from '@/helpers/matomo-client';
@ -231,7 +231,7 @@ export default {
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import 'styles/helpers';
.snapshot-list-item {
display: flex;

View File

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

View File

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

View File

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

View File

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

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