diff --git a/api/src/Etemplate.php b/api/src/Etemplate.php
index fac9520b28..fdffd37f24 100644
--- a/api/src/Etemplate.php
+++ b/api/src/Etemplate.php
@@ -55,7 +55,10 @@ class Etemplate extends Etemplate\Widget\Template
$this->sitemgr = isset($GLOBALS['Common_BO']) && is_object($GLOBALS['Common_BO']);
- if ($name) $this->read($name,$template='default','default',0,'',$load_via);
+ if($name)
+ {
+ $this->read($name, null, 'default', 0, '', $load_via);
+ }
// generate new etemplate request object, if not already existing
if(!isset(self::$request)) self::$request = Etemplate\Request::read();
@@ -276,7 +279,8 @@ class Etemplate extends Etemplate\Widget\Template
'>' . "\n" .
'';
}
- $GLOBALS['egw']->framework->response->generic("data", array($content));
+
+ $GLOBALS['egw']->framework->response->generic("data", $this->template_set == "kdots" ? $load_array : array($content));
$GLOBALS['egw']->framework->response->generic('et2_load',$load_array+Framework::get_extra());
Framework::clear_extra(); // to not send/set it twice for multiple etemplates (eg. CRM view)
@@ -565,6 +569,10 @@ class Etemplate extends Etemplate\Widget\Template
public function read($name,$template_set=null,$lang='default',$group=0,$version='',$load_via='')
{
+ if($template_set == null && $GLOBALS['egw_info']['user']['preferences']['common']['template_set'])
+ {
+ $template_set = $GLOBALS['egw_info']['user']['preferences']['common']['template_set'];
+ }
// For mobile experience try to load custom mobile templates
if (Header\UserAgent::mobile())
{
diff --git a/kdots/js/EgwFrameworkApp.ts b/kdots/js/EgwFrameworkApp.ts
index aca28c31b2..da459c1226 100644
--- a/kdots/js/EgwFrameworkApp.ts
+++ b/kdots/js/EgwFrameworkApp.ts
@@ -9,6 +9,7 @@ import styles from "./EgwFrameworkApp.styles";
import {SlSplitPanel} from "@shoelace-style/shoelace";
import {HasSlotController} from "../../api/js/etemplate/Et2Widget/slot";
import type {EgwFramework} from "./EgwFramework";
+import {etemplate2} from "../../api/js/etemplate/etemplate2";
/**
* @summary Application component inside EgwFramework
@@ -192,7 +193,19 @@ export class EgwFrameworkApp extends LitElement
).then((data : string[]) =>
{
// Load request returns HTML. Shove it in.
- render(html`${unsafeHTML(data.join(""))}`, this);
+ if(typeof data == "string" || typeof data == "object" && typeof data[0] == "string")
+ {
+ render(html`${unsafeHTML(data.join(""))}`, this);
+ }
+ else
+ {
+ // We got some data, use it
+ if(data.DOMNodeID)
+ {
+ this.id = data.DOMNodeID;
+ }
+ }
+ this.addEventListener("load", this.handleEtemplateLoad, {once: true});
// Might have just slotted aside content, hasSlotController will requestUpdate()
// but we need to do it anyway for translation
@@ -270,6 +283,21 @@ export class EgwFrameworkApp extends LitElement
this.hasSlotController.test(side) || this.hasSlotController.test(`${side}-footer`);
}
+ /**
+ * An etemplate has loaded inside
+ * Move anything top-level that has a slot
+ */
+ protected handleEtemplateLoad(event)
+ {
+ const etemplate = etemplate2.getById(this.id);
+ if(!etemplate)
+ {
+ return;
+ }
+ // Move top level slotted components (slot watcher will requestUpdate)
+ etemplate.widgetContainer.getDOMNode().querySelectorAll(":scope > [slot]").forEach(node => {this.appendChild(node);});
+ }
+
/**
* User adjusted side slider, update preference
*
diff --git a/mail/templates/kdots/index.xet b/mail/templates/kdots/index.xet
new file mode 100644
index 0000000000..b4108e8a1f
--- /dev/null
+++ b/mail/templates/kdots/index.xet
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file