MOBILE-4077 ReportBuilder: Create handler and service
parent
14f48f374d
commit
6f869d1453
|
@ -0,0 +1,55 @@
|
|||
// (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 { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source';
|
||||
import { CoreReportBuilder, CoreReportBuilderReport, REPORTS_LIST_LIMIT } from '../services/reportbuilder';
|
||||
|
||||
/**
|
||||
* Provides a list of reports.
|
||||
*/
|
||||
export class CoreReportBuilderReportsSource extends CoreRoutedItemsManagerSource<CoreReportBuilderReport> {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getItemPath(report: CoreReportBuilderReport): string {
|
||||
return report.id.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected async loadPageItems(page: number): Promise<{ items: CoreReportBuilderReport[]; hasMoreItems: boolean }> {
|
||||
const reports = await CoreReportBuilder.getReports(page, this.getPageLength());
|
||||
|
||||
return { items: reports, hasMoreItems: reports.length > 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected setItems(reports: CoreReportBuilderReport[], hasMoreItems: boolean): void {
|
||||
const sortedReports = reports.slice(0);
|
||||
reports.sort((a, b) => a.timecreated < b.timecreated ? 1 : -1);
|
||||
super.setItems(sortedReports, hasMoreItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected getPageLength(): number {
|
||||
return REPORTS_LIST_LIMIT;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// (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 { Injectable } from '@angular/core';
|
||||
import { CoreUserDelegateService, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreReportBuilder } from '../reportbuilder';
|
||||
|
||||
/**
|
||||
* Handler to visualize custom reports.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CoreReportBuilderHandlerService implements CoreUserProfileHandler {
|
||||
|
||||
static readonly PAGE_NAME = 'reportbuilder';
|
||||
|
||||
type = CoreUserDelegateService.TYPE_NEW_PAGE;
|
||||
cacheEnabled = true;
|
||||
name = 'CoreReportBuilderDelegate';
|
||||
priority = 350;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabled(): Promise<boolean> {
|
||||
return await CoreReportBuilder.isEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getDisplayData(): CoreUserProfileHandlerData {
|
||||
return {
|
||||
class: 'core-report-builder',
|
||||
icon: 'fa-list-alt',
|
||||
title: 'core.reportbuilder.reportstab',
|
||||
action: async (event): Promise<void> => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
await CoreNavigator.navigate(`/${CoreReportBuilderHandlerService.PAGE_NAME}`);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CoreReportBuilderHandler = makeSingleton(CoreReportBuilderHandlerService);
|
|
@ -0,0 +1,265 @@
|
|||
// (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.
|
||||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreSiteWSPreSets } from '@classes/site';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
const ROOT_CACHE_KEY = 'mmaReportBuilder:';
|
||||
export const REPORTS_LIST_LIMIT = 20;
|
||||
export const REPORT_ROWS_LIMIT = 20;
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CoreReportBuilderService {
|
||||
|
||||
/**
|
||||
* Obtain the reports list.
|
||||
*
|
||||
* @param page Current page.
|
||||
* @param perpage Reports obtained per page.
|
||||
* @returns Reports list.
|
||||
*/
|
||||
async getReports(page?: number, perpage?: number): Promise<CoreReportBuilderReport[]> {
|
||||
const site = CoreSites.getRequiredCurrentSite();
|
||||
const preSets: CoreSiteWSPreSets = { cacheKey: this.getReportBuilderCacheKey() };
|
||||
const response = await site.read<CoreReportBuilderListReportsWSResponse>(
|
||||
'core_reportbuilder_list_reports',
|
||||
{ page, perpage },
|
||||
preSets,
|
||||
);
|
||||
|
||||
return response.reports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the detail of a report.
|
||||
*
|
||||
* @param reportid Report id
|
||||
* @param page Current page.
|
||||
* @param perpage Rows obtained per page.
|
||||
* @returns Detail of the report.
|
||||
*/
|
||||
async loadReport(reportid: number, page?: number, perpage?: number): Promise<CoreReportBuilderRetrieveReportMapped> {
|
||||
const site = CoreSites.getRequiredCurrentSite();
|
||||
const preSets: CoreSiteWSPreSets = { cacheKey: this.getReportBuilderReportCacheKey() };
|
||||
const report = await site.read<CoreReportBuilderRetrieveReportWSResponse>(
|
||||
'core_reportbuilder_retrieve_report',
|
||||
{ reportid, page, perpage },
|
||||
preSets,
|
||||
);
|
||||
|
||||
if (!report) {
|
||||
throw new CoreError('An error ocurred.');
|
||||
}
|
||||
|
||||
const settingsData: {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
cardview_showfirsttitle: number;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
cardview_visiblecolumns: number;
|
||||
} = report.details.settingsdata ? JSON.parse(report.details.settingsdata) : {};
|
||||
|
||||
const mappedSettingsData: CoreReportBuilderReportDetailSettingsData = {
|
||||
cardviewShowFirstTitle: settingsData.cardview_showfirsttitle === 1,
|
||||
cardviewVisibleColumns: settingsData.cardview_visiblecolumns ?? 1,
|
||||
};
|
||||
|
||||
return {
|
||||
...report,
|
||||
details: {
|
||||
...report.details,
|
||||
settingsdata: mappedSettingsData,
|
||||
},
|
||||
data: {
|
||||
...report.data,
|
||||
rows: [...report.data.rows.map(row => ({ columns: row.columns, isExpanded: row.isExpanded ?? false }))],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* View a report.
|
||||
*
|
||||
* @param reportid Report viewed.
|
||||
* @returns Response of the WS.
|
||||
*/
|
||||
async viewReport(reportid: string): Promise<void> {
|
||||
const site = CoreSites.getRequiredCurrentSite();
|
||||
|
||||
await site.write<CoreReportBuilderViewReportWSResponse>('core_reportbuilder_view_report', { reportid });
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the feature is enabled or disabled.
|
||||
*
|
||||
* @returns Feature enabled or disabled.
|
||||
*/
|
||||
async isEnabled(): Promise<boolean> {
|
||||
const site = CoreSites.getRequiredCurrentSite();
|
||||
const hasTheVersionRequired = site.isVersionGreaterEqualThan('4.1');
|
||||
const hasAdvancedFeatureEnabled = site.canUseAdvancedFeature('enablecustomreports');
|
||||
const isFeatureDisabled = site.isFeatureDisabled('CoreReportBuilderDelegate');
|
||||
|
||||
return hasTheVersionRequired && hasAdvancedFeatureEnabled && !isFeatureDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates reports list WS calls.
|
||||
*
|
||||
* @returns Promise resolved when the list is invalidated.
|
||||
*/
|
||||
async invalidateReportsList(): Promise<void> {
|
||||
const site = CoreSites.getRequiredCurrentSite();
|
||||
await site.invalidateWsCacheForKey(this.getReportBuilderCacheKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates report WS calls.
|
||||
*
|
||||
* @returns Promise resolved when report is invalidated.
|
||||
*/
|
||||
async invalidateReport(): Promise<void> {
|
||||
const site = CoreSites.getCurrentSite();
|
||||
|
||||
if (!site) {
|
||||
return;
|
||||
}
|
||||
|
||||
await site.invalidateWsCacheForKey(this.getReportBuilderReportCacheKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for report builder list WS calls.
|
||||
*
|
||||
* @returns Cache key.
|
||||
*/
|
||||
protected getReportBuilderCacheKey(): string {
|
||||
return ROOT_CACHE_KEY + 'list';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for report builder report WS calls.
|
||||
*
|
||||
* @returns Cache key.
|
||||
*/
|
||||
protected getReportBuilderReportCacheKey(): string {
|
||||
return ROOT_CACHE_KEY + 'report';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CoreReportBuilder = makeSingleton(CoreReportBuilderService);
|
||||
|
||||
type CoreReportBuilderPagination = {
|
||||
page?: number;
|
||||
perpage?: number;
|
||||
};
|
||||
|
||||
export type CoreReportBuilderRetrieveReportWSParams = CoreReportBuilderPagination & {
|
||||
reportid: number; // Report ID.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by core_reportbuilder_list_reports WS.
|
||||
*/
|
||||
export type CoreReportBuilderListReportsWSResponse = {
|
||||
reports: CoreReportBuilderReportWSResponse[];
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
||||
export type CoreReportBuilderReportWSResponse = {
|
||||
name: string; // Name.
|
||||
source: string; // Source.
|
||||
type: number; // Type.
|
||||
uniquerows: boolean; // Uniquerows.
|
||||
conditiondata: string; // Conditiondata.
|
||||
settingsdata: string | null; // Settingsdata.
|
||||
contextid: number; // Contextid.
|
||||
component: string; // Component.
|
||||
area: string; // Area.
|
||||
itemid: number; // Itemid.
|
||||
usercreated: number; // Usercreated.
|
||||
id: number; // Id.
|
||||
timecreated: number; // Timecreated.
|
||||
timemodified: number; // Timemodified.
|
||||
usermodified: number; // Usermodified.
|
||||
sourcename: string; // Sourcename.
|
||||
modifiedby: {
|
||||
id: number; // Id.
|
||||
email: string; // Email.
|
||||
idnumber: string; // Idnumber.
|
||||
phone1: string; // Phone1.
|
||||
phone2: string; // Phone2.
|
||||
department: string; // Department.
|
||||
institution: string; // Institution.
|
||||
fullname: string; // Fullname.
|
||||
identity: string; // Identity.
|
||||
profileurl: string; // Profileurl.
|
||||
profileimageurl: string; // Profileimageurl.
|
||||
profileimageurlsmall: string; // Profileimageurlsmall.
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by core_reportbuilder_retrieve_report WS.
|
||||
*/
|
||||
export type CoreReportBuilderRetrieveReportWSResponse = {
|
||||
details: CoreReportBuilderReportWSResponse;
|
||||
data: CoreReportBuilderReportDataWSResponse;
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
||||
export interface CoreReportBuilderRetrieveReportMapped extends Omit<CoreReportBuilderRetrieveReportWSResponse, 'details'> {
|
||||
details: CoreReportBuilderReportDetail;
|
||||
}
|
||||
|
||||
export type CoreReportBuilderReportDataWSResponse = {
|
||||
headers: string[]; // Headers.
|
||||
rows: { // Rows.
|
||||
columns: string[]; // Columns.
|
||||
isExpanded: boolean;
|
||||
}[];
|
||||
totalrowcount: number; // Totalrowcount.
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of core_reportbuilder_view_report WS.
|
||||
*/
|
||||
export type CoreReportBuilderViewReportWSParams = {
|
||||
reportid: number; // Report ID.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by core_reportbuilder_view_report WS.
|
||||
*/
|
||||
export type CoreReportBuilderViewReportWSResponse = {
|
||||
status: boolean; // Success.
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
||||
export interface CoreReportBuilderReportDetail extends Omit<CoreReportBuilderReportWSResponse, 'settingsdata'> {
|
||||
settingsdata: CoreReportBuilderReportDetailSettingsData;
|
||||
}
|
||||
|
||||
export type CoreReportBuilderReportDetailSettingsData = {
|
||||
cardviewShowFirstTitle: boolean;
|
||||
cardviewVisibleColumns: number;
|
||||
};
|
||||
|
||||
export interface CoreReportBuilderReport extends CoreReportBuilderReportWSResponse {};
|
Loading…
Reference in New Issue