MOBILE-2201 tag: Search page
parent
b5b480e226
commit
d00d401894
|
@ -1800,8 +1800,13 @@
|
||||||
"core.submit": "moodle",
|
"core.submit": "moodle",
|
||||||
"core.success": "moodle",
|
"core.success": "moodle",
|
||||||
"core.tablet": "local_moodlemobileapp",
|
"core.tablet": "local_moodlemobileapp",
|
||||||
|
"core.tag.defautltagcoll": "moodle",
|
||||||
"core.tag.errorareanotsupported": "local_moodlemobileapp",
|
"core.tag.errorareanotsupported": "local_moodlemobileapp",
|
||||||
|
"core.tag.inalltagcoll": "moodle",
|
||||||
"core.tag.itemstaggedwith": "moodle",
|
"core.tag.itemstaggedwith": "moodle",
|
||||||
|
"core.tag.notagsfound": "moodle",
|
||||||
|
"core.tag.searchtags": "moodle",
|
||||||
|
"core.tag.showingfirsttags": "moodle",
|
||||||
"core.tag.tag": "moodle",
|
"core.tag.tag": "moodle",
|
||||||
"core.tag.tagarea_course": "moodle",
|
"core.tag.tagarea_course": "moodle",
|
||||||
"core.tag.tagarea_course_modules": "moodle",
|
"core.tag.tagarea_course_modules": "moodle",
|
||||||
|
|
|
@ -1800,8 +1800,13 @@
|
||||||
"core.submit": "Submit",
|
"core.submit": "Submit",
|
||||||
"core.success": "Success",
|
"core.success": "Success",
|
||||||
"core.tablet": "Tablet",
|
"core.tablet": "Tablet",
|
||||||
|
"core.tag.defautltagcoll": "Default collection",
|
||||||
"core.tag.errorareanotsupported": "This tag area is not supported by the app.",
|
"core.tag.errorareanotsupported": "This tag area is not supported by the app.",
|
||||||
|
"core.tag.inalltagcoll": "Everywhere",
|
||||||
"core.tag.itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"",
|
"core.tag.itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"",
|
||||||
|
"core.tag.notagsfound": "No tags matching \"{{$a}}\" found",
|
||||||
|
"core.tag.searchtags": "Search tags",
|
||||||
|
"core.tag.showingfirsttags": "Showing {{$a}} most popular tags",
|
||||||
"core.tag.tag": "Tag",
|
"core.tag.tag": "Tag",
|
||||||
"core.tag.tagarea_course": "Courses",
|
"core.tag.tagarea_course": "Courses",
|
||||||
"core.tag.tagarea_course_modules": "Activities and resources",
|
"core.tag.tagarea_course_modules": "Activities and resources",
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
|
"defautltagcoll": "Default collection",
|
||||||
"errorareanotsupported": "This tag area is not supported by the app.",
|
"errorareanotsupported": "This tag area is not supported by the app.",
|
||||||
|
"inalltagcoll": "Everywhere",
|
||||||
"itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"",
|
"itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"",
|
||||||
|
"notagsfound": "No tags matching \"{{$a}}\" found",
|
||||||
|
"searchtags": "Search tags",
|
||||||
|
"showingfirsttags": "Showing {{$a}} most popular tags",
|
||||||
"tag": "Tag",
|
"tag": "Tag",
|
||||||
"tagarea_course": "Courses",
|
"tagarea_course": "Courses",
|
||||||
"tagarea_course_modules": "Activities and resources",
|
"tagarea_course_modules": "Activities and resources",
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-navbar core-back-button>
|
||||||
|
<ion-title>{{ 'core.tag.searchtags' | translate }}</ion-title>
|
||||||
|
</ion-navbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<ion-refresher [enabled]="loaded" (ionRefresh)="refreshData($event)">
|
||||||
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
|
</ion-refresher>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col col-12 [attr.col-sm-6]="collections && collections.length > 1 ? '' : null">
|
||||||
|
<core-search-box (onSubmit)="searchTags($event)" (onClear)="searchTags('')" [initialSearch]="query" [disabled]="searching" autocorrect="off" [spellcheck]="false" [autoFocus]="true" [lengthCheck]="0"></core-search-box>
|
||||||
|
</ion-col>
|
||||||
|
<ion-col col-12 col-sm-6 *ngIf="collections && collections.length > 1">
|
||||||
|
<ion-select text-start [(ngModel)]="collectionId" (ngModelChange)="searchTags(query)" [disabled]="searching" interface="popover" class="core-button-select">
|
||||||
|
<ion-option [value]="0">{{ 'core.tag.inalltagcoll' | translate }}</ion-option>
|
||||||
|
<ion-option *ngFor="let collection of collections" [value]="collection.id">{{ collection.name }}</ion-option>
|
||||||
|
</ion-select>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
<core-loading [hideUntil]="loaded && !searching">
|
||||||
|
<core-empty-box *ngIf="!cloud || !cloud.tags || !cloud.tags.length" icon="pricetags" [message]="'core.tag.notagsfound' | translate: {$a: query}"></core-empty-box>
|
||||||
|
|
||||||
|
<ng-container *ngIf="cloud && cloud.tags && cloud.tags.length > 0">
|
||||||
|
<div text-center class="core-tag-cloud">
|
||||||
|
<ion-badge *ngFor="let tag of cloud.tags" (click)="openTag(tag)" text-wrap>
|
||||||
|
<span [class]="'size' + tag.size" >{{ tag.name }}</span>
|
||||||
|
</ion-badge>
|
||||||
|
</div>
|
||||||
|
<p *ngIf="cloud.tags.length < cloud.totalcount" text-center>
|
||||||
|
{{ 'core.tag.showingfirsttags' | translate: {$a: cloud.tags.length} }}
|
||||||
|
</p>
|
||||||
|
</ng-container>
|
||||||
|
</core-loading>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,33 @@
|
||||||
|
// (C) Copyright 2015 Martin Dougiamas
|
||||||
|
//
|
||||||
|
// 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 { IonicPageModule } from 'ionic-angular';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { CoreTagSearchPage } from './search';
|
||||||
|
import { CoreComponentsModule } from '@components/components.module';
|
||||||
|
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
CoreTagSearchPage
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreComponentsModule,
|
||||||
|
CoreDirectivesModule,
|
||||||
|
IonicPageModule.forChild(CoreTagSearchPage),
|
||||||
|
TranslateModule.forChild()
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class CoreTagSerchPageModule {}
|
|
@ -0,0 +1,95 @@
|
||||||
|
ion-app.app-root page-core-tag-search {
|
||||||
|
core-search-box ion-card {
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-tag-cloud ion-badge {
|
||||||
|
margin: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.size20 {
|
||||||
|
font-size: 3.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size19 {
|
||||||
|
font-size: 3.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size18 {
|
||||||
|
font-size: 3.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size17 {
|
||||||
|
font-size: 3.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size16 {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size15 {
|
||||||
|
font-size: 2.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size14 {
|
||||||
|
font-size: 2.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size13 {
|
||||||
|
font-size: 2.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size12 {
|
||||||
|
font-size: 2.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size11 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size10 {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size9 {
|
||||||
|
font-size: 2.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size8 {
|
||||||
|
font-size: 2.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size7 {
|
||||||
|
font-size: 2.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size6 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size5 {
|
||||||
|
font-size: 1.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size4 {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size3 {
|
||||||
|
font-size: 1.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size2 {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size0 {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
// (C) Copyright 2015 Martin Dougiamas
|
||||||
|
//
|
||||||
|
// 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 } from '@angular/core';
|
||||||
|
import { IonicPage, NavParams, NavController } from 'ionic-angular';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { CoreAppProvider } from '@providers/app';
|
||||||
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
|
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||||
|
import { CoreTagProvider, CoreTagCloud, CoreTagCollection, CoreTagCloudTag } from '@core/tag/providers/tag';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page that displays most used tags and allows searching.
|
||||||
|
*/
|
||||||
|
@IonicPage({ segment: 'core-tag-search' })
|
||||||
|
@Component({
|
||||||
|
selector: 'page-core-tag-search',
|
||||||
|
templateUrl: 'search.html',
|
||||||
|
})
|
||||||
|
export class CoreTagSearchPage {
|
||||||
|
collectionId: number;
|
||||||
|
query: string;
|
||||||
|
collections: CoreTagCollection[] = [];
|
||||||
|
cloud: CoreTagCloud;
|
||||||
|
loaded = false;
|
||||||
|
searching = false;
|
||||||
|
|
||||||
|
constructor(private navCtrl: NavController, navParams: NavParams, private appProvider: CoreAppProvider,
|
||||||
|
private translate: TranslateService, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
||||||
|
private textUtils: CoreTextUtilsProvider, private contentLinksHelper: CoreContentLinksHelperProvider,
|
||||||
|
private tagProvider: CoreTagProvider) {
|
||||||
|
this.collectionId = navParams.get('collectionId') || 0;
|
||||||
|
this.query = navParams.get('query') || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View loaded.
|
||||||
|
*/
|
||||||
|
ionViewDidLoad(): void {
|
||||||
|
this.fetchData().finally(() => {
|
||||||
|
this.loaded = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchData(): Promise<any> {
|
||||||
|
return Promise.all([
|
||||||
|
this.fetchCollections(),
|
||||||
|
this.fetchTags()
|
||||||
|
]).catch((error) => {
|
||||||
|
this.domUtils.showErrorModalDefault(error, 'Error loading tags.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch tag collections.
|
||||||
|
*
|
||||||
|
* @return {Promise<any>} Resolved when done.
|
||||||
|
*/
|
||||||
|
fetchCollections(): Promise<any> {
|
||||||
|
return this.tagProvider.getTagCollections().then((collections) => {
|
||||||
|
collections.forEach((collection) => {
|
||||||
|
if (!collection.name && collection.isdefault) {
|
||||||
|
collection.name = this.translate.instant('core.tag.defautltagcoll');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.collections = collections;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch tags.
|
||||||
|
*
|
||||||
|
* @return {Promise<any>} Resolved when done.
|
||||||
|
*/
|
||||||
|
fetchTags(): Promise<any> {
|
||||||
|
return this.tagProvider.getTagCloud(this.collectionId, undefined, undefined, this.query).then((cloud) => {
|
||||||
|
this.cloud = cloud;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to tag index page.
|
||||||
|
*/
|
||||||
|
openTag(tag: CoreTagCloudTag): void {
|
||||||
|
const url = this.textUtils.decodeURI(tag.viewurl);
|
||||||
|
this.contentLinksHelper.handleLink(url, undefined, this.navCtrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh data.
|
||||||
|
*
|
||||||
|
* @param {any} refresher Refresher.
|
||||||
|
*/
|
||||||
|
refreshData(refresher: any): void {
|
||||||
|
this.utils.allPromises([
|
||||||
|
this.tagProvider.invalidateTagCollections(),
|
||||||
|
this.tagProvider.invalidateTagCloud(this.collectionId, undefined, undefined, this.query),
|
||||||
|
]).finally(() => {
|
||||||
|
return this.fetchData().finally(() => {
|
||||||
|
refresher.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search tags.
|
||||||
|
*
|
||||||
|
* @param {string} query Search query.
|
||||||
|
* @return {Promise<any>} Resolved when done.
|
||||||
|
*/
|
||||||
|
searchTags(query: string): Promise<any> {
|
||||||
|
this.searching = true;
|
||||||
|
this.query = query;
|
||||||
|
this.appProvider.closeKeyboard();
|
||||||
|
|
||||||
|
return this.fetchTags().catch((error) => {
|
||||||
|
this.domUtils.showErrorModalDefault(error, 'Error loading tags.');
|
||||||
|
}).finally(() => {
|
||||||
|
this.searching = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
// (C) Copyright 2015 Martin Dougiamas
|
||||||
|
//
|
||||||
|
// 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 { CoreTagProvider } from './tag';
|
||||||
|
import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@core/mainmenu/providers/delegate';
|
||||||
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to inject an option into main menu.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class CoreTagMainMenuHandler implements CoreMainMenuHandler {
|
||||||
|
name = 'CoreTag';
|
||||||
|
priority = 300;
|
||||||
|
|
||||||
|
constructor(private tagProvider: CoreTagProvider, private utils: CoreUtilsProvider) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the handler is enabled on a site level.
|
||||||
|
*
|
||||||
|
* @return {boolean | Promise<boolean>} Whether or not the handler is enabled on a site level.
|
||||||
|
*/
|
||||||
|
isEnabled(): boolean | Promise<boolean> {
|
||||||
|
return this.tagProvider.areTagsAvailable().then((available) => {
|
||||||
|
if (!available) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The only way to check whether tags are enabled on web is to perform a WS call.
|
||||||
|
return this.utils.promiseWorks(this.tagProvider.getTagCollections());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data needed to render the handler.
|
||||||
|
*
|
||||||
|
* @return {CoreMainMenuHandlerData} Data needed to render the handler.
|
||||||
|
*/
|
||||||
|
getDisplayData(): CoreMainMenuHandlerData {
|
||||||
|
return {
|
||||||
|
icon: 'pricetags',
|
||||||
|
title: 'core.tag.tags',
|
||||||
|
page: 'CoreTagSearchPage',
|
||||||
|
class: 'core-tag-search-handler'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,40 @@ import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure of a tag cloud returned by WS.
|
||||||
|
*/
|
||||||
|
export interface CoreTagCloud {
|
||||||
|
tags: CoreTagCloudTag[];
|
||||||
|
tagscount: number;
|
||||||
|
totalcount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure of a tag cloud tag returned by WS.
|
||||||
|
*/
|
||||||
|
export interface CoreTagCloudTag {
|
||||||
|
name: string;
|
||||||
|
viewurl: string;
|
||||||
|
flag: boolean;
|
||||||
|
isstandard: boolean;
|
||||||
|
count: number;
|
||||||
|
size: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure of a tag collection returned by WS.
|
||||||
|
*/
|
||||||
|
export interface CoreTagCollection {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
isdefault: boolean;
|
||||||
|
component: string;
|
||||||
|
sortoder: number;
|
||||||
|
searchable: boolean;
|
||||||
|
customurl: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure of a tag index returned by WS.
|
* Structure of a tag index returned by WS.
|
||||||
*/
|
*/
|
||||||
|
@ -57,6 +91,8 @@ export interface CoreTagItem {
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CoreTagProvider {
|
export class CoreTagProvider {
|
||||||
|
|
||||||
|
static SEARCH_LIMIT = 150;
|
||||||
|
|
||||||
protected ROOT_CACHE_KEY = 'CoreTag:';
|
protected ROOT_CACHE_KEY = 'CoreTag:';
|
||||||
|
|
||||||
constructor(private sitesProvider: CoreSitesProvider, private translate: TranslateService) {}
|
constructor(private sitesProvider: CoreSitesProvider, private translate: TranslateService) {}
|
||||||
|
@ -89,6 +125,71 @@ export class CoreTagProvider {
|
||||||
!site.isFeatureDisabled('NoDelegate_CoreTag');
|
!site.isFeatureDisabled('NoDelegate_CoreTag');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the tag cloud.
|
||||||
|
*
|
||||||
|
* @param {number} [collectionId=0] Tag collection ID.
|
||||||
|
* @param {boolean} [isStandard=false] Whether to return only standard tags.
|
||||||
|
* @param {string} [sort='name'] Sort order for display (id, name, rawname, count, flag, isstandard, tagcollid).
|
||||||
|
* @param {string} [search=''] Search string.
|
||||||
|
* @param {number} [fromContextId=0] Context ID where this tag cloud is displayed.
|
||||||
|
* @param {number} [contextId=0] Only retrieve tag instances in this context.
|
||||||
|
* @param {boolean} [recursive=true] Retrieve tag instances in the context and its children.
|
||||||
|
* @param {number} [limit] Maximum number of tags to retrieve. Defaults to SEARCH_LIMIT.
|
||||||
|
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||||
|
* @return {Promise<CoreTagCloud>} Promise resolved with the tag cloud.
|
||||||
|
* @since 3.7
|
||||||
|
*/
|
||||||
|
getTagCloud(collectionId: number = 0, isStandard: boolean = false, sort: string = 'name', search: string = '',
|
||||||
|
fromContextId: number = 0, contextId: number = 0, recursive: boolean = true, limit?: number, siteId?: string):
|
||||||
|
Promise<CoreTagCloud> {
|
||||||
|
limit = limit || CoreTagProvider.SEARCH_LIMIT;
|
||||||
|
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
const params = {
|
||||||
|
tagcollid: collectionId,
|
||||||
|
isstandard: isStandard,
|
||||||
|
limit: limit,
|
||||||
|
sort: sort,
|
||||||
|
search: search,
|
||||||
|
fromctx: fromContextId,
|
||||||
|
ctx: contextId,
|
||||||
|
rec: recursive
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
||||||
|
cacheKey: this.getTagCloudKey(collectionId, isStandard, sort, search, fromContextId, contextId, recursive),
|
||||||
|
getFromCache: search != '' // Try to get updated data when searching.
|
||||||
|
};
|
||||||
|
|
||||||
|
return site.read('core_tag_get_tag_cloud', params, preSets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the tag collections.
|
||||||
|
*
|
||||||
|
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||||
|
* @return {Promise<CoreTagCollection[]>} Promise resolved with the tag collections.
|
||||||
|
* @since 3.7
|
||||||
|
*/
|
||||||
|
getTagCollections(siteId?: string): Promise<CoreTagCollection[]> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
cacheKey: this.getTagCollectionsKey()
|
||||||
|
};
|
||||||
|
|
||||||
|
return site.read('core_tag_get_tag_collections', null, preSets).then((response) => {
|
||||||
|
if (!response || !response.collections) {
|
||||||
|
return Promise.reject(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.collections;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the tag index.
|
* Fetch the tag index.
|
||||||
*
|
*
|
||||||
|
@ -142,6 +243,40 @@ export class CoreTagProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate tag cloud.
|
||||||
|
*
|
||||||
|
* @param {number} [collectionId=0] Tag collection ID.
|
||||||
|
* @param {boolean} [isStandard=false] Whether to return only standard tags.
|
||||||
|
* @param {string} [sort='name'] Sort order for display (id, name, rawname, count, flag, isstandard, tagcollid).
|
||||||
|
* @param {string} [search=''] Search string.
|
||||||
|
* @param {number} [fromContextId=0] Context ID where this tag cloud is displayed.
|
||||||
|
* @param {number} [contextId=0] Only retrieve tag instances in this context.
|
||||||
|
* @param {boolean} [recursive=true] Retrieve tag instances in the context and its children.
|
||||||
|
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
invalidateTagCloud(collectionId: number = 0, isStandard: boolean = false, sort: string = 'name', search: string = '',
|
||||||
|
fromContextId: number = 0, contextId: number = 0, recursive: boolean = true, siteId?: string): Promise<any> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
const key = this.getTagCloudKey(collectionId, isStandard, sort, search, fromContextId, contextId, recursive);
|
||||||
|
|
||||||
|
return site.invalidateWsCacheForKey(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate tag collections.
|
||||||
|
*
|
||||||
|
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
invalidateTagCollections(siteId?: string): Promise<any> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
const key = this.getTagCollectionsKey();
|
||||||
|
|
||||||
|
return site.invalidateWsCacheForKey(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate tag index.
|
* Invalidate tag index.
|
||||||
*
|
*
|
||||||
|
@ -163,6 +298,33 @@ export class CoreTagProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for tag cloud.
|
||||||
|
*
|
||||||
|
* @param {number} collectionId Tag collection ID.
|
||||||
|
* @param {boolean} isStandard Whether to return only standard tags.
|
||||||
|
* @param {string} sort Sort order for display (id, name, rawname, count, flag, isstandard, tagcollid).
|
||||||
|
* @param {string} search Search string.
|
||||||
|
* @param {number} fromContextId Context ID where this tag cloud is displayed.
|
||||||
|
* @param {number} contextId Only retrieve tag instances in this context.
|
||||||
|
* @param {boolean} recursive Retrieve tag instances in the context and it's children.
|
||||||
|
* @return {string} Cache key.
|
||||||
|
*/
|
||||||
|
protected getTagCloudKey(collectionId: number, isStandard: boolean, sort: string, search: string, fromContextId: number,
|
||||||
|
contextId: number, recursive: boolean): string {
|
||||||
|
return this.ROOT_CACHE_KEY + 'cloud:' + collectionId + ':' + (isStandard ? 1 : 0) + ':' + sort + ':' + search + ':' +
|
||||||
|
fromContextId + ':' + contextId + ':' + (recursive ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for tag collections.
|
||||||
|
*
|
||||||
|
* @return {string} Cache key.
|
||||||
|
*/
|
||||||
|
protected getTagCollectionsKey(): string {
|
||||||
|
return this.ROOT_CACHE_KEY + 'collections';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get cache key for tag index.
|
* Get cache key for tag index.
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,9 +13,11 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
|
||||||
import { CoreTagProvider } from './providers/tag';
|
import { CoreTagProvider } from './providers/tag';
|
||||||
import { CoreTagHelperProvider } from './providers/helper';
|
import { CoreTagHelperProvider } from './providers/helper';
|
||||||
import { CoreTagAreaDelegate } from './providers/area-delegate';
|
import { CoreTagAreaDelegate } from './providers/area-delegate';
|
||||||
|
import { CoreTagMainMenuHandler } from './providers/mainmenu-handler';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -25,8 +27,13 @@ import { CoreTagAreaDelegate } from './providers/area-delegate';
|
||||||
providers: [
|
providers: [
|
||||||
CoreTagProvider,
|
CoreTagProvider,
|
||||||
CoreTagHelperProvider,
|
CoreTagHelperProvider,
|
||||||
CoreTagAreaDelegate
|
CoreTagAreaDelegate,
|
||||||
|
CoreTagMainMenuHandler
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class CoreTagModule {
|
export class CoreTagModule {
|
||||||
|
|
||||||
|
constructor(mainMenuDelegate: CoreMainMenuDelegate, mainMenuHandler: CoreTagMainMenuHandler) {
|
||||||
|
mainMenuDelegate.registerHandler(mainMenuHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue