Merge branch 'feat/wiki' into 'main'

Feat/wiki

See merge request jjimenez/safekat!582
This commit is contained in:
Alvaro
2025-03-02 12:44:46 +00:00
10 changed files with 114 additions and 43 deletions

View File

@ -53,7 +53,7 @@ class WikiController extends BaseController
$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],
['title' => $section->name->{$this->locale}, 'route' => route_to('showWikiPage', $slug), 'active' => true],
];
return view('themes/vuexy/wiki/pages/render', $this->viewData);
}else{
@ -173,8 +173,9 @@ class WikiController extends BaseController
$bodyData = $this->request->getPost();
$sectionName = $bodyData['name'];
$roles = $bodyData['roles'];
$bodyData["slug"] = implode('-', array_map(fn($e) => strtolower($e), explode(' ', $sectionName)));
$bodyData["slug"] = implode('-', array_map(fn($e) => strtolower($e), explode(' ', $sectionName['es'])));
$bodyData["order"] = $this->wikiSectionModel->selectMax('order')->first()->order + 1;
$bodyData['name'] = json_encode($sectionName);
$wikiSectionId = $this->wikiSectionModel->insert($bodyData);
if(count($roles) > 0){
foreach ($roles as $key => $role) {
@ -193,7 +194,7 @@ class WikiController extends BaseController
$wikiSectionId = $bodyData['wiki_section_id'];
$roles = $bodyData['roles'];
$this->wikiSectionModel->update($wikiSectionId, [
"name" => $bodyData['name'],
"name" => json_encode($bodyData['name']),
"icon" => $bodyData['icon']
]);
$this->wikiSectionRoleModel->where('wiki_section_id',$wikiSectionId)->delete();

View File

@ -0,0 +1,36 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class WikiSectionNameMigration extends Migration
{
public function up()
{
$sections = $this->db->table('wiki_sections')->select()->get()->getResultArray();
$this->forge->dropColumn('wiki_sections','name');
$this->forge->addColumn('wiki_sections',[
'name' => [
'type' => 'LONGTEXT',
'null' => false,
]
]);
foreach ($sections as $key => $value) {
$this->db->table('wiki_sections')->update(
[
"name" => json_encode(["es" => $value['name'],"en" => $value['name']])
],
'id = '.$value['id']
);
}
}
public function down()
{
}
}

View File

@ -17,13 +17,17 @@ class WikiSectionEntity extends Entity
"parent_id" => null
];
protected $casts = [
"name" => "string",
"slug" => "string",
"role" => "string",
"icon" => "string",
"order" => "int",
"parent_id" => "int"
];
public function getName() : object
{
return json_decode($this->attributes['name']);
}
public function withPage(): self
{

View File

@ -1,8 +1,6 @@
<?php
namespace App\Entities\Wiki;
use App\Models\Wiki\WikiContentModel;
use App\Models\Wiki\WikiPageModel;
use App\Models\Wiki\WikiSectionModel;
use CodeIgniter\Entity\Entity;

View File

@ -1,6 +1,7 @@
<?php
return [
'section_name' => "Section name",
'help' => "Help",
'intro-admin' => "Introduction",
'presupuesto-cliente' => "Client budget",
@ -22,6 +23,7 @@ return [
'new_section' => "New section",
'edit_section' => "Edit section",
'header-placeholder' => "Start writing a header ...",
'section_placeholder' => "Write the name of the section",
'errors' => [
'publish_before_save' => "You have to save before publish the content"
],
@ -39,6 +41,14 @@ return [
'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',
'save_content' => 'Save contents',
'release_content' => "Release contents",
'delete_section' => 'Delete section',
'roles' => 'Roles',
'multiple_select_role' => 'Select one or multiple roles',
'spanish' => "Spanish",
'english' => "English",
];

View File

@ -1,6 +1,7 @@
<?php
return [
'section_name' => "Nombre sección",
'help' => "Ayuda",
'intro-admin' => "Introducción",
'intro-cliente' => "Introducción",
@ -45,6 +46,14 @@ return [
'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',
'save_content' => 'Guardar contenido',
'release_content' => "Publicar contenido",
'delete_section' => 'Eliminar sección',
'roles' => 'Roles',
'multiple_select_role' => 'Selecciona uno o varios roles',
'select_icon' => 'Selecciona un icono',
'spanish' => "Español",
'english' => "Ingles",
];

View File

@ -15,8 +15,12 @@
<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="name" placeholder="<?= lang('Wiki.section_placeholder') ?>" class="form-control" required />
<label for="section-name" class="form-label"><?= lang('Wiki.section_name')." (". lang('Wiki.spanish').")" ?></label>
<input type="text" id="section-name-es" name="name-es" placeholder="<?= lang('Wiki.section_placeholder') ?>" class="form-control" required />
</div>
<div class="col-12 mb-2">
<label for="section-name" class="form-label"><?= lang('Wiki.section_name')." (". lang('Wiki.english').")" ?></label>
<input type="text" id="section-name-en" name="name-en" placeholder="<?= lang('Wiki.section_placeholder') ?>" class="form-control" required />
</div>
<div class="mb-3">
<label for="section-icon" class="form-label"><?= lang('Wiki.icon') ?></label>

View File

@ -117,7 +117,7 @@ $picture = "/assets/img/default-user.png";
<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) ?>
<?= $value->getName()->{$session->get("lang")} ?>
</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>

View File

@ -17,7 +17,7 @@ import WikiSectionForm from '../forms/WikiSectionForm.js'
class WikiEditor extends TranslationHelper{
class WikiEditor extends TranslationHelper {
constructor() {
super();
this.sectionId = $("#wiki-section-id").val();
@ -25,8 +25,7 @@ class WikiEditor extends TranslationHelper{
this.wikiFormSection = new WikiSectionForm()
this.wikiFormSection.setId(this.sectionId)
}
async initEditor()
{
async initEditor() {
this.wikiFormSection.init()
await this.get_translations("Wiki")
@ -107,46 +106,48 @@ class WikiEditor extends TranslationHelper{
},
})
}
async initViewOnly()
{
async initViewOnly() {
try {
await this.initEditor()
await this.editor.isReady;
this.handleGetDataPublished();
} catch (reason) {
console.log(`Editor.js initialization failed because of ${reason}`)
}
}
}
async init() {
try {
await this.initEditor()
$('#release-editor').attr('disabled', 'disabled')
$('#save-editor').attr('disabled', 'disabled')
await this.editor.isReady;
new DragDrop(this.editor);
/** Do anything you need after editor initialization */
$('#save-editor').on('click', () => {
this.editor.save().then(outputData => {
alertConfirmAction(this.get_lang('save_content')).then(result => {
if (result.isConfirmed) {
this.handleSaveContent(outputData)
}
});
})
this.editor.save().then(outputData => {
alertConfirmAction(this.get_lang('save_content')).then(result => {
if (result.isConfirmed) {
this.handleSaveContent(outputData)
}
});
})
})
$('#release-editor').on('click', () => {
this.editor.save().then(outputData => {
alertConfirmAction('Publicar contenido').then(result => {
if (result.isConfirmed) {
this.handlePublishContent(outputData)
}
console.log(result)
});
}).catch((error) => {
alertError(this.get_lang('need_editor_to_save')).fire()
})
this.editor.save().then(outputData => {
alertConfirmAction(this.get_lang('release_content')).then(result => {
if (result.isConfirmed) {
this.handlePublishContent(outputData)
}
console.log(result)
});
}).catch((error) => {
alertError(this.get_lang('need_editor_to_save')).fire()
})
})
$('#preview-editor').on('click', () => {
this.editor.readOnly.toggle()
$('#edit-editor').removeClass('d-none')
@ -155,12 +156,12 @@ class WikiEditor extends TranslationHelper{
$('#save-editor').attr('disabled', 'disabled')
})
$('#edit-editor').on('click', () => {
this.editor.readOnly.toggle()
$('#edit-editor').addClass('d-none')
$('#preview-editor').removeClass('d-none')
$('#release-editor').attr('disabled', null)
$('#save-editor').attr('disabled', null)
this.editor.readOnly.toggle()
})
this.handleGetData();
} catch (reason) {
@ -242,13 +243,13 @@ class WikiEditor extends TranslationHelper{
this.handleGetData()
}
handleSaveContentError(response) { }
centerImages(){
centerImages() {
setInterval(() => {
$(".image-tool img").css('margin','0 auto')
$(".image-tool__caption").css('margin','0 auto').css('border','none').css('text-align','center').css('box-shadow','none')
$(".image-tool img").css('margin', '0 auto')
$(".image-tool__caption").css('margin', '0 auto').css('border', 'none').css('text-align', 'center').css('box-shadow', 'none')
},500)
}, 500)
}
}

View File

@ -8,7 +8,9 @@ class WikiSectionForm {
this.btnNew = $("#submit-new-section")
this.btnUpdate = $("#submit-update-section")
this.btnDelete = $("#delete-section")
this.name = this.item.find('#section-name')
this.nameEs = this.item.find('#section-name-es')
this.nameEn = this.item.find('#section-name-en')
this.icon = this.item.find('#section-icon')
this.roles = this.item.find('#section-roles').select2({
dropdownParent: this.item.parent()
@ -61,7 +63,11 @@ class WikiSectionForm {
}
getFormData() {
return {
name: this.name.val(),
name: {
es : this.nameEs.val(),
en : this.nameEn.val(),
},
icon: this.icon.val(),
roles: this.roles.val()
}
@ -128,7 +134,8 @@ class WikiSectionForm {
const sectionData = await this.handleShowSection()
if (sectionData) {
console.log(sectionData)
this.name.val(sectionData.data.name)
this.nameEs.val(sectionData.data.name?.es)
this.nameEn.val(sectionData.data.name?.en)
this.icon.val(sectionData.data.icon).trigger('change')
this.roles.val(sectionData.data.roles_array).trigger('change')
}
@ -158,7 +165,8 @@ class WikiSectionForm {
})
}
empty() {
this.name.val(null)
this.nameEs.val(null)
this.nameEn.val(null)
this.icon.val("").trigger('change')
this.roles.val("").trigger('change')