Skip to content
Snippets Groups Projects
Select Git revision
  • main
  • issue-56
  • testing-systems
3 results

dashboard.php

Blame
  • Jan-Hendrik Willms's avatar
    Jan-Hendrik Willms authored
    419db330
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    dashboard.php 6.19 KiB
    <?php
    
    use TracToGitlab\GitlabIssue;
    
    /**
     * @property User|null $user
     */
    final class DashboardController extends TracToGitlab\GitlabController
    {
        public function before_filter(&$action, &$args)
        {
            parent::before_filter($action, $args);
    
            $this->user = User::findCurrent();
    
            Navigation::activateItem('/gitlab-dashboard/dashboard');
            PageLayout::setTitle(_('Übersicht der Issues in gitlab'));
            $this->activateNavigation('dashboard');
    
            $this->setupSidebar($action);
        }
    
        private function getSelected(string $what)
        {
            $source = $this->user
                    ? $this->user->getConfiguration()->TRAC2GITLAB_USER_FILTERS
                    : ($_SESSION['GITLAB_DASHBOARD_SELECTION'] ?? []);
    
            return $source[$what] ?? $this->getDefaultSelection($what);
        }
    
        private function setSelected(string $what, $value): void
        {
            if ($value === $this->getSelected($what)) {
                return;
            }
    
            if ($this->user) {
                $config = $this->user->getConfiguration();
                $config_value = $config->TRAC2GITLAB_USER_FILTERS;
                $config_value[$what] = $value;
                $config->store('TRAC2GITLAB_USER_FILTERS', $config_value);
            } else {
                if (!isset($_SESSION['GITLAB_DASHBOARD_SELECTION'])) {
                    $_SESSION['GITLAB_DASHBOARD_SELECTION'] = [];
                }
                $_SESSION['GITLAB_DASHBOARD_SELECTION'][$what] = $value;
            }
        }
    
        private function getDefaultSelection(string $what)
        {
            if ($what === 'milestone') {
                return array_reverse(array_keys($this->getMilestonesAsSelection()))[0];
            }
    
            if ($what === 'types') {
                return 'TIC,StEP';
            }
    
            if ($what === 'filters') {
                return [];
            }
    
            return null;
        }
    
        public function index_action()
        {
            $cache_index = implode('-', ['issues', $this->getSelected('milestone'), $this->getSelected('types')]);
    
            $this->issues = $this->cached(
                $cache_index,
                fn() => $this->getIssues()
            );
            $this->mapping = $this->getQMLabelMapping();
            $this->filters = $this->getSelected('filters');
    
            Sidebar::get()->addWidget(new TemplateWidget(
                _('Stand der Daten'),
                $this->get_template_factory()->open('sidebar'),
                ['time' => $this->getCachedDate($cache_index)]
            ));
        }
    
        public function select_action(string $what, string $value = null)
        {
            $this->setSelected($what, Request::get($what, $value));
    
            $this->redirect($this->indexURL());
        }
    
        public function store_filters_action()
        {
            $this->setSelected('filters', Request::getArray('filters'));
    
            if (Request::isXhr()) {
                $this->render_nothing();
            } else {
                $this->redirect($this->indexURL());
            }
        }
    
        public function testsystems_action(): void
        {
            PageLayout::setTitle(_('Übersicht der Testsysteme'));
    
            $this->systems = \TracToGitlab\Models\GitlabReviewApp::findBySQL('1 ORDER BY branch');
        }
    
        private function setupSidebar(string $action)
        {
            $views = Sidebar::get()->addWidget(new ViewsWidget());
            $views->addLink(
                _('Dashboard'),
                $this->indexURL(),
                Icon::create('list')
            )->setActive($action !== 'testsystems');
            $views->addLink(
                _('Testsysteme'),
                $this->testsystemsURL(),
                Icon::create('computer')
            )->setActive($action === 'testsystems');
    
            if ($action !== 'testsystems') {
                $options = Sidebar::get()->addWidget(new OptionsWidget());
                $options->addSelect(
                    _('Meilenstein'),
                    $this->selectURL('milestone'),
                    'milestone',
                    $this->getMilestonesAsSelection(),
                    $this->getSelected('milestone')
                );
    
                $options->addSelect(
                    _('Typ'),
                    $this->selectURL('types'),
                    'types',
                    [
                        'TIC,StEP' => 'StEPs und TICs',
                        'StEP'     => 'StEPs',
                        'TIC'      => 'TICs',
                    ],
                    $this->getSelected('types')
                );
            }
        }
    
        private function getIssues(): array
        {
            $issues = [];
            foreach (explode(',', $this->getSelected('types')) as $type) {
                $issues = array_merge(
                    $issues,
                    $this->fetchAll(
                        $this->gitlab->issues(),
                        'all',
                        [
                            $this->gitlab_project_id,
                            [
                                'sort'      => 'asc',
                                'scope'     => 'all',
                                'milestone' => $this->getSelected('milestone'),
                                'labels'    => $type,
                            ]
                        ]
                    )
                );
            }
            usort($issues, function ($a, $b) {
                return $a['id'] - $b['id'];
            });
    
            return array_map(
                function (array $issue): GitlabIssue {
                    $mrs = $this->gitlab->issues()->relatedMergeRequests(
                        $this->gitlab_project_id,
                        $issue['iid']
                    );
                    return new GitlabIssue($issue, $mrs);
                },
                $issues
            );
        }
    
        private function getMilestones()
        {
            return $this->cached('milestones', function () {
                $milestones = $this->fetchAll(
                    $this->gitlab->milestones(),
                    'all',
                    [Config::get()->TRAC2GITLAB_GITLAB_PROJECT_ID]
                );
                return array_filter($milestones, function ($milestone) {
                    return preg_match('/^Stud\.IP \d+\.\d+$/', $milestone['title']);
                });
            });
        }
    
        private function getMilestonesAsSelection()
        {
            $result = [];
            foreach ($this->getMilestones() as $milestone) {
                $result[$milestone['title']] = $milestone['title'];
            }
            return $result;
        }
    
        private function getQMLabelMapping()
        {
            return TracToGitlab\GitlabIssue::QM_LABEL_MAPPING;
        }
    }