refactor(settings/auth): migrate ldap tables to react [EE-4712] (#10822)

pull/10840/head
Chaim Lev-Ari 2024-04-08 17:24:45 +03:00 committed by GitHub
parent 45be6c2b45
commit ddb89f71b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 95 additions and 225 deletions

View File

@ -6,11 +6,8 @@ import { InternalAuth } from '@/react/portainer/settings/AuthenticationView/Inte
import { r2a } from '@/react-tools/react2angular';
import { withReactQuery } from '@/react-tools/withReactQuery';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { ApplicationSettingsPanel } from '@/react/portainer/settings/SettingsView/ApplicationSettingsPanel';
import { KubeSettingsPanel } from '@/react/portainer/settings/SettingsView/KubeSettingsPanel';
import { HelmCertPanel } from '@/react/portainer/settings/SettingsView/HelmCertPanel';
import { HiddenContainersPanel } from '@/react/portainer/settings/SettingsView/HiddenContainersPanel/HiddenContainersPanel';
import { SSLSettingsPanelWrapper } from '@/react/portainer/settings/SettingsView/SSLSettingsPanel/SSLSettingsPanel';
import { LDAPUsersTable } from '@/react/portainer/settings/AuthenticationView/LDAPAuth/LDAPUsersTable';
import { LDAPGroupsTable } from '@/react/portainer/settings/AuthenticationView/LDAPAuth/LDAPGroupsTable';
export const settingsModule = angular
.module('portainer.app.react.components.settings', [])
@ -23,20 +20,5 @@ export const settingsModule = angular
'internalAuth',
r2a(InternalAuth, ['onSaveSettings', 'isLoading', 'value', 'onChange'])
)
.component(
'applicationSettingsPanel',
r2a(withReactQuery(ApplicationSettingsPanel), ['onSuccess', 'settings'])
)
.component(
'sslSettingsPanel',
r2a(withReactQuery(SSLSettingsPanelWrapper), [])
)
.component('helmCertPanel', r2a(withReactQuery(HelmCertPanel), []))
.component(
'hiddenContainersPanel',
r2a(withUIRouter(withReactQuery(HiddenContainersPanel)), [])
)
.component(
'kubeSettingsPanel',
r2a(withUIRouter(withReactQuery(KubeSettingsPanel)), ['settings'])
).name;
.component('ldapUsersDatatable', r2a(LDAPUsersTable, ['dataset']))
.component('ldapGroupsDatatable', r2a(LDAPGroupsTable, ['dataset'])).name;

View File

@ -6,7 +6,6 @@ import { ldapSettingsCustom } from './ldap-settings-custom';
import { ldapSettingsOpenLdap } from './ldap-settings-openldap';
import { ldapConnectivityCheck } from './ldap-connectivity-check';
import { ldapGroupsDatatable } from './ldap-groups-datatable';
import { ldapGroupSearch } from './ldap-group-search';
import { ldapGroupSearchItem } from './ldap-group-search-item';
import { ldapUserSearch } from './ldap-user-search';
@ -18,7 +17,6 @@ import { ldapCustomAdminGroup } from './ldap-custom-admin-group';
import { ldapSettingsSecurity } from './ldap-settings-security';
import { ldapSettingsTestLogin } from './ldap-settings-test-login';
import { ldapCustomUserSearch } from './ldap-custom-user-search';
import { ldapUsersDatatable } from './ldap-users-datatable';
import { LDAPService } from './ldap.service';
import { LDAP } from './ldap.rest';
@ -27,7 +25,6 @@ export default angular
.service('LDAPService', LDAPService)
.service('LDAP', LDAP)
.component('ldapConnectivityCheck', ldapConnectivityCheck)
.component('ldapGroupsDatatable', ldapGroupsDatatable)
.component('ldapSettings', ldapSettings)
.component('adSettings', adSettings)
.component('ldapGroupSearch', ldapGroupSearch)
@ -42,5 +39,4 @@ export default angular
.component('ldapSettingsOpenLdap', ldapSettingsOpenLdap)
.component('ldapSettingsSecurity', ldapSettingsSecurity)
.component('ldapSettingsTestLogin', ldapSettingsTestLogin)
.component('ldapCustomUserSearch', ldapCustomUserSearch)
.component('ldapUsersDatatable', ldapUsersDatatable).name;
.component('ldapCustomUserSearch', ldapCustomUserSearch).name;

