JHipster一知半解- 4.6.8 admin目录-2

回文集目录:JHipster一知半解

docs目录

这个目录是最简单的一个组件,内嵌了一个iframe,显示swagger。

<iframe src="swagger-ui/index.html" width="100%" height="900" seamless
    target="_top" title="Swagger UI" class="border-0"></iframe>

health目录

health.service.ts

与spring原生的management/health进行通讯,获取系统的健康信息。
值得注意的是addHealthObject(),内部还有transformHealthData()对返还的数据进行解析。

JhiHealthModalComponent组件

显示健康信息详情的模态框,对硬盘容量数据有特殊处理。

JhiHealthCheckComponent组件

根据后端数据返还值,显示当前系统状态。有通过refresh(),重新获取和showHealth()跳出详细模态框的两个方法。

    refresh() {
        //先修改自己的状态
        this.updatingHealth = true;
        //调用通讯接口获取健康信息
        this.healthService.checkHealth().subscribe((health) => {
            this.healthData = this.healthService.transformHealthData(health);
            this.updatingHealth = false;
        }, (error) => {
            //如果报错,就显示错误信息
            if (error.status === 503) {
                this.healthData = this.healthService.transformHealthData(error.json());
                this.updatingHealth = false;
            }
        });
    }
    //通过modalService弹出模态框
    showHealth(health: any) {
        const modalRef  = this.modalService.open(JhiHealthModalComponent);
        //向模态框赋值的方法要通过componentInstance
        modalRef.componentInstance.currentHealth = health;
        //由于只是显示,并没有额外操作
        modalRef.result.then((result) => {
            // Left blank intentionally, nothing to do here
        }, (reason) => {
            // Left blank intentionally, nothing to do here
        });
    }

logs目录

与web.rest.LogsResource对应,内部使用了logback的LoggerContext修改日志等级。
显示所有log,和修改的html如下:

<tr *ngFor="let logger of (loggers | pureFilter:filter:'name' | orderBy:orderProp:reverse)">
            <!--利用slice管道截断日志名-->
            <td><small>{{logger.name | slice:0:140}}</small></td>
            <td>
                <!--利用ngClass显示当前等级,默认用btn-light的样式-->
                <!--每个等级都是一个按钮,点击时候触发changeLevel()方法-->
                <button (click)="changeLevel(logger.name, 'TRACE')" [ngClass]="(logger.level=='TRACE') ? 'btn-danger' : 'btn-light'" class="btn btn-sm">TRACE</button>
                <button (click)="changeLevel(logger.name, 'DEBUG')" [ngClass]="(logger.level=='DEBUG') ? 'btn-warning' : 'btn-light'" class="btn btn-sm">DEBUG</button>
                <button (click)="changeLevel(logger.name, 'INFO')" [ngClass]="(logger.level=='INFO') ? 'btn-info' : 'btn-light'" class="btn btn-sm">INFO</button>
                <button (click)="changeLevel(logger.name, 'WARN')" [ngClass]="(logger.level=='WARN') ? 'btn-success' : 'btn-light'" class="btn btn-sm">WARN</button>
                <button (click)="changeLevel(logger.name, 'ERROR')" [ngClass]="(logger.level=='ERROR') ? 'btn-primary' : 'btn-light'" class="btn btn-sm">ERROR</button>
            </td>
        </tr>

metrics目录

显示spring提供的统计信息,与spring原生的management/metrics和management/dump交互,其中现场状态是在模态框显示的。这个还是推荐jvm自带的jvisual。

user-management目录

用户管理是该模块最复杂的一个页面,包含用户增删改查、激活/反激活、权限编辑。

user-modal.service.ts

由于用户管理逻辑在UserService中,UserModalService的作用是弹出交互的模态框

export class UserModalService {
    private ngbModalRef: NgbModalRef;
    //注入modalService,路由,用户服务
    constructor(
        private modalService: NgbModal,
        private router: Router,
        private userService: UserService
    ) {
        this.ngbModalRef = null;
    }

