navigating to another content_id link from cms app reloads the content instead of entire page; WIP implementing abstract reload functionality for all content types;

This commit is contained in:
Johann Hoffmann
2024-12-13 11:52:34 +01:00
parent 82e7783259
commit 98d4a08836
6 changed files with 163 additions and 84 deletions
+7 -9
View File
@@ -29,17 +29,15 @@ class Dashboard extends Auth_Controller
{
$this->load->model('person/Person_model','PersonModel');
$begruesung = $this->PersonModel->getFirstName(getAuthUID());
if(isError($begruesung))
{
show_error("name couldn't be loaded for username ".getAuthUID());
}
$begruesung = getData($begruesung);
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
$viewData = array(
'name' => $begruesung
'uid' => getAuthUID(),
'name' => $personData->vorname,
'person_id' => $personData->person_id
);
$this->load->view('CisVue/Dashboard.php', ['viewData' => $viewData]);
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
}
}
+99 -31
View File
@@ -2,43 +2,111 @@ import BsConfirm from "../../components/Bootstrap/Confirm.js";
import CmsNews from "../../components/Cis/Cms/News.js";
import CmsContent from "../../components/Cis/Cms/Content.js";
import Phrasen from "../../plugin/Phrasen.js";
import fhcapifactory from "../api/fhcapifactory.js";
Vue.$fhcapi = fhcapifactory;
import {setScrollbarWidth} from "../../helpers/CssVarCalcHelpers";
import FhcApi from "../../plugin/FhcApi";
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
console.log('ciPath', ciPath)
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(`/${ciPath}/CisVue/Cms/`),
routes: [
{
path: `/content/:content_id`,
name: 'Content',
component: CmsContent,
props: true
},
{
path: `/news`,
name: 'News',
component: CmsNews,
}
]
})
const app = Vue.createApp({
name: 'CmsApp',
components: {
CmsNews,
CmsContent,
},
mounted() {
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
el.addEventListener("click", (evt) => {
evt.preventDefault();
BsConfirm.popup(el.dataset.confirm)
.then(() => {
Axios.get(el.href)
.then((res) => {
// TODO(chris): check for success then show message and/or reload
location = location;
})
.catch((err) => console.error("ERROR:", err));
})
.catch(() => {});
});
});
document.querySelectorAll("#cms [data-href]").forEach((el) => {
el.href = el.dataset.href.replace(
/^ROOT\//,
FHC_JS_DATA_STORAGE_OBJECT.app_root
);
});
},
name: 'CmsApp',
data() {
return {
instance: null,
interceptHandler: this.intercept//.bind(this)
}
},
components: {
CmsNews,
CmsContent,
},
methods: {
intercept(e) {
if (e.target.tagName === "A" && e.target.pathname?.includes(ciPath) && e.target.pathname.includes('Cms/content')) {
const pathParts = e.target.pathname.split('/').filter(Boolean);
const idString = pathParts[pathParts.length - 1];
const content_id = idString && !isNaN(Number(idString)) ? idString : null; // only return id if it is a number string since the path might contain invalid elements
e.preventDefault() // prevents normal browser page load
this.$router.push({ // add new content id to browser history
name: 'Content',
params: {
content_id
}
})
// load and show new content from id without reloading page with menu overhead etc.
// from a generic reload function required by every affected child component
this.instance.subTree.type.methods.reload(
content_id,
this.instance.appContext.config.globalProperties.$fhcApi,
this.instance.subTree.component.proxy // this pointer of component reloading and setting its own content
)
} else if(e.target.tagName === "A" && e.target.pathname?.includes(ciPath) && e.target.pathname.includes('Cms/news')) {
//handle news content
}
}
},
mounted() {
this.instance = Vue.getCurrentInstance()
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
el.addEventListener("click", (evt) => {
evt.preventDefault();
BsConfirm.popup(el.dataset.confirm)
.then(() => {
Axios.get(el.href)
.then((res) => {
// TODO(chris): check for success then show message and/or reload
location = location;
})
.catch((err) => console.error("ERROR:", err));
})
.catch(() => {
});
});
});
document.querySelectorAll("#cms [data-href]").forEach((el) => {
el.href = el.dataset.href.replace(
/^ROOT\//,
FHC_JS_DATA_STORAGE_OBJECT.app_root
);
});
document.addEventListener("click", this.interceptHandler, {capture: true, passive: false})
},
unmounted() {
document.removeEventListener('click', this.interceptHandler)
}
});
setScrollbarWidth();
app.use(primevue.config.default, { zIndex: { overlay: 9999 } });
app.use(FhcApi);
app.use(router);
app.use(primevue.config.default, {zIndex: {overlay: 9999}});
app.use(Phrasen, {reload: true});
app.mount("#cms");
//#cms [data-confirm], #cms [data-href]
app.mount("#cms");
+21 -11
View File
@@ -1,8 +1,9 @@
import raum_contentmittitel from './Content_types/Raum_contentmittitel.js'
import general from './Content_types/General.js'
export default {
name: "ContentComponent",
props: {
content_id: {
type: Number,
@@ -20,8 +21,6 @@ export default {
type: [String, Number],
default: null,
}
},
components: {
raum_contentmittitel,
@@ -30,8 +29,24 @@ export default {
data() {
return {
content: null,
content_idInternal: this.content_id
};
},
methods: {
reload(id, api, context) {
// to be called from app bound interceptor function that has access to the same api, but not via this
context.content_idInternal = id
this.load(api, context)
},
load(apiParam = null, context = this) {
const api = apiParam ?? context.$fhcApi
api.factory.cms.content(context.content_idInternal, context.version, context.sprache, context.sichtbar).then(res => {
context.content = res.data.content;
context.content_type = res.data.type;
});
}
},
computed: {
computeContentType: function () {
switch (this.content_type) {
@@ -39,22 +54,17 @@ export default {
return "raum_contentmittitel";
default:
return "general";
}
;
};
},
},
created() {
this.$fhcApi.factory.cms.content(this.content_id, this.version, this.sprache, this.sichtbar).then(res => {
this.content = res.data.content;
this.content_type = res.data.type;
});
this.load()
},
mounted() {
},
template: /*html*/ `
<!-- div that contains the content -->
<component :is="computeContentType" v-if="content" :content="content" :content_id="content_id" />
<component ref="content" :is="computeContentType" v-if="content" :content="content" :content_id="content_idInternal" />
<p v-else>No content is available to display</p>
`,
};
@@ -1,5 +1,6 @@
export default {
name: "GeneralComponent",
props:{
content:{
type:String,
@@ -1,5 +1,6 @@
export default {
name: "RaumComponent",
props:{
content:{
type:String,
+34 -33
View File
@@ -2,40 +2,41 @@ import Pagination from "../../Pagination/Pagination.js";
import StudiengangInformation from "./StudiengangInformation/StudiengangInformation.js";
export default {
components: {
Pagination,
},
data() {
return {
content: null,
maxPageCount: 0,
page_size: 10,
};
},
methods: {
loadNewPageContent: function (data) {
this.$fhcApi.factory.cms.getNews(data.page, data.rows)
.then(res => res.data)
.then(result => {
this.content = result;
});
},
},
created() {
this.$fhcApi.factory.cms.getNews(1, this.page_size)
.then(res => res.data)
.then(result => {
this.content = result;
});
name: "NewsComponent",
components: {
Pagination,
},
data() {
return {
content: null,
maxPageCount: 0,
page_size: 10,
};
},
methods: {
loadNewPageContent: function (data) {
this.$fhcApi.factory.cms.getNews(data.page, data.rows)
.then(res => res.data)
.then(result => {
this.content = result;
});
this.$fhcApi.factory.cms.getNewsRowCount()
.then(res => res.data)
.then(result => {
this.maxPageCount = result;
});
},
template: /*html*/ `
},
},
created() {
this.$fhcApi.factory.cms.getNews(1, this.page_size)
.then(res => res.data)
.then(result => {
this.content = result;
});
this.$fhcApi.factory.cms.getNewsRowCount()
.then(res => res.data)
.then(result => {
this.maxPageCount = result;
});
},
template: /*html*/ `
<h2 >News</h2>
<hr/>
<pagination :page_size="page_size" @page="loadNewPageContent" :maxPageCount="maxPageCount">