diff --git a/admin/forms/filter_packages.xml b/admin/forms/filter_packages.xml index 85dd0da..b961585 100644 --- a/admin/forms/filter_packages.xml +++ b/admin/forms/filter_packages.xml @@ -25,10 +25,12 @@ label="JGLOBAL_SORT_BY" statuses="*,0,1,2,-2" class="js-select-submit-on-change" - default="p.name ASC" + default="" validate="options" > + + diff --git a/admin/forms/package.xml b/admin/forms/package.xml index 600de76..f693d39 100644 --- a/admin/forms/package.xml +++ b/admin/forms/package.xml @@ -78,5 +78,13 @@ class="readonly" readonly="true" /> + diff --git a/admin/services/provider.php b/admin/services/provider.php index 8a210a6..3a845e3 100644 --- a/admin/services/provider.php +++ b/admin/services/provider.php @@ -17,8 +17,7 @@ use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use KW4NZ\Component\Depot\Administrator\Extension\DepotComponent; -return new class implements ServiceProviderInterface -{ +return new class implements ServiceProviderInterface { public function register(Container $container) { $container->registerServiceProvider(new ComponentDispatcherFactory('\\KW4NZ\\Component\\Depot')); @@ -26,8 +25,7 @@ return new class implements ServiceProviderInterface $container->set( ComponentInterface::class, - function (Container $container) - { + function (Container $container) { $component = new DepotComponent($container->get(ComponentDispatcherFactoryInterface::class)); $component->setMVCFactory($container->get(MVCFactoryInterface::class)); diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index fb40888..b4be42b 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -135,6 +135,9 @@ CREATE TABLE `#__depot_package` ( `created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0, `checked_out` INT(11) NOT NULL DEFAULT 0, `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0, + `ordering` INT(11) NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE = InnoDB AUTO_INCREMENT=0 diff --git a/admin/sql/updates/mysql/0.9.11.sql b/admin/sql/updates/mysql/0.9.11.sql new file mode 100644 index 0000000..0183e25 --- /dev/null +++ b/admin/sql/updates/mysql/0.9.11.sql @@ -0,0 +1,8 @@ +-- @package Depot.SQL MariaDB -- UPDATE to 0.9.11 +-- @subpackage com_depot +-- @author Thomas Kuschel +-- @copyright (C) 2023 KW4NZ, +-- @license GNU General Public License version 2 or later; see LICENSE.md +-- @since 0.9 +ALTER TABLE `#__depot_package` +ADD COLUMN `ordering` INT(11) NOT NULL DEFAULT 0 AFTER `modified_by`; diff --git a/admin/sql/updates/mysql/0.9.12.sql b/admin/sql/updates/mysql/0.9.12.sql new file mode 100644 index 0000000..148c774 --- /dev/null +++ b/admin/sql/updates/mysql/0.9.12.sql @@ -0,0 +1,9 @@ +-- @package Depot.SQL MariaDB -- UPDATE to 0.9.12 +-- @subpackage com_depot +-- @author Thomas Kuschel +-- @copyright (C) 2023 KW4NZ, +-- @license GNU General Public License version 2 or later; see LICENSE.md +-- @since 0.9 +ALTER TABLE `#__depot_package` +ADD COLUMN `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `checked_out_time`, +ADD COLUMN `modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `modified`; diff --git a/admin/src/Model/PackagesModel.php b/admin/src/Model/PackagesModel.php index 1c4fa1e..a212087 100644 --- a/admin/src/Model/PackagesModel.php +++ b/admin/src/Model/PackagesModel.php @@ -10,11 +10,14 @@ namespace KW4NZ\Component\Depot\Administrator\Model; +use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\MVC\Model\ListModel; -// use Joomla\CMS\Table\Table; +use Joomla\CMS\Table\Table; use Joomla\Database\ParameterType; +// phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects class PackagesModel extends ListModel { @@ -36,6 +39,10 @@ class PackagesModel extends ListModel 'mounting_style', 'description', 'p.description', + 'ordering', + 'p.ordering', + 'checked_out', + 'p.checked_out', ]; parent::__construct($config); } @@ -73,6 +80,12 @@ class PackagesModel extends ListModel $db->quoteName('p.description'), $db->quoteName('p.image'), $db->quoteName('p.state'), + $db->quoteName('p.ordering'), + $db->quoteName('p.checked_out'), + $db->quoteName('p.checked_out_time'), + $db->quoteName('p.modified'), + $db->quoteName('p.modified_by'), + $db->quoteName('p.mounting_style_id'), ] ) ) @@ -104,10 +117,27 @@ class PackagesModel extends ListModel } // add list ordering clause - $orderCol = $this->state->get('list.ordering', 'id'); - $orderDirn = $this->state->get('list.direction', 'asc'); - $query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn)); + $query->order( + $db->quoteName($db->escape($this->getState('list.ordering', 'p.ordering'))) . ' ' . + $db->escape($this->getState('list.direction', 'ASC')) + ); return $query; } + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return Table A Table object + * + * @since 1.6 + */ + public function getTable($type = 'Package', $prefix = 'Administrator', $config = []) + { + return parent::getTable($type, $prefix, $config); + } + } \ No newline at end of file diff --git a/admin/src/Model/PartsModel.php b/admin/src/Model/PartsModel.php index a44b666..0795d10 100644 --- a/admin/src/Model/PartsModel.php +++ b/admin/src/Model/PartsModel.php @@ -23,6 +23,8 @@ class PartsModel extends ListModel $config['filter_fields'] = [ 'id', 'd.id', + 'state', + 'd.state', 'component_name', 'd.component_name', 'alias', @@ -65,6 +67,7 @@ class PartsModel extends ListModel 'list.select', [ $db->quoteName('d.id'), + $db->quoteName('d.state'), $db->quoteName('d.component_name'), $db->quoteName('d.alias'), $db->quoteName('d.description'), diff --git a/admin/src/Model/StocksModel.php b/admin/src/Model/StocksModel.php index 0f27407..e92ea44 100644 --- a/admin/src/Model/StocksModel.php +++ b/admin/src/Model/StocksModel.php @@ -97,10 +97,10 @@ class StocksModel extends ListModel $query->where($db->quoteName('s.state') . ' IN (0, 1)'); } - // add list ordering clause - $orderCol = $this->state->get('list.ordering', 'id'); - $orderDirn = $this->state->get('list.direction', 'asc'); - $query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn)); + // Add the list ordering clause. + $query->order( + $db->quoteName($db->escape($this->getState('list.ordering', 'id'))) . ' ' . $db->escape($this->getState('list.direction', 'ASC')) + ); return $query; } diff --git a/admin/src/Table/PackageTable.php b/admin/src/Table/PackageTable.php index 6b91bdc..6cc1f9d 100644 --- a/admin/src/Table/PackageTable.php +++ b/admin/src/Table/PackageTable.php @@ -26,6 +26,41 @@ class PackageTable extends Table $this->setColumnAlias('published', 'state'); } + public function check() + { + try { + parent::check(); + } catch (\Exception $e) { + $this->setError($e->getMessage()); + return false; + } + + // Set created date if not set. + if (!(int) $this->created) { + $this->created = Factory::getDate()->toSql(); + } + + // Set ordering + if ($this->state < 0) { + // Set ordering to 0 if state is archived or trashed + $this->ordering = 0; + } elseif (empty($this->ordering)) { + // Set ordering to last if ordering was 0 + $this->ordering = self::getNextOrder($this->_db->quoteName('state') . ' >= 0'); + } + + // Set modified to created if not set + if ($this->modified) { + $this->modified = $this->created; + } + // Set modified_by to created_by if not set + if (empty($this->modified_by)) { + $this->modified_by = $this->created_by; + } + + return true; + } + public function store($updateNulls = true) { $app = Factory::getApplication(); @@ -56,18 +91,20 @@ class PackageTable extends Table } } - // Verify that the alias is unique - $table = $app->bootComponent('com_depot')->getMVCFactory()->createTable('Package', 'Administrator'); - if ($table->load(['alias' => $this->alias]) && ($table->id != $this->id || $this->id == 0)) { - $this->setError('Alias is not unique.'); - - if ($table->state == -2) { - $this->setError('Alias is not unique. The item is in Trash.'); - } - - return false; - } + /*** + if (!empty($this->alias)) { + // Verify that the alias is unique + $table = $app->bootComponent('com_depot')->getMVCFactory()->createTable('Package', 'Administrator'); + if ($table->load(['alias' => $this->alias]) && ($table->id != $this->id || $this->id == 0)) { + $this->setError('Alias is not unique.'); + if ($table->state == -2) { + $this->setError('Alias is not unique. The item is in Trash.'); + } + return false; + } + } + */ return parent::store($updateNulls); } } \ No newline at end of file diff --git a/admin/src/View/Packages/HtmlView.php b/admin/src/View/Packages/HtmlView.php index d30117d..e097079 100644 --- a/admin/src/View/Packages/HtmlView.php +++ b/admin/src/View/Packages/HtmlView.php @@ -10,35 +10,32 @@ namespace KW4NZ\Component\Depot\Administrator\View\Packages; -defined('_JEXEC') or die; - use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; // use Joomla\CMS\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; -// use Joomla\CMS\Language\Text; +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects class HtmlView extends BaseHtmlView { public function display($tpl = null) { - // Get application - $app = Factory::getApplication(); + /** @var PackagesModel $model */ + $model = $this->getModel(); + $this->items = $model->getItems(); + $this->pagination = $model->getPagination(); + $this->state = $model->getState(); + $this->filterForm = $model->getFilterForm(); + $this->activeFilters = $model->getActiveFilters(); - $this->items = $this->get('Items'); - $this->state = $this->get('State'); - // list order - $this->listOrder = $this->escape($this->state->get('list.ordering')); - $this->listDirn = $this->escape($this->state->get('list.direction')); - // add pagination - $this->pagination = $this->get('Pagination'); - - // adding filters - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); + if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) { + $this->setLayout('emptystate'); + } // set the toolbar $this->addToolbar(); diff --git a/admin/src/View/Parts/HtmlView.php b/admin/src/View/Parts/HtmlView.php index 1a471cf..068d360 100644 --- a/admin/src/View/Parts/HtmlView.php +++ b/admin/src/View/Parts/HtmlView.php @@ -25,19 +25,13 @@ class HtmlView extends BaseHtmlView { public function display($tpl = null) { - // Get application - $app = Factory::getApplication(); - - $this->items = $this->get('Items'); - $this->state = $this->get('State'); - // list order - $this->listOrder = $this->escape($this->state->get('list.ordering')); - $this->listDirn = $this->escape($this->state->get('list.direction')); - // add pagination - $this->pagination = $this->get('Pagination'); - // adding filters - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); + // Get model + $model = $this->getModel(); + $this->items = $model->getItems(); + $this->pagination = $model->getPagination(); + $this->state = $model->getState(); + $this->filterForm = $model->getFilterForm(); + $this->activeFilters = $model->getActiveFilters(); // set the toolbar $this->addToolbar(); @@ -45,7 +39,7 @@ class HtmlView extends BaseHtmlView parent::display($tpl); } - protected function addToolbar() + protected function addToolbar(): void { ToolbarHelper::title(Text::_('COM_DEPOT_MANAGER_PARTS')); ToolbarHelper::addNew('part.add'); diff --git a/admin/tmpl/packages/default.php b/admin/tmpl/packages/default.php index 46e4510..95a721a 100644 --- a/admin/tmpl/packages/default.php +++ b/admin/tmpl/packages/default.php @@ -12,7 +12,23 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Layout\LayoutHelper; +use Joomla\CMS\Session\Session; +/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */ +$wa = $this->document->getWebAssetManager(); +$wa->useScript('table.columns') + ->useScript('multiselect'); + +$user = $this->getCurrentUser(); +$userID = $user->get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'p.ordering'; + +if ($saveOrder && !empty($this->items)) { + $saveOrderingUrl = 'index.php?option=com_depot&task=packages.saveOrderAjax&tmpl=component'; + HTMLHelper::_('draggablelist.draggable'); +} ?>
@@ -26,29 +42,34 @@ use Joomla\CMS\Layout\LayoutHelper; - - +
+ - + - + - - items as $i => $item): ?> - - class="js-draggable" data-url="" + data-direction="" data-nested="true" > + items as $i => $item): + $ordering = ($listOrder == 'ordering'); + $canChange = true; + ?> + + + - - + diff --git a/admin/tmpl/parts/default.php b/admin/tmpl/parts/default.php index 8a53e3b..77ccb7c 100644 --- a/admin/tmpl/parts/default.php +++ b/admin/tmpl/parts/default.php @@ -10,11 +10,24 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; -use Joomla\CMS\Router\Route; use Joomla\CMS\Layout\LayoutHelper; +use Joomla\CMS\Router\Route; +/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */ +$wa = $this->document->getWebAssetManager(); +$wa->useScript('table.columns') + ->useScript('multiselect'); + +$canChange = true; +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'd.ordering'; + +if ($saveOrder && !empty($this->items)) { + $saveOrderingUrl = 'index.php?option=com_depot&task=parts.saveOrderAjax&tmpl=component'; + HTMLHelper::_('draggablelist.draggable'); +} ?> - $this]); ?> @@ -26,28 +39,31 @@ use Joomla\CMS\Layout\LayoutHelper; -
+ , + + + , + + + +
+ + + - listDirn, - $this->listOrder - ); ?> + + listDirn, - $this->listOrder + $listDirn, + $listOrder ); ?> @@ -56,8 +77,8 @@ use Joomla\CMS\Layout\LayoutHelper; 'searchtools.sort', 'COM_DEPOT_TABLE_HEAD_DESCRIPTION', 'p.description', - $this->listDirn, - $this->listOrder + $listDirn, + $listOrder ); ?> @@ -65,33 +86,72 @@ use Joomla\CMS\Layout\LayoutHelper; 'searchtools.sort', 'COM_DEPOT_TABLE_HEAD_MOUNTING_STYLE', 'p.mounting_style', - $this->listDirn, - $this->listOrder + $listDirn, + $listOrder + ); ?> + +
+
id); ?> + + + + + + + + +
+ ordering; ?> +
- id ?> + + state, $i, 'packages.', $canChange); ?> + escape($item->name); ?> - + escape($item->description); ?> escape($item->mounting_style); ?> + id ?> +
+
+ - + - - + @@ -85,13 +110,13 @@ use Joomla\CMS\Layout\LayoutHelper; items as $i => $item): ?> - - - @@ -124,7 +149,6 @@ use Joomla\CMS\Layout\LayoutHelper; + diff --git a/depot.xml b/depot.xml index 4e1cd3c..428a862 100644 --- a/depot.xml +++ b/depot.xml @@ -2,12 +2,12 @@ Depot KW4NZ - 2023-11-01 + 2023-11-02 (C) KW4NZ Thomas Kuschel GPL v2 +; see LICENSE.md thomas@kuschel.at https://kuschel.at - 0.9.10 + 0.9.12 COM_DEPOT_XML_DESCRIPTION KW4NZ\Component\Depot
+ , + + + , + + + +
+ + + - listDirn, - $this->listOrder - ); ?> - + listDirn, - $this->listOrder + $listDirn, + $listOrder ); ?> @@ -55,8 +71,8 @@ use Joomla\CMS\Layout\LayoutHelper; 'searchtools.sort', 'COM_DEPOT_TABLE_HEAD_QUANTITY', 'd.quantity', - $this->listDirn, - $this->listOrder + $listDirn, + $listOrder ); ?> @@ -67,8 +83,8 @@ use Joomla\CMS\Layout\LayoutHelper; 'searchtools.sort', 'COM_DEPOT_TABLE_HEAD_MANUFACTURER', 'manufacturer', - $this->listDirn, - $this->listOrder + $listDirn, + $listOrder ); ?> @@ -76,8 +92,17 @@ use Joomla\CMS\Layout\LayoutHelper; 'searchtools.sort', 'COM_DEPOT_TABLE_HEAD_STOCK', 'stock_name', - $this->listDirn, - $this->listOrder + $listDirn, + $listOrder + ); ?> + +
- id); ?> + + id, false, 'cid', 'cb', $item->component_name); ?> - id ?> + + state, $i, 'parts.', $canChange); ?> + - + escape($item->quantity); ?> - escape($item->stock_name); ?> @@ -132,7 +156,9 @@ use Joomla\CMS\Layout\LayoutHelper;
escape($item->owner); ?>
- +
+ id ?>