Merge pull request #2649 from crazyserver/MOBILE-3608

Mobile 3608
main
Dani Palou 2020-12-15 08:10:37 +01:00 committed by GitHub
commit 003357d19d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
174 changed files with 8060 additions and 198 deletions

View File

@ -398,6 +398,9 @@ function override_component_lang_files($keys, $translations) {
case 'assets':
$path .= $type.'/'.$component.'.json';
break;
default:
$path .= $type.'/lang.json';
break;
}

View File

@ -14,6 +14,28 @@
import { NgModule } from '@angular/core';
import { AddonBlockActivityResultsModule } from './block/activityresults/activityresults.module';
import { AddonBlockBadgesModule } from './block/badges/badges.module';
import { AddonBlockBlogMenuModule } from './block/blogmenu/blogmenu.module';
import { AddonBlockBlogRecentModule } from './block/blogrecent/blogrecent.module';
import { AddonBlockBlogTagsModule } from './block/blogtags/blogtags.module';
import { AddonBlockCalendarMonthModule } from './block/calendarmonth/calendarmonth.module';
import { AddonBlockCalendarUpcomingModule } from './block/calendarupcoming/calendarupcoming.module';
import { AddonBlockCommentsModule } from './block/comments/comments.module';
import { AddonBlockCompletionStatusModule } from './block/completionstatus/completionstatus.module';
import { AddonBlockGlossaryRandomModule } from './block/glossaryrandom/glossaryrandom.module';
import { AddonBlockHtmlModule } from './block/html/html.module';
import { AddonBlockLearningPlansModule } from './block/learningplans/learningplans.module';
import { AddonBlockMyOverviewModule } from './block/myoverview/myoverview.module';
import { AddonBlockNewsItemsModule } from './block/newsitems/newsitems.module';
import { AddonBlockOnlineUsersModule } from './block/onlineusers/onlineusers.module';
import { AddonBlockPrivateFilesModule } from './block/privatefiles/privatefiles.module';
import { AddonBlockRecentlyAccessedCoursesModule } from './block/recentlyaccessedcourses/recentlyaccessedcourses.module';
import { AddonBlockRssClientModule } from './block/rssclient/rssclient.module';
import { AddonBlockSelfCompletionModule } from './block/selfcompletion/selfcompletion.module';
import { AddonBlockSiteMainMenuModule } from './block/sitemainmenu/sitemainmenu.module';
import { AddonBlockStarredCoursesModule } from './block/starredcourses/starredcourses.module';
import { AddonBlockTagsModule } from './block/tags/tags.module';
import { AddonPrivateFilesModule } from './privatefiles/privatefiles.module';
import { AddonFilterModule } from './filter/filter.module';
import { AddonUserProfileFieldModule } from './userprofilefield/userprofilefield.module';
@ -22,6 +44,28 @@ import { AddonUserProfileFieldModule } from './userprofilefield/userprofilefield
imports: [
AddonPrivateFilesModule,
AddonFilterModule,
AddonBlockActivityResultsModule,
AddonBlockBadgesModule,
AddonBlockBlogMenuModule,
AddonBlockBlogRecentModule,
AddonBlockBlogTagsModule,
AddonBlockCalendarMonthModule,
AddonBlockCalendarUpcomingModule,
AddonBlockCommentsModule,
AddonBlockCompletionStatusModule,
AddonBlockGlossaryRandomModule,
AddonBlockHtmlModule,
AddonBlockMyOverviewModule,
AddonBlockLearningPlansModule,
AddonBlockNewsItemsModule,
AddonBlockOnlineUsersModule,
AddonBlockPrivateFilesModule,
AddonBlockRecentlyAccessedCoursesModule,
AddonBlockRssClientModule,
AddonBlockSelfCompletionModule,
AddonBlockSiteMainMenuModule,
AddonBlockStarredCoursesModule,
AddonBlockTagsModule,
AddonUserProfileFieldModule,
],
})

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockActivityResultsHandler } from './services/block-handler';
import { AddonBlockActivityResultsComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockActivityResultsComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockActivityResultsHandler.instance);
},
},
],
})
export class AddonBlockActivityResultsModule {}

View File

@ -0,0 +1,29 @@
:host .core-block-content ::ng-deep {
table.grades {
text-align: start;
width: 100%;
.number {
text-align: start;
width: 10%;
}
.name {
text-align: start;
width: 77%;
}
.grade {
text-align: end;
}
caption {
text-align: start;
padding-top: .75rem;
padding-bottom: .75rem;
color: var(--gray-darker);
font-weight: bold;
font-size: 18px;
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a activity results block.
*/
@Component({
selector: 'addon-block-activity-results',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['activityresults.scss'],
})
export class AddonBlockActivityResultsComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockActivityResultsComponent } from './activityresults/activityresults';
@NgModule({
declarations: [
AddonBlockActivityResultsComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockActivityResultsComponent,
],
entryComponents: [
AddonBlockActivityResultsComponent,
],
})
export class AddonBlockActivityResultsComponentsModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Activity results"
}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockActivityResultsComponent } from '../components/activityresults/activityresults';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockActivityResultsHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockActivityResults';
blockName = 'activity_results';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_activityresults.pluginname',
class: 'addon-block-activity-results',
component: AddonBlockActivityResultsComponent,
};
}
}
export class AddonBlockActivityResultsHandler extends makeSingleton(AddonBlockActivityResultsHandlerService) {}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockBadgesHandler } from './services/block-handler';
import { AddonBlockBadgesComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockBadgesComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockBadgesHandler.instance);
},
},
],
})
export class AddonBlockBadgesModule {}

View File

@ -0,0 +1,22 @@
:host .core-block-content ::ng-deep {
ul.badges {
list-style: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li {
position: relative;
display: inline-block;
padding-top: 1em;
text-align: center;
vertical-align: top;
width: 150px;
.badge-name {
display: block;
padding: 5px;
}
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a badges block.
*/
@Component({
selector: 'addon-block-badges',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['badges.scss'],
})
export class AddonBlockBadgesComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockBadgesComponent } from './badges/badges';
@NgModule({
declarations: [
AddonBlockBadgesComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockBadgesComponent,
],
entryComponents: [
AddonBlockBadgesComponent,
],
})
export class AddonBlockBadgesComponentsModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Latest badges"
}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockBadgesComponent } from '../components/badges/badges';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockBadgesHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockBadges';
blockName = 'badges';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_badges.pluginname',
class: 'addon-block-badges',
component: AddonBlockBadgesComponent,
};
}
}
export class AddonBlockBadgesHandler extends makeSingleton(AddonBlockBadgesHandlerService) {}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockBlogMenuHandler } from './services/block-handler';
import { AddonBlockBlogMenuComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockBlogMenuComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockBlogMenuHandler.instance);
},
},
],
})
export class AddonBlockBlogMenuModule {}

View File

@ -0,0 +1,17 @@
:host {
.core-block-content ::ng-deep {
ul.list {
list-style: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li {
padding-bottom: 8px;
}
}
}
.core-block-footer ::ng-deep {
display: none;
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a blog menu block.
*/
@Component({
selector: 'addon-block-blog-menu',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['blogmenu.scss'],
})
export class AddonBlockBlogMenuComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockBlogMenuComponent } from './blogmenu/blogmenu';
@NgModule({
declarations: [
AddonBlockBlogMenuComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockBlogMenuComponent,
],
entryComponents: [
AddonBlockBlogMenuComponent,
],
})
export class AddonBlockBlogMenuComponentsModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Blog menu"
}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockBlogMenuComponent } from '../components/blogmenu/blogmenu';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockBlogMenuHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockBlogMenu';
blockName = 'blog_menu';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_blogmenu.pluginname',
class: 'addon-block-blog-menu',
component: AddonBlockBlogMenuComponent,
};
}
}
export class AddonBlockBlogMenuHandler extends makeSingleton(AddonBlockBlogMenuHandlerService) {}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockBlogRecentHandler } from './services/block-handler';
import { AddonBlockBlogRecentComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockBlogRecentComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockBlogRecentHandler.instance);
},
},
],
})
export class AddonBlockBlogRecentModule {}

View File

