luyadev/luya-module-admin

View on GitHub
src/views/ngrest/crud.php

Summary

Maintainability
A
2 hrs
Test Coverage
B
83%
<?php
use luya\admin\helpers\Angular;
use luya\admin\Module;
use luya\admin\ngrest\render\RenderCrud;
use luya\helpers\ArrayHelper;
use luya\helpers\Json;
use yii\helpers\Markdown;

/** @var \luya\admin\ngrest\ConfigInterface $config */
/** @var \luya\admin\ngrest\render\RenderCrudView $this */
/** @var boolean $isInline Whether current window mode is inline or not. $isInline means you are opening a ngrest crud inside a modal. */
/** @var boolean $relationCall Whether the current request is a relation call, this means you can switch between tabs. */
/** @var string|boolean $modelSelection Whether a model can be selected from isInline call, if yes it contains the value from the previous selected model in order to highlight this id. If false the selection is disabled. */
$this->beginPage();
$this->beginBody();


$groups = [];

foreach ($config->getPointer('list') as $p) {
    if ($this->context->isHiddenInList($p)) {
        continue;
    }
    $groups[$p['name']] = $p['alias'];
}
$filters = ArrayHelper::combine(array_keys($config->getFilters()));
$filters = Angular::optionsArrayInput($filters);
?>
<?php $this->registerAngularControllerScript(); ?>
<div ng-controller="<?= $config->hash; ?>" class="crud">
    <!-- This fake ui-view is used to render the detail item, which actuals uses the parent scope in the ui router controller. -->
    <div style="display: none;" ui-view></div>
    <?php if (!$relationCall): ?>
        <?php if (!$isInline): ?>
            <div class="crud-header">
                <h1 class="crud-title"><?= $currentMenu['alias']; ?></h1>
                <modal is-modal-hidden="isExportModalHidden" modal-title="<?= Module::t('crud_exportdata_btn'); ?>">
                    <div ng-if="!isExportModalHidden">
                        <?php if (!empty($filters)): ?>
                        <?= Angular::select('exportdata.filter', Module::t('crud_exportdata_col_filter'), $filters); ?>
                        <?php endif; ?>
                        <?= Angular::radio('exportdata.type', Module::t('crud_exportdata_col_format'), ['xlsx' => Module::t('crud_exportdata_col_format_xlsx'), 'csv' => Module::t('crud_exportdata_col_format_csv')]); ?>
                        <?php // Angular::radio('exportdata.header', Module::t('crud_exportdata_col_header'), [1 => Module::t('button_yes'), 0 => Module::t('button_no')]);?>
                        <?= Angular::checkboxArray('exportdata.attributes', Module::t('crud_exportdata_col_columns'), $downloadAttributes, ['preselect' => true]); ?>
                        <button ng-hide="exportResponse" type="button" class="btn btn-icon btn-secondary" ng-click="generateExport()"><?= Module::t('crud_exportdata_btn_generateexport')?></button>
                        <button ng-show="exportResponse" type="button" class="btn btn-icon btn-download" ng-click="downloadExport()"><?= Module::t('crud_exportdata_btn_downloadexport'); ?></button>
                    </div>
                </modal>
                <div class="crud-toolbar">
                    <div class="btn-group" ng-class="{'show': isSettingsVisible}">
                        <button class="btn btn-toolbar" type="button" ng-click="toggleSettingsMenu()">
                            <i class="material-icons">more_vert</i>
                        </button>
                        <div class="dropdown-menu dropdown-menu-right" ng-class="{'show': isSettingsVisible}">
                            <a class="dropdown-item" ng-click="toggleExportModal()">
                                <i class="material-icons">get_app</i><span><?= Module::t('crud_exportdata_btn'); ?></span>
                            </a>
                            <a class="dropdown-item" ng-click="toggleNotificationMute()">
                                <span ng-show="serviceResponse._notifcation_mute_state">
                                    <i class="material-icons">visibility</i><span><?= Module::t('crud_notification_enable'); ?></span>
                                </span>
                                <span ng-show="!serviceResponse._notifcation_mute_state">
                                    <i class="material-icons">visibility_off</i><span><?= Module::t('crud_notification_disable'); ?></span>
                                </span>
                            </a>
                            <?php foreach ($this->context->getSettingButtonDefinitions() as $button): ?>
                                <?= $button; ?>
                            <?php endforeach; ?>
                        </div>
                    </div>
                </div>
            </div>
            <?php if ($this->context->description): ?>
                <p class="text-muted"><?= Markdown::processParagraph($this->context->description); ?></p>
            <?php endif; ?>