    open(component: Component, id?: number | any): Promise<NgbModalRef> {
        return new Promise<NgbModalRef>((resolve, reject) => {
            const isOpen = this.ngbModalRef !== null;
            if (isOpen) {
                resolve(this.ngbModalRef);
            }
            //根据是否有传入Id信息,显示不同的内容,
            if (id) {
                this.userService.find(id).subscribe((user) => {
                    this.ngbModalRef = this.userModalRef(component, user);
                    resolve(this.ngbModalRef);
                });
            } else {
                // setTimeout used as a workaround for getting ExpressionChangedAfterItHasBeenCheckedError
                //注册页面需要异步打开。
                setTimeout(() => {
                    this.ngbModalRef = this.userModalRef(component, new User());
                    resolve(this.ngbModalRef);
                }, 0);
            }
        });
    }
    //内部方法,应该加个private
    userModalRef(component: Component, user: User): NgbModalRef {
        const modalRef = this.modalService.open(component, { size: 'lg', backdrop: 'static'});
        modalRef.componentInstance.user = user;
        modalRef.result.then((result) => {
            //这里的模态返回就有操作了,调用路由的navigate(),进行用户信息的跳转,并且清空ngbModalRef。
            this.router.navigate([{ outlets: { popup: null }}], { replaceUrl: true, queryParamsHandling: 'merge' });
            this.ngbModalRef = null;
        }, (reason) => {
            this.router.navigate([{ outlets: { popup: null }}], { replaceUrl: true, queryParamsHandling: 'merge' });
            this.ngbModalRef = null;
        });
        return modalRef;
    }

user-management.component.ts

export class UserMgmtComponent implements OnInit, OnDestroy {
    //当前账号
    currentAccount: any;
    //记录查询回来的所有用户
    users: User[];
    error: any;
    success: any;
    routeData: any;
    links: any;
    totalItems: any;
    queryCount: any;
    itemsPerPage: any;
    page: any;
    predicate: any;
    previousPage: any;
    reverse: any;

    constructor(
        private userService: UserService,
        private alertService: JhiAlertService,
        private principal: Principal,
        private parseLinks: JhiParseLinks,
        private activatedRoute: ActivatedRoute,
        private router: Router,
        private eventManager: JhiEventManager
    ) {
        this.itemsPerPage = ITEMS_PER_PAGE;
        //从当前的URL信息中获取路由信息
        this.routeData = this.activatedRoute.data.subscribe((data) => {
            this.page = data['pagingParams'].page;
            this.previousPage = data['pagingParams'].page;
            this.reverse = data['pagingParams'].ascending;
            this.predicate = data['pagingParams'].predicate;
        });
    }
    //初始化时候,记录当前用户,加载第一页用户列表,注册用户变动通知
    ngOnInit() {
        this.principal.identity().then((account) => {
            this.currentAccount = account;
            this.loadAll();
            this.registerChangeInUsers();
        });
    }
    //销毁时候要反注册
    ngOnDestroy() {
        this.routeData.unsubscribe();
    }