@ -0,0 +1,12 @@
:host .core-block-content ::ng-deep {
ul.list {
list-style: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li {
padding-bottom: 8px;
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a blog recent block.
*/
@Component({
selector: 'addon-block-blog-recent',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['blogrecent.scss'],
})
export class AddonBlockBlogRecentComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockBlogRecentComponent } from './blogrecent/blogrecent';
@NgModule({
declarations: [
AddonBlockBlogRecentComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockBlogRecentComponent,
],
entryComponents: [
AddonBlockBlogRecentComponent,
],
})
export class AddonBlockBlogRecentComponentsModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Recent blog entries"
}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockBlogRecentComponent } from '../components/blogrecent/blogrecent';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockBlogRecentHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockBlogRecent';
blockName = 'blog_recent';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_blogrecent.pluginname',
class: 'addon-block-blog-recent',
component: AddonBlockBlogRecentComponent,
};
}
}
export class AddonBlockBlogRecentHandler extends makeSingleton(AddonBlockBlogRecentHandlerService) {}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockBlogTagsHandler } from './services/block-handler';
import { AddonBlockBlogTagsComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockBlogTagsComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockBlogTagsHandler.instance);
},
},
],
})
export class AddonBlockBlogTagsModule {}

View File

@ -0,0 +1,99 @@
:host .core-block-content ::ng-deep {
ul.inline-list {
font-size: 80%;
list-style: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li {
padding: .2em;
display: inline-block;
a {
background: var(--ion-color-primary);
color: var(--ion-color-primary-contrast);
padding: 3px 8px;
-webkit-font-smoothing: antialiased;
display: inline-block;
min-width: 10px;
font-weight: bold;
line-height: 1;
text-align: center;
white-space: nowrap;
contain: content;
vertical-align: baseline;
text-decoration: none;
border-radius: 4px;
}
.s20 {
font-size: 1.5em;
font-weight: bold;
}
.s19 {
font-size: 1.5em;
}
.s18 {
font-size: 1.4em;
font-weight: bold;
}
.s17 {
font-size: 1.4em;
}
.s16 {
font-size: 1.3em;
font-weight: bold;
}
.s15 {
font-size: 1.3em;
}
.s14 {
font-size: 1.2em;
font-weight: bold;
}
.s13 {
font-size: 1.2em;
}
.s12,
.s11 {
font-size: 1.1em;
font-weight: bold;
}
.s10,
.s9 {
font-size: 1.1em;
}
.s8,
.s7 {
font-size: 1em;
font-weight: bold;
}
.s6,
.s5 {
font-size: 1em;
}
.s4,
.s3 {
font-size: 0.9em;
font-weight: bold;
}
.s2,
.s1 {
font-size: 0.9em;
}
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a blo gtags block.
*/
@Component({
selector: 'addon-block-blog-tags',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['blogtags.scss'],
})
export class AddonBlockBlogTagsComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockBlogTagsComponent } from './blogtags/blogtags';
@NgModule({
declarations: [
AddonBlockBlogTagsComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockBlogTagsComponent,
],
entryComponents: [
AddonBlockBlogTagsComponent,
],
})
export class AddonBlockBlogTagsComponentsModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Blog tags"
}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockBlogTagsComponent } from '../components/blogtags/blogtags';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockBlogTagsHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockBlogTags';
blockName = 'blog_tags';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_blogtags.pluginname',
class: 'addon-block-blog-tags',
component: AddonBlockBlogTagsComponent,
};
}
}
export class AddonBlockBlogTagsHandler extends makeSingleton(AddonBlockBlogTagsHandlerService) {}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockCalendarMonthHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockCalendarMonthHandler.instance);
},
},
],
})
export class AddonBlockCalendarMonthModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Calendar"
}

View File

@ -0,0 +1,61 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
// import { AddonCalendar } from '@addon/calendar/services/calendar';
import { CoreCourseBlock } from '@features/course/services/course';
import { Params } from '@angular/router';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockCalendarMonthHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockCalendarMonth';
blockName = 'calendar_month';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData {
// @todo
const link = 'AddonCalendarListPage';
const linkParams: Params = contextLevel == 'course' ? { courseId: instanceId } : {};
/* if (AddonCalendar.instance.canViewMonthInSite()) {
link = 'AddonCalendarIndexPage';
}*/
return {
title: 'addon.block_calendarmonth.pluginname',
class: 'addon-block-calendar-month',
component: CoreBlockOnlyTitleComponent,
link: link,
linkParams: linkParams,
};
}
}
export class AddonBlockCalendarMonthHandler extends makeSingleton(AddonBlockCalendarMonthHandlerService) {}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockCalendarUpcomingHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockCalendarUpcomingHandler.instance);
},
},
],
})
export class AddonBlockCalendarUpcomingModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Upcoming events"
}

View File

@ -0,0 +1,62 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
// import { AddonCalendar } from '@addon/calendar/services/calendar';
import { CoreCourseBlock } from '@features/course/services/course';
import { Params } from '@angular/router';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockCalendarUpcomingHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockCalendarUpcoming';
blockName = 'calendar_upcoming';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData {
// @todo
const link = 'AddonCalendarListPage';
const linkParams: Params = contextLevel == 'course' ? { courseId: instanceId } : {};
/* if (AddonCalendar.instance.canViewMonthInSite()) {
link = 'AddonCalendarIndexPage';
linkParams.upcoming = true;
}*/
return {
title: 'addon.block_calendarupcoming.pluginname',
class: 'addon-block-calendar-upcoming',
component: CoreBlockOnlyTitleComponent,
link: link,
linkParams: linkParams,
};
}
}
export class AddonBlockCalendarUpcomingHandler extends makeSingleton(AddonBlockCalendarUpcomingHandlerService) {}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockCommentsHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockCommentsHandler.instance);
},
},
],
})
export class AddonBlockCommentsModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Comments"
}

View File

@ -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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { CoreCourseBlock } from '@features/course/services/course';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockCommentsHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockComments';
blockName = 'comments';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData {
// @todo
return {
title: 'addon.block_comments.pluginname',
class: 'addon-block-comments',
component: CoreBlockOnlyTitleComponent,
link: 'CoreCommentsViewerPage',
linkParams: {
contextLevel: contextLevel,
instanceId: instanceId,
componentName: 'block_comments',
area: 'page_comments',
itemId: 0,
},
};
}
}
export class AddonBlockCommentsHandler extends makeSingleton(AddonBlockCommentsHandlerService) {}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockCompletionStatusHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockCompletionStatusHandler.instance);
},
},
],
})
export class AddonBlockCompletionStatusModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Course completion status"
}

View File

@ -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 { Injectable } from '@angular/core';
import { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { CoreCourseBlock } from '@features/course/services/course';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockCompletionStatusHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockCompletionStatus';
blockName = 'completionstatus';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData {
// @todo
return {
title: 'addon.block_completionstatus.pluginname',
class: 'addon-block-completion-status',
component: CoreBlockOnlyTitleComponent,
link: 'AddonCourseCompletionReportPage',
linkParams: {
courseId: instanceId,
},
};
}
}
export class AddonBlockCompletionStatusHandler extends makeSingleton(AddonBlockCompletionStatusHandlerService) {}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockGlossaryRandomHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockGlossaryRandomHandler.instance);
},
},
],
})
export class AddonBlockGlossaryRandomModule {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Random glossary entry"
}

View File

@ -0,0 +1,48 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { CoreCourseBlock } from '@features/course/services/course';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockGlossaryRandomHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockGlossaryRandom';
blockName = 'glossary_random';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock): CoreBlockHandlerData {
return {
title: block.contents?.title || 'addon.block_glossaryrandom.pluginname',
class: 'addon-block-glossary-random',
component: CoreBlockPreRenderedComponent,
};
}
}
export class AddonBlockGlossaryRandomHandler extends makeSingleton(AddonBlockGlossaryRandomHandlerService) {}

View File

@ -0,0 +1,30 @@
// (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 { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockHtmlHandler } from './services/block-handler';
@NgModule({
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockHtmlHandler.instance);
},
},
],
})
export class AddonBlockHtmlModule {}

View File

