Skip to content

Commit

Permalink
BC-3844 - upgrade to Vue3 and Vuetify3 (#2789)
Browse files Browse the repository at this point in the history
To be able to use the latest features of Vue we want to upgrade the frontend to Vue 3.
Doing that we have to upgrade to Vuetify 3.

---------

Co-authored-by: NFriedo <[email protected]>
Co-authored-by: odalys-dataport <[email protected]>
Co-authored-by: Christian Darsow <[email protected]>
Co-authored-by: Odalys Adam <[email protected]>
Co-authored-by: Oliver Happe <[email protected]>
Co-authored-by: hoeppner-dataport <[email protected]>
Co-authored-by: Murat Merdoglu <[email protected]>
Co-authored-by: hoeppner-dataport <[email protected]>
Co-authored-by: Martin Schuhmacher <[email protected]>
Co-authored-by: Murat Merdoglu <[email protected]>
Co-authored-by: Max Bischof <[email protected]>
Co-authored-by: Max Bischof <[email protected]>
Co-authored-by: Sergej Hoffmann <[email protected]>
Co-authored-by: Omar Ezzat <[email protected]>
Co-authored-by: KalliSfak <[email protected]>
Co-authored-by: ezzato <[email protected]>
Co-authored-by: Oliver Happe <[email protected]>
Co-authored-by: agnisa-cap <[email protected]>
Co-authored-by: virgilchiriac <[email protected]>
Co-authored-by: bergatco <[email protected]>
Co-authored-by: Marvin Öhlerking <[email protected]>
Co-authored-by: odalys-dataport <[email protected]>
Co-authored-by: virgilchiriac <[email protected]>
Co-authored-by: MartinSchuhmacher <[email protected]>
  • Loading branch information
25 people authored Feb 27, 2024
1 parent ae40403 commit 8b2bb66
Show file tree
Hide file tree
Showing 702 changed files with 29,340 additions and 49,335 deletions.
8 changes: 2 additions & 6 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
node: true,
},
extends: [
"plugin:vue/essential",
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"plugin:prettier/recommended",
Expand All @@ -13,9 +13,9 @@ module.exports = {
ecmaVersion: 2020,
},
rules: {
"@typescript-eslint/no-explicit-any": "warn",
"no-console": process.env.NODE_ENV === "production" ? "off" : "warn",
"no-debugger": process.env.NODE_ENV === "production" ? "off" : "warn",
// ----
"no-useless-escape": "error",
"no-irregular-whitespace": "error",
"no-undef": "warn",
Expand All @@ -28,7 +28,6 @@ module.exports = {
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/ban-types": "error",
"@typescript-eslint/no-explicit-any": "warn",
"vue/no-v-text-v-html-on-component": "error",
"vue/no-v-html": "error",
"vue/html-self-closing": [
Expand Down Expand Up @@ -119,9 +118,6 @@ module.exports = {
globals: {
mount: false,
shallowMount: false,
createComponentMocks: false,
rendersSlotContent: false,
wait: false,
},
},
],
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Dependency Review'
name: "Dependency Review"
on: [pull_request]

permissions:
Expand All @@ -9,9 +9,9 @@ jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
- name: "Checkout Repository"
uses: actions/checkout@v4
- name: 'Dependency Review'
- name: "Dependency Review"
uses: actions/dependency-review-action@v4
with:
allow-licenses: AGPL-3.0-only, LGPL-3.0, MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, X11, 0BSD, GPL-3.0, AGPL-3.0
allow-licenses: AGPL-3.0-only, LGPL-3.0, MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, X11, 0BSD, GPL-3.0, AGPL-3.0, CC-BY-4.0
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ LICENSE.md
/src/serverApi/**
/src/fileStorageApi/**
/src/h5pEditorApi/**
/VUE3-UPGRADE-RESULTS/**/*.md
21 changes: 21 additions & 0 deletions VUE3-UPGRADE-RESULTS/BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# BREAKING CHANGES

- [Vue.2x -> Vue.3x](https://v3-migration.vuejs.org/breaking-changes/)
- [Vuetify.2x -> Vuetify.3x](https://vuetifyjs.com/en/getting-started/upgrade-guide/)
- [Vuex.3x -> Vuex.4x](https://vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html)
- [Vue Router.3x -> Vuex.4x](https://router.vuejs.org/guide/migration/)
- [Vue Test Utils](https://test-utils.vuejs.org/migration/)
- [vue instance vs app instance](https://v3-migration.vuejs.org/breaking-changes/global-api.html)

| 2.x Global API | 3.x Instance API (app) |
| -------------------------- | ------------------------------------------ |
| Vue.config | app.config |
| Vue.config.productionTip | **removed** |
| Vue.config.ignoredElements | app.config.compilerOptions.isCustomElement |
| Vue.component | app.component |
| Vue.directive | app.directive |
| Vue.mixin | app.mixin |
| Vue.use | app.use |
| Vue.prototype | app.config.globalProperties |
| Vue.extend | **removed** |
| Vue.set | can be replaced by just setting `reactive` properties (used in `src/utils/service-template.js`) |
17 changes: 17 additions & 0 deletions VUE3-UPGRADE-RESULTS/BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Build

## Vue-I18n

We have to precompile our i18n translations. That can be done using the `@intlify/bundle-tools` package:

https://github.com/intlify/bundle-tools

For webpack that means we have to use the `@intlify/vue-i18n-loader` package. This reports lots of errors when building because we have HTML-tags in our locales (which is generally not allowed from a XSS security perspective).

There is an option `strictMessage: false` for the locales compilation but this option is not supported in `@intlify/vue-i18n-loader`.

Possible solutions:

1. Implement an own (quiet simple) custom resolver for locales compilation in webpack, see https://github.com/intlify/bundle-tools/blob/main/packages/vue-i18n-loader/src/index.ts

2. Move to unplugin/webpack and use the newer package `@intlify/unplugin-vue-i18n`. However this can be a lot of effort depending on how much we will have to change in our build process.
9 changes: 9 additions & 0 deletions VUE3-UPGRADE-RESULTS/DATA-TABLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# DATA TABLES

- Currently, we have `DataTable` and `BackendDataTable` components. Their structures are very complicated and hard to maintain. We recommend refactoring the data tables with Vuetify components. So that we have clean, maintainable code. After changing, we also have a chance to remove all `base` components.


- We have 3 options:
1. Reimplement `vue-filter-ui` dependency as our own
2. Refactor `DataFilter` component
3. Refactor `DataTables` component
71 changes: 71 additions & 0 deletions VUE3-UPGRADE-RESULTS/DEPENDENCY-UPGRADES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# DEPENDENCIES

## Upgraded

- "@ckeditor/ckeditor5-vue": "^5.1.0"
- "@mdi/js": "^7.2.96" (devDep)
- "@vuelidate/core": "^2.0.3"
- "@vuelidate/validators": "^2.0.4"
- "vue": "^3.3.4"
- "vue-dndrop": "^1.3.1" ??
- "vue-i18n": "^9.2.2"
- "vue-router": "^4.2.4"
- "vuedraggable": "^4.1.0"
- "vuetify": "^3.3.14"
- "vuex": "^4.0.2"

## Removed

- "flush-promises": "^1.0.2"
- "tiptap": "^1.32.2"
- "tiptap-extensions": "^1.35.2"
- "vue-mq": "^1.0.1"
- "vuelidate": "^0.7.7"

## Added

- "vue3-mq": "^3.1.3"
- "resize-observer-polyfill": "^1.5.1"

## Can not be upgraded

- "vue-filter-ui": "^0.8.0"

## Library Notes

### vue-i18n

```html
<template>
<p>We can use the $t helper in templates: {{ $t('translation.key') }}</p>
</template>

<script setup>
// we can use the official composable now.
// no need for provide / inject anymore
const { t } = useI18n();
// translations have to be reactive!
const translatedValue = computed(() => t("translation.key"));
</script>
```

### vue-dndrop

```sh
npm i vue-dndrop@next
```

_Note: should be replaced by `vue-draggable` (based on sortable.js) because of re-rendering issues_

### Vue3-MQ

`$mq` has to be replaced by injection

<https://vue3-mq.info/migration/from-version-2.html#removal-of-global-properties-and-functions>

### vue-filter-ui

- The `DataTable` component uses `vue-filter-ui` dependency which is not competible with vue-3. And seems there is no info or plan to upgrade the dependeny in its repository.
- **Recommended Solution-1:** Implement our own methods as the dependency does.
- **Recommended Solution-2:** Refactor `datatables` with vuetify components.
17 changes: 17 additions & 0 deletions VUE3-UPGRADE-RESULTS/ESTIMATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ESTIMATIONS FOR VUE.3x UPGRADE

| Issue | Remarks | Effort Estimation min PD | Effort Estimation max PD | Comment |
| ---------------------------- | ------------------------------------------------------------ | -----------------------: | -----------------------: | -------------------- |
| Dependency Upgrades | [details](DEPENDENCY-UPGRADES.md) | 3 | 5 | |
| Breaking Changes | [details](BREAKING-CHANGES.md) | - | - | covered by following |
| Vue 3.x Upgrade | [details](VUE3-UPGRADE.md) | 3 | 5 | |
| Vuetify 3.x Upgrade | [details](VUETIFY-UPGRADE.md) | 7 | 10 | |
| Refactoring Pages/Components | [details](FilesToBeRefactored.md) | 15 | 20 | |
| Refactoring Unit Tests | [details](TESTING.md) | 20 | 25 | |
| Refactoring Stores | [details](STORE-REFACTORING.md) | 1 | 2 | |
| Refactoring DataTables | [details](DATA-TABLES.md) | 5 | 7 | decided for Option-1 |
| | - Option-1 Reimplement `vue-filter-ui` dependency as our own | 5 | 7 | |
| | - Option-2 Refactor `DataFilter` | - | - | |
| | - Option-3 Refactor `DataTables` | - | - | |
| Unpredictable issues | | 3 | 5 | |
| **TOTAL** | | 57 | 79 | |
85 changes: 85 additions & 0 deletions VUE3-UPGRADE-RESULTS/FilesToBeRefactored.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# REFACTORING LIST AND ESTIMATIONS

## FILES MUST BE REFACTORED

### `src/components/organisms/DataFilter/DataFilter.vue`

- The component uses `vue-filter-ui` dependency which is not competible with vue-3. And seems there is no info or plan to upgrade the dependeny in its repository.
- **Recommended Solution:** We need to find a way to get rid of the dependency.
- **Potantial Effort:** The custom data tables are using this component, so the data tables must be refactored.
- **Estimation time for refactoring:** _TBD_

### `src/utils/service-template.js`

- This util file is used for generalizing the boilerplate of using basis of some vuex stores. And it uses `Vue.set()` function which is deprecated in vue-3.
- **Recommended Solution-1:** Find another way to introduce some data into the vue instance as `Vue.set()` does in the vue-2 version.
- **Recommended Solution-2:** Refactor the store files which are currently using the `service-template.js` file. The store files are `activation.js, calendar.js, classes.js, content-search.js, course-group.js, courses.js, lessons.js, public-teachers.js, teams.js, users.js`
- **Potantial Effort:** depending on selected solution
- **Estimation time for refactoring:** _TBD depending on selected solution_

### `src/pages/rooms/RoomOverview.page.vue`

- The moving avatar components are based on the `this.$refs` selector. The `$refs` object's properties have been changed in vue-3. So we need to find another way to spot the dragging object properties instead of using `$refs`. This whole page refactoring might be necessary.
- **Recommended Solution:** Find another way to spot the dragging component properties. Especially `getElementNameByRef` method should be replaced.
- **Estimation time for refactoring:** _TBD_

### [v-model breaking change](https://v3-migration.vuejs.org/breaking-changes/v-model.html)

- Some components use `model property` inside which is changed in vue-3 and they need some tiny refactorings.
- These components:
- `src/components/atoms/vCustomAutocomplete.vue` -- completely removed, vuetify autocomplete component is used instead
- `src/components/atoms/vCustomSwitch.vue` -- removed, vuetify v-switch will be used
- `src/components/base/BaseInput/BaseInput.vue`
- `src/components/base/BaseInput/BaseInputCheckbox.vue`
- `src/components/base/BaseInput/BaseInputDefault.vue`
- `src/components/base/BaseInput/BaseInputHidden.vue`
- `src/components/base/BaseInput/BaseInputRadio.vue`
- `src/components/molecules/ImportModal.vue`
- `src/components/molecules/RoomModal.vue`
- `src/components/molecules/TextEditor.vue`
- `src/components/molecules/TitleInput.vue`
- `src/components/organisms/FormNews.vue`
- `src/components/organisms/Pagination.vue`
+ `src/components/organisms/vCustomDialog.vue`
- **Estimation time for refactoring:** _TBD_

## VUETIFY BASED REFACTORINGS

### Vuetify Labs Component

- Some vuetify-3 components are not released yet.
- These components:
- `v-calendar`
- `v-date-picker`
- `v-data-table`
- `v-skeleton-loader`
- `v-stepper`
- `v-time-picker`
- `v-tree-view`
- `v-data-iterator`
- **Recommended Solution-1:** Wait until it's upcoming release.
- **Recommended Solution-2:** Imported from vuelabs to use until they're released. But it needs another refactoring after then.
- **Estimation time for refactoring:** _TBD depending on selected solution_

### Some vuetify components props' usage have been changed. The detailed list can be found [here](VUE3-UPGRADE-SUMMARY.md)

- These components:
- `v-menu`
- `v-list`
- `v-list-item`
- `v-alert`
- `v-btn`
- `v-input`
- `v-checkbox`
- `v-radio`
- `v-switch`
- `v-tabs`
- `v-menu`
- `v-select`
- `v-combobox`
- `v-autocomplete`
- `v-expansion-panel`
- `v-card`
- `v-dialog`
- They need tiny refactoring with changing renaming their props etc.
- **Estimation time for refactoring:** _TBD_
21 changes: 21 additions & 0 deletions VUE3-UPGRADE-RESULTS/STORE-REFACTORING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# STORE REFACTORING

- `src/utils/service-template.js`
- This util file is used for generalizing the boilerplate of using basis of some vuex stores. And it uses `Vue.set()` function which is deprecated in vue-3.

- **Recommended Solution:** Refactor the store files which are currently using the `service-template.js` file. Introducing **Pinia** store will be good for these refactorings.

- The store files are:

```sh
activation.js
calendar.js
classes.js
content-search.js
course-group.js
courses.js,
lessons.js
public-teachers.js
teams.js,
users.js
```
61 changes: 61 additions & 0 deletions VUE3-UPGRADE-RESULTS/TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# UNIT TESTS

## Testing

### Setup
We have a couple of test helpers taht can be used to setup unit tests: `tests/test-utils/setup/index.ts`

The global setup file `tests/setup.js` has to be refactored and adapted to the new requirements.
### Mounting a component

Example: `src/components/organisms/vCustomDialog.unit.ts`

We added helpers for creating the nessesary vue plugins, currently `vuetify` and `i18n`. This is necessary because the setup of the plugins can differ heavily from other environments. In the case of vuetify e.g. the way we have to import vuetify in a Jest test setup has changed.

```typescript
const wrapper = mount(Component, {
global: {
plugins: [createTestingVuetify(), createTestingI18n()],
},
// Note: "propsData" is deprecated now. we should use "props" instead
props: {}
});
```

The helper files can be found in `tests/test-utils/setup/` folder.

### Testing dialogs

Vuetify is using the `<Teleport>` component now to "teleport" the contents of the dialog outside the components own `<template>`.

In order to access the dialog components in tests we have to use `findComponent` or `getComponent()` on the wrapper instead of the more general methods like `find`.

For a further explanation see:
https://test-utils.vuejs.org/guide/advanced/teleport.html

### Testing router

```typescript
const mockRoute = {
params: {
id: 1
}
}
const mockRouter = {
push: jest.fn()
}

const wrapper = mount(Component, {
props: {
isAuthenticated: true
},
global: {
mocks: {
$route: mockRoute,
$router: mockRouter
}
}
})
```

https://test-utils.vuejs.org/guide/advanced/vue-router.html
Loading

0 comments on commit 8b2bb66

Please sign in to comment.