Skip to content

Commit

Permalink
Added users tab in server details page (#5802)
Browse files Browse the repository at this point in the history
* Added Users tab UI

Signed-off-by: chaitali-mane <cmane@progress.com>

* Added enitites api integration

Signed-off-by: chaitali-mane <cmane@progress.com>

* minor changes

Signed-off-by: chaitali-mane <cmane@progress.com>

* Updated minor change

Signed-off-by: chaitali-mane <cmane@progress.com>
  • Loading branch information
chaitali-mane authored and kalroy committed Apr 28, 2022
1 parent 3e3ccda commit fae3022
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 26 deletions.
31 changes: 28 additions & 3 deletions components/automate-ui/src/app/entities/servers/server.actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Action } from '@ngrx/store';

import { Server } from './server.model';
import { Server , User } from './server.model';

export enum ServerActionTypes {
GET_ALL = 'SERVER::GET_ALL',
Expand All @@ -18,7 +18,10 @@ export enum ServerActionTypes {
UPDATE_FAILURE = 'SERVER::UPDATE::FAILURE',
DELETE = 'SERVER::CREATE::DELETE',
DELETE_SUCCESS = 'SERVER::CREATE::DELETE::SUCCESS',
DELETE_FAILURE = 'SERVER::CREATE::DELETE::FAILURE'
DELETE_FAILURE = 'SERVER::CREATE::DELETE::FAILURE',
GET_USERS = 'SERVER::GET_USERS',
GET_USERS_SUCCESS = 'SERVER::GET_USERS::SUCCESS',
GET_USERS_FAILURE = 'SERVER::GET_USERS::FAILURE'
}


Expand Down Expand Up @@ -118,6 +121,25 @@ export class UpdateServerFailure implements Action {
constructor(public payload: HttpErrorResponse) { }
}

export interface UsersSuccessPayload {
users: User[];
}

export class GetUsers implements Action {
readonly type = ServerActionTypes.GET_USERS;
constructor(public payload: {server_id: string} ) { }
}

export class GetUsersSuccess implements Action {
readonly type = ServerActionTypes.GET_USERS_SUCCESS;
constructor(public payload: UsersSuccessPayload) { }
}

export class GetUsersFailure implements Action {
readonly type = ServerActionTypes.GET_USERS_FAILURE;
constructor(public payload: HttpErrorResponse) { }
}

export type ServerActions =
| GetServers
| GetServersSuccess
Expand All @@ -133,4 +155,7 @@ export type ServerActions =
| UpdateServerFailure
| DeleteServer
| DeleteServerSuccess
| DeleteServerFailure;
| DeleteServerFailure
| GetUsers
| GetUsersSuccess
| GetUsersFailure;
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import {
UpdateServerFailure,
DeleteServer,
DeleteServerSuccess,
DeleteServerFailure
DeleteServerFailure,
GetUsers,
GetUsersSuccess,
GetUsersFailure,
UsersSuccessPayload
} from './server.actions';

import {
Expand Down Expand Up @@ -166,4 +170,22 @@ export class ServerEffects {
});
})));

getUsers$ = createEffect(() =>
this.actions$.pipe(
ofType(ServerActionTypes.GET_USERS),
mergeMap((action: GetUsers) =>
this.requests.getUser(action.payload).pipe(
map((resp: UsersSuccessPayload) => new GetUsersSuccess(resp)),
catchError((error: HttpErrorResponse) => observableOf(new GetUsersFailure(error)))))));

getUsersFailure$ = createEffect(() =>
this.actions$.pipe(
ofType(ServerActionTypes.GET_USERS_FAILURE),
map(({ payload: {error} }: GetUsersFailure) => {
const msg = error.error;
return new CreateNotification({
type: Type.error,
message: `Could not get users: ${msg || error}`
});
})));
}
10 changes: 10 additions & 0 deletions components/automate-ui/src/app/entities/servers/server.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ export interface Server {
ip_address: string;
orgs_count?: number;
}

export interface User {
id: string;
server_id: string;
infra_server_username: string;
credential_id: string;
connector: string;
automate_user_id: string;
is_server_admin: boolean;
}
25 changes: 23 additions & 2 deletions components/automate-ui/src/app/entities/servers/server.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { HttpErrorResponse } from '@angular/common/http';
import { pipe, set, unset } from 'lodash/fp';
import { EntityStatus } from 'app/entities/entities';
import { ServerActionTypes, ServerActions } from './server.actions';
import { Server } from './server.model';
import { Server, User } from './server.model';

export interface ServerEntityState extends EntityState<Server> {
getAllStatus: EntityStatus;
Expand All @@ -12,6 +12,8 @@ export interface ServerEntityState extends EntityState<Server> {
getStatus: EntityStatus;
updateStatus: EntityStatus;
deleteStatus: EntityStatus;
getUsers: User[];
getUsersStatus: EntityStatus;
}

const GET_ALL_STATUS = 'getAllStatus';
Expand All @@ -20,6 +22,7 @@ const SAVE_ERROR = 'saveError';
const UPDATE_STATUS = 'updateStatus';
const GET_STATUS = 'getStatus';
const DELETE_STATUS = 'deleteStatus';
const GET_USERS_STATUS = 'getUsersStatus';

export const serverEntityAdapter: EntityAdapter<Server> = createEntityAdapter<Server>();

Expand All @@ -30,7 +33,9 @@ export const ServerEntityInitialState: ServerEntityState =
saveError: null,
updateStatus: EntityStatus.notLoaded,
getStatus: EntityStatus.notLoaded,
deleteStatus: EntityStatus.notLoaded
deleteStatus: EntityStatus.notLoaded,
getUsers: null,
getUsersStatus: EntityStatus.notLoaded
});