@ -0,0 +1,49 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { CoreCourseBlock } from '@features/course/services/course';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockHtmlHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockHtml';
blockName = 'html';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock): CoreBlockHandlerData {
return {
title: block.contents?.title || '',
class: 'addon-block-html',
component: CoreBlockPreRenderedComponent,
};
}
}
export class AddonBlockHtmlHandler extends makeSingleton(AddonBlockHtmlHandlerService) {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Learning plans"
}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockLearningPlansHandler } from './services/block-handler';
import { CoreBlockComponentsModule } from '@features/block/components/components.module';
@NgModule({
imports: [
IonicModule,
CoreBlockComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockLearningPlansHandler.instance);
},
},
],
})
export class AddonBlockLearningPlansModule {}

View File

@ -0,0 +1,48 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockLearningPlansHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockLearningPlans';
blockName = 'lp';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
// @todo
return {
title: 'addon.block_learningplans.pluginname',
class: 'addon-block-learning-plans',
component: CoreBlockOnlyTitleComponent,
link: 'AddonCompetencyPlanListPage',
};
}
}
export class AddonBlockLearningPlansHandler extends makeSingleton(AddonBlockLearningPlansHandlerService) {}

View File

@ -0,0 +1,47 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { CoreCoursesComponentsModule } from '@features/courses/components/components.module';
import { AddonBlockMyOverviewComponent } from './myoverview/myoverview';
@NgModule({
declarations: [
AddonBlockMyOverviewComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
CoreCoursesComponentsModule,
],
exports: [
AddonBlockMyOverviewComponent,
],
entryComponents: [
AddonBlockMyOverviewComponent,
],
})
export class AddonBlockMyOverviewComponentsModule {}

View File

@ -0,0 +1,93 @@
<ion-item-divider sticky="true">
<ion-label>
<h2>{{ 'addon.block_myoverview.pluginname' | translate }}</h2>
</ion-label>
<!-- Download all courses. -->
<div *ngIf="downloadCoursesEnabled && downloadEnabled && filteredCourses.length > 1 && !showFilter" class="core-button-spinner"
slot="end">
<ion-button *ngIf="!prefetchCoursesData[selectedFilter].loading" fill="clear" color="dark" (click)="prefetchCourses()">
<ion-icon [name]="prefetchCoursesData[selectedFilter].icon" slot="icon-only">
</ion-icon>
</ion-button>
<ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData[selectedFilter].badge">
{{prefetchCoursesData[selectedFilter].badge}}
</ion-badge>
<ion-spinner *ngIf="prefetchCoursesData[selectedFilter].loading"></ion-spinner>
</div>
<core-context-menu slot="end">
<core-context-menu-item *ngIf="loaded && showFilterSwitchButton()" [priority]="1000"
[content]="'core.courses.filtermycourses' | translate" (action)="switchFilter()" iconAction="fas-filter"
(onClosed)="switchFilterClosed()"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && showSortFilter" [priority]="900"
content="{{('core.sortby' | translate) + ' ' + ('addon.block_myoverview.title' | translate)}}"
(action)="switchSort('fullname')" [iconAction]="sort == 'fullname' ? 'far-check-circle' : 'far-circle'">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && showSortFilter && showSortByShortName" [priority]="800"
content="{{('core.sortby' | translate) + ' ' + ('addon.block_myoverview.shortname' | translate)}}"
(action)="switchSort('shortname')" [iconAction]="sort == 'shortname' ? 'far-check-circle' : 'far-circle'">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && showSortFilter" [priority]="700"
content="{{('core.sortby' | translate) + ' ' + ('addon.block_myoverview.lastaccessed' | translate)}}"
(action)="switchSort('lastaccess')" [iconAction]="sort == 'lastaccess' ? 'far-check-circle' : 'far-circle'">
</core-context-menu-item>
</core-context-menu>
</ion-item-divider>
<core-loading [hideUntil]="loaded" class="core-loading-center">
<div class="ion-padding" [hidden]="showFilter || !showSelectorFilter" class="safe-padding-horizontal">
<!-- "Time" selector. -->
<ion-select class="ion-text-start" [title]="'core.show' | translate" [(ngModel)]="selectedFilter"
(ngModelChange)="selectedChanged()" interface="popover" class="core-button-select">
<ion-select-option value="allincludinghidden" *ngIf="showFilters.allincludinghidden != 'hidden'">
{{ 'addon.block_myoverview.allincludinghidden' | translate }}
</ion-select-option>
<ion-select-option value="all" *ngIf="showFilters.all != 'hidden'">
{{ 'addon.block_myoverview.all' | translate }}
</ion-select-option>
<ion-select-option value="inprogress" *ngIf="showFilters.inprogress != 'hidden'"
[disabled]="showFilters.inprogress == 'disabled'">
{{ 'addon.block_myoverview.inprogress' | translate }}
</ion-select-option>
<ion-select-option value="future" *ngIf="showFilters.future != 'hidden'" [disabled]="showFilters.future == 'disabled'">
{{ 'addon.block_myoverview.future' | translate }}
</ion-select-option>
<ion-select-option value="past" *ngIf="showFilters.past != 'hidden'" [disabled]="showFilters.past == 'disabled'">
{{ 'addon.block_myoverview.past' | translate }}
</ion-select-option>
<ng-container *ngIf="showFilters.custom != 'hidden'">
<ng-container *ngFor="let customOption of customFilter; let index = index">
<ion-select-option value="custom-{{index}}">{{ customOption.name }}</ion-select-option>
</ng-container>
</ng-container>
<ion-select-option value="favourite" *ngIf="showFilters.favourite != 'hidden'"
[disabled]="showFilters.favourite == 'disabled'">
{{ 'addon.block_myoverview.favourites' | translate }}
</ion-select-option>
<ion-select-option value="hidden" *ngIf="showFilters.hidden != 'hidden'" [disabled]="showFilters.hidden == 'disabled'">
{{ 'addon.block_myoverview.hiddencourses' | translate }}
</ion-select-option>
</ion-select>
</div>
<!-- Filter courses. -->
<ion-searchbar #searchbar *ngIf="showFilter" [(ngModel)]="courses.filter" (ionInput)="filterChanged($event)"
(ionCancel)="filterChanged($event)" [placeholder]="'core.courses.filtermycourses' | translate">
</ion-searchbar>
<core-empty-box *ngIf="filteredCourses.length == 0" image="assets/img/icons/courses.svg"
[message]="'addon.block_myoverview.nocourses' | translate" class="core-empty-inline">
</core-empty-box>
<!-- List of courses. -->
<div class="safe-area-page">
<ion-grid class="ion-no-padding">
<ion-row class="ion-no-padding">
<ion-col *ngFor="let course of filteredCourses" class="ion-no-padding"
size="12" size-sm="6" size-md="6" size-lg="4" size-xl="3" align-self-stretch>
<core-courses-course-progress [course]="course" class="core-courseoverview" showAll="true"
[showDownload]="downloadCourseEnabled && downloadEnabled">
</core-courses-course-progress>
</ion-col>
</ion-row>
</ion-grid>
</div>
</core-loading>

View File

