mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 12:19:28 +00:00
Merge branch 'cis40_2026-05_ma_rc' into demo-cis40
This commit is contained in:
@@ -25,12 +25,6 @@ class ProjektabgabeUebersicht extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// TODO create permission
|
||||
$viewData = array(
|
||||
'uid' => getAuthUID(),
|
||||
'showEdit' => true
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'ProjektabgabeUebersicht']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'ProjektabgabeUebersicht']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,12 @@ class PaabgabeUebersicht extends FHCAPI_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'viewData' => self::PERM_LOGGED,
|
||||
'getPaAbgaben' => array('lehre/abgabetool:r'),
|
||||
'getStudiengaenge' => array('lehre/abgabetool:r'),
|
||||
'getTermine' => array('lehre/abgabetool:r'),
|
||||
'getPaAbgabetypen' => array('lehre/abgabetool:r'),
|
||||
'downloadZip' => array('lehre/abgabetool:r')
|
||||
'downloadZip' => array('lehre/abgabetool:r'),
|
||||
//'downloadProjektarbeit' => array('lehre/abgabetool:r')
|
||||
]);
|
||||
|
||||
@@ -45,6 +46,17 @@ class PaabgabeUebersicht extends FHCAPI_Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function viewData()
|
||||
{
|
||||
$viewData = [
|
||||
"uid" => getAuthUID(),
|
||||
// TODO create permission
|
||||
"showEdit" => true,
|
||||
];
|
||||
|
||||
$this->terminateWithSuccess($viewData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Projektabgaben for search criteria.
|
||||
*/
|
||||
|
||||
@@ -361,7 +361,10 @@ class StundenplanLib
|
||||
if (isError($ort_content_object)) {
|
||||
return error(getData($ort_content_object));
|
||||
}
|
||||
$ort_content_object = getData($ort_content_object)[0];
|
||||
$ort_content_object_data = getData($ort_content_object);
|
||||
$ort_content_object = (is_array($ort_content_object_data) && count($ort_content_object_data) > 0)
|
||||
? $ort_content_object_data[0]
|
||||
: null;
|
||||
if($ort_content_object) {
|
||||
$item->ort_content_id = $ort_content_object->content_id;
|
||||
}
|
||||
|
||||
@@ -26,5 +26,11 @@ export default {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/education/PaabgabeUebersicht/getPaAbgabetypen'
|
||||
};
|
||||
},
|
||||
getViewData() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/education/PaabgabeUebersicht/viewData'
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -19,7 +19,8 @@ export default {
|
||||
originalBackgrounds: "backgrounds",
|
||||
dropAllowed: "dropAllowed",
|
||||
timezone: "timezone",
|
||||
reservierbar: "isReservierbar"
|
||||
reservierbar: "isReservierbar",
|
||||
reservierbarMap: "reservierbarMap",
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
@@ -328,6 +329,9 @@ export default {
|
||||
return !dayEvents.some(ev => ev.start < end && ev.end > start);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$p.loadCategory(["LvPlan"]);
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.disableAutoScroll();
|
||||
},
|
||||
@@ -424,9 +428,11 @@ export default {
|
||||
class="fhc-calendar-empty-slot"
|
||||
style="position:absolute; inset:0; z-index:1"
|
||||
v-cal-click:slot="{ date, part }"
|
||||
:title="this.reservierbarMap?.[date.toISODate()] ? $p.t('LvPlan/add_reservation') : $p.t('LvPlan/reservation_not_allowed')"
|
||||
>
|
||||
<div class="fhc-calendar-empty-slot-plus">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
<i v-if="this.reservierbarMap?.[date.toISODate()]" class="fa-solid fa-plus"></i>
|
||||
<i v-else class="fa-solid fa-ban" style="color: red;"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -230,6 +230,9 @@ export default {
|
||||
:is="renderers[event.type]?.calendarEvent"
|
||||
:event="event"
|
||||
@delete-event="(event) => $emit('delete-event', event)"
|
||||
:timeSlotDisplayBehavior="
|
||||
$props.mode.toLowerCase() === 'list' ? 'always' : 'default'
|
||||
"
|
||||
></component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -97,6 +97,7 @@ export default {
|
||||
<component
|
||||
:is="renderers[event.type]?.calendarEvent"
|
||||
:event="event"
|
||||
:timeSlotDisplayBehavior="'always'"
|
||||
></component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -340,7 +340,7 @@ export default {
|
||||
<div class="row">
|
||||
<div class="d-md-none col-12">
|
||||
<!-- Bearbeiten Button -->
|
||||
<div v-if="isEditable" class="row mb-4">
|
||||
<div v-if="isEditable" class="row mb-3 ">
|
||||
<div class="col">
|
||||
<button @click="()=>showEditProfilModal()" type="button" class="text-start card w-100 btn btn-outline-secondary" >
|
||||
<div class="row">
|
||||
|
||||
@@ -176,6 +176,7 @@ export const Profil = {
|
||||
this.data = data.profil_data.data;
|
||||
this.calendarSyncUrls = data.calendar_sync_urls ?? [];
|
||||
this.authPermissions = data.permissions;
|
||||
console.log(data.profil_data);
|
||||
},
|
||||
zustellAdressenCount() {
|
||||
if (!this.data || !this.data.adressen) {
|
||||
|
||||
@@ -4,9 +4,6 @@ import Loader from "../../Loader.js";
|
||||
|
||||
export const ProjektabgabeUebersicht = {
|
||||
name: "ProjektabgabeUebersicht",
|
||||
props: {
|
||||
viewData: Object // NOTE: this is inherited from router-view
|
||||
},
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
Loader
|
||||
@@ -60,7 +57,7 @@ export const ProjektabgabeUebersicht = {
|
||||
});
|
||||
container.append(downloadButton);
|
||||
|
||||
if (this.viewData.showEdit)
|
||||
if (this.showEdit)
|
||||
{
|
||||
let editButton = document.createElement('button');
|
||||
editButton.className = 'btn btn-outline-secondary';
|
||||
@@ -116,7 +113,9 @@ export const ProjektabgabeUebersicht = {
|
||||
this.tableBuiltResolve()
|
||||
}
|
||||
}
|
||||
]};
|
||||
],
|
||||
showEdit: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
tableResolve(resolve) {
|
||||
@@ -220,7 +219,12 @@ export const ProjektabgabeUebersicht = {
|
||||
if (this.selectedTermin) url.searchParams.append('abgabedatum', this.selectedTermin);
|
||||
if (this.personSearchString) url.searchParams.append('personSearchString', this.personSearchString);
|
||||
window.open(url.toString(), '_blank');
|
||||
}
|
||||
},
|
||||
async getViewData() {
|
||||
const viewDataResponse = await this.$api.call(ApiPaabgabe.getViewData());
|
||||
const viewData = viewDataResponse.data;
|
||||
this.showEdit = viewData.showEdit;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isDarkMode() {
|
||||
@@ -236,7 +240,8 @@ export const ProjektabgabeUebersicht = {
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/api/frontend/v1/education/PaabgabeUebersicht/downloadZip';
|
||||
}
|
||||
},
|
||||
created() {
|
||||
async created() {
|
||||
await this.getViewData();
|
||||
this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global', 'person', 'ui']);
|
||||
this.phrasenPromise.then(()=> {this.phrasenResolved = true});
|
||||
},
|
||||
|
||||
@@ -3,6 +3,11 @@ export default {
|
||||
event: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
timeSlotDisplayBehavior: {
|
||||
type: String,
|
||||
default: "default",
|
||||
// options: default, always, never
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
@@ -50,7 +55,17 @@ export default {
|
||||
return luxon.Duration
|
||||
.fromISOTime(this.event.ende)
|
||||
.toISOTime({ suppressSeconds: true });
|
||||
}
|
||||
},
|
||||
timeSlotDisplayClasses() {
|
||||
switch (this.$props.timeSlotDisplayBehavior) {
|
||||
case "always":
|
||||
return "d-grid";
|
||||
case "never":
|
||||
return "d-none";
|
||||
default:
|
||||
return "d-none d-xl-grid";
|
||||
}
|
||||
},
|
||||
},
|
||||
template: /*html*/`
|
||||
<div
|
||||
@@ -58,8 +73,9 @@ export default {
|
||||
@wheel.stop
|
||||
>
|
||||
<div
|
||||
v-if="!event.allDayEvent && event?.beginn && event?.ende"
|
||||
class="event-time d-none d-xl-grid h-100"
|
||||
v-if="!event?.allDayEvent && event?.beginn && event?.ende"
|
||||
:class="timeSlotDisplayClasses"
|
||||
class="event-time h-100"
|
||||
>
|
||||
<span>{{ start }}</span>
|
||||
<span>{{ end }}</span>
|
||||
|
||||
@@ -3,6 +3,11 @@ export default {
|
||||
event: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
timeSlotDisplayBehavior: {
|
||||
type: String,
|
||||
default: "default",
|
||||
// options: default, always, never
|
||||
}
|
||||
},
|
||||
inject: {
|
||||
@@ -63,14 +68,25 @@ export default {
|
||||
methods: {
|
||||
handleDelete() {
|
||||
this.$emit('delete-event', this.event);
|
||||
}
|
||||
},
|
||||
timeSlotDisplayClasses() {
|
||||
switch (this.$props.timeSlotDisplayBehavior) {
|
||||
case "always":
|
||||
return "d-grid";
|
||||
case "never":
|
||||
return "d-none";
|
||||
default:
|
||||
return "d-none d-xl-grid";
|
||||
}
|
||||
},
|
||||
},
|
||||
template: /* html */`
|
||||
<div
|
||||
class="cis-renderer-reservierungen-calendar-event calendar-event-default h-100 w-100 p-1 position-relative">
|
||||
<div
|
||||
v-if="!event.allDayEvent && event?.beginn && event?.ende"
|
||||
class="event-time d-grid h-100"
|
||||
v-if="!event?.allDayEvent && event?.beginn && event?.ende"
|
||||
:class="timeSlotDisplayClasses"
|
||||
class="event-time h-100"
|
||||
>
|
||||
<span>{{ start }}</span>
|
||||
<span>{{ end }}</span>
|
||||
@@ -86,6 +102,7 @@ export default {
|
||||
</button>
|
||||
|
||||
<span class="event-topic">{{ event.topic }}</span>
|
||||
<span class="event-place">{{ event.ort_kurzbz }}</span>
|
||||
<span
|
||||
v-for="lektor in event.lektor.slice(0, 3)"
|
||||
class="event-lectors"
|
||||
@@ -98,7 +115,6 @@ export default {
|
||||
>
|
||||
... +{{ event.lektor.length - 3 }}
|
||||
</span>
|
||||
<span class="event-place">{{ event.ort_kurzbz }}</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
@@ -75,6 +75,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
switchFilter(evt) {
|
||||
console.log(evt);
|
||||
this.$emit('switchFilter', evt.currentTarget.value);
|
||||
},
|
||||
applyFilterConfig() {
|
||||
|
||||
@@ -29924,6 +29924,46 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'LvPlan',
|
||||
'phrase' => 'add_reservation',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Reservierung hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add reservation',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'LvPlan',
|
||||
'phrase' => 'reservation_not_allowed',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Reservierung nicht erlaubt',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Reservation not allowed',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
// LvPlan Phrasen ende
|
||||
//ProfilUpdate Phrasen start
|
||||
array(
|
||||
|
||||
Reference in New Issue
Block a user