OmET Frontend

https://gitlab.com/hobbes/cinedia-webapp

Vue.js Components

Aufteilung des UI in Komponenten. So können Logik und Design in kleine Stücke aufgeteilt werden.

<template>
<td
:class="['dateslotCell', dynamicStyles]"
@mouseover.prevent="dateslotOver"
@mousedown.prevent="dateslotDown"
>
<span class="remaining" v-if="slotIsBookable && remainingBookingTimeThreshold">{{remainingBookingTimeFromNow}}</span>
</td>
</template>
https://gitlab.com/hobbes/cinedia-webapp/-/blob/master/src/components/DateslotCell.vue#L30

Drag & Drop

Ort und Datum der Buchung können in einer übersichtlichen Tabelle intuitiv mit Drag & Drop gemacht werden.

<tbody>
<tr :class="{lastCompanyRow: lastRowOfCompany(stages, index)}" v-for="(stage, index) in stages">
<td :title="stage.company.name" class="companyName name" v-if="isFirst('company', stages, index)" :rowspan="calcCompanyRowspan('company', stages, index)">
{{stage.company.nameshort}}
</td>
<td :class="[markStageRow(stage), 'name']">
{{stage.name}}
</td>
<DateslotCell
v-for="(date, index) in dateslots"
:key="date.id + stage.id + index"
:currentDateIndex="index"
:schedule="schedule"
:scheduleUi="scheduleUi"
:dateslots="dateslots"
:stage="stage"
:enabled="enabled"
:notGuaranteed="notGuaranteed"
:selectedDateslots="selectedDateslots"
:selectedStages="selectedStages"
@dateslotdown="dateslotDown"
@dateslotover="dateslotOver"
/>
</tr>
</tbody>
https://gitlab.com/hobbes/cinedia-webapp/-/blob/master/src/components/Schedule.vue#L1

Uploads grosser Files direkt in Object-Storage

Die Files werden ohne Umweg über den Application-Server vom Webbrowser direkt in den Object-Storage hochgeladen. Dafür wird vom Application-Server eine signiert URL angefordert.

export function getUploadUrl(filename) {
return request({
url: `${HOST}/storage/uploads`,
method: "POST",
body: {
filename,
},
});
}
https://gitlab.com/hobbes/cinedia-webapp/-/blob/master/src/assets/api.js#L96

i18n

Die SPA wurde mit dem Internationalization-Framework i18next für die Übersetzung in mehrere Sprachen vorbereitet.

Vue.use(VueI18Next);
i18next.on("initialized", function (options) {
moment.locale(options.lng);
});
i18next.on("languageChanged", function (lng) {
moment.locale(lng);
});
https://gitlab.com/hobbes/cinedia-webapp/-/blob/master/src/i18n/index.js#L18

Redux State Management Pattern

State Management mit Vuex neu Pinia

export default {
namespaced: true,
state: {
data: {
entities: {},
},
},
mutations: {
setUserActivities(state, data) {
state.data.entities[data.userId] = data.data;
},
},
actions: {
load(context, userId) {
return findUserActivities(userId).then((result) => {
context.commit("setUserActivities", {
userId,
data: result,
});
});
},
edit(context, { userId, activityId, add }) {
return editUserActivities(userId, activityId, add).then((result) => {
context.commit("setUserActivities", {
userId,
data: result,
});
});
},
},
getters: {
getByUserId: (state) => (userId) => {
if (state.data.entities[userId]) {
return state.data.entities[userId].entities;
} else {
return null;
}
},
},
};
https://gitlab.com/hobbes/cinedia-webapp/-/blob/master/src/store/userActivities.js#L6