public function index(): void
    {
        if (!static::userCan('browse')) {
            unauthorised();
        }

        $oInput  = Factory::service('Input');
        $oModel  = $this->getModel();
        $aConfig = $this->getConfig();

        $sAlias      = $oModel->getTableAlias();
        $aSortConfig = $aConfig['SORT_OPTIONS'];

        if (classUses($oModel, Nestable::class)) {
            $aSortConfig = array_merge(['Hierarchy' => 'order'], $aSortConfig);
        }

        //  Get the first key (i.e the default sort)
        $sFirstKey = reset($aSortConfig);

        //  Prepare the sort options so they have the appropriate table alias
        $aSortCol = [];
        foreach ($aSortConfig as $sLabel => $sColumn) {
            if (strpos($sColumn, '.') === false) {
                $aSortCol[$sAlias . '.' . $sColumn] = $sLabel;
            } else {
                $aSortCol[$sColumn] = $sLabel;
            }
        }

        //  Other parameters
        $iPage      = $oInput->get('page') ? $oInput->get('page') : 0;
        $iPerPage   = $oInput->get('perPage') ? $oInput->get('perPage') : 50;
        $sSortOn    = $oInput->get('sortOn') ? $oInput->get('sortOn') : $sAlias . '.' . $sFirstKey;
        $sSortOrder = $oInput->get('sortOrder') ? $oInput->get('sortOrder') : $aConfig['SORT_DIRECTION'];
        $sKeywords  = $oInput->get('keywords');
        $aCbFilters = $this->indexCheckboxFilters();
        $aDdFilters = $this->indexDropdownFilters();

        $aData = [
                'cbFilters' => $aCbFilters,
                'ddFilters' => $aDdFilters,
                'keywords'  => $sKeywords,
                'sort'      => [
                    [$sSortOn, $sSortOrder],
                ],
            ] + $aConfig['INDEX_DATA'];

        // --------------------------------------------------------------------------

        if (classUses($oModel, Localised::class)) {
            $aData['NO_LOCALISE_FILTER'] = true;
        }

        // --------------------------------------------------------------------------

        $iTotalRows               = $oModel->countAll($aData);
        $this->data['items']      = $oModel->getAll($iPage, $iPerPage, $aData);
        $this->data['pagination'] = Helper::paginationObject($iPage, $iPerPage, $iTotalRows);
        $this->data['search']     = Helper::searchObject(
            true,
            $aSortCol,
            $sSortOn,
            $sSortOrder,
            $iPerPage,
            $sKeywords,
            $aCbFilters,
            $aDdFilters
        );

        // --------------------------------------------------------------------------

        static::addHeaderButtons($aConfig['INDEX_HEADER_BUTTONS']);

        // --------------------------------------------------------------------------

        $this->data['page']->title = $aConfig['TITLE_PLURAL'] . ' &rsaquo; Manage';
        Helper::loadView('index');
    }