add files for manipulating tabs from feature-30660

This commit is contained in:
Harald Bamberger
2023-12-20 14:30:11 +01:00
parent 52cc0db5da
commit d9cd3a0b1d
3 changed files with 150 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use CI3_Events as Events;
/**
* NOTE(chris): example:
Events::on('stv_conf_student', function (&$res) {
$res['test'] = [
'title' => 'TEST',
'component' => './Stv/Studentenverwaltung/Details/Notizen.js'
];
});
*/
+51
View File
@@ -0,0 +1,51 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class CI3_Events
{
const PRIORITY_LOW = 200;
const PRIORITY_NORMAL = 100;
const PRIORITY_HIGH = 10;
private static $events = [];
private static $eventsSorted = [];
public static function on($event, $function, $priority = self::PRIORITY_NORMAL)
{
if (!isset(self::$events[$event]))
self::$events[$event] = [];
self::$events[$event][] = [$priority, $function];
if (!isset(self::$eventsSorted[$event]))
self::$eventsSorted[$event] = true;
else
self::$eventsSorted[$event] = false;
}
public static function trigger($event, ...$args)
{
if (!isset(self::$events[$event]))
return;
if (!self::$eventsSorted[$event]) {
usort(self::$events[$event], function ($a, $b) {
return $a[0] - $b[0];
});
self::$eventsSorted[$event] = true;
}
foreach (self::$events[$event] as $conf) {
$conf[1](...$args);
}
}
}
/**
* NOTE(chris): Autoload Events config
*/
require_once(APPPATH.'config/Events.php');
foreach (scandir(APPPATH.'config/extensions') as $dir)
if ($dir[0] != '.' && file_exists(APPPATH.'config/extensions/'.$dir.'/Events.php'))
require_once APPPATH.'config/extensions/'.$dir.'/Events.php';
+85
View File
@@ -0,0 +1,85 @@
import {CoreRESTClient} from '../RESTClient.js';
import accessibility from "../directives/accessibility.js";
export default {
directives: {
accessibility
},
emits: [
'update:modelValue'
],
props: {
configUrl: String,
default: String,
modelValue: [String, Number, Boolean, Array, Object, Date, Function, Symbol]
},
data() {
return {
current: null,
tabs: {}
}
},
computed: {
currentTab() {
if (this.tabs[this.current])
return this.tabs[this.current];
return { component: 'div' };
},
value: {
get() {
return this.modelValue;
},
set(v) {
this.$emit('update:modelValue', v);
}
}
},
created() {
CoreRESTClient
.get(this.configUrl)
.then(result => CoreRESTClient.getData(result.data))
.then(result => {
const tabs = {};
// TODO(chris): check if result is array
Object.entries(result).forEach(([key, config]) => {
if (!config.component)
return console.error('Component missing for ' + key);
tabs[key] = {
component: Vue.defineAsyncComponent(() => import(config.component)),
title: config.title || key,
config: config.config,
key
}
});
if (tabs[this.default])
this.current = this.default;
else
this.current = Object.keys(tabs)[0];
this.tabs = tabs;
})
.catch(this.$fhcAlert.handleSystemError);
},
template: `
<div class="fhc-tabs d-flex flex-column">
<div class="nav nav-tabs">
<div
v-for="tab in tabs"
:key="tab.key"
class="nav-item nav-link"
:class="{active: tab.key == current}"
@click="current=tab.key"
:aria-current="tab.key == current ? 'page' : ''"
v-accessibility:tab
>
{{tab.title}}
</div>
</div>
<div style="flex: 1 1 0%; height: 0%" class="border-bottom border-start border-end overflow-auto p-3">
<keep-alive>
<component :is="currentTab.component" v-model="value" :config="currentTab.config"></component>
</keep-alive>
</div>
</div>`
};