@ -0,0 +1,586 @@
// (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, Input, OnDestroy, ViewChild, OnChanges, SimpleChange } from '@angular/core';
import { IonSearchbar } from '@ionic/angular';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreSites } from '@services/sites';
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData, CoreCourses } from '@features/courses/services/courses';
import { CoreCoursesHelper, CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
import { CoreCourseHelper, CorePrefetchStatusInfo } from '@features/course/services/course-helper';
import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
import { CoreSite } from '@classes/site';
import { CoreUtils } from '@services/utils/utils';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
import { AddonCourseCompletion } from '@/addons/coursecompletion/services/coursecompletion';
const FILTER_PRIORITY = ['all', 'allincludinghidden', 'inprogress', 'future', 'past', 'favourite', 'hidden', 'custom'];
/**
* Component to render a my overview block.
*/
@Component({
selector: 'addon-block-myoverview',
templateUrl: 'addon-block-myoverview.html',
})
export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implements OnInit, OnChanges, OnDestroy {
@ViewChild('searchbar') searchbar?: IonSearchbar;
@Input() downloadEnabled = false;
courses = {
filter: '',
all: <CoreEnrolledCourseDataWithOptions[]> [],
allincludinghidden: <CoreEnrolledCourseDataWithOptions[]> [],
past: <CoreEnrolledCourseDataWithOptions[]> [],
inprogress: <CoreEnrolledCourseDataWithOptions[]> [],
future: <CoreEnrolledCourseDataWithOptions[]> [],
favourite: <CoreEnrolledCourseDataWithOptions[]> [],
hidden: <CoreEnrolledCourseDataWithOptions[]> [],
custom: <CoreEnrolledCourseDataWithOptions[]> [], // Leave it empty to avoid download all those courses.
};
customFilter: {
name: string;
value: string;
}[] = [];
selectedFilter = 'inprogress';
sort = 'fullname';
currentSite?: CoreSite;
filteredCourses: CoreEnrolledCourseDataWithOptions[] = [];
prefetchCoursesData = {
all: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
allincludinghidden: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
inprogress: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
past: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
future: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
favourite: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
hidden: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
},
custom: <CorePrefetchStatusInfo> {
icon: '',
statusTranslatable: '',
status: '',
loading: false,
}, // Leave it empty to avoid download all those courses.
};
showFilters = { // Options are show, disabled, hidden.
all: 'show',
allincludinghidden: 'show',
past: 'show',
inprogress: 'show',
future: 'show',
favourite: 'show',
hidden: 'show',
custom: 'hidden',
};
showFilter = false;
showSelectorFilter = false;
showSortFilter = false;
downloadCourseEnabled = false;
downloadCoursesEnabled = false;
showSortByShortName = false;
protected prefetchIconsInitialized = false;
protected isDestroyed = false;
protected coursesObserver?: CoreEventObserver;
protected updateSiteObserver?: CoreEventObserver;
protected courseIds: number[] = [];
protected fetchContentDefaultError = 'Error getting my overview data.';
constructor() {
super('AddonBlockMyOverviewComponent');
}
/**
* Component being initialized.
*/
async ngOnInit(): Promise<void> {
// Refresh the enabled flags if enabled.
this.downloadCourseEnabled = !CoreCourses.instance.isDownloadCourseDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.instance.isDownloadCoursesDisabledInSite();
// Refresh the enabled flags if site is updated.
this.updateSiteObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
this.downloadCourseEnabled = !CoreCourses.instance.isDownloadCourseDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.instance.isDownloadCoursesDisabledInSite();
}, CoreSites.instance.getCurrentSiteId());
this.coursesObserver = CoreEvents.on(
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED,
(data: CoreCoursesMyCoursesUpdatedEventData) => {
if (data.action == CoreCoursesProvider.ACTION_ENROL || data.action == CoreCoursesProvider.ACTION_STATE_CHANGED) {
this.refreshCourseList();
}
},
CoreSites.instance.getCurrentSiteId(),
);
this.currentSite = CoreSites.instance.getCurrentSite();
const promises: Promise<void>[] = [];
if (this.currentSite) {
promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewSort', this.sort).then((value) => {
this.sort = value;
return;
}));
promises.push(this.currentSite.getLocalSiteConfig('AddonBlockMyOverviewFilter', this.selectedFilter).then((value) => {
this.selectedFilter = value;
return;
}));
}
Promise.all(promises).finally(() => {
super.ngOnInit();
});
}
/**
* Detect changes on input properties.
*/
ngOnChanges(changes: {[name: string]: SimpleChange}): void {
if (changes.downloadEnabled && !changes.downloadEnabled.previousValue && this.downloadEnabled && this.loaded) {
// Download all courses is enabled now, initialize it.
this.initPrefetchCoursesIcons();
}
}
/**
* Perform the invalidate content function.
*
* @return Resolved when done.
*/
protected async invalidateContent(): Promise<void> {
const promises: Promise<void>[] = [];
// Invalidate course completion data.
promises.push(CoreCourses.instance.invalidateUserCourses().finally(() =>
CoreUtils.instance.allPromises(this.courseIds.map((courseId) =>
AddonCourseCompletion.instance.invalidateCourseCompletion(courseId)))));
promises.push(CoreCourseOptionsDelegate.instance.clearAndInvalidateCoursesOptions());
if (this.courseIds.length > 0) {
promises.push(CoreCourses.instance.invalidateCoursesByField('ids', this.courseIds.join(',')));
}
await CoreUtils.instance.allPromises(promises).finally(() => {
this.prefetchIconsInitialized = false;
});
}
/**
* Fetch the courses for my overview.
*
* @return Promise resolved when done.
*/
protected async fetchContent(): Promise<void> {
const config = this.block.configsRecord || {};
const showCategories = config && config.displaycategories && config.displaycategories.value == '1';
const courses = await CoreCoursesHelper.instance.getUserCoursesWithOptions(this.sort, undefined, undefined, showCategories);
// Check to show sort by short name only if the text is visible.
if (courses.length > 0) {
const sampleCourse = courses[0];
this.showSortByShortName = !!sampleCourse.displayname && !!sampleCourse.shortname &&
sampleCourse.fullname != sampleCourse.displayname;
}
// Rollback to sort by full name if user is sorting by short name then Moodle web change the config.
if (!this.showSortByShortName && this.sort === 'shortname') {
this.switchSort('fullname');
}
this.courseIds = courses.map((course) => course.id);
this.showSortFilter = courses.length > 0 && typeof courses[0].lastaccess != 'undefined';
this.initCourseFilters(courses);
this.courses.filter = '';
this.showFilter = false;
this.showFilters.all = this.getShowFilterValue(
!config || config.displaygroupingall.value == '1',
this.courses.all.length === 0,
);
// Do not show allincludinghiddenif config it's not present (before 3.8).
this.showFilters.allincludinghidden =
this.getShowFilterValue(
config.displaygroupingallincludinghidden.value == '1',
this.courses.allincludinghidden.length === 0,
);
this.showFilters.inprogress = this.getShowFilterValue(
!config || config.displaygroupinginprogress.value == '1',
this.courses.inprogress.length === 0,
);
this.showFilters.past = this.getShowFilterValue(
!config || config.displaygroupingpast.value == '1',
this.courses.past.length === 0,
);
this.showFilters.future = this.getShowFilterValue(
!config || config.displaygroupingfuture.value == '1',
this.courses.future.length === 0,
);
this.showSelectorFilter = courses.length > 0 && (this.courses.past.length > 0 || this.courses.future.length > 0 ||
typeof courses[0].enddate != 'undefined');
this.showFilters.hidden = this.getShowFilterValue(
this.showSelectorFilter && typeof courses[0].hidden != 'undefined' &&
(!config || config.displaygroupinghidden.value == '1'),
this.courses.hidden.length === 0,
);
this.showFilters.favourite = this.getShowFilterValue(
this.showSelectorFilter && typeof courses[0].isfavourite != 'undefined' &&
(!config || (config.displaygroupingstarred && config.displaygroupingstarred.value == '1') ||
(config.displaygroupingfavourites && config.displaygroupingfavourites.value == '1')),
this.courses.favourite.length === 0,
);
this.showFilters.custom = this.getShowFilterValue(
this.showSelectorFilter && config?.displaygroupingcustomfield.value == '1' &&
!!config?.customfieldsexport && !!config?.customfieldsexport.value,
false,
);
if (this.showFilters.custom == 'show') {
this.customFilter = CoreTextUtils.instance.parseJSON(config.customfieldsexport.value, []);
} else {
this.customFilter = [];
}
if (this.showSelectorFilter) {
// Check if any selector is shown and not disabled.
this.showSelectorFilter = Object.keys(this.showFilters).some((key) => this.showFilters[key] == 'show');
if (!this.showSelectorFilter) {
// All filters disabled, display all the courses.
this.showFilters.all = 'show';
}
}
if (!this.showSelectorFilter) {
// No selector, display all the courses.
this.selectedFilter = 'all';
}
this.setCourseFilter(this.selectedFilter);
this.initPrefetchCoursesIcons();
}
/**
* Helper function to help with filter values.
*
* @param showCondition If true, filter will be shown.
* @param disabledCondition If true, and showCondition is also met, it will be shown as disabled.
* @return show / disabled / hidden value.
*/
protected getShowFilterValue(showCondition: boolean, disabledCondition: boolean): string {
return showCondition ? (disabledCondition ? 'disabled' : 'show') : 'hidden';
}
/**
* The filter has changed.
*
* @param Received Event.
*/
filterChanged(event: Event): void {
const target = <HTMLInputElement>event?.target || null;
const newValue = target?.value.trim().toLowerCase();
if (!newValue || this.courses.allincludinghidden.length <= 0) {
this.filteredCourses = this.courses.allincludinghidden;
} else {
// Use displayname if avalaible, or fullname if not.
if (this.courses.allincludinghidden.length > 0 &&
typeof this.courses.allincludinghidden[0].displayname != 'undefined') {
this.filteredCourses = this.courses.allincludinghidden.filter((course) =>
course.displayname && course.displayname.toLowerCase().indexOf(newValue) > -1);
} else {
this.filteredCourses = this.courses.allincludinghidden.filter((course) =>
course.fullname.toLowerCase().indexOf(newValue) > -1);
}
}
}
/**
* Initialize the prefetch icon for selected courses.
*/
protected initPrefetchCoursesIcons(): void {
if (this.prefetchIconsInitialized || !this.downloadEnabled) {
// Already initialized.
return;
}
this.prefetchIconsInitialized = true;
Object.keys(this.prefetchCoursesData).forEach(async (filter) => {
this.prefetchCoursesData[filter] =
await CoreCourseHelper.instance.initPrefetchCoursesIcons(this.courses[filter], this.prefetchCoursesData[filter]);
});
}
/**
* Prefetch all the shown courses.
*
* @return Promise resolved when done.
*/
async prefetchCourses(): Promise<void> {
const selected = this.selectedFilter;
const initialIcon = this.prefetchCoursesData[selected].icon;
try {
await CoreCourseHelper.instance.prefetchCourses(this.courses[selected], this.prefetchCoursesData[selected]);
} catch (error) {
if (!this.isDestroyed) {
CoreDomUtils.instance.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
this.prefetchCoursesData[selected].icon = initialIcon;
}
}
}
/**
* Refresh the list of courses.
*
* @return Promise resolved when done.
*/
protected async refreshCourseList(): Promise<void> {
CoreEvents.trigger(CoreCoursesProvider.EVENT_MY_COURSES_REFRESHED);
try {
await CoreCourses.instance.invalidateUserCourses();
} catch (error) {
// Ignore errors.
}
await this.loadContent(true);
}
/**
* The selected courses filter have changed.
*/
selectedChanged(): void {
this.setCourseFilter(this.selectedFilter);
}
/**
* Set selected courses filter.
*
* @param filter Filter name to set.
*/
protected async setCourseFilter(filter: string): Promise<void> {
this.selectedFilter = filter;
if (this.showFilters.custom == 'show' && filter.startsWith('custom-') &&
typeof this.customFilter[filter.substr(7)] != 'undefined') {
const filterName = this.block.configsRecord!.customfiltergrouping.value;
const filterValue = this.customFilter[filter.substr(7)].value;
this.loaded = false;
try {
const courses = await CoreCourses.instance.getEnrolledCoursesByCustomField(filterName, filterValue);
// Get the courses information from allincludinghidden to get the max info about the course.
const courseIds = courses.map((course) => course.id);
this.filteredCourses = this.courses.allincludinghidden.filter((allCourse) =>
courseIds.indexOf(allCourse.id) !== -1);
} catch (error) {
CoreDomUtils.instance.showErrorModalDefault(error, this.fetchContentDefaultError);
} finally {
this.loaded = true;
}
return;
}
// Only save the filter if not a custom one.
this.currentSite?.setLocalSiteConfig('AddonBlockMyOverviewFilter', filter);
if (this.showFilters[filter] == 'show') {
this.filteredCourses = this.courses[filter];
} else {
const activeFilter = FILTER_PRIORITY.find((name) => this.showFilters[name] == 'show');
if (activeFilter) {
this.setCourseFilter(activeFilter);
}
}
}
/**
* Init courses filters.
*
* @param courses Courses to filter.
*/
initCourseFilters(courses: CoreEnrolledCourseDataWithOptions[]): void {
this.courses.allincludinghidden = courses;
if (this.showSortFilter) {
if (this.sort == 'lastaccess') {
courses.sort((a, b) => (b.lastaccess || 0) - (a.lastaccess || 0));
} else if (this.sort == 'fullname') {
courses.sort((a, b) => {
const compareA = a.fullname.toLowerCase();
const compareB = b.fullname.toLowerCase();
return compareA.localeCompare(compareB);
});
} else if (this.sort == 'shortname') {
courses.sort((a, b) => {
const compareA = a.shortname.toLowerCase();
const compareB = b.shortname.toLowerCase();
return compareA.localeCompare(compareB);
});
}
}
this.courses.all = [];
this.courses.past = [];
this.courses.inprogress = [];
this.courses.future = [];
this.courses.favourite = [];
this.courses.hidden = [];
const today = CoreTimeUtils.instance.timestamp();
courses.forEach((course) => {
if (course.hidden) {
this.courses.hidden.push(course);
} else {
this.courses.all.push(course);
if ((course.enddate && course.enddate < today) || course.completed) {
// Courses that have already ended.
this.courses.past.push(course);
} else if (course.startdate && course.startdate > today) {
// Courses that have not started yet.
this.courses.future.push(course);
} else {
// Courses still in progress.
this.courses.inprogress.push(course);
}
if (course.isfavourite) {
this.courses.favourite.push(course);
}
}
});
this.setCourseFilter(this.selectedFilter);
}
/**
* The selected courses sort filter have changed.
*
* @param sort New sorting.
*/
switchSort(sort: string): void {
this.sort = sort;
this.currentSite?.setLocalSiteConfig('AddonBlockMyOverviewSort', this.sort);
this.initCourseFilters(this.courses.allincludinghidden);
}
/**
* Show or hide the filter.
*/
switchFilter(): void {
this.showFilter = !this.showFilter;
this.courses.filter = '';
if (this.showFilter) {
this.filteredCourses = this.courses.allincludinghidden;
} else {
this.setCourseFilter(this.selectedFilter);
}
}
/**
* Popover closed after clicking switch filter.
*/
switchFilterClosed(): void {
if (this.showFilter) {
setTimeout(() => {
this.searchbar?.setFocus();
});
}
}
/**
* If switch button that enables the filter input is shown or not.
*
* @return If switch button that enables the filter input is shown or not.
*/
showFilterSwitchButton(): boolean {
return this.loaded && this.courses.allincludinghidden && this.courses.allincludinghidden.length > 5;
}
/**
* Component being destroyed.
*/
ngOnDestroy(): void {
this.isDestroyed = true;
this.coursesObserver?.off();
this.updateSiteObserver?.off();
}
}

