forked from CIT/Vmeda.Online
		
	MOBILE-4077 ReportBuilder: Create page and module
This commit is contained in:
		
							parent
							
								
									6f869d1453
								
							
						
					
					
						commit
						cb2d17af9b
					
				@ -43,6 +43,7 @@ import { CoreUserModule } from './user/user.module';
 | 
			
		||||
import { CoreUserToursModule } from './usertours/user-tours.module';
 | 
			
		||||
import { CoreViewerModule } from './viewer/viewer.module';
 | 
			
		||||
import { CoreXAPIModule } from './xapi/xapi.module';
 | 
			
		||||
import { CoreReportBuilderModule } from './reportbuilder/reportbuilder.module';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports: [
 | 
			
		||||
@ -74,6 +75,7 @@ import { CoreXAPIModule } from './xapi/xapi.module';
 | 
			
		||||
        CoreUserToursModule,
 | 
			
		||||
        CoreViewerModule,
 | 
			
		||||
        CoreXAPIModule,
 | 
			
		||||
        CoreReportBuilderModule,
 | 
			
		||||
 | 
			
		||||
        // Import last to allow overrides.
 | 
			
		||||
        CoreEmulatorModule,
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,36 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { CoreReportBuilderReportColumnComponent } from './report-column/report-column';
 | 
			
		||||
import { CoreReportBuilderReportDetailComponent } from './report-detail/report-detail';
 | 
			
		||||
import { CoreReportBuilderReportSummaryComponent } from './report-summary/report-summary';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    declarations: [
 | 
			
		||||
        CoreReportBuilderReportDetailComponent,
 | 
			
		||||
        CoreReportBuilderReportColumnComponent,
 | 
			
		||||
        CoreReportBuilderReportSummaryComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        CoreReportBuilderReportDetailComponent,
 | 
			
		||||
        CoreReportBuilderReportColumnComponent,
 | 
			
		||||
        CoreReportBuilderReportSummaryComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderComponentsModule {}
 | 
			
		||||
@ -0,0 +1,11 @@
 | 
			
		||||
<ion-item class="ion-text-wrap" lines="inset" [detail]="false" [button]="isExpandable" [attr.aria-expanded]="isExpanded"
 | 
			
		||||
    [attr.aria-controls]="'core-report-builder-column-' + rowIndex"
 | 
			
		||||
    [attr.aria-label]="(isExpanded ? 'core.hidecolumns' : 'core.showcolumns') | translate" (click)="toggleRow()">
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h3 *ngIf="columnIndex !== 0 || (columnIndex === 0 && showFirstTitle)"> {{ header }} </h3>
 | 
			
		||||
        <core-format-text [text]="column" contextLevel="site" [contextInstanceId]="contextId"></core-format-text>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
    <ion-icon [class.expandable-status-icon-expanded]="!isExpanded" slot="end" aria-hidden="true" name="fas-chevron-up"
 | 
			
		||||
        class="expandable-status-icon" *ngIf="isExpandable" flip-rtl>
 | 
			
		||||
    </ion-icon>
 | 
			
		||||
</ion-item>
 | 
			
		||||
@ -0,0 +1,11 @@
 | 
			
		||||
@import "~theme/globals";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
    --rotate-expandable: rotate(180deg);
 | 
			
		||||
 | 
			
		||||
    .expandable-status-icon {
 | 
			
		||||
        font-size: var(--text-size);
 | 
			
		||||
        @include margin-horizontal(0, 2px);
 | 
			
		||||
        @include core-transition(transform, 200ms);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,41 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-report-builder-report-column',
 | 
			
		||||
    templateUrl: './report-column.html',
 | 
			
		||||
    styleUrls: ['./report-column.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderReportColumnComponent {
 | 
			
		||||
 | 
			
		||||
    @Input() isExpanded = false;
 | 
			
		||||
    @Input() isExpandable = false;
 | 
			
		||||
    @Input() showFirstTitle = false;
 | 
			
		||||
    @Input() columnIndex!: number;
 | 
			
		||||
    @Input() rowIndex!: number;
 | 
			
		||||
    @Input() column!: string;
 | 
			
		||||
    @Input() contextId!: number;
 | 
			
		||||
    @Input() header!: string;
 | 
			
		||||
    @Output() onToggleRow: EventEmitter<number> = new EventEmitter();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Emits row click
 | 
			
		||||
     */
 | 
			
		||||
    toggleRow(): void {
 | 
			
		||||
        this.onToggleRow.emit(this.rowIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,60 @@
 | 
			
		||||
<ng-container *ngIf="state$ | async as state">
 | 
			
		||||
 | 
			
		||||
    <core-loading [hideUntil]="state.loaded">
 | 
			
		||||
 | 
			
		||||
        <ng-container *ngIf="state.report?.data?.rows && state.report?.data?.headers && state.report?.details; else empty">
 | 
			
		||||
 | 
			
		||||
            <ion-refresher slot="fixed" [disabled]="!state.loaded" (ionRefresh)="refreshReport($event.target)">
 | 
			
		||||
                <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
			
		||||
            </ion-refresher>
 | 
			
		||||
 | 
			
		||||
            <ng-container *ngIf="isCardLayout">
 | 
			
		||||
                <ion-card *ngFor="let row of state.report.data.rows; let rowIndex = index">
 | 
			
		||||
                    <ion-list class="ion-text-wrap">
 | 
			
		||||
                        <core-report-builder-report-column *ngFor="let column of row.columns | slice:0:row.isExpanded ?
 | 
			
		||||
                            row.columns.length : state.cardVisibleColumns; let columnIndex = index" [columnIndex]="columnIndex"
 | 
			
		||||
                            [rowIndex]="rowIndex" [isExpandable]="columnIndex === 0 && row.columns.length > state.cardVisibleColumns"
 | 
			
		||||
                            [isExpanded]="row.isExpanded" [showFirstTitle]="state.cardviewShowFirstTitle"
 | 
			
		||||
                            [contextId]="state.report.details.contextid" [header]="state.report.data.headers[columnIndex]" [column]="column"
 | 
			
		||||
                            (onToggleRow)="toggleRow(rowIndex)">
 | 
			
		||||
                        </core-report-builder-report-column>
 | 
			
		||||
                    </ion-list>
 | 
			
		||||
                </ion-card>
 | 
			
		||||
            </ng-container>
 | 
			
		||||
 | 
			
		||||
            <ng-container *ngIf="!isCardLayout">
 | 
			
		||||
                <table>
 | 
			
		||||
                    <thead>
 | 
			
		||||
                        <tr>
 | 
			
		||||
                            <th *ngFor="let header of state.report.data.headers">
 | 
			
		||||
                                {{ header }}
 | 
			
		||||
                            </th>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                    </thead>
 | 
			
		||||
                    <tbody>
 | 
			
		||||
                        <tr *ngFor="let row of state.report.data.rows">
 | 
			
		||||
                            <td *ngFor="let column of row.columns">
 | 
			
		||||
                                <core-format-text [text]="column" [contextLevel]="'site'"
 | 
			
		||||
                                    [contextInstanceId]="state.report.details.contextid">
 | 
			
		||||
                                </core-format-text>
 | 
			
		||||
                            </td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                    </tbody>
 | 
			
		||||
                </table>
 | 
			
		||||
            </ng-container>
 | 
			
		||||
 | 
			
		||||
        </ng-container>
 | 
			
		||||
 | 
			
		||||
        <ng-template #empty>
 | 
			
		||||
            <core-empty-box *ngIf="!state.report?.data?.rows || !state.report?.data?.headers || !state.report?.details" icon="fa-list-alt"
 | 
			
		||||
                [message]="'core.course.nocontentavailable' | translate"></core-empty-box>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
 | 
			
		||||
        <core-infinite-loading *ngIf="!isBlock && state.report?.data?.rows && state.report?.data?.headers && state.report?.details"
 | 
			
		||||
            [enabled]="state.canLoadMoreRows" (action)="fetchMoreInfo($event)" [error]="state.errorLoadingRows">
 | 
			
		||||
        </core-infinite-loading>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </core-loading>
 | 
			
		||||
 | 
			
		||||
</ng-container>
 | 
			
		||||
@ -0,0 +1,44 @@
 | 
			
		||||
@import "~theme/globals";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
    --header-background: var(--white);
 | 
			
		||||
    --border-color: var(--stroke);
 | 
			
		||||
 | 
			
		||||
    .report-title {
 | 
			
		||||
        ion-item {
 | 
			
		||||
            width: 100%;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    table {
 | 
			
		||||
        width: 98%;
 | 
			
		||||
        margin: 1em auto;
 | 
			
		||||
        border-collapse: collapse;
 | 
			
		||||
        color: var(--ion-text-color);
 | 
			
		||||
        overflow-x: auto;
 | 
			
		||||
        display: block;
 | 
			
		||||
 | 
			
		||||
        tbody {
 | 
			
		||||
            display: table;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        th {
 | 
			
		||||
            background-color: var(--header-background);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tr {
 | 
			
		||||
            border-bottom: 1px solid var(--border-color);
 | 
			
		||||
 | 
			
		||||
            &:nth-child(even) {
 | 
			
		||||
                background: var(--light);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        th, td {
 | 
			
		||||
            @include padding(8px, 8px, 8px, null);
 | 
			
		||||
            text-align: start;
 | 
			
		||||
            min-width: 200px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,201 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 | 
			
		||||
import { CoreError } from '@classes/errors/error';
 | 
			
		||||
import {
 | 
			
		||||
    CoreReportBuilder,
 | 
			
		||||
    CoreReportBuilderReportDetail,
 | 
			
		||||
    CoreReportBuilderRetrieveReportMapped,
 | 
			
		||||
    REPORT_ROWS_LIMIT,
 | 
			
		||||
} from '@features/reportbuilder/services/reportbuilder';
 | 
			
		||||
import { IonRefresher } from '@ionic/angular';
 | 
			
		||||
import { CoreNavigator } from '@services/navigator';
 | 
			
		||||
import { CoreScreen } from '@services/screen';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreUtils } from '@services/utils/utils';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-report-builder-report-detail',
 | 
			
		||||
    templateUrl: './report-detail.html',
 | 
			
		||||
    styleUrls: ['./report-detail.scss'],
 | 
			
		||||
    changeDetection: ChangeDetectionStrategy.OnPush,
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderReportDetailComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    @Input() reportId!: string;
 | 
			
		||||
    @Input() isBlock = true;
 | 
			
		||||
    @Input() perPage?: number;
 | 
			
		||||
    @Input() layout: 'card' | 'table' | 'adaptative' = 'adaptative';
 | 
			
		||||
    @Output() onReportLoaded = new EventEmitter<CoreReportBuilderReportDetail>();
 | 
			
		||||
 | 
			
		||||
    get isCardLayout(): boolean {
 | 
			
		||||
        return this.layout === 'card' || (CoreScreen.isMobile && this.layout === 'adaptative');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state$: Readonly<BehaviorSubject<CoreReportBuilderReportDetailState>> = new BehaviorSubject({
 | 
			
		||||
        report: null,
 | 
			
		||||
        loaded: false,
 | 
			
		||||
        canLoadMoreRows: true,
 | 
			
		||||
        errorLoadingRows: false,
 | 
			
		||||
        cardviewShowFirstTitle: false,
 | 
			
		||||
        cardVisibleColumns: 1,
 | 
			
		||||
        page: 0,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async ngOnInit(): Promise<void> {
 | 
			
		||||
        await this.getReport();
 | 
			
		||||
        this.updateState({ loaded: true });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get report data.
 | 
			
		||||
     */
 | 
			
		||||
    async getReport(): Promise<void> {
 | 
			
		||||
        if (!this.reportId) {
 | 
			
		||||
            CoreDomUtils.showErrorModal(new CoreError('No report found'));
 | 
			
		||||
            CoreNavigator.back();
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const { page } = this.state$.getValue();
 | 
			
		||||
 | 
			
		||||
        const report = await CoreReportBuilder.loadReport(parseInt(this.reportId), page,this.perPage ?? REPORT_ROWS_LIMIT);
 | 
			
		||||
 | 
			
		||||
        if (!report) {
 | 
			
		||||
            CoreDomUtils.showErrorModal(new CoreError('No report found'));
 | 
			
		||||
            CoreNavigator.back();
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await CoreReportBuilder.viewReport(this.reportId);
 | 
			
		||||
 | 
			
		||||
        this.updateState({
 | 
			
		||||
            report,
 | 
			
		||||
            cardVisibleColumns: report.details.settingsdata.cardviewVisibleColumns,
 | 
			
		||||
            cardviewShowFirstTitle: report.details.settingsdata.cardviewShowFirstTitle,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.onReportLoaded.emit(report.details);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updateState(state: Partial<CoreReportBuilderReportDetailState>): void {
 | 
			
		||||
        const previousState = this.state$.getValue();
 | 
			
		||||
        this.state$.next({ ...previousState, ...state });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update report data.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ionRefresher ionic refresher.
 | 
			
		||||
     */
 | 
			
		||||
    async refreshReport(ionRefresher?: IonRefresher): Promise<void> {
 | 
			
		||||
        await CoreUtils.ignoreErrors(CoreReportBuilder.invalidateReport());
 | 
			
		||||
        this.updateState({ page: 0, canLoadMoreRows: false });
 | 
			
		||||
        await CoreUtils.ignoreErrors(this.getReport());
 | 
			
		||||
        await ionRefresher?.complete();
 | 
			
		||||
        this.updateState({ canLoadMoreRows: true });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Increment page of report rows.
 | 
			
		||||
     */
 | 
			
		||||
    protected incrementPage(): void {
 | 
			
		||||
        const { page } = this.state$.getValue();
 | 
			
		||||
        this.updateState({ page: page + 1 });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Load a new batch of pages.
 | 
			
		||||
     *
 | 
			
		||||
     * @param complete Completion callback.
 | 
			
		||||
     */
 | 
			
		||||
    async fetchMoreInfo(complete: () => void): Promise<void> {
 | 
			
		||||
        const { canLoadMoreRows, report } = this.state$.getValue();
 | 
			
		||||
 | 
			
		||||
        if (!canLoadMoreRows) {
 | 
			
		||||
            complete();
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            this.incrementPage();
 | 
			
		||||
 | 
			
		||||
            const { page: currentPage } = this.state$.getValue();
 | 
			
		||||
 | 
			
		||||
            const newReport = await CoreReportBuilder.loadReport(parseInt(this.reportId), currentPage, REPORT_ROWS_LIMIT);
 | 
			
		||||
 | 
			
		||||
            if (!report || !newReport || newReport.data.rows.length === 0) {
 | 
			
		||||
                this.updateState({ canLoadMoreRows: false });
 | 
			
		||||
                complete();
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.updateState({
 | 
			
		||||
                report: {
 | 
			
		||||
                    ...report,
 | 
			
		||||
                    data: {
 | 
			
		||||
                        ...report.data,
 | 
			
		||||
                        rows: [
 | 
			
		||||
                            ...report.data.rows,
 | 
			
		||||
                            ...newReport.data.rows,
 | 
			
		||||
                        ],
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            });
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            CoreDomUtils.showErrorModalDefault(error, 'Error loading more reports');
 | 
			
		||||
 | 
			
		||||
            this.updateState({ canLoadMoreRows: false });
 | 
			
		||||
            this.updateState({ errorLoadingRows: true });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        complete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Expand or close card.
 | 
			
		||||
     *
 | 
			
		||||
     * @param rowIndex card to expand or close.
 | 
			
		||||
     */
 | 
			
		||||
    toggleRow(rowIndex: number): void {
 | 
			
		||||
        const { report } = this.state$.getValue();
 | 
			
		||||
 | 
			
		||||
        if (!report?.data?.rows[rowIndex]) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        report.data.rows[rowIndex].isExpanded = !report.data.rows[rowIndex].isExpanded;
 | 
			
		||||
        this.updateState({ report });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type CoreReportBuilderReportDetailState = {
 | 
			
		||||
    report: CoreReportBuilderRetrieveReportMapped | null;
 | 
			
		||||
    loaded: boolean;
 | 
			
		||||
    canLoadMoreRows: boolean;
 | 
			
		||||
    errorLoadingRows: boolean;
 | 
			
		||||
    cardviewShowFirstTitle: boolean;
 | 
			
		||||
    cardVisibleColumns: number;
 | 
			
		||||
    page: number;
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,39 @@
 | 
			
		||||
<ion-header class="no-title">
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
        </ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
</ion-header>
 | 
			
		||||
 | 
			
		||||
<ion-content>
 | 
			
		||||
    <div class="list-item-limited-width">
 | 
			
		||||
        <ion-item class="ion-text-wrap course-name">
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <h1>
 | 
			
		||||
                    <core-format-text [text]="reportDetail.name" contextLevel="report" [contextInstanceId]="reportDetail.id">
 | 
			
		||||
                    </core-format-text>
 | 
			
		||||
                </h1>
 | 
			
		||||
            </ion-label>
 | 
			
		||||
            <ion-button fill="clear" [href]="reportUrl" core-link [showBrowserWarning]="false"
 | 
			
		||||
                [attr.aria-label]="'core.openinbrowser' | translate" slot="end">
 | 
			
		||||
                <ion-icon name="fas-external-link-alt" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
 | 
			
		||||
        <ion-item class="ion-text-wrap" [detail]="false" *ngFor="let item of reportDetailToDisplay">
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <p>{{ item.title | translate }}</p>
 | 
			
		||||
                <core-format-text [text]="item.text" contextLevel="report" [contextInstanceId]="reportDetail.id">
 | 
			
		||||
                </core-format-text>
 | 
			
		||||
            </ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </div>
 | 
			
		||||
</ion-content>
 | 
			
		||||
@ -0,0 +1,60 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
 | 
			
		||||
import { CoreReportBuilderReportDetail } from '@features/reportbuilder/services/reportbuilder';
 | 
			
		||||
import { CoreFormatDatePipe } from '@pipes/format-date';
 | 
			
		||||
import { CoreSites } from '@services/sites';
 | 
			
		||||
import { ModalController } from '@singletons';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-report-builder-report-summary',
 | 
			
		||||
    templateUrl: './report-summary.html',
 | 
			
		||||
    changeDetection: ChangeDetectionStrategy.OnPush,
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderReportSummaryComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    @Input() reportDetail!: CoreReportBuilderReportDetail;
 | 
			
		||||
    reportUrl!: string;
 | 
			
		||||
    reportDetailToDisplay!: { title: string; text: string }[];
 | 
			
		||||
 | 
			
		||||
    ngOnInit(): void {
 | 
			
		||||
        const formatDate = new CoreFormatDatePipe();
 | 
			
		||||
        const site = CoreSites.getRequiredCurrentSite();
 | 
			
		||||
        this.reportUrl = `${site.getURL()}/reportbuilder/view.php?id=${this.reportDetail.id}`;
 | 
			
		||||
        this.reportDetailToDisplay = [
 | 
			
		||||
            {
 | 
			
		||||
                title: 'core.reportbuilder.reportsource',
 | 
			
		||||
                text: this.reportDetail.sourcename,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                title: 'core.reportbuilder.timecreated',
 | 
			
		||||
                text: formatDate.transform(this.reportDetail.timecreated * 1000),
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                title: 'addon.mod_data.timemodified',
 | 
			
		||||
                text: formatDate.transform(this.reportDetail.timemodified * 1000),
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                title: 'core.reportbuilder.modifiedby',
 | 
			
		||||
                text: this.reportDetail.modifiedby.fullname,
 | 
			
		||||
            },
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    closeModal(): void {
 | 
			
		||||
        ModalController.dismiss();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/core/features/reportbuilder/pages/list/list.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/core/features/reportbuilder/pages/list/list.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <h1>{{ 'core.reportbuilder.reportstab' | translate }}</h1>
 | 
			
		||||
        </ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
</ion-header>
 | 
			
		||||
<ion-content *ngIf="state$ | async as state">
 | 
			
		||||
    <ion-refresher slot="fixed" [disabled]="!state.loaded" (ionRefresh)="refreshReports($event.target)">
 | 
			
		||||
        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
			
		||||
    </ion-refresher>
 | 
			
		||||
    <core-loading [hideUntil]="state.loaded">
 | 
			
		||||
        <ion-list *ngIf="reports.items?.length; else empty">
 | 
			
		||||
            <ion-item [attr.aria-current]="reports.getItemAriaCurrent(report)" [detail]="true" class="ion-text-wrap" [button]="true"
 | 
			
		||||
                *ngFor="let report of reports.items" (click)="reports.select(report)">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h3>{{ report.name }}</h3>
 | 
			
		||||
                    <p>{{ report.sourcename }}</p>
 | 
			
		||||
                </ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-list>
 | 
			
		||||
 | 
			
		||||
        <ng-template #empty>
 | 
			
		||||
            <core-empty-box *ngIf="!reports.items?.length" icon="fa-list-alt" [message]="'core.course.nocontentavailable' | translate">
 | 
			
		||||
            </core-empty-box>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
 | 
			
		||||
        <core-infinite-loading *ngIf="reports.items?.length" [enabled]="reports.loaded && !reports.completed"
 | 
			
		||||
            (action)="fetchMoreReports($event)" [error]="state.loadMoreError">
 | 
			
		||||
        </core-infinite-loading>
 | 
			
		||||
    </core-loading>
 | 
			
		||||
</ion-content>
 | 
			
		||||
							
								
								
									
										128
									
								
								src/core/features/reportbuilder/pages/list/list.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/core/features/reportbuilder/pages/list/list.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,128 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core';
 | 
			
		||||
import { CoreListItemsManager } from '@classes/items-management/list-items-manager';
 | 
			
		||||
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
 | 
			
		||||
import { CoreReportBuilderReportsSource } from '@features/reportbuilder/classes/reports-source';
 | 
			
		||||
import { CoreReportBuilder, CoreReportBuilderReport, REPORTS_LIST_LIMIT } from '@features/reportbuilder/services/reportbuilder';
 | 
			
		||||
import { IonRefresher } from '@ionic/angular';
 | 
			
		||||
import { CoreNavigator } from '@services/navigator';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreUtils } from '@services/utils/utils';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-report-builder-list',
 | 
			
		||||
    templateUrl: './list.html',
 | 
			
		||||
    changeDetection: ChangeDetectionStrategy.OnPush,
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderListPage implements AfterViewInit, OnDestroy {
 | 
			
		||||
 | 
			
		||||
    reports!: CoreListItemsManager<CoreReportBuilderReport, CoreReportBuilderReportsSource>;
 | 
			
		||||
 | 
			
		||||
    state$: Readonly<BehaviorSubject<CoreReportBuilderListState>> = new BehaviorSubject({
 | 
			
		||||
        page: 1,
 | 
			
		||||
        perpage: REPORTS_LIST_LIMIT,
 | 
			
		||||
        loaded: false,
 | 
			
		||||
        loadMoreError: false,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        try {
 | 
			
		||||
            const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(CoreReportBuilderReportsSource, []);
 | 
			
		||||
            this.reports = new CoreListItemsManager(source, CoreReportBuilderListPage);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            CoreDomUtils.showErrorModal(error);
 | 
			
		||||
            CoreNavigator.back();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async ngAfterViewInit(): Promise<void> {
 | 
			
		||||
        try {
 | 
			
		||||
            await this.fetchReports(true);
 | 
			
		||||
            this.updateState({ loaded: true });
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            CoreDomUtils.showErrorModalDefault(error, 'Error loading reports');
 | 
			
		||||
 | 
			
		||||
            this.reports.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update reports list or loads it.
 | 
			
		||||
     *
 | 
			
		||||
     * @param reload is reoading or not.
 | 
			
		||||
     */
 | 
			
		||||
    async fetchReports(reload: boolean): Promise<void> {
 | 
			
		||||
        reload ? await this.reports.reload() : await this.reports.load();
 | 
			
		||||
        this.updateState({ loadMoreError: false });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Properties of the state to update.
 | 
			
		||||
     *
 | 
			
		||||
     * @param state Object to update.
 | 
			
		||||
     */
 | 
			
		||||
    updateState(state: Partial<CoreReportBuilderListState>): void {
 | 
			
		||||
        const previousState = this.state$.getValue();
 | 
			
		||||
        this.state$.next({ ...previousState, ...state });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Load a new batch of Reports.
 | 
			
		||||
     *
 | 
			
		||||
     * @param complete Completion callback.
 | 
			
		||||
     */
 | 
			
		||||
    async fetchMoreReports(complete: () => void): Promise<void> {
 | 
			
		||||
        try {
 | 
			
		||||
            await this.fetchReports(false);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            CoreDomUtils.showErrorModalDefault(error, 'Error loading more reports');
 | 
			
		||||
 | 
			
		||||
            this.updateState({ loadMoreError: true });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        complete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Refresh reports list.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ionRefresher ionRefresher.
 | 
			
		||||
     */
 | 
			
		||||
    async refreshReports(ionRefresher?: IonRefresher): Promise<void> {
 | 
			
		||||
        await CoreUtils.ignoreErrors(CoreReportBuilder.invalidateReportsList());
 | 
			
		||||
        await CoreUtils.ignoreErrors(this.fetchReports(true));
 | 
			
		||||
        await ionRefresher?.complete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    ngOnDestroy(): void {
 | 
			
		||||
        this.reports.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CoreReportBuilderListState = {
 | 
			
		||||
    page: number;
 | 
			
		||||
    perpage: number;
 | 
			
		||||
    loaded: boolean;
 | 
			
		||||
    loadMoreError: boolean;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										21
									
								
								src/core/features/reportbuilder/pages/report/report.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/core/features/reportbuilder/pages/report/report.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button fill="clear" (click)="openInfo()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-info-circle" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="reportDetail">
 | 
			
		||||
            <h1> {{ reportDetail.name }} </h1>
 | 
			
		||||
            <p class="subheading"> {{ reportDetail.sourcename }} </p>
 | 
			
		||||
        </ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
</ion-header>
 | 
			
		||||
 | 
			
		||||
<ion-content>
 | 
			
		||||
    <core-report-builder-report-detail [isBlock]="false" [reportId]="reportId" (onReportLoaded)="loadReportDetail($event)">
 | 
			
		||||
    </core-report-builder-report-detail>
 | 
			
		||||
</ion-content>
 | 
			
		||||
							
								
								
									
										52
									
								
								src/core/features/reportbuilder/pages/report/report.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/core/features/reportbuilder/pages/report/report.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { CoreReportBuilderReportSummaryComponent } from '@features/reportbuilder/components/report-summary/report-summary';
 | 
			
		||||
import { CoreReportBuilderReportDetail } from '@features/reportbuilder/services/reportbuilder';
 | 
			
		||||
import { CoreNavigator } from '@services/navigator';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-report-builder-report',
 | 
			
		||||
    templateUrl: './report.html',
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderReportPage implements OnInit {
 | 
			
		||||
 | 
			
		||||
    reportId!: string;
 | 
			
		||||
    reportDetail?: CoreReportBuilderReportDetail;
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    ngOnInit(): void {
 | 
			
		||||
        this.reportId = CoreNavigator.getRequiredRouteParam('id');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Save the report detail
 | 
			
		||||
     *
 | 
			
		||||
     * @param reportDetail it contents the detail of the report.
 | 
			
		||||
     */
 | 
			
		||||
    loadReportDetail(reportDetail: CoreReportBuilderReportDetail): void {
 | 
			
		||||
        this.reportDetail = reportDetail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    openInfo(): void {
 | 
			
		||||
        CoreDomUtils.openSideModal<void>({
 | 
			
		||||
            component: CoreReportBuilderReportSummaryComponent,
 | 
			
		||||
            componentProps: { reportDetail: this.reportDetail },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/core/features/reportbuilder/reportbuilder-lazy.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/core/features/reportbuilder/reportbuilder-lazy.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { CoreReportBuilderComponentsModule } from './components/components.module';
 | 
			
		||||
import { CoreReportBuilderListPage } from './pages/list/list';
 | 
			
		||||
import { CoreReportBuilderReportPage } from './pages/report/report';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path: '',
 | 
			
		||||
        component: CoreReportBuilderListPage,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path: ':id',
 | 
			
		||||
        component: CoreReportBuilderReportPage,
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
        CoreReportBuilderComponentsModule,
 | 
			
		||||
        RouterModule.forChild(routes),
 | 
			
		||||
    ],
 | 
			
		||||
    declarations: [
 | 
			
		||||
        CoreReportBuilderListPage,
 | 
			
		||||
        CoreReportBuilderReportPage,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderLazyModule {}
 | 
			
		||||
							
								
								
									
										39
									
								
								src/core/features/reportbuilder/reportbuilder.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/core/features/reportbuilder/reportbuilder.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { CoreUserDelegate } from '@features/user/services/user-delegate';
 | 
			
		||||
import { CoreReportBuilderHandler, CoreReportBuilderHandlerService } from './services/handlers/reportbuilder';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path: CoreReportBuilderHandlerService.PAGE_NAME,
 | 
			
		||||
        loadChildren: () => import('./reportbuilder-lazy.module').then(m => m.CoreReportBuilderLazyModule),
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports: [RouterModule.forChild(routes)],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            useValue: () => {
 | 
			
		||||
                CoreUserDelegate.registerHandler(CoreReportBuilderHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class CoreReportBuilderModule {}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user