Merge branch 'feature-25999/C4' into feature-39912/Room_planning_calendar

This commit is contained in:
SimonGschnell
2024-05-27 10:55:44 +02:00
7 changed files with 262 additions and 26 deletions
+26 -18
View File
@@ -78,6 +78,31 @@ class Content_model extends DB_Model
*/
public function getMenu($root_content_id, $uid, $sprache = DEFAULT_LANGUAGE)
{
/*,
{
"content_id": 1000007,
"template_kurzbz": "redirect",
"titel": "Anrechnung",
"content": "<content><url><![CDATA[' . site_url('/lehre/anrechnung/RequestAnrechnung') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
}
*/
/*
{
"content_id": 1000003,
"template_kurzbz": "redirect",
"titel": "COVID-19",
"content": "<content><url><![CDATA[' . site_url('/CisHtml/Cms/content/10012') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
*/
if ($root_content_id === null) {
$res = json_decode('{
"content_id": 1000000,
@@ -105,15 +130,6 @@ class Content_model extends DB_Model
"aktiv": true,
"childs": []
},
{
"content_id": 1000003,
"template_kurzbz": "redirect",
"titel": "COVID-19",
"content": "<content><url><![CDATA[' . site_url('/CisHtml/Cms/content/10012') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000004,
"template_kurzbz": "redirect",
@@ -149,16 +165,8 @@ class Content_model extends DB_Model
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000007,
"template_kurzbz": "redirect",
"titel": "Anrechnung",
"content": "<content><url><![CDATA[' . site_url('/lehre/anrechnung/RequestAnrechnung') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
}
]
}');
return success($res);
+2
View File
@@ -1,4 +1,5 @@
import FhcCalendar from "../../components/Calendar/Calendar.js";
import Phrasen from "../../plugin/Phrasen.js";
const app = Vue.createApp({
components: {
@@ -50,4 +51,5 @@ const app = Vue.createApp({
}
});
app.config.unwrapInjectedRef = true;
app.use(Phrasen);
app.mount('#content');
+14 -1
View File
@@ -5,6 +5,7 @@ import CalendarWeek from './Week.js';
import CalendarWeeks from './Weeks.js';
import CalendarMinimized from './Minimized.js';
import CalendarDate from '../../composables/CalendarDate.js';
import CalendarModal from './CalendarModal.js';
// TODO(chris): week/month toggle
@@ -15,7 +16,8 @@ export default {
CalendarYears,
CalendarWeek,
CalendarWeeks,
CalendarMinimized
CalendarMinimized,
CalendarModal
},
provide() {
return {
@@ -61,6 +63,7 @@ export default {
],
data() {
return {
currentlySelectedEvent:null,
header: '',
prevMode: null,
currMode: null,
@@ -102,6 +105,15 @@ export default {
},
methods: {
handleInput(day) {
// set the event when clicking on the lernveranstaltung in the data
this.currentlySelectedEvent = day[1];
console.log(this.currentlySelectedEvent)
// showing the modal
Vue.nextTick(()=>{
this.$refs.calendarModal.show();
})
console.log(day,"this is the day")
this.$emit(day[0], day[1]);
}
},
@@ -135,6 +147,7 @@ export default {
},
template: `
<div ref="container" class="fhc-calendar card" :class="sizeClass">
<calendar-modal v-if="currentlySelectedEvent" :event="currentlySelectedEvent" ref="calendarModal" />
<component :is="'calendar-' + mode" @update:mode="mode=$event" @change:range="$emit('change:range',$event)" @input="handleInput" />
</div>`
}
@@ -0,0 +1,190 @@
import BsModal from "../Bootstrap/Modal.js";
import Alert from "../Bootstrap/Alert.js";
export default {
components: {
BsModal,
Alert,
},
mixins: [BsModal],
props: {
event:Object,
title:{
type:String,
default:"title"
},
/*
* NOTE(chris):
* Hack to expose in "emits" declared events to $props which we use
* in the v-bind directive to forward all events.
* @see: https://github.com/vuejs/core/issues/3432
*/
onHideBsModal: Function,
onHiddenBsModal: Function,
onHidePreventedBsModal: Function,
onShowBsModal: Function,
onShownBsModal: Function,
},
data() {
return {
data:this.event,
topic: null,
profilUpdate: null,
editData: this.value,
fileID: null,
breadcrumb: null,
loading: false,
result: false,
info: null,
};
},
methods: {
updateFileIDFunction: function (newFileID) {
this.fileID = newFileID;
},
async submitProfilChange() {
//? check if data is valid before making a request
if (this.topic && this.profilUpdate) {
//? if profil update contains any attachment
if (this.fileID) {
const fileData = await this.uploadFiles(this.fileID);
this.fileID = fileData ? fileData : null;
}
//? inserts new row in public.tbl_cis_profil_update
//* calls the update api call if an update field is present in the data that was passed to the modal
const handleApiResponse = (res) => {
//? toggles the loading to false and closes the loading modal
this.loading = false;
this.setLoading(false);
if (res.data.error == 0) {
this.result = true;
this.hide();
Alert.popup(
"Ihre Anfrage wurde erfolgreich gesendet. Bitte warten Sie, während sich das Team um Ihre Anfrage kümmert."
);
} else {
this.result = false;
this.hide();
Alert.popup(
"Ein Fehler ist aufgetreten: " + JSON.stringify(res.data.retval)
);
}
};
//* v-show on EditProfil modal binded to this.loading
//? hides the EditProfil modal and shows the loading modal by calling a callback that was passed as prop from the parent component
this.loading = true;
this.setLoading(true);
this.editData.updateID
? Vue.$fhcapi.ProfilUpdate.updateProfilRequest(
this.topic,
this.profilUpdate,
this.editData.updateID,
this.fileID ? this.fileID[0] : null
)
.then((res) => {
handleApiResponse(res);
})
.catch((err) => {
console.error(err);
})
: Vue.$fhcapi.ProfilUpdate.insertProfilRequest(
this.topic,
this.profilUpdate,
this.fileID ? this.fileID[0] : null
)
.then((res) => {
handleApiResponse(res);
})
.catch((err) => {
console.error(err);
});
}
},
uploadFiles: async function (files) {
if (files[0].type !== "application/x.fhc-dms+json") {
let formData = new FormData();
formData.append("files[]", files[0]);
const result = this.editData.updateID
? //? updating old attachment by replacing
//* second parameter of api request insertFile checks if the file has to be replaced or not
await Vue.$fhcapi.ProfilUpdate.insertFile(
formData,
this.editData.updateID
).then((res) => {
return res.data?.map((file) => file.dms_id);
})
: //? fresh insert of new attachment
await Vue.$fhcapi.ProfilUpdate.insertFile(formData).then((res) => {
return res.data?.map((file) => file.dms_id);
});
return result;
} else {
//? attachment hasn't been replaced
return false;
}
},
},
computed: {
start_time: function(){
if(!this.data.start) return 'N/A';
return this.data.start.getHours() + ":" + this.data.start.getMinutes();
},
end_time: function(){
if(!this.data.end) return 'N/A';
return this.data.end.getHours() + ":" + this.data.end.getMinutes();
}
},
created() {
console.log("this is an test")
},
mounted() {
this.modal = this.$refs.modalContainer.modal;
},
popup(options) {
return BsModal.popup.bind(this)(null, options);
},
template: /*html*/ `
<bs-modal ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" backdrop="false" >
<template v-slot:title>
{{data.title + ' - ' + data.lehrfach_bez + ' [' + data.ort_kurzbz+']' }}
</template>
<template v-slot:default>
<div class="row">
<div class="offset-3 col-4"><span>Datum:</span></div>
<div class=" col"><span>{{data.datum}}</span></div>
</div>
<div class="row">
<div class="offset-3 col-4"><span>Raum:</span></div>
<div class=" col"><span>{{data.ort_kurzbz}}</span></div>
</div>
<div class="row">
<div class="offset-3 col-4"><span>LV:</span></div>
<div class=" col"><span>{{'('+data.lehrform+') ' + data.lehrfach_bez}}</span></div>
</div>
<div class="row">
<div class="offset-3 col-4"><span>Lektor:</span></div>
<div class=" col"><span>{{data.lektor}}</span></div>
</div>
<div class="row">
<div class="offset-3 col-4"><span>Zeitraum:</span></div>
<div class=" col"><span>{{start_time + ' - ' + end_time}}</span></div>
</div>
</template>
<!-- optional footer -->
<template v-slot:footer >
<button class="btn btn-outline-secondary " @click="hide">{{$p.t('ui','cancel')}}</button>
</template>
<!-- end of optional footer -->
</bs-modal>`,
};
+2 -1
View File
@@ -46,7 +46,8 @@ export default {
},
template: `
<div ref="carousel" class="calendar-pane carousel slide" @[\`slid.bs.carousel\`]="slid" :data-queue="queue">
<div class="carousel-inner">
<!--height calc function just for user testing purpose (has to be fixed)-->
<div class="carousel-inner " style="height:calc(100vh - 220px); overflow:scroll">
<div v-for="i in [...Array(3).keys()]" :key="i" class="carousel-item">
<slot :index="i" :offset="offsets[i]" />
</div>
+8 -6
View File
@@ -100,22 +100,24 @@ export default {
<div class="fhc-calendar-week-page">
<div class="d-flex flex-column border-top">
<div class="fhc-calendar-week-page-header border-2 border-bottom text-center d-flex">
<div style="position:sticky; top:10px; z-index:1020;" class="fhc-calendar-week-page-header border-2 border-bottom text-center d-flex">
<div v-for="day in days" :key="day" class="flex-grow-1" :title="day.toLocaleString(undefined, {dateStyle:'short'})">
<div class="fw-bold">{{day.toLocaleString(undefined, {weekday: size < 2 ? 'narrow' : (size < 3 ? 'short' : 'long')})}}</div>
<a href="#" class="small text-secondary text-decoration-none" @click.prevent="changeToMonth(day)">{{day.toLocaleString(undefined, [{day:'numeric',month:'numeric'},{day:'numeric',month:'numeric'},{day:'numeric',month:'numeric'},{dateStyle:'short'}][this.size])}}</a>
</div>
</div>
<div ref="eventcontainer" class="flex-grow-1 overflow-auto">
<div ref="eventcontainer" class="flex-grow-1">
<div class="events">
<div class="hours">
<div v-for="hour in hours" :key="hour" class="text-muted text-end small" :ref="'hour' + hour">{{hour}}:00</div>
</div>
<div v-for="day in eventsPerDayAndHour" :key="day" class="day border-start" :style="{'grid-template-columns': 'repeat(' + day.lanes + ', 1fr)', 'grid-template-rows': 'repeat(' + (1440 / smallestTimeFrame) + ', 1fr)'}">
<span>test</span>
<a href="#" @click="printTest(event)" v-for="event in day.events" :key="event" class="small rounded overflow-hidden text-decoration-none text-dark" :style="{'grid-column-start': 1+(event.lane-1)*day.lanes/event.maxLane, 'grid-column-end': 1+event.lane*day.lanes/event.maxLane, 'grid-row-start': dateToMinutesOfDay(event.start), 'grid-row-end': dateToMinutesOfDay(event.end), '--test': dateToMinutesOfDay(event.end), background: event.orig.color}" @click.prevent="$emit('input', event.orig)">
{{event.orig.title}}-->
<a href="#" @click="printTest(event)" :title="event.orig.title + ' - ' + event.orig.lehrfach_bez + ' [' + event.orig.ort_kurzbz+']'" v-for="event in day.events" :key="event" class="mx-2 border border-dark border-2 small rounded overflow-hidden text-decoration-none text-dark" :style="{'grid-column-start': 1+(event.lane-1)*day.lanes/event.maxLane, 'grid-column-end': 1+event.lane*day.lanes/event.maxLane, 'grid-row-start': dateToMinutesOfDay(event.start), 'grid-row-end': dateToMinutesOfDay(event.end), 'background': event.orig.farbe?event.orig.farbe:'white' ,'--test': dateToMinutesOfDay(event.end)}" @click.prevent="$emit('input', event.orig)">
<div class="d-flex flex-column align-items-center justify-content-evenly h-100">
<span>{{event.orig.title}}</span>
<span>{{event.orig.ort_kurzbz}}</span>
<span>{{event.orig.mitarbeiter_kurzbz}}</span>
</div>
</a>
</div>
</div>
+20
View File
@@ -2263,6 +2263,26 @@ $phrases = array(
),
//**************** CORE/lehre
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'noGrades',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unbewertet',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Not Graded',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',