View File

@ -67,8 +67,4 @@
</div>
</div>
<div ng-if="$ctrl.showTable">
<div class="form-group col-sm-12">
<ldap-groups-datatable dataset="$ctrl.groups" title-text="Groups" title-icon="users" table-key="ldapGroups"></ldap-groups-datatable>
</div>
</div>
<ldap-groups-datatable ng-if="$ctrl.showTable" dataset="$ctrl.groups"></ldap-groups-datatable>

View File

@ -56,8 +56,4 @@
</div>
</div>
<div ng-if="$ctrl.showTable">
<div class="form-group col-sm-12">
<ldap-users-datatable dataset="$ctrl.users" title-text="Users" title-icon="users" table-key="ldapUsers" order-by="" reverse-order=""></ldap-users-datatable>
</div>
</div>
<ldap-users-datatable ng-if="$ctrl.showTable" dataset="$ctrl.users"></ldap-users-datatable>

View File

@ -25,8 +25,4 @@
</div>
</div>
<div ng-if="$ctrl.showTable">
<div class="form-group col-sm-12">
<ldap-groups-datatable dataset="$ctrl.groups" title-text="Groups" title-icon="users" table-key="ldapGroups"></ldap-groups-datatable>
</div>
</div>
<ldap-groups-datatable ng-if="$ctrl.showTable" dataset="$ctrl.groups"></ldap-groups-datatable>

View File

@ -1,12 +0,0 @@
export const ldapGroupsDatatable = {
templateUrl: './ldap-groups-datatable.html',
controller: 'GenericDatatableController',
bindings: {
titleText: '@',
titleIcon: '@',
dataset: '<',
tableKey: '@',
orderBy: '@',
reverseOrder: '<',
},
};

View File

@ -1,80 +0,0 @@
<div class="datatable">
<rd-widget>
<rd-widget-body classes="no-padding">
<div class="toolBar">
<div class="toolBarTitle vertical-center">
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
{{ $ctrl.titleText }}
</div>
<div class="searchBar vertical-center">
<pr-icon icon="'search'"></pr-icon>
<input
type="text"
class="searchInput"
ng-model="$ctrl.state.textFilter"
ng-change="$ctrl.onTextFilterChange()"
placeholder="Search..."
auto-focus
ng-model-options="{ debounce: 300 }"
/>
</div>
</div>
<div class="table-responsive">
<table class="table-hover nowrap-cells table">
<thead>
<tr>
<th>
<table-column-header
col-title="'User Name'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'Name'"
is-sorted-desc="$ctrl.state.orderBy === 'Name' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('Name')"
></table-column-header>
</th>
<th>
<table-column-header col-title="'Groups'" can-sort="false"></table-column-header>
</th>
</tr>
</thead>
<tbody>
<tr
dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit))"
ng-class="{ active: item.Checked }"
>
<td>
{{ item.Name }}
</td>
<td>
<p ng-repeat="group in item.Groups" style="margin: 0">{{ group }}</p>
</td>
</tr>
<tr ng-if="!$ctrl.dataset">
<td colspan="3" class="text-muted text-center">Loading...</td>
</tr>
<tr ng-if="$ctrl.state.filteredDataSet.length === 0">
<td colspan="5" class="text-muted text-center">No groups found.</td>
</tr>
</tbody>
</table>
</div>
<div class="footer" ng-if="$ctrl.dataset">
<div class="paginationControls">
<form class="form-inline">
<span class="limitSelector">
<span style="margin-right: 5px"> Items per page </span>
<select class="form-control" ng-model="$ctrl.state.paginatedItemLimit" ng-change="$ctrl.changePaginationLimit()">
<option value="0">All</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</span>
<dir-pagination-controls max-size="5"></dir-pagination-controls>
</form>
</div>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -32,8 +32,4 @@
</div>
</div>
<div ng-if="$ctrl.showTable">
<div class="form-group col-sm-12">
<ldap-users-datatable dataset="$ctrl.users" title-text="Users" title-icon="users" table-key="ldapUsers" order-by="" reverse-order=""></ldap-users-datatable>
</div>
</div>
<ldap-users-datatable ng-if="$ctrl.showTable" dataset="$ctrl.users"></ldap-users-datatable>