View File

@ -0,0 +1,14 @@
{
"all": "All (except removed from view)",
"allincludinghidden": "All",
"favourites": "Starred",
"future": "Future",
"hiddencourses": "Removed from view",
"inprogress": "In progress",
"lastaccessed": "Last accessed",
"nocourses": "No courses",
"past": "Past",
"pluginname": "Course overview",
"shortname": "Short name",
"title": "Course name"
}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockMyOverviewComponentsModule } from './components/components.module';
import { AddonBlockMyOverviewHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
AddonBlockMyOverviewComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockMyOverviewHandler.instance);
},
},
],
})
export class AddonBlockMyOverviewModule {}

View File

@ -0,0 +1,58 @@
// (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 { CoreSites } from '@services/sites';
import { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreCourses } from '@features/courses/services/courses';
import { AddonBlockMyOverviewComponent } from '../components/myoverview/myoverview';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockMyOverviewHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockMyOverview';
blockName = 'myoverview';
/**
* Check if the handler is enabled on a site level.
*
* @return Whether or not the handler is enabled on a site level.
*/
async isEnabled(): Promise<boolean> {
return (CoreSites.instance.getCurrentSite()?.isVersionGreaterEqualThan('3.6')) ||
!CoreCourses.instance.isMyCoursesDisabledInSite();
}
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_myoverview.pluginname',
class: 'addon-block-myoverview',
component: AddonBlockMyOverviewComponent,
};
}
}
export class AddonBlockMyOverviewHandler extends makeSingleton(AddonBlockMyOverviewHandlerService) {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockNewsItemsComponent } from './newsitems/newsitems';
@NgModule({
declarations: [
AddonBlockNewsItemsComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockNewsItemsComponent,
],
entryComponents: [
AddonBlockNewsItemsComponent,
],
})
export class AddonBlockNewsItemsComponentsModule {}

