diff --git a/src/addon/block/myoverview/component/myoverview.ts b/src/addon/block/myoverview/components/myoverview/myoverview.ts
similarity index 100%
rename from src/addon/block/myoverview/component/myoverview.ts
rename to src/addon/block/myoverview/components/myoverview/myoverview.ts
diff --git a/src/addon/block/myoverview/lang/en.json b/src/addon/block/myoverview/lang/en.json
index 3e7c5ea22..64d436ecd 100644
--- a/src/addon/block/myoverview/lang/en.json
+++ b/src/addon/block/myoverview/lang/en.json
@@ -2,11 +2,12 @@
"all": "All",
"future": "Future",
"inprogress": "In progress",
- "past": "Past",
+ "lastaccessed": "Last accessed",
"morecourses": "More courses",
"nocoursesfuture": "No future courses",
"nocoursesinprogress": "No in progress courses",
"nocoursespast": "No past courses",
- "lastaccessed": "Last accessed",
+ "past": "Past",
+ "pluginname": "Course Overview",
"title": "Title"
}
diff --git a/src/addon/block/myoverview/myoverview.module.ts b/src/addon/block/myoverview/myoverview.module.ts
index d628b58d1..91e854546 100644
--- a/src/addon/block/myoverview/myoverview.module.ts
+++ b/src/addon/block/myoverview/myoverview.module.ts
@@ -15,22 +15,26 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
-import { CoreComponentsModule } from '@components/components.module';
-import { CoreCoursesComponentsModule } from '@core/courses/components/components.module';
-import { AddonBlockMyOverviewComponent } from './component/myoverview';
+import { CoreBlockDelegate } from '@core/block/providers/delegate';
+import { AddonBlockMyOverviewComponentsModule } from './components/components.module';
+import { AddonBlockMyOverviewHandler } from './providers/block-handler';
@NgModule({
declarations: [
- AddonBlockMyOverviewComponent
],
imports: [
IonicModule,
- CoreComponentsModule,
- CoreCoursesComponentsModule,
+ AddonBlockMyOverviewComponentsModule,
TranslateModule.forChild()
],
exports: [
- AddonBlockMyOverviewComponent
+ ],
+ providers: [
+ AddonBlockMyOverviewHandler
]
})
-export class AddonBlockMyOverviewModule {}
+export class AddonBlockMyOverviewModule {
+ constructor(blockDelegate: CoreBlockDelegate, blockHandler: AddonBlockMyOverviewHandler) {
+ blockDelegate.registerHandler(blockHandler);
+ }
+}
diff --git a/src/addon/block/myoverview/providers/block-handler.ts b/src/addon/block/myoverview/providers/block-handler.ts
new file mode 100644
index 000000000..5f723467c
--- /dev/null
+++ b/src/addon/block/myoverview/providers/block-handler.ts
@@ -0,0 +1,62 @@
+// (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, Injector } from '@angular/core';
+import { CoreSitesProvider } from '@providers/sites';
+import { CoreBlockHandlerData } from '@core/block/providers/delegate';
+import { CoreCoursesProvider } from '@core/courses/providers/courses';
+import { AddonBlockMyOverviewComponent } from '../components/myoverview/myoverview';
+import { CoreBlockBaseHandler } from '@core/block/classes/base-block-handler';
+
+/**
+ * Block handler.
+ */
+@Injectable()
+export class AddonBlockMyOverviewHandler extends CoreBlockBaseHandler {
+ name = 'AddonBlockMyOverview';
+ blockName = 'myoverview';
+
+ constructor(private coursesProvider: CoreCoursesProvider, private sitesProvider: CoreSitesProvider) {
+ super();
+ }
+
+ /**
+ * Check if the handler is enabled on a site level.
+ *
+ * @return {boolean} Whether or not the handler is enabled on a site level.
+ */
+ isEnabled(): boolean | Promise
{
+ return this.sitesProvider.getCurrentSite().isVersionGreaterEqualThan('3.6') ||
+ !this.coursesProvider.isMyCoursesDisabledInSite();
+ }
+
+ /**
+ * Returns the data needed to render the block.
+ *
+ * @param {Injector} injector Injector.
+ * @param {any} block The block to render.
+ * @param {string} contextLevel The context where the block will be used.
+ * @param {number} instanceId The instance ID associated with the context level.
+ * @return {CoreBlockHandlerData|Promise} Data or promise resolved with the data.
+ */
+ getDisplayData?(injector: Injector, block: any, contextLevel: string, instanceId: number)
+ : CoreBlockHandlerData | Promise {
+
+ return {
+ title: 'addon.block_myoverview.pluginname',
+ class: 'addon-block-myoverview',
+ component: AddonBlockMyOverviewComponent
+ };
+ }
+}
diff --git a/src/addon/block/sitemainmenu/components/sitemainmenu/addon-block-sitemainmenu.html b/src/addon/block/sitemainmenu/components/sitemainmenu/addon-block-sitemainmenu.html
index 5941df804..74ec899a7 100644
--- a/src/addon/block/sitemainmenu/components/sitemainmenu/addon-block-sitemainmenu.html
+++ b/src/addon/block/sitemainmenu/components/sitemainmenu/addon-block-sitemainmenu.html
@@ -1,3 +1,6 @@
+
+ {{ 'addon.block_sitemainmenu.pluginname' | translate }}
+
diff --git a/src/addon/block/sitemainmenu/providers/block-handler.ts b/src/addon/block/sitemainmenu/providers/block-handler.ts
index 09a94796d..8c699aff0 100644
--- a/src/addon/block/sitemainmenu/providers/block-handler.ts
+++ b/src/addon/block/sitemainmenu/providers/block-handler.ts
@@ -13,28 +13,20 @@
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
-import { CoreBlockHandler, CoreBlockHandlerData } from '@core/block/providers/delegate';
+import { CoreBlockHandlerData } from '@core/block/providers/delegate';
import { AddonBlockSiteMainMenuComponent } from '../components/sitemainmenu/sitemainmenu';
+import { CoreBlockBaseHandler } from '@core/block/classes/base-block-handler';
/**
- * Course nav handler.
+ * Block handler.
*/
@Injectable()
-export class AddonBlockSiteMainMenuHandler implements CoreBlockHandler {
- name = 'AddonBlockSiteMainMenuHandler';
+export class AddonBlockSiteMainMenuHandler extends CoreBlockBaseHandler {
+ name = 'AddonBlockSiteMainMenu';
blockName = 'site_main_menu';
constructor() {
- // Nothing to do.
- }
-
- /**
- * Check if the handler is enabled on a site level.
- *
- * @return {boolean} Whether or not the handler is enabled on a site level.
- */
- isEnabled(): boolean | Promise {
- return true;
+ super();
}
/**
diff --git a/src/addon/block/timeline/components/components.module.ts b/src/addon/block/timeline/components/components.module.ts
new file mode 100644
index 000000000..c408138ef
--- /dev/null
+++ b/src/addon/block/timeline/components/components.module.ts
@@ -0,0 +1,53 @@
+// (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 { CommonModule } from '@angular/common';
+import { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { CorePipesModule } from '@pipes/pipes.module';
+import { CoreCoursesComponentsModule } from '@core/courses/components/components.module';
+import { AddonBlockTimelineComponent } from './timeline/timeline';
+import { AddonBlockTimelineEventsComponent } from './events/events';
+import { CoreCourseComponentsModule } from '@core/course/components/components.module';
+
+@NgModule({
+ declarations: [
+ AddonBlockTimelineComponent,
+ AddonBlockTimelineEventsComponent
+ ],
+ imports: [
+ CommonModule,
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ CorePipesModule,
+ CoreCoursesComponentsModule,
+ CoreCourseComponentsModule
+ ],
+ providers: [
+ ],
+ exports: [
+ AddonBlockTimelineComponent,
+ AddonBlockTimelineEventsComponent
+ ],
+ entryComponents: [
+ AddonBlockTimelineComponent,
+ AddonBlockTimelineEventsComponent
+ ]
+})
+export class AddonBlockTimelineComponentsModule {}
diff --git a/src/addon/block/timeline/components/timeline/addon-block-timeline.html b/src/addon/block/timeline/components/timeline/addon-block-timeline.html
index 037e8b7a3..50096c64f 100644
--- a/src/addon/block/timeline/components/timeline/addon-block-timeline.html
+++ b/src/addon/block/timeline/components/timeline/addon-block-timeline.html
@@ -1,34 +1,39 @@
-
-
-
- {{ 'core.all' | translate }}
- {{ 'addon.block_timeline.overdue' | translate }}
- {{ 'addon.block_timeline.duedate' | translate }}
- {{ 'addon.block_timeline.next7days' | translate }}
- {{ 'addon.block_timeline.next30days' | translate }}
- {{ 'addon.block_timeline.next3months' | translate }}
- {{ 'addon.block_timeline.next6months' | translate }}
-
-
-
-
- {{ 'addon.block_timeline.sortbydates' | translate }}
- {{ 'addon.block_timeline.sortbycourses' | translate }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {{ 'addon.block_timeline.pluginname' | translate }}
+
+
+
+
+
+ {{ 'core.all' | translate }}
+ {{ 'addon.block_timeline.overdue' | translate }}
+ {{ 'addon.block_timeline.duedate' | translate }}
+ {{ 'addon.block_timeline.next7days' | translate }}
+ {{ 'addon.block_timeline.next30days' | translate }}
+ {{ 'addon.block_timeline.next3months' | translate }}
+ {{ 'addon.block_timeline.next6months' | translate }}
+
+
+
+
+ {{ 'addon.block_timeline.sortbydates' | translate }}
+ {{ 'addon.block_timeline.sortbycourses' | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/addon/block/timeline/lang/en.json b/src/addon/block/timeline/lang/en.json
index 1086d152e..a9460e4d7 100644
--- a/src/addon/block/timeline/lang/en.json
+++ b/src/addon/block/timeline/lang/en.json
@@ -7,6 +7,7 @@
"nocoursesinprogress": "No in progress courses",
"noevents": "No upcoming activities due",
"overdue": "Overdue",
+ "pluginname": "Timeline",
"sortbycourses": "Sort by courses",
"sortbydates": "Sort by dates"
}
\ No newline at end of file
diff --git a/src/addon/block/timeline/providers/block-handler.ts b/src/addon/block/timeline/providers/block-handler.ts
new file mode 100644
index 000000000..c0f60e7dd
--- /dev/null
+++ b/src/addon/block/timeline/providers/block-handler.ts
@@ -0,0 +1,65 @@
+// (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, Injector } from '@angular/core';
+import { CoreSitesProvider } from '@providers/sites';
+import { CoreBlockHandlerData } from '@core/block/providers/delegate';
+import { CoreCoursesProvider } from '@core/courses/providers/courses';
+import { AddonBlockTimelineProvider } from '@addon/block/timeline/providers/timeline';
+import { AddonBlockTimelineComponent } from '../components/timeline/timeline';
+import { CoreBlockBaseHandler } from '@core/block/classes/base-block-handler';
+
+/**
+ * Block handler.
+ */
+@Injectable()
+export class AddonBlockTimelineHandler extends CoreBlockBaseHandler {
+ name = 'AddonBlockTimeline';
+ blockName = 'timeline';
+
+ constructor(private timelineProvider: AddonBlockTimelineProvider, private coursesProvider: CoreCoursesProvider,
+ private sitesProvider: CoreSitesProvider) {
+
+ super();
+ }
+
+ /**
+ * Check if the handler is enabled on a site level.
+ *
+ * @return {boolean} Whether or not the handler is enabled on a site level.
+ */
+ isEnabled(): boolean | Promise {
+ return this.timelineProvider.isAvailable() && (this.sitesProvider.getCurrentSite().isVersionGreaterEqualThan('3.6') ||
+ !this.coursesProvider.isMyCoursesDisabledInSite());
+ }
+
+ /**
+ * Returns the data needed to render the block.
+ *
+ * @param {Injector} injector Injector.
+ * @param {any} block The block to render.
+ * @param {string} contextLevel The context where the block will be used.
+ * @param {number} instanceId The instance ID associated with the context level.
+ * @return {CoreBlockHandlerData|Promise} Data or promise resolved with the data.
+ */
+ getDisplayData?(injector: Injector, block: any, contextLevel: string, instanceId: number)
+ : CoreBlockHandlerData | Promise {
+
+ return {
+ title: 'addon.block_timeline.pluginname',
+ class: 'addon-block-timeline',
+ component: AddonBlockTimelineComponent
+ };
+ }
+}
diff --git a/src/addon/block/timeline/timeline.module.ts b/src/addon/block/timeline/timeline.module.ts
index 3c2f5fa80..92ed2cefc 100644
--- a/src/addon/block/timeline/timeline.module.ts
+++ b/src/addon/block/timeline/timeline.module.ts
@@ -15,33 +15,28 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
-import { CoreComponentsModule } from '@components/components.module';
-import { CoreDirectivesModule } from '@directives/directives.module';
-import { CorePipesModule } from '@pipes/pipes.module';
-import { CoreCoursesComponentsModule } from '@core/courses/components/components.module';
-import { AddonBlockTimelineComponent } from './components/timeline/timeline';
-import { AddonBlockTimelineEventsComponent } from './components/events/events';
+import { CoreBlockDelegate } from '@core/block/providers/delegate';
+import { AddonBlockTimelineComponentsModule } from './components/components.module';
import { AddonBlockTimelineProvider } from './providers/timeline';
+import { AddonBlockTimelineHandler } from './providers/block-handler';
@NgModule({
declarations: [
- AddonBlockTimelineComponent,
- AddonBlockTimelineEventsComponent
],
imports: [
IonicModule,
- CoreComponentsModule,
- CoreDirectivesModule,
- CorePipesModule,
- CoreCoursesComponentsModule,
+ AddonBlockTimelineComponentsModule,
TranslateModule.forChild()
],
exports: [
- AddonBlockTimelineComponent,
- AddonBlockTimelineEventsComponent
],
providers: [
- AddonBlockTimelineProvider
+ AddonBlockTimelineProvider,
+ AddonBlockTimelineHandler
]
})
-export class AddonBlockTimelineModule {}
+export class AddonBlockTimelineModule {
+ constructor(blockDelegate: CoreBlockDelegate, blockHandler: AddonBlockTimelineHandler) {
+ blockDelegate.registerHandler(blockHandler);
+ }
+}
diff --git a/src/addon/files/pages/list/list.html b/src/addon/files/pages/list/list.html
index 9bb3ee955..ef80bd1e1 100644
--- a/src/addon/files/pages/list/list.html
+++ b/src/addon/files/pages/list/list.html
@@ -11,7 +11,7 @@
-
+
{{ 'addon.files.privatefiles' | translate }}
{{ 'addon.files.sitefiles' | translate }}
diff --git a/src/addon/messages/pages/discussion/discussion.scss b/src/addon/messages/pages/discussion/discussion.scss
index aac4cfeea..ef82fdd82 100644
--- a/src/addon/messages/pages/discussion/discussion.scss
+++ b/src/addon/messages/pages/discussion/discussion.scss
@@ -63,7 +63,7 @@ ion-app.app-root page-addon-messages-discussion {
min-height: initial;
line-height: initial;
@include margin(0, 0, 0, 10px);
- height: auto;
+ height: 1.6em !important;
-webkit-align-self: flex-end;
-ms-flex-item-align: end;
align-self: flex-end;
diff --git a/src/app/app.scss b/src/app/app.scss
index f5bad6d6d..145f1165f 100644
--- a/src/app/app.scss
+++ b/src/app/app.scss
@@ -738,6 +738,19 @@ ion-app.app-root {
}
}
+ .core-#{$color-name}-selected-item {
+ @include border-start(5px, solid, $color-base);
+ &.item-md {
+ @include padding(null, null, null, $item-md-padding-start - 5px);
+ }
+ &.item-ios {
+ @include padding(null, null, null, $item-ios-padding-start - 5px);
+ }
+ &.item-wp {
+ @include padding(null, null, null, $item-wp-padding-start - 5px);
+ }
+ }
+
.core-#{$color-name}-circle {
margin: 0 4px;
}
diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json
index 5cd0e4be3..9f4093645 100644
--- a/src/assets/lang/en.json
+++ b/src/assets/lang/en.json
@@ -20,6 +20,7 @@
"addon.block_myoverview.nocoursesinprogress": "No in progress courses",
"addon.block_myoverview.nocoursespast": "No past courses",
"addon.block_myoverview.past": "Past",
+ "addon.block_myoverview.pluginname": "Course Overview",
"addon.block_myoverview.title": "Title",
"addon.block_sitemainmenu.pluginname": "Main menu",
"addon.block_timeline.duedate": "Due date",
@@ -30,6 +31,7 @@
"addon.block_timeline.nocoursesinprogress": "No in progress courses",
"addon.block_timeline.noevents": "No upcoming activities due",
"addon.block_timeline.overdue": "Overdue",
+ "addon.block_timeline.pluginname": "Timeline",
"addon.block_timeline.sortbycourses": "Sort by courses",
"addon.block_timeline.sortbydates": "Sort by dates",
"addon.calendar.calendar": "Calendar",
@@ -1192,7 +1194,6 @@
"core.courses.searchcoursesadvice": "You can use the search courses button to find courses to access as a guest or enrol yourself in courses that allow it.",
"core.courses.selfenrolment": "Self enrolment",
"core.courses.sendpaymentbutton": "Send payment via PayPal",
- "core.courses.timeline": "Timeline",
"core.courses.totalcoursesearchresults": "Total courses: {{$a}}",
"core.currentdevice": "Current device",
"core.datastoredoffline": "Data stored in the device because it couldn't be sent. It will be sent automatically later.",
diff --git a/src/components/tabs/tabs.ts b/src/components/tabs/tabs.ts
index 07dfebfb2..81f2f89f5 100644
--- a/src/components/tabs/tabs.ts
+++ b/src/components/tabs/tabs.ts
@@ -287,6 +287,7 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges, OnDe
this.slideChanged();
setTimeout(() => {
+ this.calculateTabBarHeight();
this.slides.update();
this.slides.resize();
diff --git a/src/core/block/components/block/core-block.html b/src/core/block/components/block/core-block.html
index 80ef357de..591977ecd 100644
--- a/src/core/block/components/block/core-block.html
+++ b/src/core/block/components/block/core-block.html
@@ -1,6 +1,4 @@
- {{ title | translate }}
-
diff --git a/src/core/block/providers/default-block-handler.ts b/src/core/block/providers/default-block-handler.ts
index c4d04891f..23257b2c5 100644
--- a/src/core/block/providers/default-block-handler.ts
+++ b/src/core/block/providers/default-block-handler.ts
@@ -21,7 +21,7 @@ import { CoreBlockBaseHandler } from '../classes/base-block-handler';
@Injectable()
export class CoreBlockDefaultHandler extends CoreBlockBaseHandler {
name = 'CoreBlockDefault';
- type = 'default';
+ blockName = 'default';
constructor() {
super();
diff --git a/src/core/block/providers/delegate.ts b/src/core/block/providers/delegate.ts
index b6d605bfa..363dff591 100644
--- a/src/core/block/providers/delegate.ts
+++ b/src/core/block/providers/delegate.ts
@@ -80,6 +80,8 @@ export class CoreBlockDelegate extends CoreDelegate {
protected handlerNameProperty = 'blockName';
+ protected featurePrefix = 'CoreBlockDelegate_';
+
constructor(logger: CoreLoggerProvider, sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider,
protected defaultHandler: CoreBlockDefaultHandler) {
super('CoreBlockDelegate', logger, sitesProvider, eventsProvider);
diff --git a/src/core/course/pages/section-selector/section-selector.html b/src/core/course/pages/section-selector/section-selector.html
index 6f54622ed..3939c589f 100644
--- a/src/core/course/pages/section-selector/section-selector.html
+++ b/src/core/course/pages/section-selector/section-selector.html
@@ -10,7 +10,7 @@
-
+
{{ 'core.course.hiddenfromstudents' | translate }}
diff --git a/src/core/courses/lang/en.json b/src/core/courses/lang/en.json
index a372d5c29..f961a47ef 100644
--- a/src/core/courses/lang/en.json
+++ b/src/core/courses/lang/en.json
@@ -28,6 +28,5 @@
"searchcoursesadvice": "You can use the search courses button to find courses to access as a guest or enrol yourself in courses that allow it.",
"selfenrolment": "Self enrolment",
"sendpaymentbutton": "Send payment via PayPal",
- "timeline": "Timeline",
"totalcoursesearchresults": "Total courses: {{$a}}"
}
\ No newline at end of file
diff --git a/src/core/courses/pages/dashboard/dashboard.html b/src/core/courses/pages/dashboard/dashboard.html
index 5e24c1474..4bf752f86 100644
--- a/src/core/courses/pages/dashboard/dashboard.html
+++ b/src/core/courses/pages/dashboard/dashboard.html
@@ -23,26 +23,23 @@
-
-
+
+
-
+
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
diff --git a/src/core/courses/pages/dashboard/dashboard.module.ts b/src/core/courses/pages/dashboard/dashboard.module.ts
index 6ce594cd4..90258ff39 100644
--- a/src/core/courses/pages/dashboard/dashboard.module.ts
+++ b/src/core/courses/pages/dashboard/dashboard.module.ts
@@ -19,9 +19,8 @@ import { CoreCoursesDashboardPage } from './dashboard';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { CoreCoursesComponentsModule } from '../../components/components.module';
-import { AddonBlockMyOverviewModule } from '@addon/block/myoverview/myoverview.module';
-import { AddonBlockTimelineModule } from '@addon/block/timeline/timeline.module';
import { CoreSiteHomeComponentsModule } from '@core/sitehome/components/components.module';
+import { CoreBlockComponentsModule } from '@core/block/components/components.module';
@NgModule({
declarations: [
@@ -32,8 +31,7 @@ import { CoreSiteHomeComponentsModule } from '@core/sitehome/components/componen
CoreDirectivesModule,
CoreCoursesComponentsModule,
CoreSiteHomeComponentsModule,
- AddonBlockMyOverviewModule,
- AddonBlockTimelineModule,
+ CoreBlockComponentsModule,
IonicPageModule.forChild(CoreCoursesDashboardPage),
TranslateModule.forChild()
],
diff --git a/src/core/courses/pages/dashboard/dashboard.ts b/src/core/courses/pages/dashboard/dashboard.ts
index e02bb632c..51a52a9e7 100644
--- a/src/core/courses/pages/dashboard/dashboard.ts
+++ b/src/core/courses/pages/dashboard/dashboard.ts
@@ -12,17 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { Component, OnDestroy, ViewChild } from '@angular/core';
+import { Component, OnDestroy, ViewChild, ViewChildren, QueryList } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';
import { CoreEventsProvider } from '@providers/events';
import { CoreSitesProvider } from '@providers/sites';
-import { CoreCoursesProvider } from '../../providers/courses';
-import { CoreSiteHomeProvider } from '@core/sitehome/providers/sitehome';
-import { AddonBlockMyOverviewComponent } from '@addon/block/myoverview/component/myoverview';
-import { AddonBlockTimelineComponent } from '@addon/block/timeline/components/timeline/timeline';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTabsComponent } from '@components/tabs/tabs';
+import { CoreBlockDelegate } from '@core/block/providers/delegate';
+import { CoreBlockComponent } from '@core/block/components/block/block';
+import { CoreSiteHomeProvider } from '@core/sitehome/providers/sitehome';
import { CoreSiteHomeIndexComponent } from '@core/sitehome/components/index/index';
-import { AddonBlockTimelineProvider } from '@addon/block/timeline/providers/timeline';
+import { CoreCoursesProvider } from '../../providers/courses';
+import { CoreCoursesDashboardProvider } from '../../providers/dashboard';
/**
* Page that displays the dashboard.
@@ -35,25 +36,26 @@ import { AddonBlockTimelineProvider } from '@addon/block/timeline/providers/time
export class CoreCoursesDashboardPage implements OnDestroy {
@ViewChild(CoreTabsComponent) tabsComponent: CoreTabsComponent;
@ViewChild(CoreSiteHomeIndexComponent) siteHomeComponent: CoreSiteHomeIndexComponent;
- @ViewChild(AddonBlockMyOverviewComponent) blockMyOverview: AddonBlockMyOverviewComponent;
- @ViewChild(AddonBlockTimelineComponent) blockTimeline: AddonBlockTimelineComponent;
+ @ViewChildren(CoreBlockComponent) blocksComponents: QueryList;
firstSelectedTab: number;
siteHomeEnabled = false;
- timelineEnabled = false;
- coursesEnabled = false;
tabsReady = false;
searchEnabled: boolean;
tabs = [];
siteName: string;
+ blocks: any[];
+ dashboardEnabled = false;
+ userId: number;
+ dashboardLoaded = false;
protected isDestroyed;
protected updateSiteObserver;
- protected courseIds = '';
constructor(private navCtrl: NavController, private coursesProvider: CoreCoursesProvider,
private sitesProvider: CoreSitesProvider, private siteHomeProvider: CoreSiteHomeProvider,
- private eventsProvider: CoreEventsProvider, private timelineProvider: AddonBlockTimelineProvider) {
+ private eventsProvider: CoreEventsProvider, private dashboardProvider: CoreCoursesDashboardProvider,
+ private domUtils: CoreDomUtilsProvider, private blockDelegate: CoreBlockDelegate) {
this.loadSiteName();
}
@@ -71,25 +73,21 @@ export class CoreCoursesDashboardPage implements OnDestroy {
const promises = [];
- // Decide which tab to load first.
promises.push(this.siteHomeProvider.isAvailable().then((enabled) => {
this.siteHomeEnabled = enabled;
}));
- promises.push(this.timelineProvider.isAvailable().then((enabled) => {
- this.timelineEnabled = enabled;
- }));
-
- this.coursesEnabled = !this.coursesProvider.isMyCoursesDisabledInSite();
+ promises.push(this.loadDashboardContent());
+ // Decide which tab to load first.
Promise.all(promises).finally(() => {
- if (this.siteHomeEnabled && (this.coursesEnabled || this.timelineEnabled)) {
+ if (this.siteHomeEnabled && this.dashboardEnabled) {
const site = this.sitesProvider.getCurrentSite(),
displaySiteHome = site.getInfo() && site.getInfo().userhomepage === 0;
this.firstSelectedTab = displaySiteHome ? 0 : 1;
} else {
- this.firstSelectedTab = this.siteHomeEnabled ? 1 : 0;
+ this.firstSelectedTab = 0;
}
this.tabsReady = true;
@@ -124,6 +122,72 @@ export class CoreCoursesDashboardPage implements OnDestroy {
this.siteName = this.sitesProvider.getCurrentSite().getInfo().sitename;
}
+ /**
+ * Convenience function to fetch the dashboard data.
+ *
+ * @return {Promise} Promise resolved when done.
+ */
+ protected loadDashboardContent(): Promise {
+ return this.dashboardProvider.isAvailable().then((enabled) => {
+ if (enabled) {
+ this.userId = this.sitesProvider.getCurrentSiteUserId();
+
+ return this.dashboardProvider.getDashboardBlocks().then((blocks) => {
+ this.blocks = blocks;
+ }).catch((error) => {
+ this.domUtils.showErrorModal(error);
+
+ // Cannot get the blocks, just show dashboard if needed.
+ this.loadFallbackBlocks();
+ });
+ }
+
+ // Not enabled, check separated tabs.
+ this.loadFallbackBlocks();
+ }).finally(() => {
+ this.dashboardEnabled = this.blockDelegate.hasSupportedBlock(this.blocks);
+ this.dashboardLoaded = true;
+ });
+ }
+
+ /**
+ * Refresh the dashboard data.
+ *
+ * @param {any} refresher Refresher.
+ */
+ refreshDashboard(refresher: any): void {
+ const promises = [];
+
+ promises.push(this.dashboardProvider.invalidateDashboardBlocks());
+
+ // Invalidate the blocks.
+ this.blocksComponents.forEach((blockComponent) => {
+ promises.push(blockComponent.invalidate().catch(() => {
+ // Ignore errors.
+ }));
+ });
+
+ Promise.all(promises).finally(() => {
+ this.loadDashboardContent().finally(() => {
+ refresher.complete();
+ });
+ });
+ }
+
+ /**
+ * Load fallback blocks to shown before 3.6 when dashboard blocks are not supported.
+ */
+ protected loadFallbackBlocks(): void {
+ this.blocks = [
+ {
+ name: 'myoverview'
+ },
+ {
+ name: 'timeline'
+ }
+ ];
+ }
+
/**
* Component being destroyed.
*/
diff --git a/src/core/courses/providers/dashboard.ts b/src/core/courses/providers/dashboard.ts
index 0cc2b8b10..7270bf539 100644
--- a/src/core/courses/providers/dashboard.ts
+++ b/src/core/courses/providers/dashboard.ts
@@ -13,8 +13,7 @@
// limitations under the License.
import { Injectable } from '@angular/core';
-import { CoreCoursesProvider } from './courses';
-import { AddonBlockTimelineProvider } from '@addon/block/timeline/providers/timeline';
+import { CoreSitesProvider } from '@providers/sites';
/**
* Service that provides some features regarding course overview.
@@ -22,30 +21,69 @@ import { AddonBlockTimelineProvider } from '@addon/block/timeline/providers/time
@Injectable()
export class CoreCoursesDashboardProvider {
- constructor(private coursesProvider: CoreCoursesProvider, private timelineProvider: AddonBlockTimelineProvider) { }
+ constructor(private sitesProvider: CoreSitesProvider) { }
+
+ protected ROOT_CACHE_KEY = 'CoreCoursesDashboard:';
/**
- * Returns whether or not My Overview is available for a certain site.
+ * Get cache key for dashboard blocks WS calls.
+ *
+ * @param {number} [userId] User ID. Default, 0 means current user.
+ * @return {string} Cache key.
+ */
+ protected getDashboardBlocksCacheKey(userId: number = 0): string {
+ return this.ROOT_CACHE_KEY + 'blocks:' + userId;
+ }
+
+ /**
+ * Get dashboard blocks.
+ *
+ * @param {number} [userId] User ID. Default, current user.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved with the list of blocks.
+ * @since 3.6
+ */
+ getDashboardBlocks(userId?: number, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ const params = {
+ },
+ preSets = {
+ cacheKey: this.getDashboardBlocksCacheKey(userId)
+ };
+
+ if (userId) {
+ params['userid'] = userId;
+ }
+
+ return site.read('core_block_get_dashboard_blocks', params, preSets).then((result) => {
+ return result.blocks || [];
+ });
+ });
+ }
+
+ /**
+ * Invalidates dashboard blocks WS call.
+ *
+ * @param {number} [userId] User ID. Default, current user.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateDashboardBlocks(userId?: number, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.invalidateWsCacheForKey(this.getDashboardBlocksCacheKey(userId));
+ });
+ }
+
+ /**
+ * Returns whether or not block based Dashboard is available for a certain site.
*
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise} Promise resolved with true if available, resolved with false or rejected otherwise.
+ * @since 3.6
*/
isAvailable(siteId?: string): Promise {
- return this.timelineProvider.isAvailable(siteId);
- }
-
- /**
- * Check if My Overview is available and not disabled.
- *
- * @return {Promise} Promise resolved with true if enabled, resolved with false otherwise.
- */
- isEnabled(): Promise {
- if (!this.coursesProvider.isMyCoursesDisabledInSite()) {
- return this.isAvailable().catch(() => {
- return false;
- });
- }
-
- return Promise.resolve(false);
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.wsAvailable('core_block_get_dashboard_blocks');
+ });
}
}
diff --git a/src/core/courses/providers/mainmenu-handler.ts b/src/core/courses/providers/mainmenu-handler.ts
index 95036e22a..6f4679e48 100644
--- a/src/core/courses/providers/mainmenu-handler.ts
+++ b/src/core/courses/providers/mainmenu-handler.ts
@@ -17,6 +17,7 @@ import { CoreCoursesProvider } from './courses';
import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@core/mainmenu/providers/delegate';
import { CoreCoursesDashboardProvider } from '../providers/dashboard';
import { CoreSiteHomeProvider } from '@core/sitehome/providers/sitehome';
+import { AddonBlockTimelineProvider } from '@addon/block/timeline/providers/timeline';
/**
* Handler to add Dashboard into main menu.
@@ -27,7 +28,7 @@ export class CoreDashboardMainMenuHandler implements CoreMainMenuHandler {
priority = 1100;
constructor(private coursesProvider: CoreCoursesProvider, private dashboardProvider: CoreCoursesDashboardProvider,
- private siteHomeProvider: CoreSiteHomeProvider) { }
+ private siteHomeProvider: CoreSiteHomeProvider, private timelineProvider: AddonBlockTimelineProvider) { }
/**
* Check if the handler is enabled on a site level.
@@ -35,20 +36,27 @@ export class CoreDashboardMainMenuHandler implements CoreMainMenuHandler {
* @return {boolean | Promise} Whether or not the handler is enabled on a site level.
*/
isEnabled(): boolean | Promise {
- // Check if my overview is enabled.
- return this.dashboardProvider.isEnabled().then((enabled) => {
+ // Check if 3.6 dashboard is enabled.
+ return this.dashboardProvider.isAvailable().then((enabled) => {
if (enabled) {
return true;
}
- return this.siteHomeProvider.isAvailable().then((enabled) => {
- // Show in case siteHome is enabled.
+ // Check if my overview is enabled.
+ return this.timelineProvider.isAvailable().then((enabled) => {
if (enabled) {
return true;
}
- // My overview not enabled, check if my courses is enabled.
- return !this.coursesProvider.isMyCoursesDisabledInSite();
+ return this.siteHomeProvider.isAvailable().then((enabled) => {
+ // Show in case siteHome is enabled.
+ if (enabled) {
+ return true;
+ }
+
+ // My overview not enabled, check if my courses is enabled.
+ return !this.coursesProvider.isMyCoursesDisabledInSite();
+ });
});
});
}
diff --git a/src/core/settings/pages/space-usage/space-usage.html b/src/core/settings/pages/space-usage/space-usage.html
index 1d2af6c8d..491da352e 100644
--- a/src/core/settings/pages/space-usage/space-usage.html
+++ b/src/core/settings/pages/space-usage/space-usage.html
@@ -8,7 +8,7 @@
-
+
{{ site.fullName }}
{{ site.spaceUsage | coreBytesToSize }}
diff --git a/src/core/settings/pages/synchronization/synchronization.html b/src/core/settings/pages/synchronization/synchronization.html
index cf802612b..12e7a753b 100644
--- a/src/core/settings/pages/synchronization/synchronization.html
+++ b/src/core/settings/pages/synchronization/synchronization.html
@@ -16,7 +16,7 @@
{{ 'core.settings.sites' | translate }}
-
+
{{ site.fullName }}
{{ site.siteUrl }}