Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup

This commit is contained in:
SimonGschnell
2024-11-20 10:36:04 +01:00
26 changed files with 289 additions and 151 deletions
+4 -1
View File
@@ -34,7 +34,10 @@ class Cis4 extends Auth_Controller
show_error("name couldn't be loaded for username ".getAuthUID());
}
$begruesung = getData($begruesung);
$viewData = array(
'name' => $begruesung
);
$this->load->view('CisVue/Dashboard.php',["name"=> $begruesung]);
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
}
}
+5 -1
View File
@@ -35,7 +35,11 @@ class Dashboard extends Auth_Controller
show_error("name couldn't be loaded for username ".getAuthUID());
}
$begruesung = getData($begruesung);
$this->load->view('CisVue/Dashboard.php',["name"=> $begruesung]);
$viewData = array(
'name' => $begruesung
);
$this->load->view('CisVue/Dashboard.php', ['viewData' => $viewData]);
}
}
+16 -4
View File
@@ -178,6 +178,7 @@ class SearchBarLib
protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr)
{
$searchstr = preg_replace('/[[:punct:]]/', ' ', $searchstr);
$document = implode(' || \' \' || ', $columns);
$query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\'';
$reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\'';
@@ -297,13 +298,15 @@ EOSC;
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND b.aktiv = TRUE
) bfLeader ON(bfLeader.oe_kurzbz = o.oe_kurzbz)
WHERE ' .
WHERE
o.aktiv = true
AND (' .
$this->buildSearchClause(
$dbModel,
array('o.oe_kurzbz', 'o.bezeichnung', 'ot.bezeichnung'),
$searchstr
) .
'
')
GROUP BY type, o.oe_kurzbz, o.bezeichnung, ot.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung, otParent.bezeichnung
');
@@ -507,8 +510,17 @@ EOSC;
FROM public.tbl_standort
LEFT JOIN public.tbl_adresse USING(adresse_id)
) standort USING(standort_id)
WHERE LOWER(ort.ort_kurzbz) like LOWER(\'%'. $searchstr . '%\') '
WHERE
ort.aktiv = true
AND
ort.lehre = true
AND (' .
$this->buildSearchClause(
$dbModel,
array('ort.ort_kurzbz', 'ort.bezeichnung'),
$searchstr
) .
')'
);
// If something has been found
+1 -3
View File
@@ -13,9 +13,7 @@ $this->load->view('templates/CISVUE-Header', $includesArray);
?>
<div id="content">
<h2>Hallo <?= $name?>!</h2>
<hr>
<fhc-dashboard dashboard="CIS"/>
<fhc-dashboard dashboard="CIS" view-data-string='<?php echo json_encode($viewData) ?>' />
</div>
<?php $this->load->view('templates/CISVUE-Footer', $includesArray); ?>
+41
View File
@@ -473,4 +473,45 @@ html {
transition-property: background,color;
transition-duration: 0.3s,0.2s;
transition-timing-function: ease-out,ease-out;
}
@media screen and ( max-width: 767px ) {
#nav-search {
position: static;
}
#nav-search .searchbar_results {
top: 100%;
width: 98vw !important;
left: 1vw !important;
right: 1vw !important;
}
}
@media screen and ( max-width: 576px ) {
.searchbar_icon img {
max-width: 65px !important;
}
.searchbar_icon i {
font-size: 3em !important;
}
.searchbar_grid {
grid-template-columns: [icon] 75px [data] auto;
}
.searchbar_table,
.searchbar_tablerow,
.searchbar_tablecell {
display: block;
}
.searchbar_tablecell.searchbar_label {
font-weight: bold;
}
.searchbar_tablecell.searchbar_value {
padding-left: 2.5rem;
overflow-wrap: anywhere;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
@import './Fhc.css';
@import './components/searchbar.css';
@import './components/searchbar/searchbar.css';
@import './components/verticalsplit.css';
@import './components/FilterComponent.css';
@import './components/Tabs.css';
+1 -1
View File
@@ -134,7 +134,7 @@
.fhc-calendar-lg .fhc-calendar-month-page-day .events,
.fhc-calendar-md .fhc-calendar-month-page-day .events {
display: block;
overflow: scroll;
overflow: auto;
font-size: 0.7em;
}
.fhc-calendar-lg .fhc-calendar-month-page-day .events span,
@@ -21,14 +21,18 @@
z-index: 9998;
background-color: #fff;
border: 1px solid lightgrey;
padding: 1rem;
overflow-y: auto;
padding: .5rem;
top: 100%;
width: 100%;
left: 0;
right: 0;
}
.searchbar_results_scroller {
overflow-y: auto;
overscroll-behavior: none;
}
.searchbar_result {
border-bottom: 1px solid lightgrey;
margin-bottom: 1rem;
@@ -104,4 +108,4 @@
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
}
}
+10 -2
View File
@@ -15,6 +15,7 @@ const app = Vue.createApp({
return {
searchbaroptions: {
cssclass: "",
calcheightonly: true,
types: [
"mitarbeiter",
"raum",
@@ -75,9 +76,16 @@ const app = Vue.createApp({
},
organisationunit: {
defaultaction: {
type: "function",
type: "link",
renderif: function(data) {
if(data.mailgroup) {
return true;
}
return false;
},
action: function(data) {
alert('organisationunit defaultaction ' + JSON.stringify(data));
const link = 'mailto:' + data.mailgroup;
return link;
}
},
childactions: []
+1 -1
View File
@@ -48,7 +48,7 @@ export default {
template: /*html*/`
<div class="calendar-header card-header w-100" :class="classHeader">
<div class="row align-items-center ">
<div class="col offset-0 offset-md-3" :style="{'padding-left':headerPadding}">
<div class="col offset-0" :style="{'padding-left':headerPadding}">
<div class="row align-items-center justify-content-center">
<div class="col-auto ">
<button class="btn btn-outline-secondary border-0" :class="{'btn-sm':!this.size}" @click="$emit('prev')"><i class="fa fa-chevron-left"></i></button>
+18 -4
View File
@@ -9,11 +9,21 @@ export default {
},
props: [
"dashboard",
"viewDataString"
],
data: () => ({
sections: [],
widgets: null
}),
data() {
return {
sections: [],
widgets: null,
viewData: JSON.parse(this.viewDataString),
editMode: false
}
},
provide() {
return {
editMode: Vue.computed(()=>this.editMode),
}
},
computed: {
apiurl() {
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/dashboard';
@@ -142,6 +152,10 @@ export default {
},
template: `
<div class="core-dashboard">
<h3>
{{ $p.t('global/personalGreeting', [ viewData?.name ]) }}
<button style="margin-left: 8px;" class="btn" @click="editMode = !editMode"><i class="fa-solid fa-gear"></i></button>
</h3>
<dashboard-section v-for="(section, index) in sections" :key="section.name" :seperator="index" :name="section.name" :widgets="section.widgets" @widgetAdd="widgetAdd" @widgetUpdate="widgetUpdate" @widgetRemove="widgetRemove"></dashboard-section>
<dashboard-widget-picker ref="widgetpicker" :widgets="widgets"></dashboard-widget-picker>
</div>`
+14 -7
View File
@@ -43,6 +43,10 @@ export default {
},
},
methods: {
getWidgetC4Link(widget) {
return (FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router + widget.setup.cis4link)
},
handleShowBsModal() {
this.$emit('configOpened')
},
@@ -113,19 +117,22 @@ export default {
</div>
</div>
<div v-else-if="!hidden || editMode" class="dashboard-item card overflow-hidden h-100" :class="arguments && arguments.className ? arguments.className : ''">
<div v-if="editMode && widget" class="card-header d-flex ps-0 pe-2">
<span drag-action="move" class="col-auto mx-2 px-2 cursor-move"><i class="fa-solid fa-grip-vertical"></i></span>
<span class="col">{{ widget.setup.name }}</span>
<div v-if="widget" class="card-header d-flex ps-0 pe-2">
<span v-if="editMode" drag-action="move" class="col-auto mx-2 px-2 cursor-move"><i class="fa-solid fa-grip-vertical"></i></span>
<span class="col mx-2 px-2">{{ widget.setup.name }}</span>
<a v-if="widget.setup.cis4link" :href="getWidgetC4Link(widget)" class="ms-auto mb-2">
<i class="fa fa-arrow-up-right-from-square me-1"></i>
</a>
<a v-if="hasConfig" class="col-auto px-1" href="#" @click.prevent="openConfig"><i class="fa-solid fa-gear"></i></a>
<a v-if="custom" class="col-auto px-1" href="#" @click.prevent="$emit('remove')">
<a v-if="custom && editMode" class="col-auto px-1" href="#" @click.prevent="$emit('remove')">
<i class="fa-solid fa-trash"></i>
</a>
<div v-else class="col-auto px-1 form-switch">
<div v-else-if="editMode" class="col-auto px-1 form-switch">
<input class="form-check-input ms-0" type="checkbox" role="switch" id="flexSwitchCheckChecked" :checked="!hidden" @input="$emit('remove', hidden)">
</div>
</div>
<div v-if="ready" class="card-body overflow-hidden">
<component :is="component" v-model:shared-data="sharedData" :config="arguments" :width="width" :height="height" @setConfig="setConfig" @change="changeConfigManually"></component>
<div v-if="ready" class="card-body overflow-hidden" style="padding: 0px;">
<component :is="component" v-model:shared-data="sharedData" :config="arguments" :width="width" :height="height" @setConfig="setConfig" @change="changeConfigManually"></component>
</div>
<div v-else class="card-body overflow-hidden text-center d-flex flex-column justify-content-center"><i class="fa-solid fa-spinner fa-pulse fa-3x"></i></div>
<bs-modal v-if="hasConfig" ref="config" @hideBsModal="handleHideBsModal" @showBsModal="handleShowBsModal">
+16 -9
View File
@@ -12,12 +12,15 @@ export default {
adminMode: {
type: Boolean,
default: false
},
editMode: {
type: Boolean,
default: false
}
},
props: [
"name",
"widgets",
"seperator"
"widgets"
],
emits: [
"widgetAdd",
@@ -29,10 +32,19 @@ export default {
configOpened: false,
gridWidth: 1,
gridHeight: null,
editMode: this.adminMode
}
},
provide() {
return {
editModeIsActive: Vue.computed(() =>
this.editModeIsActive
),
}
},
computed: {
editModeIsActive() {
return (this.editMode || this.adminMode) && !this.configOpened
},
getSectionStyle() {
return 'margin-bottom: 8px;';
},
@@ -181,13 +193,8 @@ export default {
});
},
template: `
<div v-if="seperator" class="fhc-seperator"/>
<div class="dashboard-section" ref="container" :style="getSectionStyle">
<h3>
<span >{{$p.t('ui/section' + name)}}</span>
<button style="margin-left: 8px;" class="btn" @click="editMode = !editMode"><i class="fa-solid fa-gear"></i></button>
</h3>
<drop-grid v-model:cols="gridWidth" :items="items" :placeholders="items_placeholders" :active="editMode && !configOpened" :resize-limit="checkResizeLimit" :margin-for-extra-row=".01" @rearrange-items="updatePositions" @gridHeight="gridHeight=$event" >
<drop-grid v-model:cols="gridWidth" :items="items" :placeholders="items_placeholders" :active="editModeIsActive" :resize-limit="checkResizeLimit" :margin-for-extra-row=".01" @rearrange-items="updatePositions" @gridHeight="gridHeight=$event" >
<template #default="item" #default>
<dashboard-item v-if="!item.placeholder"
@@ -121,7 +121,7 @@ export default {
}
},
template: /*html*/`
<div class="widgets-ampel w-100 h-100">
<div class="widgets-ampel w-100 h-100" style="padding: 1rem 1rem;">
<div v-if="!configMode">
<div v-if="activeAmpeln" class="d-flex flex-column justify-content-between">
<div class="d-flex">
+12 -20
View File
@@ -11,6 +11,9 @@ export default {
}),
mixins: [AbstractWidget],
computed: {
getNewsWidgetStyle() {
return this.width == 1 ? "padding: 1rem 1rem;" : "padding: 0px;"
},
newsList() {
//Return news amount depending on widget width and size
let quantity = this.width;
@@ -61,33 +64,22 @@ export default {
this.$refs.newsModal.show();
},
},
template: /*html*/ `<div class="widgets-news h-100">
template: /*html*/ `<div class="widgets-news h-100" :style="getNewsWidgetStyle">
<div class="d-flex flex-column h-100 ">
<div class="d-flex">
<header><b>{{$p.t('news','topNews')}}</b></header>
<a :href="allNewsURI()" class="ms-auto mb-2">
<i class="fa fa-arrow-up-right-from-square me-1"></i>{{$p.t('news','allNews')}}</a>
</div>
<div class="h-100" style="overflow-y: auto" v-if="width == 1">
<div v-for="news in newsList" :key="news.id" class="mt-2">
<div class="card">
<div class="card-body">
<a :href="contentURI(news.content_id)" class="stretched-link" >{{ news.content_obj.betreff?news.content_obj.betreff:getDate(news.insertamum) }}</a><br>
<span class="small text-muted">{{ formatDateTime(news.insertamum) }}</span>
</div>
</div>
<div v-for="(news, index) in newsList" :key="news.id" class="mt-2">
<div v-if="index > 0 " class="fhc-seperator"></div>
<a :href="contentURI(news.content_id)" >{{ news.content_obj.betreff?news.content_obj.betreff:getDate(news.insertamum) }}</a><br>
<span class="small text-muted">{{ formatDateTime(news.insertamum) }}</span>
</div>
</div>
<div v-else-if="width > 1 && height === 1" class="h-100" :class="'row row-cols-' + width">
<div class="h-100" v-for="news in newsList" :key="news.id">
<div class="news-content h-100" :style="'--news-widget-height: '+height" ref="htmlContent" v-html="news.content_obj.content"></div>
</div>
</div>
<div v-else class="h-100" :class="'row row-cols-' + width">
<div class="news-content h-100" :style="'--news-widget-height: '+height" ref="htmlContent" v-html="news.content_obj.content"></div>
</div>
</div>
<div v-else class="h-100" :class="'row row-cols-' + width + ' gx-2'">
<div class="h-100" v-for="news in newsList" :key="news.id">
<div class="news-content h-100" :style="'--news-widget-height: '+height" ref="htmlContent" v-html="news.content_obj.content"></div>
</div>
@@ -189,7 +189,6 @@ export default {
<div class="dashboard-widget-stundenplan d-flex flex-column h-100">
<lv-modal v-if="selectedEvent" ref="lvmodal" :event="selectedEvent" />
<content-modal :contentID="roomInfoContentID" :ort_kurzbz="" dialogClass="modal-lg" ref="contentModal"/>
<header><b>{{ $p.t('lehre/stundenplan') }}</b></header>
<fhc-calendar @change:range="updateRange" :initial-date="currentDay" class="border-0" class-header="p-0" @select:day="selectDay" v-model:minimized="minimized" :events="events" no-week-view :show-weeks="false" >
<template #minimizedPage >
<div class="flex-grow-1" style="overflow-y: auto; overflow-x: hidden">
+32 -31
View File
@@ -1,7 +1,14 @@
import AbstractWidget from './Abstract';
export default {
name: "WidgetsUrl",
name: "WidgetsUrl",
mixins: [AbstractWidget],
inject: {
editModeIsActive: {
type: Boolean,
default: false
}
},
data: () => ({
title_input: "",
url_input: "",
@@ -10,7 +17,7 @@ export default {
invalidTitel:false,
}
}),
mixins: [AbstractWidget],
computed: {
tagName() {
return this.config.tag !== undefined && this.config.tag.length > 0
@@ -97,16 +104,30 @@ export default {
},
created()
{
this.$emit('setConfig', true);
//
// this.$emit('setConfig', true); -> use this to enable widget config mode if needed
},
template: /*html*/ `
<div class="widgets-url w-100 h-100">
<div v-if="configMode">
<div class="mb-3">
<header><b>{{$p.t('bookmark','newLink')}}</b></header><br>
<div>
<div class="form-group">
<div class="widgets-url w-100 h-100" style="padding: 1rem 1rem;">
<div class="d-flex flex-column justify-content-between">
<!-- todo: widgetTag ?? -->
<template v-if="shared">
<template v-if="!emptyBookmarks">
<div v-for="link in shared" :key="link.id" class="d-flex mt-2">
<a target="_blank" :href="link.url">
<i class="fa fa-solid fa-arrow-up-right-from-square"></i>
{{ link.title }}
</a>
<a class="ms-auto" href="#" @click.prevent="removeLink(link.bookmark_id)" v-show="configMode || editModeIsActive">
<i class="fa fa-regular fa-trash-can" style="color: #e01b24;"></i>
</a>
</div>
</template>
<div v-else class="d-flex mt-2">
<span>{{$p.t('bookmark','emptyBookmarks')}}</span>
</div>
<div v-if="editModeIsActive " class="mt-2">
<div class="form-group">
<input maxlength="255" required class="form-control form-control-sm" :class="{'is-invalid':validation.invalidTitel}" placeholder="Titel" type="text" v-model="title_input" name="title" >
<!-- validation html for titel -->
<div class="invalid-feedback">
@@ -123,27 +144,7 @@ export default {
</div>
<button class="btn btn-outline-secondary btn-sm w-100 mt-2" @click="addLink" type="button">{{$p.t('bookmark','saveLink')}}</button>
</div>
</div>
</div>
<div class="d-flex flex-column justify-content-between">
<!-- todo: widgetTag ?? -->
<template v-if="shared">
<header><b>{{ tagName }}</b></header>
<template v-if="!emptyBookmarks">
<div v-for="link in shared" :key="link.id" class="d-flex mt-2">
<a target="_blank" :href="link.url">
<i class="fa fa-solid fa-arrow-up-right-from-square"></i>
{{ link.title }}
</a>
<a class="ms-auto" href="#" @click.prevent="removeLink(link.bookmark_id)" v-show="configMode">
<i class="fa fa-regular fa-trash-can" style="color: #e01b24;"></i>
</a>
</div>
</template>
<div v-else class="d-flex mt-2">
<span>{{$p.t('bookmark','emptyBookmarks')}}</span>
</div>
</div>
</template>
<template v-else>
<p v-for="i in 4" class="placeholder-glow">
+1 -1
View File
@@ -61,7 +61,7 @@ export default {
return {
'--fhc-dg-row-height': 100/(this.rows + addH) + '%',
'--fhc-dg-col-width': 100/this.cols + '%',
'--fhc-dg-item-padding-horizontal': '0.5%',
'--fhc-dg-item-padding-horizontal': '0.25%',
'--fhc-dg-item-padding-top': '0.5%',
'padding-bottom': 100 * (this.rows + addH)/this.cols + '%'
}
@@ -67,6 +67,8 @@ export default {
return {
selected: [],
searchbaroptions: {
cssclass: "position-relative",
calcheightonly: true,
types: [
"student",
"prestudent"
+8 -8
View File
@@ -30,8 +30,8 @@ export default {
<div class="searchbar_table">
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Standard-Kostenstelle</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Standard-Kostenstelle</div>
<div class="searchbar_tablecell searchbar_value">
<ul class="searchbar_inline_ul" v-if="res.standardkostenstelle.length > 0">
<li v-for="(stdkst, idx) in res.standardkostenstelle" :key="idx">{{ stdkst }}</li>
</ul>
@@ -40,8 +40,8 @@ export default {
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Organisations-Einheit</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Organisations-Einheit</div>
<div class="searchbar_tablecell searchbar_value">
<ul class="searchbar_inline_ul" v-if="res.organisationunit_name.length > 0">
<li v-for="(oe, idx) in res.organisationunit_name" :key="idx">{{ oe }}</li>
</ul>
@@ -50,8 +50,8 @@ export default {
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">EMail</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">EMail</div>
<div class="searchbar_tablecell searchbar_value">
<a :href="this.mailtourl">
{{ res.email }}
</a>
@@ -59,8 +59,8 @@ export default {
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Telefon</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Telefon</div>
<div class="searchbar_tablecell searchbar_value">
<a :href="this.telurl">
{{ res.phone }}
</a>
@@ -28,24 +28,25 @@ export default {
<div class="searchbar_table">
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">übergeordnete OrgEinheit</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">übergeordnete OrgEinheit</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.parentoe_name }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Gruppen-EMail</div>
<div class="searchbar_tablecell">
<a :href="this.mailtourl">
<div class="searchbar_tablecell searchbar_label">Gruppen-EMail</div>
<div class="searchbar_tablecell searchbar_value">
<a :href="this.mailtourl" v-if="res.mailgroup">
{{ res.mailgroup }}
</a>
<span v-else>-</span>
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Leiter</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Leiter</div>
<div class="searchbar_tablecell searchbar_value">
<ul class="searchbar_inline_ul" v-if="res.leaders.length > 0">
<li v-for="(leader, idx) in res.leaders" :key="idx">{{ leader.name }}</li>
</ul>
@@ -54,8 +55,8 @@ export default {
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Mitarbeiter-Anzahl</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Mitarbeiter-Anzahl</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.number_of_people }}
</div>
</div>
@@ -64,7 +65,7 @@ export default {
<actions :res="this.res" :actions="this.actions.childactions" @actionexecuted="$emit('actionexecuted')"></actions>
</div>
</div>
</div>
</div>
+2 -2
View File
@@ -29,8 +29,8 @@ export default {
<div class="searchbar_table">
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">EMail</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">EMail</div>
<div class="searchbar_tablecell searchbar_value">
<a :href="this.mailtourl">
{{ res.mail }}
</a>
+10 -10
View File
@@ -31,36 +31,36 @@ export default {
<div class="searchbar_table">
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Prestudent_id</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Prestudent_id</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.prestudent_id }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Student_uid</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Student_uid</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.uid }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Person_id</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Person_id</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.person_id }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Studiengang</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">Studiengang</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.bezeichnung }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">EMail</div>
<div class="searchbar_tablecell">
<div class="searchbar_tablecell searchbar_label">EMail</div>
<div class="searchbar_tablecell searchbar_value">
<a :href="this.mailtourl">
{{ res.email }}
</a>
+8 -8
View File
@@ -25,20 +25,20 @@ export default {
<div class="searchbar_table">
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Standort</div>
<div class="searchbar_tablecell">{{ res.standort }}</div>
<div class="searchbar_tablecell searchbar_label">Standort</div>
<div class="searchbar_tablecell searchbar_value">{{ res.standort }}</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Sitzplätze</div>
<div class="searchbar_tablecell">{{ res.sitzplaetze }}</div>
<div class="searchbar_tablecell searchbar_label">Sitzplätze</div>
<div class="searchbar_tablecell searchbar_value">{{ res.sitzplaetze }}</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Gebäude</div>
<div class="searchbar_tablecell">{{ res.building }}</div>
<div class="searchbar_tablecell searchbar_label">Gebäude</div>
<div class="searchbar_tablecell searchbar_value">{{ res.building }}</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell">Zusatz Informationen</div>
<div class="searchbar_tablecell"><div v-html="res.austattung.replace('<br />','')"></div></div>
<div class="searchbar_tablecell searchbar_label">Zusatz Informationen</div>
<div class="searchbar_tablecell searchbar_value"><div v-html="res.austattung.replace('<br />','')"></div></div>
</div>
</div>
+47 -22
View File
@@ -36,30 +36,33 @@ export default {
<form ref="searchform" class="d-flex me-3" :class="searchoptions.cssclass" action="javascript:void(0);"
@focusin="this.searchfocusin" @focusout="this.searchfocusout">
<div class="h-100 input-group me-2 bg-white">
<input ref="searchbox" @keyup="this.search" @focus="this.showsearchresult"
<div ref="searchbox" class="h-100 input-group me-2 bg-white">
<input @keyup="this.search" @focus="this.showsearchresult"
v-model="this.searchsettings.searchstr" class="form-control"
type="search" :placeholder="'Search: '+ searchsettings.types.join(' / ')" aria-label="Search">
<button data-bs-toggle="collapse" data-bs-target="#searchSettings" aria-expanded="false" aria-controls="searchSettings" ref="settingsbutton" class="btn btn-outline-secondary" type="button" id="search-filter"><i class="fas fa-cog"></i></button>
</div>
<div v-show="this.showresult" ref="result"
<div v-show="this.showresult"
class="searchbar_results" tabindex="-1">
<div v-if="this.searching">
<i class="fas fa-spinner fa-spin fa-2x"></i>
<div class="searchbar_results_scroller" ref="result">
<div class="searchbar_results_wrapper" ref="results">
<div v-if="this.searching">
<i class="fas fa-spinner fa-spin fa-2x"></i>
</div>
<div v-else-if="this.error !== null">{{ this.error }}</div>
<div v-else-if="searchresult.length < 1">Es wurden keine Ergebnisse gefunden.</div>
<template v-else="" v-for="res in searchresult">
<person v-if="res.type === 'person'" :res="res" :actions="this.searchoptions.actions.person" @actionexecuted="this.hideresult"></person>
<student v-else-if="res.type === 'student'" :res="res" :actions="this.searchoptions.actions.student" @actionexecuted="this.hideresult"></student>
<prestudent v-else-if="res.type === 'prestudent'" :res="res" :actions="this.searchoptions.actions.prestudent" @actionexecuted="this.hideresult"></prestudent>
<employee v-else-if="res.type === 'mitarbeiter' || res.type === 'mitarbeiter_ohne_zuordnung'" :res="res" :actions="this.searchoptions.actions.employee" @actionexecuted="this.hideresult"></employee>
<organisationunit v-else-if="res.type === 'organisationunit'" :res="res" :actions="this.searchoptions.actions.organisationunit" @actionexecuted="this.hideresult"></organisationunit>
<raum v-else-if="res.type === 'raum'" :res="res" :actions="this.searchoptions.actions.raum" @actionexecuted="this.hideresult"></raum>
<div v-else="">Unbekannter Ergebnistyp: '{{ res.type }}'.</div>
</template>
</div>
</div>
<div v-else-if="this.error !== null">{{ this.error }}</div>
<div v-else-if="searchresult.length < 1">Es wurden keine Ergebnisse gefunden.</div>
<template v-else="" v-for="res in searchresult">
<person v-if="res.type === 'person'" :res="res" :actions="this.searchoptions.actions.person" @actionexecuted="this.hideresult"></person>
<student v-else-if="res.type === 'student'" :res="res" :actions="this.searchoptions.actions.student" @actionexecuted="this.hideresult"></student>
<prestudent v-else-if="res.type === 'prestudent'" :res="res" :actions="this.searchoptions.actions.prestudent" @actionexecuted="this.hideresult"></prestudent>
<employee v-else-if="res.type === 'mitarbeiter' || res.type === 'mitarbeiter_ohne_zuordnung'" :res="res" :actions="this.searchoptions.actions.employee" @actionexecuted="this.hideresult"></employee>
<organisationunit v-else-if="res.type === 'organisationunit'" :res="res" :actions="this.searchoptions.actions.organisationunit" @actionexecuted="this.hideresult"></organisationunit>
<raum v-else-if="res.type === 'raum'" :res="res" :actions="this.searchoptions.actions.raum" @actionexecuted="this.hideresult"></raum>
<div v-else="">Unbekannter Ergebnistyp: '{{ res.type }}'.</div>
</template>
</div>
<div id="searchSettings" ref="settings" @[\`show.bs.collapse\`]="$emit('showSettings','settings')"
@@ -91,6 +94,13 @@ export default {
toggle: false
});
},
updated() {
if(this.showresult) {
Vue.nextTick(() => {
this.calcSearchResultHeight();
});
}
},
methods: {
updateSearchOptions: function() {
this.searchsettings.types = [];
@@ -98,12 +108,26 @@ export default {
this.searchsettings.types.push(this.searchoptions.types[idx]);
}
},
calcSearchResultHeight: function() {
const rect = this.$refs.results.getBoundingClientRect();
if( rect.height > 0 && rect.height < (window.innerHeight * 0.8) ) {
this.$refs.result.style.height = Math.ceil(rect.height + 16) + 'px';
} else {
this.$refs.result.style.height = Math.floor(window.innerHeight * 0.8) + 'px';
}
},
calcSearchResultExtent: function() {
var rect = this.$refs.searchbox.getBoundingClientRect();
this.$refs.result.style.top = Math.floor(rect.bottom + 3) + 'px';
this.$refs.result.style.right = Math.floor(window.innerWidth - rect.right) + 'px';
this.$refs.result.style.width = Math.floor(window.innerWidth * 0.75) + 'px';
this.$refs.result.style.height = Math.floor(window.innerHeight * 0.75) + 'px';
if(!this.showresult) {
return;
}
if(this.searchoptions?.calcheightonly === undefined
|| this.searchoptions.calcheightonly === false) {
var rect = this.$refs.searchbox.getBoundingClientRect();
this.$refs.result.style.top = Math.floor(rect.bottom + 3) + 'px';
this.$refs.result.style.right = Math.floor(rect.right) + 'px';
this.$refs.result.style.width = Math.floor(rect.width) + 'px';
}
this.calcSearchResultHeight();
},
search: function() {
if( this.searchtimer !== null ) {
@@ -159,6 +183,7 @@ export default {
if( this.searchsettings.searchstr.length >= 2 ) {
this.showresult = true;
window.addEventListener('resize', this.calcSearchResultExtent);
this.calcSearchResultExtent();
}
},
searchfocusin: function(e) {
+20
View File
@@ -37136,6 +37136,26 @@ array(
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'personalGreeting',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => "{0}'s persönliches Dashboard",
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => "{0}'s personal Dashboard",
'description' => '',
'insertvon' => 'system'
)
)
)
// CIS4 phrases from legacy code end
);