This commit is contained in:
amazuecos
2025-02-22 20:56:06 +01:00
parent 339c979ded
commit f270b6dee8
27 changed files with 981 additions and 92 deletions

View File

@ -5,4 +5,13 @@ use CodeIgniter\Router\RouteCollection;
$routes->group('wiki', ['namespace' => 'App\Controllers\Wiki'], function ($routes) { $routes->group('wiki', ['namespace' => 'App\Controllers\Wiki'], function ($routes) {
$routes->get('','WikiController::index',["as" => "wikiIndex"]); $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('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"]);
}); });

View File

@ -3,12 +3,111 @@
namespace App\Controllers\Wiki; namespace App\Controllers\Wiki;
use App\Controllers\BaseController; use App\Controllers\BaseController;
use App\Models\Wiki\WikiContentModel;
use App\Models\Wiki\WikiFileModel;
use App\Models\Wiki\WikiPageModel;
use App\Models\Wiki\WikiSectionModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class WikiController extends BaseController class WikiController extends BaseController
{ {
protected WikiSectionModel $wikiSectionModel;
protected WikiContentModel $wikiContentModel;
protected WikiPageModel $wikiPageModel;
protected WikiFileModel $wikiFileModel;
protected string $locale;
protected array $viewData;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->wikiSectionModel = model(WikiSectionModel::class);
$this->wikiPageModel = model(WikiPageModel::class);
$this->wikiContentModel = model(WikiContentModel::class);
$this->wikiFileModel = model(WikiFileModel::class);
$sections = $this->wikiSectionModel->sections();
$this->locale = session()->get('lang');
$this->viewData['wiki_sections'] = $sections;
parent::initController($request, $response, $logger);
}
public function index() public function index()
{ {
return view('themes/vuexy/wiki/pages/home'); return view('themes/vuexy/wiki/pages/render', $this->viewData);
}
public function show_page(string $slug)
{
$section = $this->wikiSectionModel->where('slug', $slug)->first();
$this->viewData['slug'] = $slug;
$this->viewData['section'] = $section->withAll($this->locale);
return view('themes/vuexy/wiki/pages/render', $this->viewData);
}
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")]);
}
public function store_save_page(int $section_id)
{
$bodyData = $this->request->getPost();
$wikiSectionPage = $this->wikiSectionModel->find($section_id)->page();
if ($wikiSectionPage) {
$wikiPageId = $wikiSectionPage->id;
} else {
$wikiPageId = $this->wikiPageModel->insert(['section_id' => $section_id]);
}
$content = $this->wikiContentModel->where('locale', $this->locale)->where('page_id', $wikiPageId)->countAllResults();
if ($content > 0) {
$this->wikiContentModel->where('locale', $this->locale)->where('page_id', $wikiPageId)->delete();
}
$this->wikiContentModel->insert([
"locale" => $this->locale,
"page_id" => $wikiPageId,
"editor_data" => json_encode($bodyData)
]);
return $this->response->setJSON(["data" => [], "message" => lang("App.global_alert_save_success")]);
}
public function wiki_file_upload(int $section_id)
{
try {
$file = $this->request->getFile('image');
$section = $this->wikiSectionModel->find($section_id);
$content = $section->content();
$r = null;
$fullpath = null;
if ($file->isValid() && !$file->hasMoved()) {
$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
]]);
}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());
}
}
public function get_wiki_file(int $wiki_file_id)
{
$wikiFile = $this->wikiFileModel->find($wiki_file_id);
if ($wikiFile->path) {
$filePath = WRITEPATH . 'uploads/' . $wikiFile->path;
$mimeType = mime_content_type($filePath);
return $this->response
->setHeader('Content-Type', $mimeType)
->setHeader('Content-Length', filesize($filePath))
->setBody(file_get_contents($filePath));
} else {
return $this->response->setJSON(["message" => "Portada error", "error" => "No hay portada"])->setStatusCode(400);
}
} }
} }

View File

