diff --git a/src/core/Controller/Site/PageAdminController.php b/src/core/Controller/Site/PageAdminController.php index cb0a794..658724a 100644 --- a/src/core/Controller/Site/PageAdminController.php +++ b/src/core/Controller/Site/PageAdminController.php @@ -101,6 +101,7 @@ class PageAdminController extends CrudController ->setForm('edit', Type::class, []) ->setForm('filter', FilterType::class) ->setView('form', '@Core/site/page_admin/_form.html.twig') + ->setView('edit', '@Core/site/page_admin/edit.html.twig') ->setAction('index', 'new', false) ->setAction('index', 'show', false) diff --git a/src/core/Form/Site/Page/GrapesJsBlockType.php b/src/core/Form/Site/Page/GrapesJsBlockType.php new file mode 100644 index 0000000..bc16e93 --- /dev/null +++ b/src/core/Form/Site/Page/GrapesJsBlockType.php @@ -0,0 +1,21 @@ +add( + 'value', + GrapesJsType::class, + array_merge([ + 'required' => false, + 'label' => false, + ], $options['options']), + ); + } +} diff --git a/src/core/Form/Type/GrapesJsType.php b/src/core/Form/Type/GrapesJsType.php new file mode 100644 index 0000000..1e8b9d6 --- /dev/null +++ b/src/core/Form/Type/GrapesJsType.php @@ -0,0 +1,30 @@ +vars['attr']['data-grapesjs'])) { + $view->vars['attr']['data-grapesjs'] = ''; + } + + return parent::buildView($view, $form, $options); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'grapesjs'; + } +} diff --git a/src/core/Resources/assets/css/admin.scss b/src/core/Resources/assets/css/admin.scss index bf8a81f..04fd863 100644 --- a/src/core/Resources/assets/css/admin.scss +++ b/src/core/Resources/assets/css/admin.scss @@ -15,6 +15,7 @@ $pagination-active-bg: #343a40 !default; @import "~@fortawesome/fontawesome-free/css/all.css"; @import "~flag-icon-css/sass/flag-icon.scss"; @import "~flag-icon-css/sass/flag-icon.scss"; +@import '~grapesjs/dist/css/grapes.min.css'; @for $i from 1 through 100 { .miw-#{$i*5} { @@ -575,3 +576,12 @@ form { } } } + +.gjs-editor-cont { + border-radius: 10px; + overflow: hidden !important; +} + +.gjs-one-bg { + background: map-get($theme-colors, 'dark-blue'); +} diff --git a/src/core/Resources/assets/js/admin.js b/src/core/Resources/assets/js/admin.js index 04c7c27..dc3a10f 100644 --- a/src/core/Resources/assets/js/admin.js +++ b/src/core/Resources/assets/js/admin.js @@ -14,6 +14,7 @@ require('./modules/password.js')() require('./modules/tooltip.js')() require('./modules/tinymce.js')() require('./modules/editorjs.js')() +require('./modules/grapesjs.js')() require('./modules/panel.js')() require('./modules/choices.js')() require('./modules/checkbox-checker.js')() @@ -25,3 +26,4 @@ require('./modules/batch.js')() require('./modules/file-manager.js')() require('./modules/file-picker.js')() require('./modules/analytics.js')() +require('./modules/page.js')() diff --git a/src/core/Resources/assets/js/modules/editorjs.js b/src/core/Resources/assets/js/modules/editorjs.js index 2f5e225..a5e9dcf 100644 --- a/src/core/Resources/assets/js/modules/editorjs.js +++ b/src/core/Resources/assets/js/modules/editorjs.js @@ -1,7 +1,7 @@ const $ = require('jquery') const EditorJS = require('@editorjs/editorjs') const InlineTools = require('editorjs-inline-tool') -const Routing = require('../../../../../../../../friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js') +const Routing = require('../../../../../../../../friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js') const routes = require('../../../../../../../../../public/js/fos_js_routes.json') const UnderlineInlineTool = InlineTools.UnderlineInlineTool @@ -84,24 +84,24 @@ const tools = { bold: { class: createGenericInlineTool({ sanitize: { - strong: {}, + strong: {} }, shortcut: 'CMD+B', tagName: 'STRONG', toolboxIcon: - '', - }), + '' + }) }, italic: { class: createGenericInlineTool({ sanitize: { - em: {}, + em: {} }, shortcut: 'CMD+I', tagName: 'EM', toolboxIcon: - '', - }), + '' + }) }, underline: UnderlineInlineTool } diff --git a/src/core/Resources/assets/js/modules/grapesjs.js b/src/core/Resources/assets/js/modules/grapesjs.js new file mode 100644 index 0000000..1113167 --- /dev/null +++ b/src/core/Resources/assets/js/modules/grapesjs.js @@ -0,0 +1,106 @@ +const $ = require('jquery') +const GrapesJs = require('grapesjs') +const bootstrap4 = require('grapesjs-blocks-bootstrap4').default + +const makeId = () => { + let result = '' + const characters = 'abcdefghijklmnopqrstuvwxyz0123456789' + const charactersLength = characters.length + + for (let i = 0; i < 20; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)) + } + + return 'grapesjs-' + result +} + +const doInitEditor = () => { + $('textarea[data-grapesjs]').each((i, v) => { + const textarea = $(v) + const element = textarea.parent().prev() + const id = element.attr('id') ? element.attr('id') : makeId() + + element.attr('id', id) + + const editor = GrapesJs.init({ + container: '#' + id, + fromElement: false, + height: '900px', + width: 'auto', + storageManager: { + autoload: false + }, + noticeOnUnload: 0, + showOffsets: 1, + showDevices: false, + plugins: ['grapesjs-blocks-bootstrap4'], + colorPicker: { + appendTo: 'parent', + offset: { + top: 26, + left: -166 + } + }, + pluginsOpts: { + 'grapesjs-blocks-bootstrap4': { + blocks: {}, + blockCategories: {}, + labels: {}, + gridDevicesPanel: true, + formPredefinedActions: [ + ] + } + }, + canvas: { + styles: [ + 'https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css' + ], + scripts: [ + 'https://code.jquery.com/jquery-3.5.1.slim.min.js', + 'https://unpkg.com/@popperjs/core@2', + 'https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js' + ] + } + }) + + const deviceManager = editor.DeviceManager + + const devices = [ + 'Extra Small', + 'Small', + 'Medium', + 'Large', + 'Extra Large', + 'Desktop', + 'Tablet', + 'mobileLandscape', + 'mobilePortrait' + ] + + for (const device of devices) { + deviceManager.remove(device) + } + + deviceManager.add('All', '100%') + + editor.Panels.getPanels().remove('devices-buttons') + + editor.on('update', () => { + textarea.val(JSON.stringify(editor.storeData())) + }) + + console.log(textarea.val()) + + try { + editor.loadData(JSON.parse(textarea.val())) + } catch (e) { + editor.loadData({ html: '' }) + } + }) +} + +module.exports = () => { + $(() => { + doInitEditor() + }) +} diff --git a/src/core/Resources/assets/js/modules/page.js b/src/core/Resources/assets/js/modules/page.js new file mode 100644 index 0000000..4636b51 --- /dev/null +++ b/src/core/Resources/assets/js/modules/page.js @@ -0,0 +1,41 @@ +const $ = require('jquery') + +const doExpandCollapse = (stmt) => { + stmt = (stmt == 1) + + const button = $('#page-form-expand') + const mainForm = $('#page-main-form') + const metasForm = $('#page-metas-form') + + mainForm + .toggleClass('col-md-8', !stmt) + .toggleClass('col-md-12', stmt) + + metasForm + .toggleClass('d-none', stmt) + + button + .children() + .toggleClass('fa-expand-arrows-alt', !stmt) + .toggleClass('fa-compress-arrows-alt', stmt) + + localStorage.setItem('pageFormExpandStmt', stmt ? 1 : null) +} + +const initExpander = () => { + const button = $('#page-form-expand') + + if (button.length) { + doExpandCollapse(localStorage.getItem('pageFormExpandStmt')) + + button.click(() => { + doExpandCollapse(button.children().hasClass('fa-expand-arrows-alt')) + }) + } +} + +module.exports = () => { + $(() => { + initExpander() + }) +} diff --git a/src/core/Resources/views/form/bootstrap_4_form_theme.html.twig b/src/core/Resources/views/form/bootstrap_4_form_theme.html.twig index 870f728..d7210b0 100644 --- a/src/core/Resources/views/form/bootstrap_4_form_theme.html.twig +++ b/src/core/Resources/views/form/bootstrap_4_form_theme.html.twig @@ -1,5 +1,12 @@ {% extends 'bootstrap_4_layout.html.twig' %} +{% block grapesjs_widget %} +
+
+ +
+{% endblock %} + {% block file_widget -%}
diff --git a/src/core/Resources/views/site/page_admin/_form.html.twig b/src/core/Resources/views/site/page_admin/_form.html.twig index 6254d32..4bb35c8 100644 --- a/src/core/Resources/views/site/page_admin/_form.html.twig +++ b/src/core/Resources/views/site/page_admin/_form.html.twig @@ -20,10 +20,10 @@ {% endset %}
-
+
{{ form_widget(form, {attr: {class: 'row'}}) }}
-
+