Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/vue3 migration #271

Merged
merged 11 commits into from
Feb 28, 2024
8 changes: 8 additions & 0 deletions system/classes/DbService.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ public function __construct(Web $w)
$this->w = $w;
}

/**
* @return MenuLinkType[]
*/
public function navList(): array
{
return [];
}

/**
* Formats a timestamp
* per default MySQL datetime format is used
Expand Down
2 changes: 1 addition & 1 deletion system/classes/History.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public static function remove($object = null)
*/
private static function sort($a, $b)
{
return $a['time'] - $b['time'];
return $b['time'] - $a['time'];
}

/**
Expand Down
18 changes: 18 additions & 0 deletions system/classes/MenuLinkStruct.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

enum MenuLinkType {
case Link;
case Modal;
}

class MenuLinkStruct {
public function __construct(
public string $title,
public string $url,
public MenuLinkType $type = MenuLinkType::Link,
) {
if ($url[0] !== '/') {
$this->url = '/' . $url;
}
}
}
13 changes: 13 additions & 0 deletions system/classes/components/CmfiveScriptComponentRegister.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,17 @@ public static function outputScripts() {
}, static::getComponents() ? : []);
}

public static function requireVue3()
{
static::registerComponent('vue3', new CmfiveScriptComponent('/system/templates/base/node_modules/vue3/dist/vue.global.prod.js'));
if (array_key_exists('vue2', static::$_register)) {
unset(static::$_register['vue2']);
}
}

public static function requireVue2()
{
static::registerComponent('vue2', new CmfiveScriptComponent('/system/templates/js/vue.js'));
}

}
101 changes: 101 additions & 0 deletions system/classes/html/cmfive/DismissableAlert.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php namespace Html\Cmfive;

use Html\GlobalAttributes;

enum DismissableAlertType {
case Primary;
case Secondary;
case Info;
case Warning;
case Error;
}

/**
* Class DismissableAlert
*
* Represents a dismissable alert component that can be displayed to the user.
* This class provides methods to set the alert content, type, and dismiss button.
* It also handles the rendering of the alert HTML markup.
*
* Note: requires Web instance to namespace the dismissKey
*/
class DismissableAlert extends \Html\Element
{
use GlobalAttributes;

public \Web $w;
public DismissableAlertType $type = DismissableAlertType::Warning;
public string $content = '';
public string $dismissKey = '';

/**
* Sets the type of alert
*
* @param DismissableAlertType $type
* @return this
*/
public function setType(DismissableAlertType $type): self {
$this->type = $type;

return $this;
}

public function setDismissKey(string $dismissKey): self {
$this->dismissKey = $dismissKey;

return $this;
}

public function setWeb(\Web $w): self {
$this->w = $w;

return $this;
}

/**
* Gets the Bootstrap 5 class of the alert
*
* @return string
*/
private function getAlertClass(): string {
return match ($this->type) {
DismissableAlertType::Primary => 'alert-primary',
DismissableAlertType::Secondary => 'alert-secondary',
DismissableAlertType::Info => 'alert-info',
DismissableAlertType::Warning => 'alert-warning',
DismissableAlertType::Error => 'alert-danger',
};
}

/**
* Gets the Bootstrap 5 icon class for the alert
*
* @return string
*/
private function getAlertIcon(): string
{
return match ($this->type) {
DismissableAlertType::Primary => 'bi-info-circle',
DismissableAlertType::Secondary => 'bi-info-circle',
DismissableAlertType::Info => 'bi-info-circle',
DismissableAlertType::Warning => 'bi-exclamation-triangle',
DismissableAlertType::Error => 'bi-exclamation-triangle',
};
}

public function __toString(): string {
$setting = \AuthService::getInstance($this->w)->getSettingByKey($this->w->_module . '__' . $this->dismissKey);
if (!empty($setting->id)) {
return '';
}

return <<<RETURN
<div class="alert {$this->getAlertClass()} {$this->class}" role="alert">
<i class="bi {$this->getAlertIcon()} float-start me-2"></i>
{$this->content}
<button type="button" class="btn-close float-end" data-bs-dismiss="alert" aria-label="Close"></button>
<button type="button" class="btn btn-sm btn-outline-secondary float-end me-3" style="margin-top: -3px;" data-bs-dismiss="alert" onclick="fetch('/auth/ajax_set_setting?key={$this->w->_module}__{$this->dismissKey}&value=true')">Don't show this again</button>
</div>
RETURN;
}
}
2 changes: 1 addition & 1 deletion system/classes/html/form/InputField.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public function setAccept($accept)
*/
public function setAutocomplete($autocomplete)
{
$this->autcomplete = $autocomplete;
$this->autocomplete = $autocomplete;

return $this;
}
Expand Down
21 changes: 21 additions & 0 deletions system/functions.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
<?php