@ -0,0 +1,69 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class WikiSectionsMigration extends Migration
{
protected array $COLUMNS = [
'id' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true,
],
'name' => [
'type' => 'VARCHAR',
'constraint' => 255,
],
'slug' => [
'type' => 'VARCHAR',
'constraint' => 255,
],
'role' => [
'type' => 'VARCHAR',
'constraint' => 255,
'default' => 'admin'
],
'parent_section_id' => [
'type' => 'INT',
'unsigned' => true,
'null' => true,
],
];
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('parent_section_id','wiki_sections','id');
$this->forge->createTable("wiki_sections");
}
public function down()
{
$this->forge->dropTable("wiki_sections");
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class WikiPagesMigration extends Migration
{
protected array $COLUMNS = [
'id' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true,
],
'section_id' => [
'type' => 'INT',
'unsigned' => true,
],
];
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('section_id','wiki_sections','id');
$this->forge->createTable("wiki_pages");
}
public function down()
{
$this->forge->dropTable("wiki_pages");
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class WikiContentsMigration extends Migration
{
protected array $COLUMNS = [
'id' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true,
],
'locale' => [
'type' => 'VARCHAR',
'constraint' => 255,
'default' => 'es',
],
'page_id' => [
'type' => 'INT',
'unsigned' => true,
],
'editor_data' => [
'type' => 'LONGTEXT',
'null' => true,
],
'published_data' => [
'type' => 'LONGTEXT',
'null' => true,
],
];
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('page_id','wiki_pages','id');
$this->forge->createTable("wiki_contents");
}
public function down()
{
$this->forge->dropTable("wiki_contents");
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class WikiFilesMigration extends Migration
{
protected array $COLUMNS = [
'id' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true,
],
'content_id' => [
'type' => 'INT',
'unsigned' => true,
],
'path' => [
'type' => 'LONGTEXT',
'null' => true,
],
];
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('content_id','wiki_contents','id');
$this->forge->createTable("wiki_files");
}
public function down()
{
$this->forge->dropTable("wiki_files");
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Entities\Wiki;
use CodeIgniter\Entity\Entity;
class WikiContentEntity extends Entity
{
protected $attributes = [
"locale" => null,
"page_id" => null,
"editor_data" => null,
"published_data" => null,
];
protected $casts = [
"locale" => "string",
"page_id" => "int",
"editor_data" => "string",
"published_data" => "string",
];
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Entities\Wiki;
use CodeIgniter\Entity\Entity;
class WikiFileEntity extends Entity
{
protected $attributes = [
"content_id" => null,
"path" => null,
];
protected $casts = [
"content_id" => "int",
"path" => "string",
];
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Entities\Wiki;
use CodeIgniter\Entity\Entity;
class WikiPageEntity extends Entity
{
protected $attributes = [
"section_id" => null,
];
protected $casts = [
"section_id" => "int",
];
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Entities\Wiki;
use App\Models\Wiki\WikiContentModel;
use App\Models\Wiki\WikiPageModel;
use CodeIgniter\Entity\Entity;
class WikiSectionEntity extends Entity
{
protected $attributes = [
"name" => null,
"slug" => null,
"role" => null,
"parent_id" => null
];
protected $casts = [
"name" => "string",
"slug" => "string",
"role" => "string",
"parent_id" => "int"
];
public function withPage(): self
{
$this->attributes['pages'] = $this->page();
return $this;
}
public function withContents(string $locale = "es"): self
{
$m = model(WikiContentModel::class);
$this->attributes['contents'] = $this->content($locale);
return $this;
}
public function withAll(string $locale = "es") : self
{
$this->withPage();
$this->withContents($locale);
return $this;
}
public function page(): ?WikiPageEntity
{
$m = model(WikiPageModel::class);
return $m->where('section_id',$this->attributes['id'])->first();
}
public function content(string $locale = "es"): ?WikiContentEntity
{
$page = $this->page();
$content = null;
$m = model(WikiContentModel::class);
if($page){
$content = $m->where('page_id',$page->id)
->where('locale',$locale)
->first();
}
return $content;
}
}

View File

@ -19,6 +19,7 @@ return [
"global_come_back" => "Volver", "global_come_back" => "Volver",
"global_save" => "Guardar", "global_save" => "Guardar",
"global_alert_save_success" => "¡Guardado exitosamente!", "global_alert_save_success" => "¡Guardado exitosamente!",
"global_alert_fetch_success" => "Obtenido exitosamente!",
"global_alert_save_error" => "¡Error al guardar!", "global_alert_save_error" => "¡Error al guardar!",
"global_activate" => "Activar", "global_activate" => "Activar",
"global_disable" => "Desactivar", "global_disable" => "Desactivar",

View File

@ -0,0 +1,53 @@
<?php
namespace App\Models\Wiki;
use App\Entities\Wiki\WikiContentEntity;
use CodeIgniter\Model;
class WikiContentModel extends Model
{
protected $table = 'wiki_contents';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = WikiContentEntity::class;
protected $useSoftDeletes = true;
protected $protectFields = true;
protected $allowedFields = [
"locale",
"page_id",
"editor_data",
"published_data"
];
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 = [];
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Models\Wiki;
use App\Entities\Wiki\WikiFileEntity;
use CodeIgniter\Model;
class WikiFileModel extends Model
{
protected $table = 'wiki_files';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = WikiFileEntity::class;
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = [
"content_id",
"path"
];
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 = [];
}

View File

@ -0,0 +1,49 @@
<?php
namespace App\Models\Wiki;
use App\Entities\Wiki\WikiPageEntity;
use CodeIgniter\Model;
class WikiPageModel extends Model
{
protected $table = 'wiki_pages';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = WikiPageEntity::class;
protected $useSoftDeletes = true;
protected $protectFields = true;
protected $allowedFields = [
"section_id",
];
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 = [];
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Models\Wiki;
use App\Entities\Wiki\WikiSectionEntity;
use CodeIgniter\Model;
class WikiSectionModel extends Model
{
protected $table = 'wiki_sections';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = WikiSectionEntity::class;
protected $useSoftDeletes = true;
protected $protectFields = true;
protected $allowedFields = [
"name",
"slug",
"role",
"parent_id"
];
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 = [];
/**
* Get wiki sections
*
* @return array<WikiSectionEntity>
*/
public function sections() : array
{
return $this->where('role','admin')->findAll();
}
}

View File

@ -90,7 +90,38 @@ $picture = "/assets/img/default-user.png";
<!-- Layout wrapper --> <!-- Layout wrapper -->
<div class="layout-wrapper layout-content-navbar"> <div class="layout-wrapper layout-content-navbar">
<div class="layout-container"> <div class="layout-container">
<?php include "sidebar.php" ?> <aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
<div class="app-brand">
<a href="<?= site_url('home') ?>" class="app-brand-link">
<span class="app-brand-logo">
<img src="<?= site_url('themes/vuexy/img/safekat/logos/sk-logo.png') ?>" width="150px">
</span>
</a>
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto">
<i class="ti menu-toggle-icon d-none d-xl-block ti-sm align-middle"></i>
<i class="ti ti-x d-block d-xl-none ti-sm align-middle"></i>
</a>
</div>
<div class="menu-inner-shadow"></div>
<ul class="menu-inner py-1">
<li class="menu-item">
<!-- Iterate throught sections -->
<?php foreach ($wiki_sections as $key => $value) : ?>
<!-- Check if user can view the section link -->
<?php if (auth()->user()->inGroup($value->role)): ?>
<a href="<?= site_url("wiki/render/".$value->slug) ?>" class="menu-link">
<i class="menu-icon tf-icons ti ti-book"></i>
<?= $value->name ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</li>
</ul>
</aside>
<!-- Layout container --> <!-- Layout container -->
<div class="layout-page"> <div class="layout-page">
@ -236,7 +267,7 @@ $picture = "/assets/img/default-user.png";
<script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/libs/hammer/hammer.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/libs/hammer/hammer.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/js/menu.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> <script type="module" src="<?= site_url('assets/js/safekat/pages/layout.js') ?>"></script>
<!-- Helpers --> <!-- Helpers -->
<script src="<?= site_url('themes/vuexy/vendor/js/helpers.js') ?>"></script> <script src="<?= site_url('themes/vuexy/vendor/js/helpers.js') ?>"></script>

View File

@ -1,6 +1,7 @@
<?= $this->include('themes/_commonPartialsBs/select2bs5') ?> <?= $this->include('themes/_commonPartialsBs/select2bs5') ?>
<?= $this->include('themes/_commonPartialsBs/datatables') ?> <?= $this->include('themes/_commonPartialsBs/datatables') ?>
<?= $this->include('themes/_commonPartialsBs/_confirm2delete') ?> <?= $this->include('themes/_commonPartialsBs/_confirm2delete') ?>
<?= $this->include("themes/_commonPartialsBs/sweetalert") ?>
<?= $this->extend('themes/vuexy/wiki/layout') ?> <?= $this->extend('themes/vuexy/wiki/layout') ?>
<?= $this->section('content'); ?> <?= $this->section('content'); ?>
@ -13,7 +14,12 @@
</div><!--//.card-header --> </div><!--//.card-header -->
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<form action="POST" id="form-wiki">
<input type="hidden" name="slug" id="section-slug">
<input type="hidden" name="wiki_page_id" id="wiki-section-id" value="<?=$section->id?>">
<input type="hidden" name="wiki_page_id" id="wiki-page-id">
<input type="hidden" name="wiki_page_id" id="wiki-content-id">
</form>
<?php if (auth()->user()->inGroup('admin')): ?> <?php if (auth()->user()->inGroup('admin')): ?>
<div class="col-md-10"> <div class="col-md-10">
<div id="editorjs"></div> <div id="editorjs"></div>
@ -27,6 +33,7 @@
</div> </div>
</div> </div>
<?php else : ?> <?php else : ?>
<div class="col-md-12"> <div class="col-md-12">
<div id="editorjs"></div> <div id="editorjs"></div>
</div> </div>
@ -40,7 +47,15 @@
</div><!--//.card --> </div><!--//.card -->
</div><!--//.col --> </div><!--//.col -->
</div><!--//.row --> </div><!--//.row -->
<?= $this->section("additionalExternalJs") ?>
<script type="module" src="<?= site_url('assets/js/safekat/pages/wiki/home.js') ?>"></script>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('css') ?>
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.css') ?>" />
<?= $this->endSection() ?>
<?= $this->section("additionalExternalJs") ?>
<script src="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.js') ?>"></script>
<script type="module" src="<?= site_url('assets/js/safekat/pages/wiki/home.js') ?>"></script>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -17,17 +17,12 @@
<ul class="menu-inner py-1"> <ul class="menu-inner py-1">
<li class="menu-item"> <li class="menu-item">
<a href="javascript:void(0);" class="menu-link menu-toggle"> <?php foreach ($wiki_sections as $key => $value) :?>
<a href="<?= site_url("wiki/presupuesto")?>" class="menu-link menu-toggle">
<i class="menu-icon tf-icons ti ti-book"></i> <i class="menu-icon tf-icons ti ti-book"></i>
<?= lang("App.menu_presupuestos") ?> <?= lang("App.menu_presupuestos") ?>
</a> </a>
<ul class="menu-sub"> <?php endforeach;?>
<li class="menu-item">
<a href="<?= site_url("wiki/presupuesto") ?>" class="menu-link">
<?= lang("App.menu_presupuestos") ?>
</a>
</li>
</ul>
</li> </li>
</ul> </ul>

View File

@ -1,6 +1,5 @@
export const alertConfirmationDelete = (title, type = "primary") => { export const alertConfirmationDelete = (title, type = "primary") => {
return Swal.fire({ return Swal.fire({
title: '¿Está seguro?', title: '¿Está seguro?',
@ -63,4 +62,54 @@ export const toastPresupuestoSummary = (value, target = 'body') => {
timerProgressBar: false, timerProgressBar: false,
stopKeydownPropagation: false, stopKeydownPropagation: false,
}) })
}
export const alertSuccess = (value, target = 'body') => {
return Swal.mixin({
toast: true,
position: 'bottom-end',
html: `
<span class="badge badge-label-primary fs-big">${value}</span>`,
customClass: {
popup: 'bg-success text-white',
},
icon : 'success',
iconColor: 'white',
target: target,
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
})
}
export const alertError = (value, target = 'body') => {
return Swal.mixin({
toast: true,
position: 'bottom-end',
html: `<span class="badge badge-label-error fs-big">${value}</span>`,
customClass: {
popup: 'bg-error text-white',
},
icon : 'error',
iconColor: 'white',
target: target,
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
})
}
export const alertWarning = (value, target = 'body') => {
return Swal.mixin({
toast: true,
position: 'bottom-end',
html: `
<span class="badge badge-label-warning fs-big">${value}</span>`,
customClass: {
popup: 'bg-warning text-white',
},
icon : 'warning',
iconColor: 'white',
target: target,
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
})
} }

View File

@ -0,0 +1,170 @@
import { es } from './lang/es.js';
import EditorJS from '../../../../../themes/vuexy/js/editorjs.mjs';
import '../../../../../../themes/vuexy/js/editorjs/header.js';
import '../../../../../themes/vuexy/js/editorjs/list.js';
import '../../../../../../themes/vuexy/js/editorjs/alert.js';
import '../../../../../../themes/vuexy/js/editorjs/drag-drop.js';
import '../../../../../../themes/vuexy/js/editorjs/image.js';
import '../../../../../themes/vuexy/js/editorjs/table.js';
import '../../../../../themes/vuexy/js/editorjs/tune.js';
import Ajax from '../ajax.js'
import { alertError, alertSuccess, alertWarning } from '../alerts/sweetAlert.js';
class WikiEditor {
constructor() {
this.sectionId = $("#wiki-section-id").val();
this.editor = new EditorJS({
holder: 'editorjs',
i18n: es,
autofocus: true,
placeholder: 'Empieza a diseñar aquí',
readOnly: true,
tunes: {
alignment: {
class: AlignmentBlockTune,
},
},
tools: {
header: {
class: Header,
tunes : ['alignment'],
config: {
placeholder: 'Introduce un encabezado ...',
levels: [1, 2, 3, 4],
defaultLevel: 3
},
},
nestedchecklist: {
class: editorjsNestedChecklist ,
config : {
maxLevel : 1,
}
},
alert: {
class: Alert,
inlineToolbar: true,
tunes : ['alignment'],
shortcut: 'CMD+SHIFT+W',
config: {
alertTypes: ['primary', 'secondary', 'info', 'success', 'warning', 'danger', 'light', 'dark'],
defaultType: 'primary',
messagePlaceholder: 'Introduzca texto',
},
},
image: {
class: ImageTool,
tunes : ['alignment'],
config: {
features: {
border: false,
caption: 'optional',
stretch: false
},
endpoints: {
byFile: `/wiki/file/upload/${this.sectionId}`, // Your backend file uploader endpoint
byUrl: 'fetchUrl', // Your endpoint that provides uploading by Url
}
}
},
table: {
class: Table,
tunes : ['alignment'],
inlineToolbar: true,
config: {
rows: 2,
cols: 3,
maxRows: 5,
maxCols: 5,
},
},
alignment: {
class:AlignmentBlockTune,
config:{
default: "left",
blocks: {
header: 'left',
list: 'left'
}
}
},
},
})
}
async init() {
try {
await this.editor.isReady;
new DragDrop(this.editor);
/** Do anything you need after editor initialization */
$('#save-editor').on('click', () => {
this.editor.save().then(outputData => {
console.log("Data saved", outputData)
this.handleSaveContent(outputData)
})
})
$('#preview-editor').on('click', () => {
this.editor.readOnly.toggle()
$('#edit-editor').removeClass('d-none')
$('#preview-editor').addClass('d-none')
})
$('#edit-editor').on('click', () => {
$('#edit-editor').addClass('d-none')
$('#preview-editor').removeClass('d-none')
this.editor.readOnly.toggle()
})
this.handleGetData();
} catch (reason) {
console.log(`Editor.js initialization failed because of ${reason}`)
}
}
handleGetData() {
const ajax = new Ajax(`/wiki/section/${this.sectionId}`,
null,
null,
this.handleGetDataSuccess.bind(this),
this.handleGetDataError.bind(this))
ajax.get()
}
handleGetDataSuccess(response) {
if (response.data.contents) {
alertSuccess(response.message).fire()
this.renderContent(response.data.contents.editor_data)
} else {
alertWarning('No hay contenido').fire()
}
}
handleGetDataError(error) {
console.log(error)
}
renderContent(content) {
try {
let parsedContent = JSON.parse(content)
this.editor.render(parsedContent)
} catch (error) {
console.log(error)
}
}
handleSaveContent(data) {
const ajax = new Ajax(`/wiki/save/${this.sectionId}`,
data,
null,
this.handleSaveContentSuccess.bind(this),
this.handleSaveContentError.bind(this))
ajax.post()
}
handleSaveContentSuccess(response) {
this.handleGetData()
// alertSuccess(response.message).fire()
}
handleSaveContentError(response) { }
}
export default WikiEditor

View File

@ -1,76 +1,13 @@
import { es } from './lang/es.js'; import WikiEditor from "../../components/editorjs/WikiEditor.js"
import '../../../../../themes/vuexy/js/editorjs/list.js';
import '../../../../../themes/vuexy/js/editorjs/header.js';
import EditorJS from '../../../../../themes/vuexy/js/editorjs.mjs';
import '../../../../../themes/vuexy/js/editorjs/alert.js';
import '../../../../../themes/vuexy/js/editorjs/drag-drop.js';
import '../../../../../themes/vuexy/js/editorjs/image.js';
import { dataExample } from './demo.js';
const editor = new EditorJS({
holder : 'editorjs', $(async() => {
i18n : es,
autofocus: true, try {
placeholder : 'Empieza a diseñar aquí', const editor = new WikiEditor()
readOnly : true, await editor.init()
tools: { } catch (error) {
header: {
class: Header, }
config: { })
placeholder: 'Introduce un encabezado ...',
levels: [1,2, 3,4],
defaultLevel: 3
},
},
list: {
class: EditorjsList,
inlineToolbar: true,
config: {
defaultStyle: 'unordered'
},
},
alert: {
class: Alert ,
inlineToolbar: true,
shortcut: 'CMD+SHIFT+W',
config: {
alertTypes: ['primary', 'secondary', 'info', 'success', 'warning', 'danger', 'light', 'dark'],
defaultType: 'primary',
messagePlaceholder: 'Introduzca texto',
},
},
image: {
class: ImageTool,
config: {
endpoints: {
byFile: 'http://localhost:8008/uploadFile', // Your backend file uploader endpoint
byUrl: 'http://localhost:8008/fetchUrl', // Your endpoint that provides uploading by Url
}
}
}
},
})
try {
await editor.isReady;
new DragDrop(editor);
editor.render(dataExample)
/** Do anything you need after editor initialization */
$('#save-editor').on('click',() => {
editor.save().then(outputData => {
console.log("Data saved",outputData)
})
})
$('#preview-editor').on('click',() => {
editor.readOnly.toggle()
$('#edit-editor').removeClass('d-none')
$('#preview-editor').addClass('d-none')
})
$('#edit-editor').on('click',() => {
$('#edit-editor').addClass('d-none')
$('#preview-editor').removeClass('d-none')
editor.readOnly.toggle()
})
} catch (reason) {
console.log(`Editor.js initialization failed because of ${reason}`)
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long