View File

@ -0,0 +1,27 @@
:host {
.core-block-content ::ng-deep {
.unlist {
list-style-type: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li.post {
padding-bottom: 16px;
}
li.post:last-child {
padding-bottom: 0;
}
}
}
// Hide RSS link.
.core-block-footer ::ng-deep {
a {
display: none;
}
a:first-child {
display: inline;
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a news items block.
*/
@Component({
selector: 'addon-block-news-items',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['newsitems.scss'],
})
export class AddonBlockNewsItemsComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Latest announcements"
}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockNewsItemsHandler } from './services/block-handler';
import { AddonBlockNewsItemsComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockNewsItemsComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockNewsItemsHandler.instance);
},
},
],
})
export class AddonBlockNewsItemsModule {}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockNewsItemsComponent } from '../components/newsitems/newsitems';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockNewsItemsHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockNewsItems';
blockName = 'news_items';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_newsitems.pluginname',
class: 'addon-block-news-items',
component: AddonBlockNewsItemsComponent,
};
}
}
export class AddonBlockNewsItemsHandler extends makeSingleton(AddonBlockNewsItemsHandlerService) {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockOnlineUsersComponent } from './onlineusers/onlineusers';
@NgModule({
declarations: [
AddonBlockOnlineUsersComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockOnlineUsersComponent,
],
entryComponents: [
AddonBlockOnlineUsersComponent,
],
})
export class AddonBlockOnlineUsersComponentsModule {}

View File

@ -0,0 +1,67 @@
:host .core-block-content ::ng-deep {
max-height: 200px;
overflow-y: auto;
.item-inner,
.input-wrapper {
overflow-y: visible;
align-self: start;
}
.list {
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li.listentry {
clear: both;
list-style-type: none;
.user {
float: left;
position: relative;
padding-bottom: 16px;
.core-adapted-img-container {
display: inline;
margin-left: 0;
margin-right: 8px;
}
.userpicture {
vertical-align: text-bottom;
}
}
.message {
float: right;
margin-top: 3px;
}
.uservisibility { // No support on the app.
display: none;
}
}
}
.info {
text-align: center;
}
}
:host-context([dir=rtl]) .core-block-content ::ng-deep {
.list li.listentry {
.user {
float: right;
.core-adapted-img-container {
margin-left: 8px;
margin-right: 0;
}
}
.message {
float: left;
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a online users block.
*/
@Component({
selector: 'addon-block-online-users',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['onlineusers.scss'],
})
export class AddonBlockOnlineUsersComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Online users"
}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockOnlineUsersHandler } from './services/block-handler';
import { AddonBlockOnlineUsersComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockOnlineUsersComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockOnlineUsersHandler.instance);
},
},
],
})
export class AddonBlockOnlineUsersModule {}

View File

@ -0,0 +1,46 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockOnlineUsersComponent } from '../components/onlineusers/onlineusers';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockOnlineUsersHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockOnlineUsers';
blockName = 'online_users';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_onlineusers.pluginname',
class: 'addon-block-online-users',
component: AddonBlockOnlineUsersComponent,
};
}
}
export class AddonBlockOnlineUsersHandler extends makeSingleton(AddonBlockOnlineUsersHandlerService) {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Private files"
}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockPrivateFilesHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockPrivateFilesHandler.instance);
},
},
],
})
export class AddonBlockPrivateFilesModule {}

View File

@ -0,0 +1,49 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonPrivateFilesMainMenuHandlerService } from '@/addons/privatefiles/services/handlers/mainmenu';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockPrivateFilesHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockPrivateFiles';
blockName = 'private_files';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_privatefiles.pluginname',
class: 'addon-block-private-files',
component: CoreBlockOnlyTitleComponent,
link: '/main/' + AddonPrivateFilesMainMenuHandlerService.PAGE_NAME,
linkParams: { root: 'my' },
};
}
}
export class AddonBlockPrivateFilesHandler extends makeSingleton(AddonBlockPrivateFilesHandlerService) {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockRecentActivityComponent } from './recentactivity/recentactivity';
@NgModule({
declarations: [
AddonBlockRecentActivityComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockRecentActivityComponent,
],
entryComponents: [
AddonBlockRecentActivityComponent,
],
})
export class AddonBlockRecentActivityComponentsModule {}

View File

@ -0,0 +1,25 @@
:host .core-block-content ::ng-deep {
.activitydate, .activityhead {
text-align: center;
}
.unlist {
list-style: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li {
margin-bottom: 1em;
.head .date {
float: right;
}
}
}
}
:host-context([dir=rtl]) .core-block-content ::ng-deep {
.unlist li .head .date {
float: left;
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a recent activity block.
*/
@Component({
selector: 'addon-block-recent-activity',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['recentactivity.scss'],
})
export class AddonBlockRecentActivityComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Recent activity"
}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockRecentActivityHandler } from './services/block-handler';
import { AddonBlockRecentActivityComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockRecentActivityComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockRecentActivityHandler.instance);
},
},
],
})
export class AddonBlockRecentActivityModule {}

View File

@ -0,0 +1,47 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { AddonBlockRecentActivityComponent } from '../components/recentactivity/recentactivity';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockRecentActivityHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockRecentActivity';
blockName = 'recent_activity';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_recentactivity.pluginname',
class: 'addon-block-recent-activity',
component: AddonBlockRecentActivityComponent,
};
}
}
export class AddonBlockRecentActivityHandler extends makeSingleton(AddonBlockRecentActivityHandlerService) {}

View File

@ -0,0 +1,45 @@
// (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 { 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 { CoreCoursesComponentsModule } from '@features/courses/components/components.module';
import { AddonBlockRecentlyAccessedCoursesComponent } from './recentlyaccessedcourses/recentlyaccessedcourses';
@NgModule({
declarations: [
AddonBlockRecentlyAccessedCoursesComponent,
],
imports: [
CommonModule,
IonicModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
CoreCoursesComponentsModule,
],
exports: [
AddonBlockRecentlyAccessedCoursesComponent,
],
entryComponents: [
AddonBlockRecentlyAccessedCoursesComponent,
],
})
export class AddonBlockRecentlyAccessedCoursesComponentsModule {}

View File