View File

@ -1,12 +0,0 @@
export const ldapUsersDatatable = {
templateUrl: './ldap-users-datatable.html',
controller: 'GenericDatatableController',
bindings: {
titleText: '@',
titleIcon: '@',
dataset: '<',
tableKey: '@',
orderBy: '@',
reverseOrder: '<',
},
};

View File

@ -1,74 +0,0 @@
<div class="datatable">
<rd-widget>
<rd-widget-body classes="no-padding">
<div class="toolBar">
<div class="toolBarTitle vertical-center">
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
{{ $ctrl.titleText }}
</div>
<div class="searchBar vertical-center">
<pr-icon icon="'search'"></pr-icon>
<input
type="text"
class="searchInput"
ng-model="$ctrl.state.textFilter"
ng-change="$ctrl.onTextFilterChange()"
placeholder="Search..."
auto-focus
ng-model-options="{ debounce: 300 }"
/>
</div>
</div>
<div class="table-responsive">
<table class="table-hover nowrap-cells table">
<thead>
<tr>
<th>
<table-column-header
col-title="'Name'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'Name'"
is-sorted-desc="$ctrl.state.orderBy === 'Name' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('Name')"
></table-column-header>
</th>
</tr>
</thead>
<tbody>
<tr
dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit)) track by $index"
ng-class="{ active: item.Checked }"
>
<td>
<a ui-sref="portainer.groups.group({id: item.Id})">{{ item }}</a>
</td>
</tr>
<tr ng-if="!$ctrl.dataset">
<td colspan="3" class="text-muted text-center">Loading...</td>
</tr>
<tr ng-if="$ctrl.state.filteredDataSet.length === 0">
<td colspan="5" class="text-muted text-center">No users found.</td>
</tr>
</tbody>
</table>
</div>
<div class="footer" ng-if="$ctrl.dataset">
<div class="paginationControls">
<form class="form-inline">
<span class="limitSelector">
<span style="margin-right: 5px"> Items per page </span>
<select class="form-control" ng-model="$ctrl.state.paginatedItemLimit" ng-change="$ctrl.changePaginationLimit()">
<option value="0">All</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</span>
<dir-pagination-controls max-size="5"></dir-pagination-controls>
</form>
</div>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -0,0 +1,49 @@
import { Users } from 'lucide-react';
import { createColumnHelper } from '@tanstack/react-table';
import { Datatable } from '@@/datatables';
import { useTableStateWithoutStorage } from '@@/datatables/useTableState';
const columns = getColumns();
interface Value {
Name: string;
Groups: string[];
}
export function LDAPGroupsTable({ dataset }: { dataset?: Value[] }) {
const tableState = useTableStateWithoutStorage();
return (
<Datatable
columns={columns}
dataset={dataset || []}
isLoading={!dataset}
title="Groups"
titleIcon={Users}
settingsManager={tableState}
emptyContentLabel="No groups found."
disableSelect
/>
);
}
function getColumns() {
const helper = createColumnHelper<Value>();
return [
helper.accessor('Name', {}),
helper.accessor((item) => item.Groups.join(','), {
header: 'Groups',
cell: ({ row: { original: item } }) => (
<>
{item.Groups.map((g) => (
<p className="m-0" key={g}>
{g}
</p>
))}
</>
),
}),
];
}

View File

@ -0,0 +1,37 @@
import { Users } from 'lucide-react';
import { Datatable } from '@@/datatables';
import { useTableStateWithoutStorage } from '@@/datatables/useTableState';
const columns = getColumns();
interface Value {
value: string;
}
export function LDAPUsersTable({ dataset }: { dataset?: string[] }) {
const tableState = useTableStateWithoutStorage();
const items = dataset?.map((value) => ({ value }));
return (
<Datatable
columns={columns}
dataset={items || []}
isLoading={!items}
title="Users"
titleIcon={Users}
settingsManager={tableState}
emptyContentLabel="No users found."
disableSelect
/>
);
}
function getColumns() {
return [
{
header: 'Name',
accessorFn: ({ value }: Value) => value,
},
];
}