export function serverEntityReducer(
Expand Down Expand Up @@ -119,6 +124,22 @@ export function serverEntityReducer(
case ServerActionTypes.UPDATE_FAILURE:
return set(UPDATE_STATUS, EntityStatus.loadingFailure, state);

case ServerActionTypes.GET_USERS:
return set(
GET_USERS_STATUS,
EntityStatus.loading,
serverEntityAdapter.removeAll(state)
) as ServerEntityState;

case ServerActionTypes.GET_USERS_SUCCESS:
return pipe(
set(GET_USERS_STATUS, EntityStatus.loadingSuccess),
set('getUsers', action.payload || [])
)(state) as ServerEntityState;

case ServerActionTypes.GET_USERS_FAILURE:
return set(
GET_USERS_STATUS, EntityStatus.loadingFailure, state);
}

return state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { mapKeys, snakeCase } from 'lodash/fp';

import { environment as env } from 'environments/environment';
import { Server } from './server.model';
import { Server, User } from './server.model';
import { CreateServerPayload, ServerSuccessPayload } from './server.actions';

export interface ServersResponse {
Expand All @@ -15,6 +15,10 @@ export interface ServerResponse {
server: Server;
}

export interface UserResponse {
users: User[];
}

@Injectable()
export class ServerRequests {

Expand All @@ -41,4 +45,8 @@ export class ServerRequests {
public deleteServer(id: string): Observable<ServerResponse> {
return this.http.delete<ServerResponse>(`${env.infra_proxy_url}/servers/${id}`);
}

public getUser(payload): Observable<UserResponse> {
return this.http.get<UserResponse>(`${env.infra_proxy_url}/servers/${payload.server_id}/automateinfraserverusers`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,13 @@ export const deleteStatus = createSelector(
serverState,
(state) => state.deleteStatus
);

export const getUsers = createSelector(
serverState,
(state) => state.getUsers
);

export const getUsersStatus = createSelector(
serverState,
(state) => state.getUsersStatus
);
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,24 @@
{{ server?.name }}
</chef-breadcrumbs>
<chef-page-header>
<chef-heading>{{ server?.name }}</chef-heading>
<table>
<thead>
<tr class="detail-row">
<th class="id-column">FQDN</th>
<th class="id-column">IP Address</th>
</tr>
</thead>
<tbody>
<tr class="detail-row">
<td class="id-column">{{ server?.fqdn }}</td>
<td class="id-column">{{ server?.ip_address }}</td>
</tr>
</tbody>
</table>
<div class="meta-box">
<div class="summary-body">
<chef-heading data-cy="page-title">{{ server?.name }}</chef-heading>
<ul>
<li>
<span class="heading">FQDN</span>
<span data-cy="node-env">{{ server?.fqdn }}</span>
</li>
<li>
<span class="heading">IP Address</span>
<span>{{ server?.ip_address }}</span>
</li>
</ul>
</div>
</div>
<chef-tab-selector [value]="tabValue" (change)="onSelectedTab($event)">
<chef-option value='orgs' data-cy="orgs-tab">Orgs</chef-option>
<chef-option value='users' data-cy="users-tab">Users</chef-option>
<chef-option value='details' data-cy="details-tab">Details</chef-option>
</chef-tab-selector>
</chef-page-header>
Expand Down Expand Up @@ -140,6 +141,34 @@
</div>
</form>
</section>
<section class="page-body" *ngIf="tabValue === 'users'">
<div id="user-table-container" *ngIf="isUserLoaded">
<chef-table>
<chef-thead>
<chef-tr>
<chef-th class="no-border">Chef Server User Name</chef-th>
<chef-th class="no-border">Automate Name</chef-th>
<chef-th class="three-dot-column no-border"></chef-th>
</chef-tr>
</chef-thead>
<chef-tbody *ngFor = "let users of users.users">
<chef-tr>
<chef-td class="userName-column">{{users.infra_server_username}}</chef-td>
<chef-td class="automate-column">{{users.automate_user_id}}</chef-td>
<chef-td class="three-dot-column">
<mat-select panelClass="chef-control-menu">
<mat-option data-cy="delete-org">Fetch PEM Key</mat-option>
</mat-select>
</chef-td>
</chef-tr>
</chef-tbody>
</chef-table>
</div>
<div data-cy="empty-list" class="empty-section" *ngIf="!isUserLoaded">
<img alt="No preview" src="/assets/img/no_preview.gif" />
<p data-cy="no-records">No users available.</p>
</div>
</section>
<section class="page-body" *ngIf="tabValue === 'orgs'">
<chef-toolbar>
<app-authorized [allOf]="['/api/v0/infra/servers/{server_id}/orgs', 'post', server?.id]">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,49 @@ chef-page-header {
padding-bottom: 0;
}

.meta-box {
border: 0.5px solid $chef-key-tab;
border-radius: 4px;
margin-bottom: 4em;
padding: 1em 0 4em;
background: $chef-white;

.summary-body {
font-size: 14px;
padding: 0 1em;

.meta-head {
text-transform: uppercase;
font-size: 15px;
font-weight: 600;
color: $chef-black;
}

ul {
color: $chef-primary-dark;
list-style: none;
padding: 0;

li {
display: flex;
margin-bottom: 5px;

span {
font-size: 14px;
line-height: 21px;
letter-spacing: 0.2px;

&.heading {
display: inline-block;
font-weight: bold;
width: 30%;
}
}
}
}
}
}

chef-toolbar {
display: block;
position: relative;
Expand Down
Loading

0 comments on commit fae3022

Please sign in to comment.