@ -0,0 +1,22 @@
<ion-item-divider>
<ion-label>
<h2>{{ 'addon.block_recentlyaccessedcourses.pluginname' | translate }}</h2>
</ion-label>
<div *ngIf="downloadCoursesEnabled && downloadEnabled && courses && courses.length > 1" class="core-button-spinner" slot="end">
<ion-button *ngIf="prefetchCoursesData.icon && !prefetchCoursesData.loading" fill="clear" color="dark" (click)="prefetchCourses()">
<ion-icon [name]="prefetchCoursesData.icon" slot="icon-only">
</ion-icon>
</ion-button>
<ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData.badge">{{prefetchCoursesData.badge}}</ion-badge>
<ion-spinner *ngIf="!prefetchCoursesData.icon || prefetchCoursesData.loading"></ion-spinner>
</div>
</ion-item-divider>
<core-loading [hideUntil]="loaded" class="core-loading-center safe-area-page">
<core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" [message]="'addon.block_recentlyaccessedcourses.nocourses' | translate"></core-empty-box>
<!-- List of courses. -->
<div class="core-horizontal-scroll">
<ng-container *ngFor="let course of courses">
<core-courses-course-progress [course]="course" class="core-recentlyaccessedcourses" [showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
</ng-container>
</div>
</core-loading>

View File

@ -0,0 +1,237 @@
// (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, OnDestroy, Input, OnChanges, SimpleChange } from '@angular/core';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites';
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData, CoreCourses } from '@features/courses/services/courses';
import { CoreCoursesHelper, CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
import { CoreCourseHelper, CorePrefetchStatusInfo } from '@features/course/services/course-helper';
import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
import { AddonCourseCompletion } from '@/addons/coursecompletion/services/coursecompletion';
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
import { CoreUtils } from '@services/utils/utils';
import { CoreDomUtils } from '@services/utils/dom';
/**
* Component to render a recent courses block.
*/
@Component({
selector: 'addon-block-recentlyaccessedcourses',
templateUrl: 'addon-block-recentlyaccessedcourses.html',
})
export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseComponent implements OnInit, OnChanges, OnDestroy {
@Input() downloadEnabled = false;
courses: CoreEnrolledCourseDataWithOptions [] = [];
prefetchCoursesData: CorePrefetchStatusInfo = {
icon: '',
statusTranslatable: 'core.loading',
status: '',
loading: true,
badge: '',
};
downloadCourseEnabled = false;
downloadCoursesEnabled = false;
protected prefetchIconsInitialized = false;
protected isDestroyed = false;
protected coursesObserver?: CoreEventObserver;
protected updateSiteObserver?: CoreEventObserver;
protected courseIds = [];
protected fetchContentDefaultError = 'Error getting recent courses data.';
constructor() {
super('AddonBlockRecentlyAccessedCoursesComponent');
}
/**
* Component being initialized.
*/
async ngOnInit(): Promise<void> {
// Refresh the enabled flags if enabled.
this.downloadCourseEnabled = !CoreCourses.instance.isDownloadCourseDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.instance.isDownloadCoursesDisabledInSite();
// Refresh the enabled flags if site is updated.
this.updateSiteObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
this.downloadCourseEnabled = !CoreCourses.instance.isDownloadCourseDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.instance.isDownloadCoursesDisabledInSite();
}, CoreSites.instance.getCurrentSiteId());
this.coursesObserver = CoreEvents.on(
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED,
(data: CoreCoursesMyCoursesUpdatedEventData) => {
if (this.shouldRefreshOnUpdatedEvent(data)) {
this.refreshCourseList();
}
},
CoreSites.instance.getCurrentSiteId(),
);
super.ngOnInit();
}
/**
* Detect changes on input properties.
*/
ngOnChanges(changes: {[name: string]: SimpleChange}): void {
if (changes.downloadEnabled && !changes.downloadEnabled.previousValue && this.downloadEnabled && this.loaded) {
// Download all courses is enabled now, initialize it.
this.initPrefetchCoursesIcons();
}
}
/**
* Perform the invalidate content function.
*
* @return Resolved when done.
*/
protected async invalidateContent(): Promise<void> {
const promises: Promise<void>[] = [];
promises.push(CoreCourses.instance.invalidateUserCourses().finally(() =>
// Invalidate course completion data.
CoreUtils.instance.allPromises(this.courseIds.map((courseId) =>
AddonCourseCompletion.instance.invalidateCourseCompletion(courseId)))));
promises.push(CoreCourseOptionsDelegate.instance.clearAndInvalidateCoursesOptions());
if (this.courseIds.length > 0) {
promises.push(CoreCourses.instance.invalidateCoursesByField('ids', this.courseIds.join(',')));
}
await CoreUtils.instance.allPromises(promises).finally(() => {
this.prefetchIconsInitialized = false;
});
}
/**
* Fetch the courses for recent courses.
*
* @return Promise resolved when done.
*/
protected async fetchContent(): Promise<void> {
const showCategories = this.block.configsRecord && this.block.configsRecord.displaycategories &&
this.block.configsRecord.displaycategories.value == '1';
this.courses = await CoreCoursesHelper.instance.getUserCoursesWithOptions('lastaccess', 10, undefined, showCategories);
this.initPrefetchCoursesIcons();
}
/**
* Refresh the list of courses.
*
* @return Promise resolved when done.
*/
protected async refreshCourseList(): Promise<void> {
CoreEvents.trigger(CoreCoursesProvider.EVENT_MY_COURSES_REFRESHED);
try {
await CoreCourses.instance.invalidateUserCourses();
} catch (error) {
// Ignore errors.
}
await this.loadContent(true);
}
/**
* Initialize the prefetch icon for selected courses.
*/
protected async initPrefetchCoursesIcons(): Promise<void> {
if (this.prefetchIconsInitialized || !this.downloadEnabled) {
// Already initialized.
return;
}
this.prefetchIconsInitialized = true;
this.prefetchCoursesData = await CoreCourseHelper.instance.initPrefetchCoursesIcons(this.courses, this.prefetchCoursesData);
}
/**
* Whether list should be refreshed based on a EVENT_MY_COURSES_UPDATED event.
*
* @param data Event data.
* @return Whether to refresh.
*/
protected shouldRefreshOnUpdatedEvent(data: CoreCoursesMyCoursesUpdatedEventData): boolean {
if (data.action == CoreCoursesProvider.ACTION_ENROL) {
// Always update if user enrolled in a course.
return true;
}
if (data.action == CoreCoursesProvider.ACTION_VIEW && data.courseId != CoreSites.instance.getCurrentSiteHomeId() &&
this.courses[0] && data.courseId != this.courses[0].id) {
// Update list if user viewed a course that isn't the most recent one and isn't site home.
return true;
}
if (data.action == CoreCoursesProvider.ACTION_STATE_CHANGED && data.state == CoreCoursesProvider.STATE_FAVOURITE &&
data.courseId && this.hasCourse(data.courseId)) {
// Update list if a visible course is now favourite or unfavourite.
return true;
}
return false;
}
/**
* Check if a certain course is in the list of courses.
*
* @param courseId Course ID to search.
* @return Whether it's in the list.
*/
protected hasCourse(courseId: number): boolean {
if (!this.courses) {
return false;
}
return !!this.courses.find((course) => course.id == courseId);
}
/**
* Prefetch all the shown courses.
*
* @return Promise resolved when done.
*/
async prefetchCourses(): Promise<void> {
const initialIcon = this.prefetchCoursesData.icon;
try {
return CoreCourseHelper.instance.prefetchCourses(this.courses, this.prefetchCoursesData);
} catch (error) {
if (!this.isDestroyed) {
CoreDomUtils.instance.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
this.prefetchCoursesData.icon = initialIcon;
}
}
}
/**
* Component being destroyed.
*/
ngOnDestroy(): void {
this.isDestroyed = true;
this.coursesObserver?.off();
this.updateSiteObserver?.off();
}
}

View File

@ -0,0 +1,4 @@
{
"nocourses": "No recent courses",
"pluginname": "Recently accessed courses"
}

View File

@ -0,0 +1,40 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockRecentlyAccessedCoursesComponentsModule } from './components/components.module';
import { AddonBlockRecentlyAccessedCoursesHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
CoreComponentsModule,
AddonBlockRecentlyAccessedCoursesComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockRecentlyAccessedCoursesHandler.instance);
},
},
],
})
export class AddonBlockRecentlyAccessedCoursesModule {}

View File

@ -0,0 +1,46 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { AddonBlockRecentlyAccessedCoursesComponent } from '../components/recentlyaccessedcourses/recentlyaccessedcourses';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockRecentlyAccessedCoursesHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockRecentlyAccessedCourses';
blockName = 'recentlyaccessedcourses';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_recentlyaccessedcourses.pluginname',
class: 'addon-block-recentlyaccessedcourses',
component: AddonBlockRecentlyAccessedCoursesComponent,
};
}
}
export class AddonBlockRecentlyAccessedCoursesHandler extends makeSingleton(AddonBlockRecentlyAccessedCoursesHandlerService) {}

View File

@ -0,0 +1,45 @@
// (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 { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockRssClientComponent } from './rssclient/rssclient';
@NgModule({
declarations: [
AddonBlockRssClientComponent,
],
imports: [
CommonModule,
IonicModule,
FormsModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
],
exports: [
AddonBlockRssClientComponent,
],
entryComponents: [
AddonBlockRssClientComponent,
],
})
export class AddonBlockRssClientComponentsModule {}

View File

@ -0,0 +1,18 @@
:host .core-block-content ::ng-deep {
.list {
list-style: none;
margin-left: 0;
margin-right: 0;
-webkit-padding-start: 0;
li {
border-top: 1px solid var(--gray);
padding: 5px;
padding-bottom: 8px;
}
li:first-child {
border-top-width: 0;
}
}
}

View File

@ -0,0 +1,26 @@
// (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 } from '@angular/core';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
/**
* Component to render a rss client block.
*/
@Component({
selector: 'addon-block-rss-client',
templateUrl: '../../../../../core/features/block/components/pre-rendered-block/core-block-pre-rendered.html',
styleUrls: ['rssclient.scss'],
})
export class AddonBlockRssClientComponent extends CoreBlockPreRenderedComponent {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Remote RSS feeds"
}