    registerChangeInUsers() {
        this.eventManager.subscribe('userListModification', (response) => this.loadAll());
    }
    //设置激活,如果成功,重新加载页面数据
    setActive(user, isActivated) {
        user.activated = isActivated;

        this.userService.update(user).subscribe(
            (response) => {
                if (response.status === 200) {
                    this.error = null;
                    this.success = 'OK';
                    this.loadAll();
                } else {
                    this.success = null;
                    this.error = 'ERROR';
                }
            });
    }
    //调用userService查询
    loadAll() {
        this.userService.query({
            page: this.page - 1,
            size: this.itemsPerPage,
            sort: this.sort()}).subscribe(
            (res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
            (res: ResponseWrapper) => this.onError(res.json)
        );
    }
    
    trackIdentity(index, item: User) {
        return item.id;
    }
    //排序回调方法,默认根据ID排序,与sort指令对应
    sort() {
        const result = [this.predicate + ',' + (this.reverse ? 'asc' : 'desc')];
        if (this.predicate !== 'id') {
            result.push('id');
        }
        return result;
    }

    loadPage(page: number) {
        if (page !== this.previousPage) {
            this.previousPage = page;
            this.transition();
        }
    }
    //重新定向到用户管理页面
    transition() {
        this.router.navigate(['/user-management'], {
            queryParams: {
                page: this.page,
                sort: this.predicate + ',' + (this.reverse ? 'asc' : 'desc')
            }
        });
        this.loadAll();
    }
    //查询成功时候的回调
    private onSuccess(data, headers) {
        this.links = this.parseLinks.parse(headers.get('link'));
        this.totalItems = headers.get('X-Total-Count');
        this.queryCount = this.totalItems;
        this.users = data;
    }
    //查询失败时候的回调
    private onError(error) {
        this.alertService.error(error.error, error.message, null);
    }
}

user-management.component.html

<div>
    <h2>
        <span jhiTranslate="userManagement.home.title">Users</span>
        <!--这里制定新建用户的弹出框的outlet为‘popup’,直接在html定义router,这样也行-->
        <button class="btn btn-primary float-right jh-create-entity" [routerLink]="['/', { outlets: { popup: ['user-management-new'] } }]">
            <span class="fa fa-plus"></span> <span jhiTranslate="userManagement.home.createLabel">Create a new User</span>
        </button>
    </h2>
    <jhi-alert></jhi-alert>
    <div class="table-responsive" *ngIf="users">
        <table class="table table-striped">
            <thead>
            <!--表头,与自定义的jhisort和jhiSortBy指令配合,完成排序工作-->
            <tr jhiSort [(predicate)]="predicate" [(ascending)]="reverse" [callback]="transition.bind(this)">
                <th jhiSortBy="id"><span jhiTranslate="global.field.id">ID</span> <span class="fa fa-sort"></span></th>
                <th jhiSortBy="login"><span jhiTranslate="userManagement.login">Login</span> <span class="fa fa-sort"></span></th>
                <th jhiSortBy="email"><span jhiTranslate="userManagement.email">Email</span> <span class="fa fa-sort"></span></th>
                <th></th>
                <th jhiSortBy="langKey"> <span jhiTranslate="userManagement.langKey">Lang Key</span> <span class="fa fa-sort"></span></th>
                <th><span jhiTranslate="userManagement.profiles">Profiles</span></th>
                <th jhiSortBy="createdDate"><span jhiTranslate="userManagement.createdDate">Created Date</span> <span class="fa fa-sort"></span></th>
                <th jhiSortBy="lastModifiedBy"><span jhiTranslate="userManagement.lastModifiedBy">Last Modified By</span> <span class="fa fa-sort"></span></th>
                <th jhiSortBy="lastModifiedDate"><span jhiTranslate="userManagement.lastModifiedDate">Last Modified Date</span> <span class="fa fa-sort"></span></th>
                <th></th>
            </tr>
            </thead>
            <!--循环读取用户信息,显示在表格里面-->
            <tbody *ngIf ="users">
            <tr *ngFor="let user of users; trackBy: trackIdentity">
                <td><a [routerLink]="['../user-management', user.login]">{{user.id}}</a></td>
                <td>{{user.login}}</td>
                <td>{{user.email}}</td>
                <td>
                    <button class="btn btn-danger btn-sm" (click)="setActive(user, true)" *ngIf="!user.activated"
                            jhiTranslate="userManagement.deactivated">Deactivated</button>
                    <button class="btn btn-success btn-sm" (click)="setActive(user, false)" *ngIf="user.activated"
                            [disabled]="currentAccount.login === user.login" jhiTranslate="userManagement.activated">Activated</button>
                </td>
                <td>{{user.langKey}}</td>
                <td>
                    <div *ngFor="let authority of user.authorities">
                        <span class="badge badge-info">{{ authority }}</span>
                    </div>
                </td>
                <td>{{user.createdDate | date:'dd/MM/yy HH:mm'}}</td>
                <td>{{user.lastModifiedBy}}</td>
                <td>{{user.lastModifiedDate | date:'dd/MM/yy HH:mm'}}</td>
                <td class="text-right">
                    <div class="btn-group flex-btn-group-container">
                        <button type="submit"
                                [routerLink]="['../user-management', user.login]"
                                class="btn btn-info btn-sm">
                            <span class="fa fa-eye"></span>
                            <span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
                        </button>
                        <!--直接定义route,弹出编辑框-->
                        <button type="submit"
                                [routerLink]="['/', { outlets: { popup: 'user-management/'+ user.login + '/edit'} }]"
                                replaceUrl="true"
                                queryParamsHandling="merge"
                                class="btn btn-primary btn-sm">
                            <span class="fa fa-pencil"></span>
                            <span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
                        </button>
                        <!--直接定义route,弹出删除确认框-->
                        <button type="submit"
                                [routerLink]="['/', { outlets: { popup: 'user-management/'+ user.login + '/delete'} }]"
                                replaceUrl="true"
                                queryParamsHandling="merge"
                                class="btn btn-danger btn-sm" [disabled]="currentAccount.login === user.login">
                            <span class="fa fa-remove"></span>
                            <span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
                        </button>
                    </div>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
    <div *ngIf="users">
        <div class="row justify-content-center">
            <jhi-item-count [page]="page" [total]="queryCount" [itemsPerPage]="itemsPerPage"></jhi-item-count>
        </div>
        <div class="row justify-content-center">
            <ngb-pagination [collectionSize]="totalItems" [(page)]="page" [pageSize]="itemsPerPage" [maxSize]="5" [rotate]="true" [boundaryLinks]="true" (pageChange)="loadPage(page)"></ngb-pagination>
        </div>
    </div>
</div>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容