mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
feat wiki/ayuda section
This commit is contained in:
@ -7,11 +7,14 @@ $routes->group('wiki', ['namespace' => 'App\Controllers\Wiki'], function ($route
|
||||
$routes->get('','WikiController::index',["as" => "wikiIndex"]);
|
||||
$routes->get('view/(:segment)','WikiController::show_page/$1',["as" => "showWikiPage"]);
|
||||
$routes->get('section/(:num)','WikiController::get_section/$1',["as" => "getWikiSection"]);
|
||||
$routes->post('section','WikiController::store_section/$1',["as" => "storeWikiSection"]);
|
||||
$routes->post('section','WikiController::store_section',["as" => "storeWikiSection"]);
|
||||
$routes->delete('section/(:num)','WikiController::delete_section/$1',["as" => "deleteWikiSection"]);
|
||||
$routes->post('update/section','WikiController::update_section',["as" => "updateWikiSection"]);
|
||||
$routes->post('save/(:num)','WikiController::store_save_page/$1',["as" => "storeWikiSavePage"]);
|
||||
$routes->post('publish/(:num)','WikiController::store_publish_page/$1',["as" => "storeWikiPublishPage"]);
|
||||
$routes->post('file/upload/(:num)','WikiController::wiki_file_upload/$1',["as" => "storeWikiFileUpload"]);
|
||||
$routes->get('file/(:num)','WikiController::get_wiki_file/$1',["as" => "getWikiFile"]);
|
||||
$routes->post('section/update/order','WikiController::wiki_section_update_order',["as" => "updateWikiSectionOrder"]);
|
||||
|
||||
|
||||
});
|
||||
@ -7,10 +7,12 @@ use App\Models\Wiki\WikiContentModel;
|
||||
use App\Models\Wiki\WikiFileModel;
|
||||
use App\Models\Wiki\WikiPageModel;
|
||||
use App\Models\Wiki\WikiSectionModel;
|
||||
use App\Models\Wiki\WikiSectionRoleModel;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\I18n\Time;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
class WikiController extends BaseController
|
||||
{
|
||||
@ -18,6 +20,8 @@ class WikiController extends BaseController
|
||||
protected WikiContentModel $wikiContentModel;
|
||||
protected WikiPageModel $wikiPageModel;
|
||||
protected WikiFileModel $wikiFileModel;
|
||||
protected WikiSectionRoleModel $wikiSectionRoleModel;
|
||||
|
||||
|
||||
protected string $locale;
|
||||
protected array $viewData;
|
||||
@ -28,6 +32,7 @@ class WikiController extends BaseController
|
||||
$this->wikiPageModel = model(WikiPageModel::class);
|
||||
$this->wikiContentModel = model(WikiContentModel::class);
|
||||
$this->wikiFileModel = model(WikiFileModel::class);
|
||||
$this->wikiSectionRoleModel = model(WikiSectionRoleModel::class);
|
||||
|
||||
$sections = $this->wikiSectionModel->sections();
|
||||
$this->locale = session()->get('lang');
|
||||
@ -41,18 +46,32 @@ class WikiController extends BaseController
|
||||
}
|
||||
public function show_page(string $slug)
|
||||
{
|
||||
|
||||
$section = $this->wikiSectionModel->where('slug', $slug)->first();
|
||||
$this->viewData['slug'] = $slug;
|
||||
$this->viewData['section'] = $section->withAll($this->locale);
|
||||
$this->viewData['breadcrumb'] = [
|
||||
['title' => lang("Wiki.".$section->slug), 'route' => route_to('showWikiPage',$slug), 'active' => true],
|
||||
];
|
||||
return view('themes/vuexy/wiki/pages/render', $this->viewData);
|
||||
if($section){
|
||||
if(auth()->user()->inGroup(...$section->roles_array()) || auth()->user()->inGroup('admin')){
|
||||
$this->viewData['slug'] = $slug;
|
||||
$this->viewData['section'] = $section->withAll($this->locale);
|
||||
$this->viewData['breadcrumb'] = [
|
||||
['title' => lang("Wiki." . $section->slug), 'route' => route_to('showWikiPage', $slug), 'active' => true],
|
||||
];
|
||||
return view('themes/vuexy/wiki/pages/render', $this->viewData);
|
||||
}else{
|
||||
return $this->response->setStatusCode(403);
|
||||
}
|
||||
}else{
|
||||
return redirect_to('/');
|
||||
}
|
||||
}
|
||||
public function get_section(int $section_id)
|
||||
{
|
||||
$section = $this->wikiSectionModel->find($section_id)->withAll($this->locale);
|
||||
return $this->response->setJSON(["data" => $section, "message" => lang("App.global_alert_fetch_success")]);
|
||||
if(auth()->user()->inGroup(...$section->roles_array()) || auth()->user()->inGroup('admin')){
|
||||
|
||||
return $this->response->setJSON(["data" => $section, "message" => lang("App.global_alert_fetch_success")]);
|
||||
}else{
|
||||
return $this->response->setStatusCode(403);
|
||||
}
|
||||
}
|
||||
public function store_save_page(int $section_id)
|
||||
{
|
||||
@ -82,8 +101,8 @@ class WikiController extends BaseController
|
||||
$wikiSectionPage = $this->wikiSectionModel->find($section_id)->page();
|
||||
if ($wikiSectionPage) {
|
||||
$wikiPageId = $wikiSectionPage->id;
|
||||
$wikiContentId = $this->wikiContentModel->where("page_id",$wikiPageId)->where('locale',$this->locale)->first()->id;
|
||||
$this->wikiContentModel->update($wikiContentId,[
|
||||
$wikiContentId = $this->wikiContentModel->where("page_id", $wikiPageId)->where('locale', $this->locale)->first()->id;
|
||||
$this->wikiContentModel->update($wikiContentId, [
|
||||
"published_by" => auth()->user()->id,
|
||||
"last_edit_by" => auth()->user()->id,
|
||||
"editor_data" => json_encode($bodyData),
|
||||
@ -109,16 +128,16 @@ class WikiController extends BaseController
|
||||
$fullpath = $file->store('wiki_images/' . $section->slug);
|
||||
$r = $this->wikiFileModel->insert(["content_id" => $content->id, "path" => $fullpath]);
|
||||
return $this->response->setJSON(["success" => 1, "file" => [
|
||||
"url" => '/wiki/file/'.$r
|
||||
"url" => '/wiki/file/' . $r
|
||||
]]);
|
||||
}else{
|
||||
} else {
|
||||
return $this->response->setJSON(["success" => 0, "file" => [
|
||||
"url" => null
|
||||
]]);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
|
||||
return $this->response->setJSON(["success" => 0, "error" => $th->getMessage()])->setStatusCode($th->getCode());
|
||||
|
||||
return $this->response->setJSON(["success" => 0, "error" => $th->getMessage()])->setStatusCode(403);
|
||||
}
|
||||
}
|
||||
public function get_wiki_file(int $wiki_file_id)
|
||||
@ -132,7 +151,69 @@ class WikiController extends BaseController
|
||||
->setHeader('Content-Length', filesize($filePath))
|
||||
->setBody(file_get_contents($filePath));
|
||||
} else {
|
||||
return $this->response->setJSON(["message" => "Portada error", "error" => "No hay portada"])->setStatusCode(400);
|
||||
return $this->response->setJSON(["success" => 0, "error" => lang('Wiki.file_dont_exist')])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function wiki_section_update_order()
|
||||
{
|
||||
try {
|
||||
$bodyData = $this->request->getPost();
|
||||
$orders = $bodyData['orders'];
|
||||
foreach ($orders as $key => $section_id) {
|
||||
$this->wikiSectionModel->update($section_id, ['order' => $key]);
|
||||
}
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.order_success')]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->response->setJSON(["status" => 0, "message" => lang('Wiki.order_error')])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function store_section()
|
||||
{
|
||||
try {
|
||||
$bodyData = $this->request->getPost();
|
||||
$sectionName = $bodyData['name'];
|
||||
$roles = $bodyData['roles'];
|
||||
$bodyData["slug"] = implode('-', array_map(fn($e) => strtolower($e), explode(' ', $sectionName)));
|
||||
$bodyData["order"] = $this->wikiSectionModel->selectMax('order')->first()->order + 1;
|
||||
$wikiSectionId = $this->wikiSectionModel->insert($bodyData);
|
||||
if(count($roles) > 0){
|
||||
foreach ($roles as $key => $role) {
|
||||
$this->wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId , 'role' => $role]);
|
||||
}
|
||||
}
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_new_success')]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function update_section()
|
||||
{
|
||||
try {
|
||||
$bodyData = $this->request->getPost();
|
||||
$wikiSectionId = $bodyData['wiki_section_id'];
|
||||
$roles = $bodyData['roles'];
|
||||
$this->wikiSectionModel->update($wikiSectionId, [
|
||||
"name" => $bodyData['name'],
|
||||
"icon" => $bodyData['icon']
|
||||
]);
|
||||
$this->wikiSectionRoleModel->where('wiki_section_id',$wikiSectionId)->delete();
|
||||
if(count($roles) > 0){
|
||||
foreach ($roles as $key => $role) {
|
||||
$this->wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId , 'role' => $role]);
|
||||
}
|
||||
}
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_edit_success')]);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
public function delete_section(int $section_id)
|
||||
{
|
||||
try{
|
||||
$this->wikiSectionModel->delete($section_id);
|
||||
return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_delete_success')]);
|
||||
}catch(Throwable $th){
|
||||
return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,11 @@ class WikiSectionsMigration extends Migration
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'null'=> true,
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
@ -22,11 +27,6 @@ class WikiSectionsMigration extends Migration
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
],
|
||||
'role' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
'default' => 'admin'
|
||||
],
|
||||
'icon' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class WikiSectionRolesMigration extends Migration
|
||||
{
|
||||
protected array $COLUMNS = [
|
||||
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'wiki_section_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
'role' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
'default' => 'admin'
|
||||
],
|
||||
|
||||
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField($this->COLUMNS);
|
||||
$currenttime = new RawSql('CURRENT_TIMESTAMP');
|
||||
$this->forge->addField([
|
||||
'created_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'default' => $currenttime,
|
||||
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'TIMESTAMP',
|
||||
'null' => true,
|
||||
|
||||
],
|
||||
]);
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('wiki_section_id','wiki_sections','id');
|
||||
$this->forge->createTable("wiki_section_roles");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable("wiki_section_roles");
|
||||
}
|
||||
}
|
||||
@ -4,102 +4,162 @@ namespace App\Database\Seeds;
|
||||
|
||||
use App\Models\Configuracion\ConfigVariableModel;
|
||||
use App\Models\Wiki\WikiSectionModel;
|
||||
use App\Models\Wiki\WikiSectionRoleModel;
|
||||
use CodeIgniter\Database\Seeder;
|
||||
|
||||
class WikiSectionSeeder extends Seeder
|
||||
{
|
||||
protected array $dataAdmin = [
|
||||
[
|
||||
"name" => 'Introducción',
|
||||
"slug" => 'intro-admin',
|
||||
"icon" => 'ti ti-home-2'
|
||||
[
|
||||
"name" => 'Introducción',
|
||||
"slug" => 'intro-admin',
|
||||
"icon" => 'ti ti-home-2',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Presupuesto',
|
||||
"slug" => 'presupuesto-admin',
|
||||
"icon" => 'ti ti-currency-dollar'
|
||||
],
|
||||
[
|
||||
"name" => 'Presupuesto',
|
||||
"slug" => 'presupuesto-admin',
|
||||
"icon" => 'ti ti-currency-dollar',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
],
|
||||
[
|
||||
"name" => 'Pedidos',
|
||||
"slug" => 'pedidos-admin',
|
||||
"icon" => 'ti ti-file-description',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Pedidos',
|
||||
"slug" => 'pedidos-admin',
|
||||
"icon" => 'ti ti-file-description'
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Facturación',
|
||||
"slug" => 'facturacion-admin',
|
||||
"icon" => 'ti ti-file-dollar',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Facturación',
|
||||
"slug" => 'facturacion-admin',
|
||||
"icon" => 'ti ti-file-dollar'
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Logística',
|
||||
"slug" => 'logistica-admin',
|
||||
"icon" => 'ti ti-truck',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Logística',
|
||||
"slug" => 'logistica-admin',
|
||||
"icon" => 'ti ti-truck'
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Tarifas',
|
||||
"slug" => 'tarifas-admin',
|
||||
"icon" => 'ti ti-receipt',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Tarifas',
|
||||
"slug" => 'tarifas-admin',
|
||||
"icon" => 'ti ti-receipt'
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Configuración',
|
||||
"slug" => 'config-admin',
|
||||
"icon" => 'ti ti-adjustments-horizontal',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Configuración',
|
||||
"slug" => 'config-admin',
|
||||
"icon" => 'ti ti-adjustments-horizontal'
|
||||
|
||||
],
|
||||
[
|
||||
"name" => 'Mensajería',
|
||||
"slug" => 'messages-admin',
|
||||
"icon" => 'ti ti-message',
|
||||
"roles" => [
|
||||
"admin",
|
||||
],
|
||||
[
|
||||
"name" => 'Mensajería',
|
||||
"slug" => 'messages-admin',
|
||||
"icon" => 'ti ti-message'
|
||||
|
||||
]
|
||||
]
|
||||
];
|
||||
protected array $dataCliente = [
|
||||
[
|
||||
"name" => 'Introducción',
|
||||
"slug" => 'intro-cliente',
|
||||
"icon" => 'ti ti-home-2',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Presupuesto(Cliente)',
|
||||
"slug" => 'presupuesto-cliente',
|
||||
"role" => 'cliente',
|
||||
"icon" => 'ti ti-currency-dollar',
|
||||
"role" => 'cliente',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Pedidos(Cliente)',
|
||||
"slug" => 'pedidos-cliente',
|
||||
"icon" => 'ti ti-file-description',
|
||||
"role" => 'cliente',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Facturación (Cliente)',
|
||||
"slug" => 'facturacion-cliente',
|
||||
"icon" => 'ti ti-file-dollar',
|
||||
"role" => 'cliente',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Tarifas (Cliente)',
|
||||
"slug" => 'tarifas-cliente',
|
||||
"icon" => 'ti ti-receipt',
|
||||
"role" => 'cliente',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => 'Mensajería (Cliente)',
|
||||
"slug" => 'messages-cliente',
|
||||
"icon" => 'ti ti-message',
|
||||
"role" => 'cliente',
|
||||
"roles" => [
|
||||
"cliente-admin",
|
||||
"cliente-editor",
|
||||
]
|
||||
]
|
||||
];
|
||||
];
|
||||
public function run()
|
||||
{
|
||||
|
||||
$wikiSectionModel = model(WikiSectionModel::class);
|
||||
$wikiSectionRoleModel = model(WikiSectionRoleModel::class);
|
||||
$section_order = 0;
|
||||
foreach ($this->dataAdmin as $key => $row) {
|
||||
# code...
|
||||
$wikiSectionModel->insert($row);
|
||||
$row['order'] = $section_order;
|
||||
$wikiSectionId = $wikiSectionModel->insert($row);
|
||||
$section_order++;
|
||||
foreach ($row['roles'] as $key => $role) {
|
||||
$wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId,"role" => $role]);
|
||||
|
||||
}
|
||||
}
|
||||
foreach ($this->dataCliente as $key => $row) {
|
||||
# code...
|
||||
$wikiSectionModel->insert($row);
|
||||
$row['order'] = $section_order;
|
||||
$wikiSectionId = $wikiSectionModel->insert($row);
|
||||
$section_order++;
|
||||
foreach ($row['roles'] as $key => $role) {
|
||||
$wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId,"role" => $role]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ namespace App\Entities\Wiki;
|
||||
|
||||
use App\Models\Wiki\WikiContentModel;
|
||||
use App\Models\Wiki\WikiPageModel;
|
||||
use App\Models\Wiki\WikiSectionRoleModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiSectionEntity extends Entity
|
||||
@ -11,6 +12,7 @@ class WikiSectionEntity extends Entity
|
||||
"name" => null,
|
||||
"slug" => null,
|
||||
"role" => null,
|
||||
"order" => null,
|
||||
"icon" => null,
|
||||
"parent_id" => null
|
||||
];
|
||||
@ -19,6 +21,7 @@ class WikiSectionEntity extends Entity
|
||||
"slug" => "string",
|
||||
"role" => "string",
|
||||
"icon" => "string",
|
||||
"order" => "int",
|
||||
"parent_id" => "int"
|
||||
];
|
||||
|
||||
@ -34,10 +37,25 @@ class WikiSectionEntity extends Entity
|
||||
$this->attributes['contents'] = $this->content($locale);
|
||||
return $this;
|
||||
}
|
||||
public function withRoles(): self
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$this->attributes['roles'] = $this->roles();
|
||||
return $this;
|
||||
}
|
||||
public function withRolesArray(): self
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$this->attributes['roles_array'] = $this->roles_array();
|
||||
return $this;
|
||||
}
|
||||
public function withAll(string $locale = "es") : self
|
||||
{
|
||||
$this->withPage();
|
||||
$this->withContents($locale);
|
||||
$this->withRoles();
|
||||
$this->withRolesArray();
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
@ -46,6 +64,19 @@ class WikiSectionEntity extends Entity
|
||||
$m = model(WikiPageModel::class);
|
||||
return $m->where('section_id',$this->attributes['id'])->first();
|
||||
}
|
||||
public function roles_array(): ?array
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$section_roles = $m->where('wiki_section_id',$this->attributes['id'])->findAll();
|
||||
$roles = array_map(fn($r) => $r->role,$section_roles);
|
||||
return $roles;
|
||||
}
|
||||
public function roles(): ?array
|
||||
{
|
||||
$m = model(WikiSectionRoleModel::class);
|
||||
$section_roles = $m->where('wiki_section_id',$this->attributes['id'])->findAll();
|
||||
return $section_roles;
|
||||
}
|
||||
public function content(string $locale = "es"): ?WikiContentEntity
|
||||
{
|
||||
$page = $this->page();
|
||||
|
||||
28
ci4/app/Entities/Wiki/WikiSectionRoleEntity.php
Normal file
28
ci4/app/Entities/Wiki/WikiSectionRoleEntity.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace App\Entities\Wiki;
|
||||
|
||||
use App\Models\Wiki\WikiContentModel;
|
||||
use App\Models\Wiki\WikiPageModel;
|
||||
use App\Models\Wiki\WikiSectionModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class WikiSectionRoleEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"wiki_section_id" => null,
|
||||
"role" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"wiki_section_id" => "int",
|
||||
"role" => "string",
|
||||
];
|
||||
|
||||
public function page(): ?WikiSectionEntity
|
||||
{
|
||||
$m = model(WikiSectionModel::class);
|
||||
return $m->where('id',$this->attributes['section_id'])->first();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,23 +1,44 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'intro' => "Introduction",
|
||||
'presupuesto-cliente' => "Cliente budget",
|
||||
'presupuesto-administrador' => "Admin budget",
|
||||
'pedidos' => "Orders",
|
||||
'facturacion' => "Invoice",
|
||||
'logistica' => "Logistic",
|
||||
'tarifas' => "Tariff",
|
||||
'config' => "Configuration",
|
||||
'messages' => "Messages",
|
||||
'help' => "Help",
|
||||
'intro-admin' => "Introduction",
|
||||
'presupuesto-cliente' => "Client budget",
|
||||
'presupuesto-admin' => "Admin budget",
|
||||
'pedidos-cliente' => "Orders",
|
||||
'pedidos-admin' => "Orders",
|
||||
'facturacion-admin' => "Invoice",
|
||||
'facturacion-cliente' => "Invoice (Client)",
|
||||
'logistica-admin' => "Logistic",
|
||||
'tarifas-admin' => "Tariff",
|
||||
'tarifas-cliente' => "Tariff (Client)",
|
||||
'config-admin' => "Configuration",
|
||||
'messages-admin' => "Messages",
|
||||
'messages-cliente' => "Messages (Client)",
|
||||
'save' => "Save",
|
||||
'release' => "Release",
|
||||
'preview' => "Preview",
|
||||
'edit' => "Edit",
|
||||
'new_section' => "New section",
|
||||
'edit_section' => "Edit section",
|
||||
'header-placeholder' => "Start writing a header ...",
|
||||
'errors' => [
|
||||
'publish_before_save' => "You have to save before publish the content"
|
||||
],
|
||||
'alt' => [
|
||||
"sort" => "Drag to set the section order"
|
||||
],
|
||||
'order_success' => 'Order updated',
|
||||
'order_error' => 'An error has ocurred',
|
||||
'published' => 'Released',
|
||||
'not_published' => 'Not released'
|
||||
'not_published' => 'Not released',
|
||||
'section_new_success' => 'Section created successfully',
|
||||
'section_edit_success' => 'Section updated successfully',
|
||||
'need_reload' => 'You need to refresh the page after creating/updating a section to see the changes.',
|
||||
'file_dont_exist' => "File doesn't exist",
|
||||
'need_editor_to_save' => 'Need to be in edit mode to save the content.',
|
||||
'no_content' => 'Page is empty',
|
||||
'dropdown_roles' => 'Roles that can see this section',
|
||||
|
||||
|
||||
];
|
||||
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'help' => "Ayuda",
|
||||
'intro-admin' => "Introducción",
|
||||
'intro-cliente' => "Introducción",
|
||||
'presupuesto-cliente' => "Presupuesto (Cliente)",
|
||||
@ -22,6 +23,7 @@ return [
|
||||
'name' => "Nombre sección",
|
||||
'icon' => "Icono sección",
|
||||
'section_placeholder' => "Introduce el nombre de la sección",
|
||||
'section_order' => "Orden",
|
||||
'section_icon_placeholder' => "Introduce el nombre de la sección",
|
||||
'edit_section' => "Editar sección",
|
||||
'new_section' => "Nueva sección",
|
||||
@ -29,6 +31,20 @@ return [
|
||||
'errors' => [
|
||||
'publish_before_save' => "Es necesario guardar antes de publicar"
|
||||
],
|
||||
'alt' => [
|
||||
"sort" => "Arrastra para establecer el orden de la sección"
|
||||
],
|
||||
'order_success' => 'Orden actualizado correctamente',
|
||||
'order_error' => 'Ha ocurriendo un error al ordenar',
|
||||
'published' => 'Publicado',
|
||||
'not_published' => 'Sin publicar',
|
||||
'section_new_success' => 'Sección creada correctamente',
|
||||
'section_edit_success' => 'Sección actualizada correctamente',
|
||||
'need_reload' => 'Es necesario recargar la página para ver la nueva sección creada o editada.',
|
||||
'file_dont_exist' => 'El fichero no existe',
|
||||
'need_editor_to_save' => 'Tienes que estar en modo editar para guardar.',
|
||||
'no_content' => 'No hay contenido en la página',
|
||||
'dropdown_roles' => 'Roles que pueden ver la sección',
|
||||
|
||||
|
||||
];
|
||||
|
||||
@ -16,8 +16,8 @@ class WikiSectionModel extends Model
|
||||
protected $allowedFields = [
|
||||
"name",
|
||||
"slug",
|
||||
"role",
|
||||
"icon",
|
||||
"order",
|
||||
"parent_id"
|
||||
];
|
||||
|
||||
@ -58,6 +58,6 @@ class WikiSectionModel extends Model
|
||||
*/
|
||||
public function sections() : array
|
||||
{
|
||||
return $this->findAll();
|
||||
return $this->orderBy('order','asc')->findAll();
|
||||
}
|
||||
}
|
||||
|
||||
52
ci4/app/Models/Wiki/WikiSectionRoleModel.php
Normal file
52
ci4/app/Models/Wiki/WikiSectionRoleModel.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Entities\Wiki\WikiSectionRoleEntity;
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class WikiSectionRoleModel extends Model
|
||||
{
|
||||
protected $table = 'wiki_section_roles';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = WikiSectionRoleEntity::class;
|
||||
protected $useSoftDeletes = false;
|
||||
protected $protectFields = true;
|
||||
protected $allowedFields = [
|
||||
"wiki_section_id",
|
||||
"role"
|
||||
];
|
||||
|
||||
protected bool $allowEmptyInserts = false;
|
||||
protected bool $updateOnlyChanged = true;
|
||||
|
||||
protected array $casts = [];
|
||||
protected array $castHandlers = [];
|
||||
|
||||
// Dates
|
||||
protected $useTimestamps = true;
|
||||
protected $dateFormat = 'datetime';
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
protected $deletedField = 'deleted_at';
|
||||
|
||||
// Validation
|
||||
protected $validationRules = [];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
protected $cleanValidationRules = true;
|
||||
|
||||
// Callbacks
|
||||
protected $allowCallbacks = true;
|
||||
protected $beforeInsert = [];
|
||||
protected $afterInsert = [];
|
||||
protected $beforeUpdate = [];
|
||||
protected $afterUpdate = [];
|
||||
protected $beforeFind = [];
|
||||
protected $afterFind = [];
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
|
||||
}
|
||||
@ -3,36 +3,47 @@
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel1"><?= lang('Wiki.new_section') ?></h5>
|
||||
<h5 class="modal-title d-none" id="modalTitleNew"><?= lang('Wiki.new_section') ?></h5>
|
||||
<h5 class="modal-title d-none" id="modalTitleEdit"><?= lang('Wiki.edit_section') ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<?= lang('Wiki.need_reload') ?>
|
||||
</div>
|
||||
<form id="formSection">
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-12 mb-2">
|
||||
<label for="section-name" class="form-label"><?= lang('Wiki.name') ?></label>
|
||||
<input type="text" id="section-name" name="title" placeholder="<?= lang('Wiki.section_placeholder') ?>" name="name" class="form-control" required />
|
||||
<input type="text" id="section-name" name="name" placeholder="<?= lang('Wiki.section_placeholder') ?>" class="form-control" required />
|
||||
</div>
|
||||
<div class="col-12 mb-2">
|
||||
<div class="mb-3">
|
||||
<label for="section-icon" class="form-label"><?= lang('Wiki.icon') ?></label>
|
||||
<input type="text" id="section-icon" name="icon" placeholder="<?= lang('Wiki.section_icon_placeholder') ?>" name="name" class="form-control" required />
|
||||
<select id="section-icon" class="select2-icons form-select">
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="section-roles" class="form-label"><?= lang('Wiki.roles') ?></label>
|
||||
<select id="section-roles" class="select2-icons form-select" name="roles[]" multiple>
|
||||
<?php
|
||||
foreach(config('AuthGroups')->groups as $key => $value):?>
|
||||
<option value="<?=$key?>"><?=isset($value['title']) ? $value['title'] : $key?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal"><?= lang('App.global_come_back') ?></button>
|
||||
<?php if (auth()->user()->inGroup('admin')) { ?>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal"><?= lang('App.global_come_back') ?></button>
|
||||
<button type="button" id="submit-new-section" class="btn btn-primary d-none"><?= lang('App.global_save') ?></button>
|
||||
<button type="button" id="submit-update-section" class="btn btn-primary d-none"><?= lang('App.global_save') ?></button>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -346,6 +346,7 @@ $picture = "/assets/img/default-user.png";
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/popper/popper.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/jquery/jquery.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/bootstrap.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/flatpickr/flatpickr.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
<?php if(auth()->user()->inGroup('admin')):?>
|
||||
<a href="<?= route_to('showWikiPage','intro-admin') ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons ti ti-books"></i>
|
||||
<?= lang("Wiki") ?>
|
||||
<?= lang("Wiki.help") ?>
|
||||
</a>
|
||||
<?php endif;?>
|
||||
<?php if(auth()->user()->inGroup('cliente-editor')):?>
|
||||
<a href="<?= route_to('showWikiPage','presupuesto-cliente') ?>" class="menu-link">
|
||||
<a href="<?= route_to('showWikiPage','intro-cliente') ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons ti ti-books"></i>
|
||||
<?= lang("Wiki") ?>
|
||||
<?= lang("Wiki.help") ?>
|
||||
</a>
|
||||
<?php endif;?>
|
||||
</li>
|
||||
@ -105,17 +105,25 @@ $picture = "/assets/img/default-user.png";
|
||||
|
||||
<div class="menu-inner-shadow"></div>
|
||||
|
||||
<ul class="menu-inner py-1">
|
||||
<ul class="menu-inner py-1 list-group list-group-flush" id="menu-inner-list">
|
||||
|
||||
<!-- Iterate throught sections -->
|
||||
|
||||
<?php foreach ($wiki_sections as $key => $value) : ?>
|
||||
<?php if (auth()->user()->inGroup($value->role) || auth()->user()->inGroup('admin')): ?>
|
||||
<li class="menu-item <?= $value->slug == $slug ? 'active' : "" ?>">
|
||||
<?php if (auth()->user()->inGroup(...$value->roles_array()) || auth()->user()->inGroup('admin')): ?>
|
||||
|
||||
<li class="menu-item <?= ($value->slug == $slug) ? "active" : "" ?>" data-id="<?= $value->id ?>">
|
||||
<!-- Check if user can view the section link -->
|
||||
<a href="<?= site_url("wiki/view/" . $value->slug) ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons <?= $value->icon ?>"></i>
|
||||
<?= lang("Wiki." . $value->slug) ?>
|
||||
</a>
|
||||
<span class="d-flex justify-content-between align-items-center">
|
||||
<a href="<?= site_url("wiki/view/" . $value->slug) ?>" class="menu-link">
|
||||
<i class="menu-icon tf-icons <?= $value->icon ?>"></i>
|
||||
<?= lang("Wiki." . $value->slug) ?>
|
||||
</a>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<i class="drag-handle cursor-grab icon-base ti ti-arrows-sort align-text-bottom me-2" title="<?= lang('Wiki.alt.sort') ?>"></i>
|
||||
<?php endif; ?>
|
||||
|
||||
</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
@ -280,6 +288,7 @@ $picture = "/assets/img/default-user.png";
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/hammer/hammer.js') ?>"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/menu.js') ?>"></script>
|
||||
|
||||
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/layout.js') ?>"></script>
|
||||
<!-- Helpers -->
|
||||
<script src="<?= site_url('themes/vuexy/vendor/js/helpers.js') ?>"></script>
|
||||
@ -291,6 +300,10 @@ $picture = "/assets/img/default-user.png";
|
||||
<?= $this->renderSection('additionalExternalJs') ?>
|
||||
|
||||
<script src="<?= site_url('themes/vuexy/js/main.js') ?>"></script>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<script type="module" src="<?= site_url('assets/js/safekat/pages/wiki/menuSortable.js') ?>"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?= sweetAlert() ?>
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ use CodeIgniter\I18n\Time;
|
||||
<div class="card card-info">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-md-6 d-flex flex-row flex-wrap justify-content-start align-items-center pb-2 gap-2">
|
||||
<div class="col-md-10 col-xs-12 col-sm-12 d-flex flex-row flex-wrap justify-content-start align-items-center pb-2 gap-2">
|
||||
<?php if ($section->content()?->published_data): ?>
|
||||
<span class="badge badge-center rounded-pill text-bg-success"><i class="ti ti-check"></i></span>
|
||||
<strong><?= lang('Wiki.published') ?></strong>
|
||||
@ -28,16 +28,38 @@ use CodeIgniter\I18n\Time;
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-md-6 d-flex flex-row flex-wrap justify-content-end align-items-stretch pb-2 gap-2">
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<button type="button" class="btn btn-success btn-xs col-xs-12 " id="new-section"><i class="icon-base ti ti-plus icon-xs me-2"></i><?= lang('Wiki.new_section') ?></button>
|
||||
<button type="button" class="btn btn-warning btn-xs col-auto " id="edit-section"><i class="icon-base ti ti-pencil icon-xs me-2"></i><?= lang('Wiki.edit_section') ?></button>
|
||||
<button type="button" class="btn btn-primary btn-xs col-auto " id="save-editor"><i class="icon-base ti ti-device-floppy icon-xs me-2"></i><?= lang('App.global_save') ?></button>
|
||||
<button type="button" class="btn btn-danger btn-xs col-auto " id="release-editor"><i class="icon-base ti ti-upload icon-xs me-2"></i>Publicar</button>
|
||||
<button type="button" class="btn btn-secondary btn-xs d-none col-auto " id="preview-editor"><i class="icon-base ti ti-eye icon-xs me-2"></i>Vista previa</button>
|
||||
<button type="button" class="btn btn-warning btn-xs col-auto " id="edit-editor"><i class="icon-base ti ti-pencil icon-xs me-2"></i>Editar</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (auth()->user()->inGroup('admin')): ?>
|
||||
<div class="col-md-2 d-flex flex-row flex-wrap justify-content-end align-items-stretch pb-2 gap-2">
|
||||
<div class="btn-sm-group">
|
||||
<button type="button" class="btn btn-sm btn-primary btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
|
||||
<i class="icon-base ti ti-dots-vertical"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><button type="button" class="dropdown-item btn btn-success btn-xs col-xs-12 " id="new-section"><i class="icon-base ti ti-plus icon-xs me-2"></i><?= lang('Wiki.new_section') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-warning btn-xs col-auto " id="edit-section"><i class="icon-base ti ti-pencil icon-xs me-2"></i><?= lang('Wiki.edit_section') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-danger btn-xs col-auto " id="delete-section"><i class="icon-base ti ti-trash icon-xs me-2"></i><?= lang('Wiki.delete_section') ?></button></li>
|
||||
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
<li><button type="button" class="dropdown-item btn btn-primary btn-xs col-auto " id="save-editor"><i class="icon-base ti ti-device-floppy icon-xs me-2"></i><?= lang('App.global_save') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-danger btn-xs col-auto " id="release-editor"><i class="icon-base ti ti-upload icon-xs me-2"></i><?= lang('Wiki.release') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-secondary btn-xs d-none col-auto " id="preview-editor"><i class="icon-base ti ti-eye icon-xs me-2"></i><?= lang('Wiki.preview') ?></button></li>
|
||||
<li><button type="button" class="dropdown-item btn btn-warning btn-xs col-auto " id="edit-editor"><i class="icon-base ti ti-pencil icon-xs me-2"></i><?= lang('Wiki.edit') ?></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="btn-sm-group">
|
||||
<button type="button" class="btn btn-sm btn-warning btn-icon rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown" title="<?=lang('Wiki.dropdown_roles')?>">
|
||||
<i class="icon-base ti ti-users"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<?php foreach ($section->roles() as $key => $roleEntity): ?>
|
||||
<li><span class="dropdown-item badge bg-label-success"><?=config("AuthGroups")->groups[$roleEntity->role]["title"]?></span></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div><!--//.card-header -->
|
||||
|
||||
|
||||
@ -19,10 +19,10 @@ export const initAutonumeric = () => {
|
||||
new AutoNumeric(this, {
|
||||
digitGroupSeparator: ".",
|
||||
decimalCharacter: ",",
|
||||
allowDecimalPadding : 'floats',
|
||||
allowDecimalPadding: 'floats',
|
||||
decimalPlaces: 2,
|
||||
unformatOnSubmit: true,
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -32,10 +32,10 @@ export const initAutonumeric = () => {
|
||||
new AutoNumeric(this, {
|
||||
digitGroupSeparator: ".",
|
||||
decimalCharacter: ",",
|
||||
allowDecimalPadding : 'floats',
|
||||
allowDecimalPadding: 'floats',
|
||||
decimalPlaces: $(this).data('decimal-places'),
|
||||
unformatOnSubmit: true,
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -49,7 +49,7 @@ export const initAutonumeric = () => {
|
||||
// allowDecimalPadding : 'floats',
|
||||
// decimalPlaces: 2,
|
||||
// unformatOnSubmit: true,
|
||||
|
||||
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
@ -85,4 +85,26 @@ export const initAutonumeric = () => {
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
export const getTablerIconClassName = () => {
|
||||
const classNames = [];
|
||||
for (const sheet of document.styleSheets) {
|
||||
try {
|
||||
if (sheet.cssRules) {
|
||||
for (const rule of sheet.cssRules) {
|
||||
if (rule.selectorText && rule.selectorText.startsWith(".ti-")) {
|
||||
let className = rule.selectorText.split(" ")[0].replace(".", "");
|
||||
className = className.split("::")[0]
|
||||
className = className.split(":")[0]
|
||||
classNames.push(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Cannot access stylesheet:", sheet.href);
|
||||
}
|
||||
}
|
||||
return classNames.reverse();
|
||||
|
||||
}
|
||||
@ -13,7 +13,6 @@ import EditorJS from '../../../../../themes/vuexy/js/editorjs.mjs';
|
||||
import TranslationHelper from '../../common/TranslationHelper.js';
|
||||
import { alertConfirmAction, alertError, alertSuccess, alertWarning } from '../alerts/sweetAlert.js';
|
||||
|
||||
import Modal from '../modal.js'
|
||||
import WikiSectionForm from '../forms/WikiSectionForm.js'
|
||||
|
||||
|
||||
@ -22,29 +21,19 @@ class WikiEditor extends TranslationHelper{
|
||||
constructor() {
|
||||
super();
|
||||
this.sectionId = $("#wiki-section-id").val();
|
||||
this.modalSection = $("#modalSection")
|
||||
this.newSectionBtn = $("#new-section")
|
||||
this.editSectionBtn = $("#edit-section")
|
||||
this.modal = new Modal(this.modalSection)
|
||||
|
||||
this.wikiFormSection = new WikiSectionForm()
|
||||
this.wikiFormSection.setId(this.sectionId)
|
||||
}
|
||||
async initEditor()
|
||||
{
|
||||
this.wikiFormSection
|
||||
this.newSectionBtn.on('click',() => {
|
||||
this.modal.toggle()
|
||||
this.wikiFormSection.initPost()
|
||||
})
|
||||
this.editSectionBtn.on('click',() => {
|
||||
this.modal.toggle()
|
||||
this.wikiFormSection.initUpdate()
|
||||
})
|
||||
this.wikiFormSection.init()
|
||||
|
||||
await this.get_translations("Wiki")
|
||||
this.editor = new EditorJS({
|
||||
holder: 'editorjs',
|
||||
i18n: this.locale == "es" ? es : null,
|
||||
autofocus: true,
|
||||
placeholder: this.get_lang('header-placeholder'),
|
||||
readOnly: true,
|
||||
tunes: {
|
||||
alignment: {
|
||||
@ -121,6 +110,7 @@ class WikiEditor extends TranslationHelper{
|
||||
async initViewOnly()
|
||||
{
|
||||
try {
|
||||
await this.initEditor()
|
||||
await this.editor.isReady;
|
||||
this.handleGetDataPublished();
|
||||
} catch (reason) {
|
||||
@ -135,7 +125,7 @@ class WikiEditor extends TranslationHelper{
|
||||
/** Do anything you need after editor initialization */
|
||||
$('#save-editor').on('click', () => {
|
||||
this.editor.save().then(outputData => {
|
||||
alertConfirmAction('Guardar contenido').then(result => {
|
||||
alertConfirmAction(this.get_lang('save_content')).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
this.handleSaveContent(outputData)
|
||||
}
|
||||
@ -153,7 +143,7 @@ class WikiEditor extends TranslationHelper{
|
||||
console.log(result)
|
||||
});
|
||||
}).catch((error) => {
|
||||
alertError('Tienes que estar en modo editar para publicar').fire()
|
||||
alertError(this.get_lang('need_editor_to_save')).fire()
|
||||
})
|
||||
|
||||
})
|
||||
@ -187,7 +177,7 @@ class WikiEditor extends TranslationHelper{
|
||||
ajax.get()
|
||||
}
|
||||
handleGetDataSuccess(response) {
|
||||
if (response.data.contents) {
|
||||
if (response.data.contents?.editor_data) {
|
||||
alertSuccess(response.message).fire()
|
||||
this.renderContent(response.data.contents.editor_data)
|
||||
} else {
|
||||
@ -202,16 +192,16 @@ class WikiEditor extends TranslationHelper{
|
||||
const ajax = new Ajax(`/wiki/section/${this.sectionId}`,
|
||||
null,
|
||||
null,
|
||||
this.handleGetDataSuccess.bind(this),
|
||||
this.handleGetDataError.bind(this))
|
||||
this.handleGetDataPublishedSuccess.bind(this),
|
||||
this.handleGetDataPublishedError.bind(this))
|
||||
ajax.get()
|
||||
}
|
||||
handleGetDataPublishedSuccess(response) {
|
||||
if (response.data.contents) {
|
||||
if (response.data.contents?.published_data) {
|
||||
alertSuccess(response.message).fire()
|
||||
this.renderContent(response.data.contents.published_data)
|
||||
} else {
|
||||
alertWarning('No hay contenido').fire()
|
||||
alertWarning(this.get_lang('no_content')).fire()
|
||||
}
|
||||
}
|
||||
handleGetDataPublishedError(error) {
|
||||
|
||||
@ -1,41 +1,73 @@
|
||||
import Ajax from "../ajax.js";
|
||||
import { alertError, alertSuccess } from "../alerts/sweetAlert.js";
|
||||
|
||||
class WikiSectionForm
|
||||
{
|
||||
import { alertConfirmAction, alertConfirmationDelete, alertError, alertSuccess } from "../alerts/sweetAlert.js";
|
||||
import Modal from "../modal.js"
|
||||
import { getTablerIconClassName } from "../../common/common.js";
|
||||
class WikiSectionForm {
|
||||
constructor() {
|
||||
this.item = $("#formSection")
|
||||
this.btnNew = $("#submit-new-section")
|
||||
this.btnUpdate = $("#submit-update-section")
|
||||
this.btnDelete = $("#delete-section")
|
||||
this.name = this.item.find('#section-name')
|
||||
this.icon = this.item.find('#section-icon')
|
||||
this.roles = this.item.find('#section-roles').select2({
|
||||
dropdownParent: this.item.parent()
|
||||
})
|
||||
|
||||
|
||||
this.newSectionBtn = $("#new-section")
|
||||
this.editSectionBtn = $("#edit-section")
|
||||
this.modalSection = $("#modalSection")
|
||||
this.modal = new Modal(this.modalSection)
|
||||
this.icons = getTablerIconClassName().map((e, index) => {
|
||||
return { 'text': e, 'id': `ti ${e}` }
|
||||
})
|
||||
}
|
||||
renderIcon(option) {
|
||||
var icon = `<i class="ti ${option.text}"></i> ${option.text}`;
|
||||
return icon;
|
||||
}
|
||||
init() {
|
||||
this.icon.wrap('<div class="position-relative"></div>').select2({
|
||||
data: this.icons,
|
||||
dropdownParent: this.icon.parent(),
|
||||
templateResult: this.renderIcon,
|
||||
templateSelection: this.renderIcon,
|
||||
escapeMarkup: function (m) { return m; }
|
||||
})
|
||||
this.icon.on('change', () => {
|
||||
console.log(this.icon.val())
|
||||
})
|
||||
this.btnNew.on('click', this.post.bind(this))
|
||||
this.btnUpdate.on('click', this.update.bind(this))
|
||||
this.btnDelete.on('click',this.deleteConfirm.bind(this))
|
||||
|
||||
initPost()
|
||||
{
|
||||
this.newSectionBtn.on('click', () => {
|
||||
this.initPost()
|
||||
})
|
||||
this.editSectionBtn.on('click', () => {
|
||||
this.initUpdate()
|
||||
})
|
||||
}
|
||||
setId(id) {
|
||||
this.sectionId = id
|
||||
}
|
||||
initPost() {
|
||||
this.showPost()
|
||||
this.btnNew.on('click',this.post.bind(this))
|
||||
this.btnUpdate.off('click')
|
||||
|
||||
}
|
||||
initUpdate()
|
||||
{
|
||||
this.showUpdate()
|
||||
this.btnUpdate.on('click',this.update.bind(this))
|
||||
this.btnNew.off('click')
|
||||
|
||||
}
|
||||
getFormData()
|
||||
{
|
||||
initUpdate() {
|
||||
this.showUpdate()
|
||||
|
||||
}
|
||||
getFormData() {
|
||||
return {
|
||||
name : this.name.val(),
|
||||
icon : this.icon.val()
|
||||
name: this.name.val(),
|
||||
icon: this.icon.val(),
|
||||
roles: this.roles.val()
|
||||
}
|
||||
}
|
||||
post(){
|
||||
|
||||
post() {
|
||||
|
||||
const ajax = new Ajax('/wiki/section',
|
||||
this.getFormData(),
|
||||
null,
|
||||
@ -45,30 +77,90 @@ class WikiSectionForm
|
||||
ajax.post()
|
||||
}
|
||||
|
||||
update(){
|
||||
update() {
|
||||
const ajax = new Ajax('/wiki/update/section',
|
||||
this.getFormData(),
|
||||
{
|
||||
wiki_section_id: this.sectionId,
|
||||
...this.getFormData()
|
||||
},
|
||||
null,
|
||||
this.success.bind(this),
|
||||
this.error.bind(this)
|
||||
)
|
||||
ajax.post()
|
||||
}
|
||||
success(response)
|
||||
{
|
||||
alertSuccess(response.message).fire()
|
||||
deleteConfirm() {
|
||||
alertConfirmAction('Eliminar sección').then(result => {
|
||||
if (result.isConfirmed) {
|
||||
this.delete()
|
||||
}
|
||||
console.log(result)
|
||||
});
|
||||
}
|
||||
error(error)
|
||||
{
|
||||
delete() {
|
||||
const ajax = new Ajax('/wiki/section/' + this.sectionId,
|
||||
null,
|
||||
null,
|
||||
this.success.bind(this),
|
||||
this.error.bind(this)
|
||||
)
|
||||
ajax.delete()
|
||||
}
|
||||
success(response) {
|
||||
alertSuccess(response.message).fire()
|
||||
this.modal.toggle()
|
||||
}
|
||||
error(error) {
|
||||
alertError(error?.message).fire()
|
||||
}
|
||||
showPost(){
|
||||
showPost() {
|
||||
this.empty()
|
||||
this.btnNew.removeClass('d-none')
|
||||
this.btnUpdate.addClass('d-none')
|
||||
$("#modalTitleNew").removeClass('d-none')
|
||||
$("#modalTitleEdit").addClass('d-none')
|
||||
this.modal.toggle()
|
||||
|
||||
|
||||
}
|
||||
showUpdate(){
|
||||
async showUpdate() {
|
||||
this.empty()
|
||||
const sectionData = await this.handleShowSection()
|
||||
if (sectionData) {
|
||||
console.log(sectionData)
|
||||
this.name.val(sectionData.data.name)
|
||||
this.icon.val(sectionData.data.icon).trigger('change')
|
||||
this.roles.val(sectionData.data.roles_array).trigger('change')
|
||||
}
|
||||
this.btnUpdate.removeClass('d-none')
|
||||
this.btnNew.addClass('d-none')
|
||||
$("#modalTitleNew").addClass('d-none')
|
||||
$("#modalTitleEdit").removeClass('d-none')
|
||||
this.modal.toggle()
|
||||
|
||||
|
||||
}
|
||||
handleShowSection() {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const ajax = new Ajax('/wiki/section/' + this.sectionId,
|
||||
null,
|
||||
null,
|
||||
(response) => {
|
||||
resolve(response)
|
||||
},
|
||||
(error) => {
|
||||
alertError(error.message).fire()
|
||||
resolve(false)
|
||||
}
|
||||
)
|
||||
ajax.get()
|
||||
})
|
||||
}
|
||||
empty() {
|
||||
this.name.val(null)
|
||||
this.icon.val("").trigger('change')
|
||||
this.roles.val("").trigger('change')
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
37
httpdocs/assets/js/safekat/components/listSortable.js
Normal file
37
httpdocs/assets/js/safekat/components/listSortable.js
Normal file
@ -0,0 +1,37 @@
|
||||
import "../../../../../themes/vuexy/vendor/libs/sortablejs/sortable.js"
|
||||
|
||||
|
||||
class ListSortable{
|
||||
constructor(listItem,config = {}) {
|
||||
|
||||
this.list = Sortable.create($(listItem)[0], {
|
||||
animation: 150,
|
||||
group: 'menuSorting',
|
||||
handle: '.drag-handle',
|
||||
direction : 'vertical',
|
||||
...config,
|
||||
});
|
||||
}
|
||||
getArray(){
|
||||
const list = this.list.toArray()
|
||||
return list
|
||||
}
|
||||
onChange(callback)
|
||||
{
|
||||
this.list.option('onChange',callback)
|
||||
}
|
||||
onMove(callback)
|
||||
{
|
||||
this.list.option('onMove',callback)
|
||||
}
|
||||
onEnd(callback)
|
||||
{
|
||||
this.list.option('onEnd',callback)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default ListSortable
|
||||
@ -9,6 +9,7 @@ class Modal{
|
||||
show(){
|
||||
this.item.modal('show');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Modal;
|
||||
@ -1,11 +1,12 @@
|
||||
import WikiEditor from "../../components/editorjs/WikiEditor.js"
|
||||
import Ajax from "../../components/ajax.js"
|
||||
|
||||
|
||||
$(async () => {
|
||||
try {
|
||||
|
||||
const editor = new WikiEditor()
|
||||
await editor.init()
|
||||
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
25
httpdocs/assets/js/safekat/pages/wiki/menuSortable.js
Normal file
25
httpdocs/assets/js/safekat/pages/wiki/menuSortable.js
Normal file
@ -0,0 +1,25 @@
|
||||
import Ajax from "../../components/ajax.js"
|
||||
import { alertError, alertSuccess } from "../../components/alerts/sweetAlert.js"
|
||||
import ListSortable from "../../components/listSortable.js"
|
||||
$(() => {
|
||||
|
||||
const menuSectionList = new ListSortable('#menu-inner-list')
|
||||
menuSectionList.onEnd(updateWikiSectionOrder)
|
||||
|
||||
})
|
||||
|
||||
const updateWikiSectionOrder = (evt) =>
|
||||
{
|
||||
let list = new ListSortable('#menu-inner-list')
|
||||
|
||||
const ajax = new Ajax('/wiki/section/update/order',
|
||||
{
|
||||
orders : list.getArray()
|
||||
},
|
||||
null,
|
||||
(response) => alertSuccess(response.message).fire(),
|
||||
(error) => alertError(error.message).fire(),
|
||||
)
|
||||
ajax.post();
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ $(async() => {
|
||||
|
||||
try {
|
||||
const editor = new WikiEditor()
|
||||
await editor.init()
|
||||
await editor.initViewOnly()
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user