View File

@ -0,0 +1,38 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockRssClientHandler } from './services/block-handler';
import { AddonBlockRssClientComponentsModule } from './components/components.module';
@NgModule({
imports: [
IonicModule,
AddonBlockRssClientComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockRssClientHandler.instance);
},
},
],
})
export class AddonBlockRssClientModule {}

View File

@ -0,0 +1,49 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { CoreCourseBlock } from '@features/course/services/course';
import { AddonBlockRssClientComponent } from '../components/rssclient/rssclient';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockRssClientHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockRssClient';
blockName = 'rss_client';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock): CoreBlockHandlerData {
return {
title: block.contents?.title || 'addon.block_rssclient.pluginname',
class: 'addon-block-rss-client',
component: AddonBlockRssClientComponent,
};
}
}
export class AddonBlockRssClientHandler extends makeSingleton(AddonBlockRssClientHandlerService) {}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Self completion"
}

View File

@ -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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockSelfCompletionHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockSelfCompletionHandler.instance);
},
},
],
})
export class AddonBlockSelfCompletionModule {}

View File

@ -0,0 +1,53 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreBlockOnlyTitleComponent } from '@features/block/components/only-title-block/only-title-block';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { CoreCourseBlock } from '@features/course/services/course';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockSelfCompletionHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockSelfCompletion';
blockName = 'selfcompletion';
/**
* Returns the data needed to render the block.
*
* @param block The block to render.
* @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level.
* @return Data or promise resolved with the data.
*/
getDisplayData(block: CoreCourseBlock, contextLevel: string, instanceId: number): CoreBlockHandlerData {
// @todo
return {
title: 'addon.block_selfcompletion.pluginname',
class: 'addon-block-self-completion',
component: CoreBlockOnlyTitleComponent,
link: 'AddonCourseCompletionReportPage',
linkParams: { courseId: instanceId },
};
}
}
export class AddonBlockSelfCompletionHandler extends makeSingleton(AddonBlockSelfCompletionHandlerService) {}

View File

@ -0,0 +1,46 @@
// (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 { 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 { CoreCourseComponentsModule } from '@features/course/components/components.module';
import { AddonBlockSiteMainMenuComponent } from './sitemainmenu/sitemainmenu';
@NgModule({
declarations: [
AddonBlockSiteMainMenuComponent,
],
imports: [
CommonModule,
IonicModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
// CoreCourseComponentsModule,
],
exports: [
AddonBlockSiteMainMenuComponent,
],
entryComponents: [
AddonBlockSiteMainMenuComponent,
],
})
export class AddonBlockSiteMainMenuComponentsModule {}

View File

@ -0,0 +1,14 @@
<ion-item-divider>
<ion-label>
<h2>{{ 'addon.block_sitemainmenu.pluginname' | translate }}</h2>
</ion-label>
</ion-item-divider>
<core-loading [hideUntil]="loaded" class="core-loading-center">
<ng-container *ngIf="mainMenuBlock">
<ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
<core-format-text [text]="mainMenuBlock.summary" [component]="component" [componentId]="siteHomeId" contextLevel="course" [contextInstanceId]="siteHomeId"></core-format-text>
</ion-item>
<!--<core-course-module *ngFor="let module of mainMenuBlock.modules" [module]="module" [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled" [section]="mainMenuBlock"></core-course-module>-->
</ng-container>
</core-loading>

View File

@ -0,0 +1,116 @@
// (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, Input } from '@angular/core';
import { CoreSites } from '@services/sites';
import { CoreCourse, CoreCourseSection } from '@features/course/services/course';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CoreSiteHome, FrontPageItemNames } from '@features/sitehome/services/sitehome';
// @todo import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
/**
* Component to render a site main menu block.
*/
@Component({
selector: 'addon-block-sitemainmenu',
templateUrl: 'addon-block-sitemainmenu.html',
})
export class AddonBlockSiteMainMenuComponent extends CoreBlockBaseComponent implements OnInit {
@Input() downloadEnabled = false;
component = 'AddonBlockSiteMainMenu';
mainMenuBlock?: CoreCourseSection;
siteHomeId = 1;
protected fetchContentDefaultError = 'Error getting main menu data.';
constructor() {
super('AddonBlockSiteMainMenuComponent');
}
/**
* Component being initialized.
*/
async ngOnInit(): Promise<void> {
this.siteHomeId = CoreSites.instance.getCurrentSite()?.getSiteHomeId() || 1;
super.ngOnInit();
}
/**
* Perform the invalidate content function.
*
* @return Resolved when done.
*/
protected async invalidateContent(): Promise<void> {
const promises: Promise<void>[] = [];
promises.push(CoreCourse.instance.invalidateSections(this.siteHomeId));
promises.push(CoreSiteHome.instance.invalidateNewsForum(this.siteHomeId));
if (this.mainMenuBlock && this.mainMenuBlock.modules) {
// Invalidate modules prefetch data.
// @todo promises.push(this.prefetchDelegate.invalidateModules(this.mainMenuBlock.modules, this.siteHomeId));
}
await Promise.all(promises);
}
/**
* Fetch the data to render the block.
*
* @return Promise resolved when done.
*/
protected async fetchContent(): Promise<void> {
const sections = await CoreCourse.instance.getSections(this.siteHomeId, false, true);
this.mainMenuBlock = sections.find((section) => section.section == 0);
if (!this.mainMenuBlock) {
return;
}
const currentSite = CoreSites.instance.getCurrentSite();
const config = currentSite ? currentSite.getStoredConfig() || {} : {};
if (!config.frontpageloggedin) {
return;
}
// Check if Site Home displays announcements. If so, remove it from the main menu block.
const items = config.frontpageloggedin.split(',');
const hasNewsItem = items.find((item) => parseInt(item, 10) == FrontPageItemNames['NEWS_ITEMS']);
const hasContent = CoreCourseHelper.instance.sectionHasContent(this.mainMenuBlock);
CoreCourseHelper.instance.addHandlerDataForModules([this.mainMenuBlock], this.siteHomeId, undefined, undefined, true);
if (!hasNewsItem || !hasContent) {
return;
}
// Remove forum activity (news one only) from the main menu block to prevent duplicates.
try {
const forum = await CoreSiteHome.instance.getNewsForum(this.siteHomeId);
// Search the module that belongs to site news.
const forumIndex =
this.mainMenuBlock.modules.findIndex((mod) => mod.modname == 'forum' && mod.instance == forum.id);
if (forumIndex >= 0) {
this.mainMenuBlock.modules.splice(forumIndex, 1);
}
} catch {
// Ignore errors.
}
}
}

View File

@ -0,0 +1,3 @@
{
"pluginname": "Main menu"
}

View File

@ -0,0 +1,46 @@
// (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 { CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { AddonBlockSiteMainMenuComponent } from '../components/sitemainmenu/sitemainmenu';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { makeSingleton } from '@singletons';
/**
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockSiteMainMenuHandlerService extends CoreBlockBaseHandler {
name = 'AddonBlockSiteMainMenu';
blockName = 'site_main_menu';
/**
* Returns the data needed to render the block.
*
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
return {
title: 'addon.block_sitemainmenu.pluginname',
class: 'addon-block-sitemainmenu',
component: AddonBlockSiteMainMenuComponent,
};
}
}
export class AddonBlockSiteMainMenuHandler extends makeSingleton(AddonBlockSiteMainMenuHandlerService) {}

View File

@ -0,0 +1,42 @@
// (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 { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonBlockSiteMainMenuComponentsModule } from './components/components.module';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { AddonBlockSiteMainMenuHandler } from './services/block-handler';
@NgModule({
imports: [
IonicModule,
CoreComponentsModule,
CoreDirectivesModule,
AddonBlockSiteMainMenuComponentsModule,
TranslateModule.forChild(),
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
useValue: () => {
CoreBlockDelegate.instance.registerHandler(AddonBlockSiteMainMenuHandler.instance);
},
},
],
})
export class AddonBlockSiteMainMenuModule {}

Some files were not shown because too many files have changed in this diff Show More