<?php endif; ?>
        <ul class="nav nav-tabs nav-tabs-mobile-icons">
            <li class="nav-item">
                <a class="nav-link" ng-class="{'active':crudSwitchType==0}" ng-click="switchTo(0, true)">
                    <i class="material-icons">list</i>
                    <span><?= Module::t('ngrest_crud_btn_list'); ?></span>
                </a>
            </li>
            <?php if ($canCreate && $config->getPointer('create')): ?>
            <li class="nav-item">
                <a class="nav-link" ng-class="{'active':crudSwitchType==1}" ng-click="switchTo(1)">
                    <i class="material-icons">add_box</i>
                    <span><?= Module::t('ngrest_crud_btn_add'); ?></span>
                </a>
            </li>
            <?php endif; ?>
            <li class="nav-item" ng-show="crudSwitchType==2">
                <a class="nav-link" ng-class="{'active' : crudSwitchType==2}" ng-click="switchTo(0, true)">
                    <i class="material-icons">cancel</i>
                    <span><?= Module::t('ngrest_crud_btn_close'); ?></span>
                </a>
            </li>
            <?php if (!$isInline): ?>
            <li class="nav-item" ng-repeat="(index,btn) in tabService.tabs">
                <a class="nav-link" ng-class="{'active' : btn.active}">
                    <i class="material-icons" ng-click="closeTab(btn, index)">cancel</i>
                    <span ng-click="switchToTab(btn)">{{btn.name}} <small class="badge badge-secondary">#{{btn.id}}</small></span>
                </a>
            </li>
            <?php endif; ?>
            <?php if (!empty($this->context->model->i18n)): ?>
            <li class="nav-item nav-item-alternative" ng-repeat="lang in AdminLangService.data" ng-class="{'ml-auto' : $first}" ng-show="crudSwitchType!=0 && AdminLangService.data.length > 1">
                <a class="nav-link" ng-click="AdminLangService.toggleSelection(lang)" ng-class="{'active' : AdminLangService.isInSelection(lang.short_code)}" role="tab">
                    <span class="flag flag-{{lang.short_code}}">
                        <span class="flag-fallback">{{lang.name}}</span>
                    </span>
                </a>
            </li>
            <?php endif; ?>
        </ul>
    <?php endif; ?>
    <div class="tab-content">
        <?php if (!$relationCall && !$isInline): ?>
        <div class="tab-pane" ng-repeat="btn in tabService.tabs" ng-class="{'active' : btn.active}" ng-if="btn.active">
            <crud-relation-loader api="{{btn.api}}" array-index="{{btn.arrayIndex}}" model-class="{{btn.modelClass}}" id="{{btn.id}}"></crud-relation-loader>
        </div>
        <?php endif; ?>
        <div class="tab-pane" ng-if="crudSwitchType==0" ng-class="{'active' : crudSwitchType==0}">
            <div class="tab-padded">
                <div class="row mt-2">
                    <div class="col-md-4 col-lg-6 col-xl-6 col-xxxl-8">
                        <div class="input-group input-group--append-clickable mb-2 mr-sm-2 mb-sm-0">
                            <div class="input-group-prepend">
                                <div class="input-group-text">
                                    <i class="material-icons">search</i>
                                </div>
                            </div>
                            <input class="form-control" ng-model="config.searchQuery" type="text" placeholder="<?= Module::t('ngrest_crud_search_text'); ?>">
                            <span class="input-group-append" ng-if="config.searchQuery" ng-click="config.searchQuery = ''">
                                <div class="input-group-text">
                                    <i class="material-icons">clear</i>
                                </div>
                            </span>
                        </div>
                    </div>
                    <div class="col-md-4 col-lg-3 col-xl-3 col-xxxl-2">
                        <luya-select ng-model="config.groupByField" initvalue="0" ng-change="changeGroupByField()" options='<?= Json::htmlEncode(Angular::optionsArrayInput($groups)); ?>'></luya-select>
                    </div>
                    <?php if (!empty($config->getFilters())): ?>
                    <div class="col-md-4 col-lg-3 col-xl-3 col-xxxl-2">
                        <luya-select ng-model="config.filter" initvalue="0" ng-change="changeNgRestFilter()" options='<?= Json::htmlEncode($filters); ?>'></luya-select>
                    </div>
                    <?php endif; ?>
                </div>
                <?php if (!$relationCall): ?>
                    <div ng-if="config.tagFilter && serviceResponse._tags && config.filter==0" class="mt-3">
                        <span ng-hide="serviceResponse._tags | isArray" class="badge"><i class="material-icons" ng-click="searchTags=!searchTags;tagSearchQuery=''">search</i><input ng-show="searchTags" ng-model="tagSearchQuery" type="text" class="ml-1" /></span>
                        <span class="badge mr-1 badge-pill" ng-class="{'badge-primary': isTagFilterActive(tag.id), 'badge-secondary' : !isTagFilterActive(tag.id)}" ng-click="toggleTagFilter(tag.id)" ng-repeat="tag in serviceResponse._tags | toArray:false | filter:tagSearchQuery">{{ tag.name }}</span>
                    </div>
                <?php endif; ?>
            </div>
            <?php if ($relationCall && $canCreate && $config->getPointer('create')): ?>
            <button type="button" class="btn btn-add ml-3 mt-3" ng-click="switchTo(1)">
                <i class="material-icons">add_box</i>
                <span><?= Module::t('ngrest_crud_btn_add'); ?></span>
            </button>
            <?php endif; ?>
            <small class="crud-counter"><?= Module::t('ngrest_crud_total_count'); ?></small>
            <div class="table-responsive">
                <table class="table table-hover table-align-middle table-striped table-crud">
                    <thead class="thead-default">
                        <tr>
                        <?php if ($hasActiveSelections): ?>
                            <th></th>
                            <?php endif; ?>
                            <?php foreach ($config->getPointer('list') as $item): if ($this->context->isHiddenInList($item)): continue; endif; ?>
                            <th class="tab-padding-left">
                                <div class="table-sorter-wrapper" ng-class="{'is-active' : isOrderBy('+<?= $item['name']; ?>') || isOrderBy('-<?= $item['name']; ?>') }">
                                    <?php if ($config->getDefaultOrderField() && $this->context->isSortable($item)): ?>
                                        <div class="table-sorter table-sorter-up" ng-click="changeOrder('<?= $item['name']; ?>', '-')" ng-class="{'is-sorting': !isOrderBy('-<?= $item['name']; ?>')}">
                                            <?php if ($this->context->getIcon($item)): ?>
                                            <i class="material-icons"><?= $this->context->getIcon($item); ?></i>
                                            <?php endif; ?>
                                            <span><?= $item['alias']; ?></span>
                                            <i class="material-icons table-sorter-icon">keyboard_arrow_up</i>
                                        </div>
                                        <div class="table-sorter table-sorter-down" ng-click="changeOrder('<?= $item['name']; ?>', '+')" ng-class="{'is-sorting': !isOrderBy('+<?= $item['name']; ?>')}">
                                            <?php if ($this->context->getIcon($item)): ?>
                                            <i class="material-icons"><?= $this->context->getIcon($item); ?></i>
                                            <?php endif; ?>
                                            <span><?= $item['alias']; ?></span>
                                            <i class="material-icons table-sorter-icon">keyboard_arrow_down</i>
                                        </div>
                                    <?php else: ?>
                                        <?php if ($this->context->getIcon($item)): ?>
                                        <i class="material-icons"><?= $this->context->getIcon($item); ?></i>
                                        <?php endif; ?>
                                        <span><?= $item['alias']; ?></span>
                                    <?php endif; ?>
                                </div>
                            </th>
                            <?php endforeach; ?>
                            <th class="crud-buttons-column"></th>
                        </tr>
                    </thead>
                    <tbody ng-repeat="(key, items) in data.listArray | groupBy: config.groupByField" ng-init="viewToggler[key]=config.groupByExpanded">
                        <tr ng-if="config.groupBy" class="table-group" ng-click="viewToggler[key]=!viewToggler[key]">
                            <?php foreach ($config->getPointer('list') as $item): if ($this->context->isHiddenInList($item)): continue; endif; ?>
                            <td ng-init="item=items[0]" ng-if="config.groupByField=='<?= $item['name']; ?>'" colspan="<?= (is_countable($config->getPointer('list')) ? count($config->getPointer('list')) : 0) + 1 ?>">
                                <strong><?= $this->context->generatePluginHtml($item, RenderCrud::TYPE_LIST); ?></strong>
                                <i class="material-icons float-right pt-1" ng-show="!viewToggler[key]">keyboard_arrow_right</i>
                                <i class="material-icons float-right pt-1" ng-show="viewToggler[key]">keyboard_arrow_down</i>
                            </td>
                            <?php endforeach; ?>
                        </tr>
                        <tr ng-repeat="(k, item) in items track by k" ng-show="viewToggler[key]" <?php if ($isInline && !$relationCall && $modelSelection): ?>ng-class="{'crud-selected-row': getRowPrimaryValue(item) == <?= $modelSelection?>}"class="crud-selectable-row"<?php endif; ?>>
                            <?php if ($hasActiveSelections): ?>
                            <td
                                width="45"
                            >
                                <input
                                    id="{{k}}"
                                    type="checkbox"
                                    ng-checked="isInSelection(item)"
                                    ng-click="toggleSelection(item)"
                                />
                                <label for="{{k}}" style="margin:0 auto"></label>
                            </td>
                            <?php endif; ?>
                            <?php $i = 0;