/**
* Determines whether or not an object has overloaded a method
*
* @param object $object
* @param string $method
* @return bool
*/
function method_exists_overloaded(object $object, string $method)
{
if (!method_exists($object, $method)) {
return false;
}

$reflector = new \ReflectionMethod($object, $method);
return $reflector->getDeclaringClass()->getName() === get_class($object);
}

/**
* Deduplicates arrays of arrays, something that array_unique can't do.
* Given an array of arrays, this function will return an array containing only
Expand Down Expand Up @@ -170,6 +187,10 @@ function humanReadableBytes($input, $rounding = 2, $bytesValue = true)
$barrier = 1000;
}

if ($input === null) {
return '0 B';
}

while ($input > $barrier) {
$input /= $barrier;
array_shift($ext);
Expand Down
5 changes: 3 additions & 2 deletions system/modules/admin/actions/templates/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ function edit_POST(Web $w)
$p = $w->pathMatch("id");
$t = $p["id"] ? TemplateService::getInstance($w)->getTemplate($p['id']) : new Template($w);
$t->fill($_POST);
$encoded_template_body = $_POST['template_body'] ?? '';
$t->template_body = json_decode($encoded_template_body);
if (array_key_exists('template_body', $_POST)) {
$t->template_body = json_decode($_POST['template_body']);
}

// Set is active if saving is originating from the first page
if (isset($_POST["title"]) && isset($_POST["module"]) && isset($_POST["category"])) {
Expand Down
2 changes: 1 addition & 1 deletion system/modules/admin/actions/user/ajax_unlock_account.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function ajax_unlock_account_POST(Web $w)
return;
}

$user = $w->Auth->getUser($request_data["id"]);
$user = AuthService::getInstance($w)->getUser($request_data["id"]);
if (empty($user)) {
$w->out((new AxiosResponse())->setErrorResponse("Unable to find user", null));
return;
Expand Down
10 changes: 5 additions & 5 deletions system/modules/admin/actions/user/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ function edit_GET(Web $w)
$w->setLayout('layout-bootstrap-5');

VueComponentRegister::registerComponent("autocomplete", new VueComponent("autocomplete", "/system/templates/vue-components/form/elements/autocomplete.vue.js", "/system/templates/vue-components/form/elements/autocomplete.vue.css"));
// CmfiveScriptComponentRegister::registerComponent("toast", new CmfiveScriptComponent("/system/templates/base/dist/Toast.js"));

$redirect_url = "/admin/users";

Expand Down Expand Up @@ -57,9 +58,9 @@ function edit_GET(Web $w)
],
"security" => [
"login" => $user->login,
"is_admin" => $user->is_admin,
"is_active" => $user->is_active,
"is_external" => $user->is_external,
"is_admin" => $user->is_admin ? 'true' : 'false',
"is_active" => $user->is_active ? 'true' : 'false',
"is_external" => $user->is_external ? 'true' : 'false',
"is_locked" => $user->is_locked,
"new_password" => "",
"repeat_new_password" => "",
Expand Down Expand Up @@ -204,5 +205,4 @@ function edit_POST(Web $w): void
}

$w->msg("User details updated", $redirect_url);

}
}
31 changes: 23 additions & 8 deletions system/modules/admin/models/AdminService.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,22 +181,37 @@ public function getLanguages(array $where = []): array
public function navigation(Web $w, $title = null, $prenav = null)
{
if ($title) {
$w->ctx("title", $title);
$w->ctx('title', $title);
}

$nav = $prenav ? $prenav : [];
if (AuthService::getInstance($w)->loggedIn()) {
$w->menuLink("admin/index", "Admin Dashboard", $nav);
$w->menuLink("admin/users", "List Users", $nav);
$w->menuLink("admin/groups", "List Groups", $nav);
$w->menuLink('admin/index', 'Admin Dashboard', $nav);
$w->menuLink('admin/users', 'List Users', $nav);
$w->menuLink('admin/groups', 'List Groups', $nav);
$w->menuLink('admin-maintenance', 'Maintenance', $nav);
$w->menuLink("admin/lookup", "Lookup", $nav);
$w->menuLink("admin-templates", "Templates", $nav);
// $w->menuLink("admin/composer", "Update composer.json", $nav, null, "_blank");
$w->menuLink("admin-migration", "Migrations", $nav);
$w->menuLink('admin/lookup', 'Lookup', $nav);
$w->menuLink('admin-templates', 'Templates', $nav);
$w->menuLink('admin-migration', 'Migrations', $nav);
}

$w->ctx("navigation", $nav);
return $nav;
}

/**
* @return MenuLinkStruct[]
*/
public function navList(): array
{
return [
new MenuLinkStruct('Admin Dashboard', 'admin/index'),
new MenuLinkStruct('List Users', 'admin/users'),
new MenuLinkStruct('List Groups', 'admin/groups'),
new MenuLinkStruct('Maintenance', 'admin-maintenance'),
new MenuLinkStruct('Lookup', 'admin/lookup'),
new MenuLinkStruct('Templates', 'admin-templates'),
new MenuLinkStruct('Migrations', 'admin-migration'),
];
}
}
41 changes: 21 additions & 20 deletions system/modules/admin/templates/templates/edit.tpl.php
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
<?php echo HtmlBootstrap5::b("/admin-templates", "Back to Templates List", null, null, false, "btn btn-sm btn-primary"); ?>
<br /><br />
<div class='tabs'>
<div class='tab-head'>
<a class='active' href="#tab-1">Details</a>
<a href="#tab-2">Template</a>
<a href="#tab-3">Test Data</a>
<?php echo HtmlBootstrap5::a("/admin-templates/rendertemplate/" . (!empty($id) ? $id : ""), "Test Output", null, null, null, '_blank'); ?>
<a href="#tab-5">Manual</a>
<div class='tab-head'>
<a class='active' href="#tab-1">Details</a>
<a href="#tab-2">Template</a>
<a href="#tab-3">Test Data</a>
<?php echo HtmlBootstrap5::a("/admin-templates/rendertemplate/" . (!empty($id) ? $id : ""), "Test Output", null, null, null, '_blank'); ?>
<a href="#tab-5">Manual</a>
</div>
<div class='tab-body'>
<div id='tab-1'>
<?php echo !empty($editdetailsform) ? $editdetailsform : ''; ?>
</div>
<div class='tab-body'>
<div id='tab-1'>
<?php echo !empty($editdetailsform) ? $editdetailsform : ''; ?>
</div>
<div id='tab-2'>
<?php echo !empty($templateform) ? $templateform : ''; ?>
</div>
<div id='tab-3'>
<?php echo !empty($testdataform) ? $testdataform : ''; ?>
</div>
<div id='tab-5'>
<p>
This is the template manual
</div>
<div id='tab-2'>
<?php echo !empty($templateform) ? $templateform : ''; ?>
</div>
<div id='tab-3'>
<?php echo !empty($testdataform) ? $testdataform : ''; ?>
</div>
<div id='tab-5'>
<p>
This is the template manual
</p>
</div>
</div>
</div>
Loading
Loading