diff --git a/config/assets.php b/config/assets.php new file mode 100644 index 0000000..b4a9773 --- /dev/null +++ b/config/assets.php @@ -0,0 +1,58 @@ + [ + 'ht7-widgets/body-overlay' => [ + ['css', 'ht7-widgets/body-overlay'], + ['javascript', 'ht7-widgets/body-overlay'] + ], + 'ht7-tools/settings' => [ + ['css', 'ht7-tools/settings'], + ['javascript', 'ht7-tools/settings'] + ] + ], + 'single' => [ + [ + 'css', + 'ht7-tools/settings', + 'css/ht7.tools.settings.css', + ['version' => '0.0.1', 'minify' => true, 'combine' => true] + ], + [ + 'css', + 'ht7-widgets/status-toggle', + 'css/ht7.widgets.statustoggle.css', + ['version' => '0.0.1', 'minify' => true, 'combine' => true] + ], + [ + 'css', + 'ht7-widgets/body-overlay', + 'css/ht7.widgets.bodyoverlay.css', + ['version' => '0.0.1', 'minify' => true, 'combine' => true], + ], + [ + 'javascript', + 'ht7-extenders', + 'js/ht7.extenders.js', + ['version' => '0.0.1', 'minify' => true, 'combine' => true], + ], + [ + 'javascript', + 'ht7-tools/settings', + 'js/ht7.tools.settings.js', + ['version' => '0.0.1', 'minify' => true, 'combine' => true] + ], + [ + 'javascript', + 'ht7-widgets/body-overlay', + 'js/ht7.widgets.bodyoverlay.js', + ['version' => '0.0.1', 'minify' => true, 'combine' => true] + ], + [ + 'javascript', + 'ht7-widgets/concrete5', + 'js/ht7.widgets.c5.js', + ['version' => '0.0.1', 'minify' => true, 'combine' => true], + ] + ] +]; diff --git a/config/forms.php b/config/forms.php new file mode 100644 index 0000000..8717eb8 --- /dev/null +++ b/config/forms.php @@ -0,0 +1,84 @@ + [ +// 'fieldsets' => [ +// 'styles' => tc('ht7_c5_base', 'Styles'), +// 'rows' => tc('ht7_c5_base', 'Row Appearance'), +// ], +// 'libraryFilePathBase' => [ +// 'label' => tc('ht7_c5_library', 'File path base'), +// 'title' => tc('ht7_c5_library', 'Base file path of the library books which will be prepend to the file specific path.'), +// 'type' => 'text', +// ], + 'saveByAjax' => [ + 'label' => tc('ht7_c5_library', 'Save these settings by AJAX request'), + 'nsValue' => 'settings.general', + 'tabId' => 'pane-general', + 'title' => tc('ht7_c5_library', 'If active the saving of these settings will be done by AJAX. This will probably not show the latest changes.'), + 'type' => 'boolean', + ], + 'showBsTooltips' => [ + 'label' => tc('ht7_c5_library', 'Show bootstrap tooltips'), + 'nsValue' => 'settings.general', + 'tabId' => 'pane-general', + 'title' => tc('ht7_c5_library', 'If active the tooltips will be displayed with the l&f of the bootstrap framework.'), + 'type' => 'boolean', + ], + 'tableStyleBordered' => [ +// 'fieldset' => 'rows', + 'label' => tc('ht7_c5_library', 'Settings with bordered l&f'), + 'nsValue' => 'settings.styles', + 'tabId' => 'pane-styles', + 'title' => tc('ht7_c5_library', 'Display the settings with bordered look & feel.'), + 'type' => 'boolean', + ], + 'tableStyleStripped' => [ +// 'fieldset' => 'rows', + 'label' => tc('ht7_c5_library', 'Settings with stripped l&f'), + 'nsValue' => 'settings.styles', + 'tabId' => 'pane-styles', + 'title' => tc('ht7_c5_library', 'Display the settings with stripped look & feel.'), + 'type' => 'boolean', + ], + 'tableRowHeightMin' => [ + 'attributes' => [ + 'max' => 50, + 'min' => 20, + 'step' => 1, + ], +// 'fieldset' => 'styles', + 'label' => tc('ht7_c5_library', 'Min Height of these rows'), + 'nsValue' => 'settings.styles', + 'tabId' => 'pane-styles', + 'title' => tc('ht7_c5_library', 'This is the min height in pixels of these settings rows.'), + 'type' => 'number', + ], + 'tablePaddingTop' => [ + 'attributes' => [ + 'max' => 10, + 'min' => 0, + 'step' => 1, + ], +// 'fieldset' => 'styles', + 'label' => tc('ht7_c5_library', 'Padding top of these rows'), + 'nsValue' => 'settings.styles', + 'tabId' => 'pane-styles', + 'title' => tc('ht7_c5_library', 'This is the padding top in pixels of these settings rows.'), + 'type' => 'number', + ], + 'tablePaddingBottom' => [ + 'attributes' => [ + 'max' => 10, + 'min' => 0, + 'step' => 1, + ], +// 'fieldset' => 'styles', + 'label' => tc('ht7_c5_library', 'Padding bottom of these rows'), + 'nsValue' => 'settings.styles', + 'tabId' => 'pane-styles', + 'title' => tc('ht7_c5_library', 'This is the padding bottom in pixels of these settings rows.'), + 'type' => 'number', + ], + ], +]; diff --git a/config/header_items.php b/config/header_items.php new file mode 100644 index 0000000..6b21759 --- /dev/null +++ b/config/header_items.php @@ -0,0 +1,14 @@ + [ + [ + 'selector' => '.ht7-tools-settings .ht7-settings-list > li', + 'items' => [ + 'min-height' => ['settings.styles.tableRowHeightMin', 'px'], + 'padding-bottom' => ['settings.styles.tablePaddingBottom', 'px'], + 'padding-top' => ['settings.styles.tablePaddingTop', 'px'] + ] + ] + ] +]; diff --git a/config/ht7_settings.php b/config/ht7_settings.php new file mode 100644 index 0000000..7e1b7da --- /dev/null +++ b/config/ht7_settings.php @@ -0,0 +1,16 @@ + [ + 'saveByAjax' => true, + 'showBsTooltips' => true, + 'libraryFilePathBase' => '', + ], + 'styles' => [ + 'tableStyleBordered' => true, + 'tableStyleStripped' => true, + 'tablePaddingBottom' => 5, + 'tablePaddingTop' => 5, + 'tableRowHeightMin' => 30, + ], +]; diff --git a/config/ht7_tabs.php b/config/ht7_tabs.php new file mode 100644 index 0000000..b07ebf0 --- /dev/null +++ b/config/ht7_tabs.php @@ -0,0 +1,36 @@ + [ + 'items' => [ + [ + 'content' => [ + 'model_type' => 'settings-simple', + 'src' => 'settings.general', + ], + 'id' => 'pane-general', + 'name' => tc('ht7_c5_library', 'General'), + ], + [ + 'content' => [ + 'model_type' => 'settings-simple', + 'src' => 'settings.styles', + ], + 'id' => 'pane-styles', + 'name' => tc('ht7_c5_library', 'Look&Feel'), + 'selected' => true, + ], + ], + 'markup' => [ + 'content' => [ + 'container' => [ + 'attributes' => [ + 'class' => 'ccm-tab-content', + 'id' => 'ccm-tab-content' + ], + 'tag' => 'article', + ] + ] + ] + ], +]; diff --git a/config/settings.php b/config/settings.php new file mode 100644 index 0000000..f7149a0 --- /dev/null +++ b/config/settings.php @@ -0,0 +1,19 @@ + [ +// 'messageTypeError' => 'alert', +// 'messageTypeInfo' => 'notify', +// 'messageTypeSuccess' => 'notify', +// 'messageTypeWarning' => 'notify', + 'saveByAjax' => false, + 'showBsTooltips' => true, + ], + 'styles' => [ + 'tableStyleBordered' => true, + 'tableStyleStripped' => true, + 'tablePaddingBottom' => 5, + 'tablePaddingTop' => 5, + 'tableRowHeightMin' => 50, + ], +]; diff --git a/config/tabs.php b/config/tabs.php new file mode 100644 index 0000000..ec9a7d1 --- /dev/null +++ b/config/tabs.php @@ -0,0 +1,30 @@ + [ + 'items' => [ + [ + 'content' => 'settings.general', + 'id' => 'pane-general', + 'name' => tc('ht7_c5_library', 'General'), + ], + [ + 'content' => 'settings.styles', + 'id' => 'pane-styles', + 'name' => tc('ht7_c5_library', 'Look&Feel'), + 'selected' => true, + ], + ], + 'markup' => [ + 'content' => [ + 'container' => [ + 'attributes' => [ + 'class' => 'ccm-tab-content', + 'id' => 'ccm-tab-content' + ], + 'tag' => 'article', + ] + ] + ] + ], +]; diff --git a/controller.php b/controller.php index 6fec4f4..d3aa880 100644 --- a/controller.php +++ b/controller.php @@ -9,6 +9,7 @@ use \Concrete\Core\Package\PackageService; use \Concrete\Core\User\Group\Group; use \Concrete\Package\Ht7C5Base\ServiceProvider; +use \Concrete\Package\Ht7C5Base\Ht7Tools\Tabs\ServiceProvider as TabsToolServiceProvider; defined('C5_EXECUTE') or die('Access Denied.'); @@ -52,11 +53,13 @@ public function install() { // Install the current package and create the defined db entities. $this->pkg = parent::install(); - // Create all pages through the content XML. - $this->installContentFile('install.xml'); + + $this->setupAutoloader(); // Make sure the package helper can be accessed by later installation // process' of this package. $this->registerServices(); + // Create all pages through the content XML. + $this->installContentFile('install.xml'); // If the path uses "-" to separate words and the filename // uses "_", the cFilename on the Pages table is empty. // Therefor we need to update this field. @@ -138,6 +141,7 @@ private function registerServices() { $list = new ProviderList($this->app); $list->registerProvider(ServiceProvider::class); + $list->registerProvider(TabsToolServiceProvider::class); } private function setupAutoloader() diff --git a/controllers/single_page/dashboard/ht7/blocks.php b/controllers/single_page/dashboard/ht7/blocks.php index 1f9d788..3da6890 100644 --- a/controllers/single_page/dashboard/ht7/blocks.php +++ b/controllers/single_page/dashboard/ht7/blocks.php @@ -2,7 +2,7 @@ namespace Concrete\Package\Ht7C5Base\Controller\SinglePage\Dashboard\Ht7; -use \Concrete\Package\Ht7C5Base\Controller\SinglePage\AbstractRedirectToFirstChild; +use \Concrete\Package\Ht7C5Base\Ht7Tools\Controllers\AbstractRedirectToFirstChild; defined('C5_EXECUTE') or die('Access Denied.'); diff --git a/controllers/single_page/dashboard/ht7/tools.php b/controllers/single_page/dashboard/ht7/tools.php new file mode 100644 index 0000000..e953e94 --- /dev/null +++ b/controllers/single_page/dashboard/ht7/tools.php @@ -0,0 +1,12 @@ +app->make('helper/ht7/package/base'); + $pkgFileConfig = $pkgH->getPackageFileConfig($this); + $pkgHandle = $pkgH->getPackageHandle($this); + + $this->definitions = new PageDefinitions( + [ + 'definitions' => ['forms.settings', $pkgFileConfig], + 'elements' => [ + 'label' => ['tools/settings/label', $pkgHandle], + 'setting' => ['tools/settings/attributes', $pkgHandle] + ], + 'tabs' => ['ht7_tabs.settings', $pkgFileConfig], + 'urls' => [ + 'form_abort' => $this->action(), + 'form_save' => $this->action('save'), + ], + 'values' => ['settings', $pkgFileConfig], + ], + PageDefinitionTypes::SIMPLE + ); + } + +} diff --git a/css/ht7.tools.settings.css b/css/ht7.tools.settings.css new file mode 100644 index 0000000..f8413fe --- /dev/null +++ b/css/ht7.tools.settings.css @@ -0,0 +1,28 @@ +#ccm-dashboard-page .ht7-dashboard.ht7-tools-settings.bordered-settings ul.ht7-settings-list li { + border-bottom: 1px solid #ddd; +} +#ccm-dashboard-page .ht7-dashboard.ht7-tools-settings.stripped-settings ul.ht7-settings-list li:nth-child(even) { + position: relative; +} +#ccm-dashboard-page .ht7-dashboard.ht7-tools-settings.stripped-settings ul.ht7-settings-list li:nth-child(even) .styler { + background-color: #efefef; + bottom: 0; + left: 0; + opacity: 0.5; + position: absolute; + right: 0; + top: 0; +} +#ccm-dashboard-page .ht7-dashboard.ht7-tools-settings ul.ht7-settings-list { + list-style: none; + margin: 0; + padding: 0; +} +#ccm-dashboard-page .ht7-dashboard.ht7-tools-settings ul.ht7-settings-list li { + /* .styler { + + }*/ +} +#ccm-dashboard-page .ht7-dashboard.ht7-tools-settings ul.ht7-settings-list li .control-label { + margin-bottom: 0; +} diff --git a/elements/tools/settings/action_buttons.php b/elements/tools/settings/action_buttons.php new file mode 100644 index 0000000..ec28450 --- /dev/null +++ b/elements/tools/settings/action_buttons.php @@ -0,0 +1,21 @@ + +
+
+ + + submit( + 'ht7-tools-settings-save', + tc('ht7_c5_library', 'Save'), + [], + 'btn-primary pull-right' + ); + ?> +
+
diff --git a/elements/tools/settings/attributes.php b/elements/tools/settings/attributes.php new file mode 100644 index 0000000..41b50f3 --- /dev/null +++ b/elements/tools/settings/attributes.php @@ -0,0 +1,84 @@ +getName(); +$defs = $item->getDefinitions(); +?> +
  • + +
    +
    + $id, 'item' => $item->getLabelModel()], + $pkgHandleLabel + ); + ?> +
    + +
    + + name="" + type="number" + value="getValueOld(); ?>" + /> +
    + +
    + +
    + +
    + getValueOld()) ? ' checked="checked"' : ''; ?> + data-value-initial="getValueOld()) ? 0 : 1; ?>" + id="" + name="" + type="checkbox" + value="1" + /> +
    + +
  • + diff --git a/elements/tools/settings/label.php b/elements/tools/settings/label.php new file mode 100644 index 0000000..ffda0a4 --- /dev/null +++ b/elements/tools/settings/label.php @@ -0,0 +1,15 @@ + + diff --git a/elements/tools/settings/main.php b/elements/tools/settings/main.php new file mode 100644 index 0000000..f631077 --- /dev/null +++ b/elements/tools/settings/main.php @@ -0,0 +1,35 @@ + +
    +
    + setFormUrl($urlSave) +// ->print($definitions, $pkgHandle); + + View::element( + 'tools/settings/action_buttons', + compact('fH', 'urlReset'), + $pkgHandleBase + ); + ?> + +
    + +
    diff --git a/elements/tools/settings/tab.php b/elements/tools/settings/tab.php new file mode 100644 index 0000000..2d44dcf --- /dev/null +++ b/elements/tools/settings/tab.php @@ -0,0 +1,91 @@ +"; +//print_r($items); +//echo ""; +////return; +?> + diff --git a/install.xml b/install.xml index 247f60e..680dd70 100644 --- a/install.xml +++ b/install.xml @@ -1,7 +1,41 @@ - - + + + + + + + + diff --git a/js/ht7.tools.settings.js b/js/ht7.tools.settings.js new file mode 100644 index 0000000..96de1af --- /dev/null +++ b/js/ht7.tools.settings.js @@ -0,0 +1,125 @@ +var ht7 = ht7 || {}; +ht7.tools = ht7.tools || {}; + +ht7.tools.settings = { + addEventListeners: function() { + this.variables.$main.find('input[type="reset"]').on('click', this.onReset); + this.variables.$main.find('#ht7-tools-settings-save').on('click', this.onSave); + }, + attributes: { + hasChanged: function($el) { + const type = ht7.tools.settings.attributes.getType($el); + + if (type === 'checkbox') { + return ($el.prop('checked') ? 1 : 0) !== Number($el.data('value-initial')); + } else if (type === 'number') { + return Number($el.val()) !== Number($el.data('value-initial')); + } else if ($.inArray(type, ['email', 'number', 'text'])) { + return $el.val() !== $el.data('value-initial'); + } + + return false; + }, + getType: function($el) { + if ($el.prop('tagName') === 'INPUT') { + return $el.prop('type'); + } else { + return $el.prop('tagName').toLowerCase(); + } + } + }, + init: function(selectorMain) { + const $main = $(selectorMain); + this.variables.$main = $main; + this.variables.$formSettings = $main.find('.settings-form'); + + this.addEventListeners(); + + if ($main.data('bs-tooltips')) { + $main.find('[data-toggle="tooltip"]').tooltip(); + } + }, + onReset: function(e) { + e.preventDefault(); + + window.location.href = $(e.target).data('url'); + }, + onSave: function(e) { + e.preventDefault(); + + const $els = ht7.tools.settings.variables.$formSettings.find('[data-value-initial]'); + const count = $els.length; + + ht7.widgets.bodyoverlay.show(); + + for (let i = 0; i < count; i++) { + const $el = $($els.get(i)); + + if (!ht7.tools.settings.attributes.hasChanged($el)) { + // Unchanged values will not be sent to the server. + $el.prop('disabled', true).addClass('ht7-to-enable'); + } else if (ht7.tools.settings.attributes.getType($el) === 'checkbox') { + // Create a hidden field to send also zeros (unchecked) states + // to the server. + const $hidden = $(''); + $hidden.attr('value', ($el.get(0).checked ? 1 : 0)); + $el.parent().append($hidden); + // "remove" the checkbox fromt the form. + $el.attr('id', $el.attr('id') + '1'); + $el.prop('disabled', true); + } + } + + if (ht7.tools.settings.variables.$main.data('is-saved-by-ajax')) { + // Get the form data. + const data = ht7.tools.settings.variables.$formSettings.serializeArray(); + console.log(data); + // Enable all previously disabled form elements. + $('.ht7-tools-settings .settings-form .ht7-to-enable').prop('disabled', false); + + $('.ht7-tools-settings .ht7-to-remove').each(function() { + const $el = $(this); + + // Reset the original attributes. + $el.parent().find('#' + $el.attr('name') + '1') + .attr('id', $el.attr('name')) + .prop('disabled', false); + // Remove the helper element. + $el.remove(); + }); + + $.ajax({ + data: data, + method: "POST", + url: ht7.tools.settings.variables.$formSettings.attr('action') + }).done(function(data) { + // Show a c5 notification with the response from the server. + let notificationType = 'info'; + let msg; + + if (data.count_updated > 0) { + notificationType = 'success'; + } + if (data.success === undefined) { + msg = data.message; + } else { + msg = data.success; + } + + ht7.widgets.c5.notification + .add('Settings Updated', msg, notificationType); + }).fail(function(data) { + + }).always(function() { + ht7.widgets.bodyoverlay.hide(); + }); + + } else { + ht7.tools.settings.variables.$formSettings.submit(); + } + }, + variables: { + $main: undefined, + $formSettings: undefined + } +}; diff --git a/less/ht7.tools.settings.less b/less/ht7.tools.settings.less new file mode 100644 index 0000000..a1efa8e --- /dev/null +++ b/less/ht7.tools.settings.less @@ -0,0 +1,42 @@ +#ccm-dashboard-page { + .ht7-dashboard { + &.ht7-tools-settings { + &.bordered-settings { + ul.ht7-settings-list { + li { + border-bottom: 1px solid #ddd; + } + } + } + &.stripped-settings { + ul.ht7-settings-list { + li:nth-child(even) { + position: relative; + .styler { + background-color: #efefef; + bottom: 0; + left: 0; + opacity: 0.5; + position: absolute; + right: 0; + top: 0; + } + } + } + } + ul.ht7-settings-list { + list-style: none; + margin: 0; + padding: 0; + li { + /* .styler { + + }*/ + .control-label { + margin-bottom: 0; + } + } + } + } + } +} diff --git a/single_pages/dashboard/ht7/tools.php b/single_pages/dashboard/ht7/tools.php new file mode 100644 index 0000000..90acbf2 --- /dev/null +++ b/single_pages/dashboard/ht7/tools.php @@ -0,0 +1,3 @@ +config = $config; + $this->namespace = $namespace; + } + +} diff --git a/src/Concrete/Ht7Tools/AbstractToolController.php b/src/Concrete/Ht7Tools/AbstractToolController.php new file mode 100644 index 0000000..902250b --- /dev/null +++ b/src/Concrete/Ht7Tools/AbstractToolController.php @@ -0,0 +1,56 @@ +app = ApplicationFacade::getFacadeApplication(); + } + + public function __toString() + { + return $this->getView()->render(); + } + + public function getFactory() + { + if (empty($this->factory)) { + $this->factory = new $this->factoryClass($this->app); + } + + return $this->factory; + } + + /** + * + * @return Renderable + */ + public function getView() + { + if (empty($this->view)) { + $this->setupView(); + } + + return $this->view; + } + + abstract protected function setupView(); +} diff --git a/src/Concrete/Ht7Tools/AbstractView.php b/src/Concrete/Ht7Tools/AbstractView.php new file mode 100644 index 0000000..0cd7075 --- /dev/null +++ b/src/Concrete/Ht7Tools/AbstractView.php @@ -0,0 +1,55 @@ +formAttributes = []; + } + + public function setFormUrl(string $url) + { + $this->formAttributes['url'] = $url; + + return $this; + } + + protected function getClosingForm() + { + return empty($this->formAttributes['url']) ? '' : ''; + } + + protected function getClosingListContainer() + { + return empty($this->formAttributes['url']) ? '' : ''; + } + + protected function getOpeningForm() + { + if (empty($this->formAttributes['url'])) { + return ''; + } + + $class = empty($this->formAttributes['class']) ? 'settings-form' : $this->formAttributes['class']; + $method = empty($this->formAttributes['method']) ? 'post' : $this->formAttributes['method']; + + return '
    '; + } + + protected function getOpeningListContainer() + { + return empty($this->formAttributes['url']) ? '' : '