foreach ($config->getPointer('list') as $item): if ($this->context->isHiddenInList($item)): continue; endif;
    $i++; ?>
                                <?php $cellColor = ($this->context->getColors($item))['cellColor'];?>
                                <td ng-class="{'table-info':isRowHighlighted(item)}" <?php if ($isInline && !$relationCall && $modelSelection !== false): ?>ng-click="parentSelectInline(item)" <?php endif; ?> class="<?= $i != 1 ?: 'tab-padding-left'; ?>" <?php if ($cellColor): ?>ng-style='{"background-color": getParsedCellColor(item, <?= Json::HtmlEncode($cellColor)?>)}' <?php endif; ?> >
                                    <?= $this->context->generatePluginHtml($item, RenderCrud::TYPE_LIST); ?>
                                </td>
                             <?php endforeach; ?>
                            <td class="crud-buttons-column" ng-hide="isLocked(config.tableName, item[config.pk])">
                                <?php if (count($this->context->getButtons()) > 0): ?>
                                    <div class="crud-buttons">
                                        <i class="crud-buttons-toggler material-icons">more_vert</i>
                                        <div class="crud-buttons-pan">
                                            <?php foreach ($this->context->getButtons() as $item): ?>
                                                <button type="button" class="crud-buttons-button" ng-show="<?= $item['ngShow']; ?>" ng-click="<?= $item['ngClick']; ?>">
                                                    <i class="crud-buttons-button-icon material-icons"><?= $item['icon']; ?></i>
                                                    <?php if (!empty($item["label"])): ?>
                                                        <span class="btn-crud-label"><?= $item["label"] ?></span>
                                                    <?php endif; ?>
                                                    <div class="crud-buttons-button-loader">
                                                        <div class="loader">
                                                            <svg class="loader-svg" viewBox="25 25 50 50">
                                                                <circle class="loader-circle" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
                                                            </svg>
                                                        </div>
                                                    </div>
                                                </button>
                                            <?php endforeach; ?>
                                        </div>
                                    </div>
                                <?php endif; ?>
                            </td>
                            <td class="text-right" style="min-width: 100px;" ng-show="isLocked(config.tableName, item[config.pk])">
                                <small><i class="material-icons btn-symbol">lock_outline</i> {{ getLockedName(config.tableName, item[config.pk]) }}</small>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div ng-show="data.listArray.length == 0" class="p-3 text-muted"><?= Module::t('ngrest_crud_empty_row'); ?></div>
            <?php if ($hasActiveSelections): ?>
                <div class="mx-2 mt-3">
                <?php foreach ($config->getActiveSelections() as $buttonIndex => $selectionButtons): ?>
                    <button 
                        ng-disabled="selectedItems.length==0"
                        type="button" 
                        class="btn btn-icon btn-outline-secondary"
                        ng-click="sendActiveSelection(<?= $buttonIndex; ?>)"    
                    ><?php if (!empty($selectionButtons->icon)): ?><i class="material-icons"><?= $selectionButtons->icon; ?></i><?php endif; ?>
                        <?= $selectionButtons->label; ?>
                        <small ng-show="selectedItems.length > 0" class="badge badge-secondary">{{selectedItems.length}}</small>
                    </button>
                <?php endforeach; ?>
                </div>
            <?php endif; ?>
            <div class="crud-pagination-wrapper" ng-show="pager.pageCount > 1">
                <div class="crud-pagination">
                    <pagination current-page="pager.currentPage" page-count="pager.pageCount"></pagination>
                </div>
            </div>
        </div>
        <?php if ($canCreate && $config->getPointer('create')): ?>
            <?= $this->render($this->context->crudFormView, ['type' => '1', 'renderer' => RenderCrud::TYPE_CREATE, 'isInline' => $isInline, 'relationCall' => $relationCall]); ?>
        <?php endif; ?>
        <?php if ($canUpdate && $config->getPointer('update')): ?>
            <?= $this->render($this->context->crudFormView, ['type' => '2', 'renderer' => RenderCrud::TYPE_UPDATE, 'isInline' => $isInline, 'relationCall' => $relationCall]); ?>
        <?php endif; ?>
        <?= $this->render($this->context->awFormView); ?>
    </div>
</div>
<?php $this->endBody(); ?>
<?php $this->endPage(); ?>