From ba1267410e83d52f3bb4445a34e158f7ff4ac09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 16 Jan 2018 15:52:07 +0100 Subject: [PATCH] MOBILE-2317 user: Add profile field delegate --- .../checkbox/checkbox.module.ts | 46 +++++ .../checkbox/component/checkbox.html | 16 ++ .../checkbox/component/checkbox.scss | 0 .../checkbox/component/checkbox.ts | 47 +++++ .../checkbox/providers/handler.ts | 70 ++++++++ .../datetime/component/datetime.html | 10 ++ .../datetime/component/datetime.scss | 0 .../datetime/component/datetime.ts | 63 +++++++ .../datetime/datetime.module.ts | 48 +++++ .../datetime/providers/handler.ts | 85 +++++++++ .../userprofilefield/menu/component/menu.html | 13 ++ .../userprofilefield/menu/component/menu.scss | 0 .../userprofilefield/menu/component/menu.ts | 55 ++++++ .../userprofilefield/menu/menu.module.ts | 48 +++++ .../menu/providers/handler.ts | 70 ++++++++ .../userprofilefield/text/component/text.html | 10 ++ .../userprofilefield/text/component/text.scss | 0 .../userprofilefield/text/component/text.ts | 55 ++++++ .../text/providers/handler.ts | 69 ++++++++ .../userprofilefield/text/text.module.ts | 48 +++++ .../textarea/component/textarea.html | 10 ++ .../textarea/component/textarea.scss | 0 .../textarea/component/textarea.ts | 50 ++++++ .../textarea/providers/handler.ts | 83 +++++++++ .../textarea/textarea.module.ts | 48 +++++ .../userprofilefield.module.ts | 35 ++++ src/app/app.module.ts | 5 +- src/core/user/components/components.module.ts | 36 ++++ .../user-profile-field.html | 2 + .../user-profile-field.scss | 5 + .../user-profile-field/user-profile-field.ts | 98 +++++++++++ src/core/user/pages/about/about.html | 1 + src/core/user/pages/about/about.module.ts | 2 + src/core/user/pages/profile/profile.ts | 3 +- .../{delegate.ts => user-delegate.ts} | 2 +- src/core/user/providers/user-handler.ts | 2 +- .../providers/user-profile-field-delegate.ts | 164 ++++++++++++++++++ src/core/user/user.module.ts | 4 +- 38 files changed, 1297 insertions(+), 6 deletions(-) create mode 100644 src/addon/userprofilefield/checkbox/checkbox.module.ts create mode 100644 src/addon/userprofilefield/checkbox/component/checkbox.html create mode 100644 src/addon/userprofilefield/checkbox/component/checkbox.scss create mode 100644 src/addon/userprofilefield/checkbox/component/checkbox.ts create mode 100644 src/addon/userprofilefield/checkbox/providers/handler.ts create mode 100644 src/addon/userprofilefield/datetime/component/datetime.html create mode 100644 src/addon/userprofilefield/datetime/component/datetime.scss create mode 100644 src/addon/userprofilefield/datetime/component/datetime.ts create mode 100644 src/addon/userprofilefield/datetime/datetime.module.ts create mode 100644 src/addon/userprofilefield/datetime/providers/handler.ts create mode 100644 src/addon/userprofilefield/menu/component/menu.html create mode 100644 src/addon/userprofilefield/menu/component/menu.scss create mode 100644 src/addon/userprofilefield/menu/component/menu.ts create mode 100644 src/addon/userprofilefield/menu/menu.module.ts create mode 100644 src/addon/userprofilefield/menu/providers/handler.ts create mode 100644 src/addon/userprofilefield/text/component/text.html create mode 100644 src/addon/userprofilefield/text/component/text.scss create mode 100644 src/addon/userprofilefield/text/component/text.ts create mode 100644 src/addon/userprofilefield/text/providers/handler.ts create mode 100644 src/addon/userprofilefield/text/text.module.ts create mode 100644 src/addon/userprofilefield/textarea/component/textarea.html create mode 100644 src/addon/userprofilefield/textarea/component/textarea.scss create mode 100644 src/addon/userprofilefield/textarea/component/textarea.ts create mode 100644 src/addon/userprofilefield/textarea/providers/handler.ts create mode 100644 src/addon/userprofilefield/textarea/textarea.module.ts create mode 100644 src/addon/userprofilefield/userprofilefield.module.ts create mode 100644 src/core/user/components/components.module.ts create mode 100644 src/core/user/components/user-profile-field/user-profile-field.html create mode 100644 src/core/user/components/user-profile-field/user-profile-field.scss create mode 100644 src/core/user/components/user-profile-field/user-profile-field.ts rename src/core/user/providers/{delegate.ts => user-delegate.ts} (98%) create mode 100644 src/core/user/providers/user-profile-field-delegate.ts diff --git a/src/addon/userprofilefield/checkbox/checkbox.module.ts b/src/addon/userprofilefield/checkbox/checkbox.module.ts new file mode 100644 index 000000000..1d85b6890 --- /dev/null +++ b/src/addon/userprofilefield/checkbox/checkbox.module.ts @@ -0,0 +1,46 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { AddonUserProfileFieldCheckboxHandler } from './providers/handler'; +import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldCheckboxComponent } from './component/checkbox'; +import { CoreComponentsModule } from '../../../components/components.module'; + +@NgModule({ + declarations: [ + AddonUserProfileFieldCheckboxComponent + ], + imports: [ + IonicModule, + TranslateModule.forChild(), + CoreComponentsModule + ], + providers: [ + AddonUserProfileFieldCheckboxHandler + ], + exports: [ + AddonUserProfileFieldCheckboxComponent + ], + entryComponents: [ + AddonUserProfileFieldCheckboxComponent + ] +}) +export class AddonUserProfileFieldCheckboxModule { + constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldCheckboxHandler) { + userProfileFieldDelegate.registerHandler(handler); + } +} \ No newline at end of file diff --git a/src/addon/userprofilefield/checkbox/component/checkbox.html b/src/addon/userprofilefield/checkbox/component/checkbox.html new file mode 100644 index 000000000..8ab6fe45f --- /dev/null +++ b/src/addon/userprofilefield/checkbox/component/checkbox.html @@ -0,0 +1,16 @@ + + +

{{ field.name }}

+

+ {{ 'core.yes' | translate }} +

+

+ {{ 'core.no' | translate }} +

+
+ + + {{ field.name }} + + + \ No newline at end of file diff --git a/src/addon/userprofilefield/checkbox/component/checkbox.scss b/src/addon/userprofilefield/checkbox/component/checkbox.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/addon/userprofilefield/checkbox/component/checkbox.ts b/src/addon/userprofilefield/checkbox/component/checkbox.ts new file mode 100644 index 000000000..28f11a4bf --- /dev/null +++ b/src/addon/userprofilefield/checkbox/component/checkbox.ts @@ -0,0 +1,47 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, OnInit } from '@angular/core'; + +/** + * Directive to render a checkbox user profile field. + */ +@Component({ + selector: 'core-user-profile-field-checkbox', + templateUrl: 'checkbox.html' +}) +export class AddonUserProfileFieldCheckboxComponent implements OnInit { + @Input() field: any; // The profile field to be rendered. + @Input() edit?: boolean = false; // True if editing the field. Defaults to false. + @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true. + + constructor() {} + + /** + * Component being initialized. + */ + ngOnInit() { + let field = this.field; + + if (field && this.edit && this.model) { + field.modelName = 'profile_field_' + field.shortname; + + // Initialize the value. + if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') { + this.model[field.modelName] = field.defaultdata && field.defaultdata !== '0' && field.defaultdata !== 'false'; + } + } + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/checkbox/providers/handler.ts b/src/addon/userprofilefield/checkbox/providers/handler.ts new file mode 100644 index 000000000..69c7ac051 --- /dev/null +++ b/src/addon/userprofilefield/checkbox/providers/handler.ts @@ -0,0 +1,70 @@ + +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { Injectable } from '@angular/core'; +import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldCheckboxComponent } from '../component/checkbox'; + +/** + * Checkbox user profile field handlers. + */ +@Injectable() +export class AddonUserProfileFieldCheckboxHandler implements CoreUserProfileFieldHandler { + name = 'checkbox'; + + constructor() {} + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled() : boolean|Promise { + return true; + } + + /** + * Get the data to send for the field based on the input data. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {CoreUserProfileFieldHandlerData} Data to send for the field. + */ + getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { + let name = 'profile_field_' + field.shortname; + + if (typeof model[name] != 'undefined') { + return { + type: 'checkbox', + name: name, + value: model[name] ? 1 : 0 + }; + } + } + + /** + * Return the Component to use to display the user profile field. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string) { + return AddonUserProfileFieldCheckboxComponent; + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/datetime/component/datetime.html b/src/addon/userprofilefield/datetime/component/datetime.html new file mode 100644 index 000000000..cd19d4595 --- /dev/null +++ b/src/addon/userprofilefield/datetime/component/datetime.html @@ -0,0 +1,10 @@ + + +

{{ field.name }}

+

{{ field.value * 1000 | coreFormatDate:"dfmediumdate"}}

+
+ + + {{ field.name }} + + \ No newline at end of file diff --git a/src/addon/userprofilefield/datetime/component/datetime.scss b/src/addon/userprofilefield/datetime/component/datetime.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/addon/userprofilefield/datetime/component/datetime.ts b/src/addon/userprofilefield/datetime/component/datetime.ts new file mode 100644 index 000000000..4526abc5e --- /dev/null +++ b/src/addon/userprofilefield/datetime/component/datetime.ts @@ -0,0 +1,63 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, OnInit } from '@angular/core'; + +/** + * Directive to render a datetime user profile field. + */ +@Component({ + selector: 'core-user-profile-field-datetime', + templateUrl: 'datetime.html' +}) +export class AddonUserProfileFieldDatetimeComponent implements OnInit { + @Input() field: any; // The profile field to be rendered. + @Input() edit?: boolean = false; // True if editing the field. Defaults to false. + @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true. + + + constructor() {} + + /** + * Component being initialized. + */ + ngOnInit() { + let field = this.field, + year; + if (field && this.edit && this.model) { + field.modelName = 'profile_field_' + field.shortname; + + // Check if it's only date or it has time too. + field.hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false'; + field.format = field.hasTime ? 'core.dffulldate' : 'core.dfdaymonthyear'; + + // Check min value. + if (field.param1) { + year = parseInt(field.param1, 10); + if (year) { + field.min = year; + } + } + + // Check max value. + if (field.param2) { + year = parseInt(field.param2, 10); + if (year) { + field.max = year; + } + } + } + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/datetime/datetime.module.ts b/src/addon/userprofilefield/datetime/datetime.module.ts new file mode 100644 index 000000000..1697b0e9f --- /dev/null +++ b/src/addon/userprofilefield/datetime/datetime.module.ts @@ -0,0 +1,48 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { AddonUserProfileFieldDatetimeHandler } from './providers/handler'; +import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldDatetimeComponent } from './component/datetime'; +import { CoreComponentsModule } from '../../../components/components.module'; +import { CorePipesModule } from '../../../pipes/pipes.module'; + +@NgModule({ + declarations: [ + AddonUserProfileFieldDatetimeComponent + ], + imports: [ + IonicModule, + TranslateModule.forChild(), + CoreComponentsModule, + CorePipesModule + ], + providers: [ + AddonUserProfileFieldDatetimeHandler + ], + exports: [ + AddonUserProfileFieldDatetimeComponent + ], + entryComponents: [ + AddonUserProfileFieldDatetimeComponent + ] +}) +export class AddonUserProfileFieldDatetimeModule { + constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldDatetimeHandler) { + userProfileFieldDelegate.registerHandler(handler); + } +} \ No newline at end of file diff --git a/src/addon/userprofilefield/datetime/providers/handler.ts b/src/addon/userprofilefield/datetime/providers/handler.ts new file mode 100644 index 000000000..ad3c95414 --- /dev/null +++ b/src/addon/userprofilefield/datetime/providers/handler.ts @@ -0,0 +1,85 @@ + +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { Injectable } from '@angular/core'; +import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldDatetimeComponent } from '../component/datetime'; +import { Platform } from 'ionic-angular'; + +/** + * Datetime user profile field handlers. + */ +@Injectable() +export class AddonUserProfileFieldDatetimeHandler implements CoreUserProfileFieldHandler { + name = 'datetime'; + + constructor(private platform: Platform) {} + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled() : boolean|Promise { + return true; + } + + /** + * Get the data to send for the field based on the input data. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {CoreUserProfileFieldHandlerData} Data to send for the field. + */ + getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { + let hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false', + modelName = 'profile_field_' + field.shortname, + date = JSON.parse(JSON.stringify(model[modelName + '_date'])), + time; + + if (date) { + if (hasTime && this.platform.is('ios')) { + // In iOS the time is in a different input. Add it to the date. + time = model[modelName + '_time']; + if (!time) { + return; + } + + date.setHours(time.getHours()); + date.setMinutes(time.getMinutes()); + } + + return { + type: 'datetime', + name: 'profile_field_' + field.shortname, + value: Math.round(date.getTime() / 1000) + }; + } + } + + /** + * Return the Component to use to display the user profile field. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string) { + return AddonUserProfileFieldDatetimeComponent; + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/menu/component/menu.html b/src/addon/userprofilefield/menu/component/menu.html new file mode 100644 index 000000000..23ee49f9b --- /dev/null +++ b/src/addon/userprofilefield/menu/component/menu.html @@ -0,0 +1,13 @@ + + +

{{ field.name }}

+

+
+ + + {{ field.name }} + + {{ 'core.choosedots' | translate }} + {{option}} + + diff --git a/src/addon/userprofilefield/menu/component/menu.scss b/src/addon/userprofilefield/menu/component/menu.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/addon/userprofilefield/menu/component/menu.ts b/src/addon/userprofilefield/menu/component/menu.ts new file mode 100644 index 000000000..98bf2f43b --- /dev/null +++ b/src/addon/userprofilefield/menu/component/menu.ts @@ -0,0 +1,55 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, OnInit } from '@angular/core'; + +/** + * Directive to render a menu user profile field. + */ +@Component({ + selector: 'core-user-profile-field-menu', + templateUrl: 'menu.html' +}) +export class AddonUserProfileFieldMenuComponent implements OnInit { + @Input() field: any; // The profile field to be rendered. + @Input() edit?: boolean = false; // True if editing the field. Defaults to false. + @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true. + + constructor() {} + + /** + * Component being initialized. + */ + ngOnInit() { + let field = this.field; + + if (field && this.edit && this.model) { + field.modelName = 'profile_field_' + field.shortname; + + // Parse options. + if (field.param1) { + field.options = field.param1.split(/\r\n|\r|\n/g); + } else { + field.options = []; + } + + // Initialize the value using default data. + if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') { + this.model[field.modelName] = field.defaultdata; + } + } + + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/menu/menu.module.ts b/src/addon/userprofilefield/menu/menu.module.ts new file mode 100644 index 000000000..dfaa1c0ea --- /dev/null +++ b/src/addon/userprofilefield/menu/menu.module.ts @@ -0,0 +1,48 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { AddonUserProfileFieldMenuHandler } from './providers/handler'; +import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldMenuComponent } from './component/menu'; +import { CoreComponentsModule } from '../../../components/components.module'; +import { CoreDirectivesModule } from '../../../directives/directives.module'; + +@NgModule({ + declarations: [ + AddonUserProfileFieldMenuComponent + ], + imports: [ + IonicModule, + TranslateModule.forChild(), + CoreComponentsModule, + CoreDirectivesModule + ], + providers: [ + AddonUserProfileFieldMenuHandler + ], + exports: [ + AddonUserProfileFieldMenuComponent + ], + entryComponents: [ + AddonUserProfileFieldMenuComponent + ] +}) +export class AddonUserProfileFieldMenuModule { + constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldMenuHandler) { + userProfileFieldDelegate.registerHandler(handler); + } +} \ No newline at end of file diff --git a/src/addon/userprofilefield/menu/providers/handler.ts b/src/addon/userprofilefield/menu/providers/handler.ts new file mode 100644 index 000000000..470fd1d3d --- /dev/null +++ b/src/addon/userprofilefield/menu/providers/handler.ts @@ -0,0 +1,70 @@ + +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { Injectable } from '@angular/core'; +import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldMenuComponent } from '../component/menu'; + +/** + * Menu user profile field handlers. + */ +@Injectable() +export class AddonUserProfileFieldMenuHandler implements CoreUserProfileFieldHandler { + name = 'menu'; + + constructor() {} + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled() : boolean|Promise { + return true; + } + + /** + * Get the data to send for the field based on the input data. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {CoreUserProfileFieldHandlerData} Data to send for the field. + */ + getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { + let name = 'profile_field_' + field.shortname; + + if (model[name]) { + return { + type: 'menu', + name: name, + value: model[name] + }; + } + } + + /** + * Return the Component to use to display the user profile field. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string) { + return AddonUserProfileFieldMenuComponent; + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/text/component/text.html b/src/addon/userprofilefield/text/component/text.html new file mode 100644 index 000000000..c27315320 --- /dev/null +++ b/src/addon/userprofilefield/text/component/text.html @@ -0,0 +1,10 @@ + + +

{{ field.name }}

+

+
+ + + {{ field.name }} + + diff --git a/src/addon/userprofilefield/text/component/text.scss b/src/addon/userprofilefield/text/component/text.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/addon/userprofilefield/text/component/text.ts b/src/addon/userprofilefield/text/component/text.ts new file mode 100644 index 000000000..f8fd5b72e --- /dev/null +++ b/src/addon/userprofilefield/text/component/text.ts @@ -0,0 +1,55 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, OnInit } from '@angular/core'; + +/** + * Directive to render a text user profile field. + */ +@Component({ + selector: 'core-user-profile-field-text', + templateUrl: 'text.html' +}) +export class AddonUserProfileFieldTextComponent implements OnInit { + @Input() field: any; // The profile field to be rendered. + @Input() edit?: boolean = false; // True if editing the field. Defaults to false. + @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true. + + constructor() {} + + /** + * Component being initialized. + */ + ngOnInit() { + let field = this.field; + + if (field && this.edit && this.model) { + field.modelName = 'profile_field_' + field.shortname; + + // Check max length. + if (field.param2) { + field.maxlength = parseInt(field.param2, 10) || ''; + } + + // Check if it's a password or text. + field.inputType = field.param3 && field.param3 !== '0' && field.param3 !== 'false' ? 'password' : 'text'; + + // Initialize the value using default data. + if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') { + this.model[field.modelName] = field.defaultdata; + } + } + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/text/providers/handler.ts b/src/addon/userprofilefield/text/providers/handler.ts new file mode 100644 index 000000000..30949f452 --- /dev/null +++ b/src/addon/userprofilefield/text/providers/handler.ts @@ -0,0 +1,69 @@ + +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { Injectable } from '@angular/core'; +import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldTextComponent } from '../component/text'; +import { CoreTextUtilsProvider } from '../../../../providers/utils/text'; + +/** + * Text user profile field handlers. + */ +@Injectable() +export class AddonUserProfileFieldTextHandler implements CoreUserProfileFieldHandler { + name = 'text'; + + constructor(private textUtils: CoreTextUtilsProvider) {} + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled() : boolean|Promise { + return true; + } + + /** + * Get the data to send for the field based on the input data. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {CoreUserProfileFieldHandlerData} Data to send for the field. + */ + getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { + let name = 'profile_field_' + field.shortname; + + return { + type: 'text', + name: name, + value: this.textUtils.cleanTags(model[name]) + }; + } + + /** + * Return the Component to use to display the user profile field. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string) { + return AddonUserProfileFieldTextComponent; + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/text/text.module.ts b/src/addon/userprofilefield/text/text.module.ts new file mode 100644 index 000000000..4264c858c --- /dev/null +++ b/src/addon/userprofilefield/text/text.module.ts @@ -0,0 +1,48 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { AddonUserProfileFieldTextHandler } from './providers/handler'; +import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldTextComponent } from './component/text'; +import { CoreComponentsModule } from '../../../components/components.module'; +import { CoreDirectivesModule } from '../../../directives/directives.module'; + +@NgModule({ + declarations: [ + AddonUserProfileFieldTextComponent + ], + imports: [ + IonicModule, + TranslateModule.forChild(), + CoreComponentsModule, + CoreDirectivesModule + ], + providers: [ + AddonUserProfileFieldTextHandler + ], + exports: [ + AddonUserProfileFieldTextComponent + ], + entryComponents: [ + AddonUserProfileFieldTextComponent + ] +}) +export class AddonUserProfileFieldTextModule { + constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldTextHandler) { + userProfileFieldDelegate.registerHandler(handler); + } +} \ No newline at end of file diff --git a/src/addon/userprofilefield/textarea/component/textarea.html b/src/addon/userprofilefield/textarea/component/textarea.html new file mode 100644 index 000000000..003d70ef2 --- /dev/null +++ b/src/addon/userprofilefield/textarea/component/textarea.html @@ -0,0 +1,10 @@ + + +

{{ field.name }}

+

+
+ + + {{ field.name }} + + diff --git a/src/addon/userprofilefield/textarea/component/textarea.scss b/src/addon/userprofilefield/textarea/component/textarea.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/addon/userprofilefield/textarea/component/textarea.ts b/src/addon/userprofilefield/textarea/component/textarea.ts new file mode 100644 index 000000000..967c4081c --- /dev/null +++ b/src/addon/userprofilefield/textarea/component/textarea.ts @@ -0,0 +1,50 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, OnInit } from '@angular/core'; + +/** + * Directive to render a textarea user profile field. + */ +@Component({ + selector: 'core-user-profile-field-textarea', + templateUrl: 'textarea.html' +}) +export class AddonUserProfileFieldTextareaComponent implements OnInit { + @Input() field: any; // The profile field to be rendered. + @Input() edit?: boolean = false; // True if editing the field. Defaults to false. + @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true. + + constructor() {} + + /** + * Component being initialized. + */ + ngOnInit() { + let field = this.field; + + if (field && this.edit && this.model) { + field.modelName = 'profile_field_' + field.shortname; + this.model[field.modelName] = { + format: 1 + }; + + // Initialize the value using default data. + if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName].text == 'undefined') { + this.model[field.modelName].text = field.defaultdata; + } + } + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/textarea/providers/handler.ts b/src/addon/userprofilefield/textarea/providers/handler.ts new file mode 100644 index 000000000..544c2ad3e --- /dev/null +++ b/src/addon/userprofilefield/textarea/providers/handler.ts @@ -0,0 +1,83 @@ + +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { Injectable } from '@angular/core'; +import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldTextareaComponent } from '../component/textarea'; +import { CoreTextUtilsProvider } from '../../../../providers/utils/text'; +import { CoreDomUtilsProvider } from '../../../../providers/utils/dom'; + +/** + * Textarea user profile field handlers. + */ +@Injectable() +export class AddonUserProfileFieldTextareaHandler implements CoreUserProfileFieldHandler { + name = 'textarea'; + + constructor(private textUtils: CoreTextUtilsProvider, private domUtils: CoreDomUtilsProvider) {} + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled() : boolean|Promise { + return true; + } + + /** + * Get the data to send for the field based on the input data. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {Promise} Data to send for the field. + */ + getData(field: any, signup: boolean, registerAuth: string, model: any): Promise { + let name = 'profile_field_' + field.shortname; + + if (model[name]) { + return this.domUtils.isRichTextEditorEnabled().then((enabled) => { + let text = model[name].text || ''; + if (!enabled) { + // Rich text editor not enabled, add some HTML to the message if needed. + text = this.textUtils.formatHtmlLines(text); + } + + return { + type: 'textarea', + name: name, + value: JSON.stringify({ + text: text, + format: model[name].format || 1 + }) + }; + }); + } + } + + /** + * Return the Component to use to display the user profile field. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string) { + return AddonUserProfileFieldTextareaComponent; + } + +} \ No newline at end of file diff --git a/src/addon/userprofilefield/textarea/textarea.module.ts b/src/addon/userprofilefield/textarea/textarea.module.ts new file mode 100644 index 000000000..b1c2212d3 --- /dev/null +++ b/src/addon/userprofilefield/textarea/textarea.module.ts @@ -0,0 +1,48 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { AddonUserProfileFieldTextareaHandler } from './providers/handler'; +import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate'; +import { AddonUserProfileFieldTextareaComponent } from './component/textarea'; +import { CoreComponentsModule } from '../../../components/components.module'; +import { CoreDirectivesModule } from '../../../directives/directives.module'; + +@NgModule({ + declarations: [ + AddonUserProfileFieldTextareaComponent + ], + imports: [ + IonicModule, + TranslateModule.forChild(), + CoreComponentsModule, + CoreDirectivesModule + ], + providers: [ + AddonUserProfileFieldTextareaHandler + ], + exports: [ + AddonUserProfileFieldTextareaComponent + ], + entryComponents: [ + AddonUserProfileFieldTextareaComponent + ] +}) +export class AddonUserProfileFieldTextareaModule { + constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldTextareaHandler) { + userProfileFieldDelegate.registerHandler(handler); + } +} \ No newline at end of file diff --git a/src/addon/userprofilefield/userprofilefield.module.ts b/src/addon/userprofilefield/userprofilefield.module.ts new file mode 100644 index 000000000..a946dab74 --- /dev/null +++ b/src/addon/userprofilefield/userprofilefield.module.ts @@ -0,0 +1,35 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { NgModule } from '@angular/core'; +import { AddonUserProfileFieldCheckboxModule } from './checkbox/checkbox.module'; +import { AddonUserProfileFieldDatetimeModule } from './datetime/datetime.module'; +import { AddonUserProfileFieldMenuModule } from './menu/menu.module'; +import { AddonUserProfileFieldTextModule } from './text/text.module'; +import { AddonUserProfileFieldTextareaModule } from './textarea/textarea.module'; + + +@NgModule({ + declarations: [], + imports: [ + AddonUserProfileFieldCheckboxModule, + AddonUserProfileFieldDatetimeModule, + AddonUserProfileFieldMenuModule, + AddonUserProfileFieldTextModule, + AddonUserProfileFieldTextareaModule + ], + providers: [ + ], + exports: [] +}) +export class AddonUserProfileFieldModule {} \ No newline at end of file diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2a824241a..c68d1071b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -64,6 +64,8 @@ import { CoreUserModule } from '../core/user/user.module'; // Addon modules. import { AddonCalendarModule } from '../addon/calendar/calendar.module'; +import { AddonUserProfileFieldModule } from '../addon/userprofilefield/userprofilefield.module'; + // For translate loader. AoT requires an exported function for factories. export function createTranslateLoader(http: HttpClient) { @@ -99,7 +101,8 @@ export function createTranslateLoader(http: HttpClient) { CoreSiteHomeModule, CoreContentLinksModule, CoreUserModule, - AddonCalendarModule + AddonCalendarModule, + AddonUserProfileFieldModule ], bootstrap: [IonicApp], entryComponents: [ diff --git a/src/core/user/components/components.module.ts b/src/core/user/components/components.module.ts new file mode 100644 index 000000000..13682bbe7 --- /dev/null +++ b/src/core/user/components/components.module.ts @@ -0,0 +1,36 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreUserProfileFieldComponent } from './user-profile-field/user-profile-field'; + +@NgModule({ + declarations: [ + CoreUserProfileFieldComponent + ], + imports: [ + CommonModule, + IonicModule, + TranslateModule.forChild(), + ], + providers: [ + ], + exports: [ + CoreUserProfileFieldComponent + ] +}) +export class CoreUserComponentsModule {} diff --git a/src/core/user/components/user-profile-field/user-profile-field.html b/src/core/user/components/user-profile-field/user-profile-field.html new file mode 100644 index 000000000..825590342 --- /dev/null +++ b/src/core/user/components/user-profile-field/user-profile-field.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/core/user/components/user-profile-field/user-profile-field.scss b/src/core/user/components/user-profile-field/user-profile-field.scss new file mode 100644 index 000000000..a5595aa37 --- /dev/null +++ b/src/core/user/components/user-profile-field/user-profile-field.scss @@ -0,0 +1,5 @@ +core-user-profile-field { + +} + + diff --git a/src/core/user/components/user-profile-field/user-profile-field.ts b/src/core/user/components/user-profile-field/user-profile-field.ts new file mode 100644 index 000000000..1b3dcfee0 --- /dev/null +++ b/src/core/user/components/user-profile-field/user-profile-field.ts @@ -0,0 +1,98 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, OnInit } from '@angular/core'; +import { CoreLoggerProvider } from '../../../../providers/logger'; +import { CoreUserProfileFieldDelegate } from '../../providers/user-profile-field-delegate'; + +/** + * Directive to render user profile field. + */ +@Component({ + selector: 'core-user-profile-field', + templateUrl: 'user-profile-field.html' +}) +export class CoreUserProfileFieldComponent implements OnInit { + @Input() field: any; // The profile field to be rendered. + @Input() signup?: boolean = false; // True if editing the field in signup. Defaults to false. + @Input() edit?: boolean = false; // True if editing the field. Defaults to false. + @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true. + @Input() registerAuth?: string; // Register auth method. E.g. 'email'. + + // Get the containers where to inject dynamic components. We use a setter because they might be inside a *ngIf. + @ViewChild('userProfileField', { read: ViewContainerRef }) set userProfileField (el: ViewContainerRef) { + if (this.field) { + this.createComponent(this.ufDelegate.getComponent(this.field, this.signup, this.registerAuth), el); + } else { + // The component hasn't been initialized yet. Store the container. + this.fieldContainer = el; + } + }; + + protected logger; + + // Instances and containers of all the components that the handler could define. + protected fieldContainer: ViewContainerRef; + protected fieldInstance: any; + + constructor(logger: CoreLoggerProvider, private factoryResolver: ComponentFactoryResolver, + private ufDelegate: CoreUserProfileFieldDelegate) { + this.logger = logger.getInstance('CoreUserProfileFieldComponent'); + } + + /** + * Component being initialized. + */ + ngOnInit() { + this.createComponent(this.ufDelegate.getComponent(this.field, this.signup, this.registerAuth), this.fieldContainer); + } + + /** + * Create a component, add it to a container and set the input data. + * + * @param {any} componentClass The class of the component to create. + * @param {ViewContainerRef} container The container to add the component to. + * @return {boolean} Whether the component was successfully created. + */ + protected createComponent(componentClass: any, container: ViewContainerRef) : boolean { + if (!componentClass || !container) { + // No component to instantiate or container doesn't exist right now. + return false; + } + + if (this.fieldInstance && container === this.fieldContainer) { + // Component already instantiated and the component hasn't been destroyed, nothing to do. + return true; + } + + try { + // Create the component and add it to the container. + const factory = this.factoryResolver.resolveComponentFactory(componentClass), + componentRef = container.createComponent(factory); + + this.fieldContainer = container; + this.fieldInstance = componentRef.instance; + + // Set the Input data. + this.fieldInstance.field = this.field; + this.fieldInstance.edit = this.edit; + this.fieldInstance.model = this.model; + + return true; + } catch(ex) { + this.logger.error('Error creating user field component', ex, componentClass); + return false; + } + } +} diff --git a/src/core/user/pages/about/about.html b/src/core/user/pages/about/about.html index 6556144a4..f95e6f7c3 100644 --- a/src/core/user/pages/about/about.html +++ b/src/core/user/pages/about/about.html @@ -59,6 +59,7 @@

{{ 'core.user.interests' | translate}}

+ {{ 'core.user.description' | translate}} diff --git a/src/core/user/pages/about/about.module.ts b/src/core/user/pages/about/about.module.ts index 07f43dbba..22ea2afdd 100644 --- a/src/core/user/pages/about/about.module.ts +++ b/src/core/user/pages/about/about.module.ts @@ -18,6 +18,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { CoreUserAboutPage } from './about'; import { CoreDirectivesModule } from '../../../../directives/directives.module'; import { CoreComponentsModule } from '../../../../components/components.module'; +import { CoreUserComponentsModule } from '../../components/components.module'; @NgModule({ declarations: [ @@ -26,6 +27,7 @@ import { CoreComponentsModule } from '../../../../components/components.module'; imports: [ CoreComponentsModule, CoreDirectivesModule, + CoreUserComponentsModule, IonicPageModule.forChild(CoreUserAboutPage), TranslateModule.forChild() ], diff --git a/src/core/user/pages/profile/profile.ts b/src/core/user/pages/profile/profile.ts index 143c5d850..75f9456a1 100644 --- a/src/core/user/pages/profile/profile.ts +++ b/src/core/user/pages/profile/profile.ts @@ -23,7 +23,7 @@ import { CoreEventsProvider } from '../../../../providers/events'; import { CoreSitesProvider } from '../../../../providers/sites'; import { CoreMimetypeUtilsProvider } from '../../../../providers/utils/mimetype'; import { CoreFileUploaderHelperProvider } from '../../../fileuploader/providers/helper'; -import { CoreUserDelegate } from '../../providers/delegate'; +import { CoreUserDelegate } from '../../providers/user-delegate'; /** * Page that displays an user profile page. @@ -103,7 +103,6 @@ export class CoreUserProfilePage { this.isLoadingHandlers = true; this.userDelegate.getProfileHandlersFor(user, this.courseId).then((handlers) => { - console.error(handlers); this.actionHandlers = []; this.newPageHandlers = []; this.communicationHandlers = []; diff --git a/src/core/user/providers/delegate.ts b/src/core/user/providers/user-delegate.ts similarity index 98% rename from src/core/user/providers/delegate.ts rename to src/core/user/providers/user-delegate.ts index 7bb2f7638..659d09ba8 100644 --- a/src/core/user/providers/delegate.ts +++ b/src/core/user/providers/user-delegate.ts @@ -124,7 +124,7 @@ export class CoreUserDelegate extends CoreDelegate { protected featurePrefix = '$mmUserDelegate_'; constructor(protected loggerProvider: CoreLoggerProvider, protected sitesProvider: CoreSitesProvider, - private coursesProvider: CoreCoursesProvider, protected eventsProvider: CoreEventsProvider) { + private coursesProvider: CoreCoursesProvider, protected eventsProvider: CoreEventsProvider) { super('CoreUserDelegate', loggerProvider, sitesProvider, eventsProvider); } diff --git a/src/core/user/providers/user-handler.ts b/src/core/user/providers/user-handler.ts index 3a37255e1..48f439250 100644 --- a/src/core/user/providers/user-handler.ts +++ b/src/core/user/providers/user-handler.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from './delegate'; +import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from './user-delegate'; import { CoreSitesProvider } from '../../../providers/sites'; /** diff --git a/src/core/user/providers/user-profile-field-delegate.ts b/src/core/user/providers/user-profile-field-delegate.ts new file mode 100644 index 000000000..b3b8784dd --- /dev/null +++ b/src/core/user/providers/user-profile-field-delegate.ts @@ -0,0 +1,164 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Injectable } from '@angular/core'; +import { CoreDelegate, CoreDelegateHandler } from '../../../classes/delegate'; +import { CoreLoggerProvider } from '../../../providers/logger'; +import { CoreSitesProvider } from '../../../providers/sites'; +import { CoreEventsProvider } from '../../../providers/events'; + +export interface CoreUserProfileFieldHandler extends CoreDelegateHandler { + + /** + * Return the Component to use to display the user profile field. + * + * @param {any} field User field to get the data for. + * @param {boolean} [signup] True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string): any; + + /** + * Get the data to send for the field based on the input data. + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {Promise|CoreUserProfileFieldHandlerData} Data to send for the field. + */ + getData?(field: any, signup: boolean, registerAuth: string, model: any): + Promise | CoreUserProfileFieldHandlerData; +}; + +export interface CoreUserProfileFieldHandlerData { + /** + * Name to display. + * @type {string} + */ + name: string; + + /** + * Field type. + * @type {string} + */ + type?: string; + + /** + * Value of the field. + * @type {any} + */ + value: any; +}; + +/** + * Service to interact with user profile fields. Provides functions to register a plugin. + */ +@Injectable() +export class CoreUserProfileFieldDelegate extends CoreDelegate { + protected handlers: {[s: string]: CoreUserProfileFieldHandler} = {}; + protected enabledHandlers: {[s: string]: CoreUserProfileFieldHandler} = {}; + + constructor(protected loggerProvider: CoreLoggerProvider, protected sitesProvider: CoreSitesProvider, + protected eventsProvider: CoreEventsProvider) { + super('CoreUserProfileFieldDelegate', loggerProvider, sitesProvider, eventsProvider); + } + + /** + * Get the component to use to display an user field. + * + * @param {any} field User field to get the directive for. + * @param {boolean} signup True if user is in signup page. + * @param {string} registerAuth Register auth method. E.g. 'email' + * @return {any} The component to use, undefined if not found. + */ + getComponent(field: any, signup: boolean, registerAuth: string) : any { + let type = field.type || field.datatype; + return this.executeFunction(type, 'getComponent', [field, signup, registerAuth]); + } + + /** + * Get the data to send for a certain field based on the input data. + * + * @param {any} field User field to get the data for. + * @param {boolean} signup True if user is in signup page. + * @param {string} registerAuth Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {Promise} Data to send for the field. + */ + getDataForField(field: any, signup: boolean, registerAuth: string, model: any): Promise { + let handler = this.getHandler(field, signup); + + if (handler) { + let name = 'profile_field_' + field.shortname; + if (handler.getData) { + return Promise.resolve(handler.getData(field, signup, registerAuth, model)); + } else if (field.shortname && typeof model[name] != 'undefined') { + // Handler doesn't implement the function, but the model has data for the field. + return Promise.resolve({ + type: field.type || field.datatype, + name: name, + value: model[name] + }); + } + } + return Promise.reject(null); + } + + /** + * Get the data to send for a list of fields based on the input data. + * + * @param {any[]} fields User fields to get the data for. + * @param {boolean} [signup] True if user is in signup page. + * @param {string} [registerAuth] Register auth method. E.g. 'email'. + * @param {any} model Model with the input data. + * @return {Promise} Data to send. + */ + getDataForFields(fields: any[], signup = false, registerAuth = "", model: any): Promise { + let result = [], + promises = []; + + fields.forEach((field) => { + this.getDataForField(field, signup, registerAuth, model).then((data) => { + result.push(data); + }).catch(() => { + // Ignore errors. + }); + }); + + return Promise.all(promises).then(() => { + return result; + }); + } + + /** + * Get a handler. + * + * @param {any} field User field to get the directive for. + * @param {boolean} signup True if user is in signup page. + * @return {any} Handler. + */ + protected getHandler(field: any, signup: boolean): any { + let type = field.type || field.datatype; + + if (signup) { + if (this.handlers[type]) { + return this.handlers[type]; + } + return false; + } + + return this.enabledHandlers[type]; + } +} diff --git a/src/core/user/user.module.ts b/src/core/user/user.module.ts index 3f052aa1d..474d9171a 100644 --- a/src/core/user/user.module.ts +++ b/src/core/user/user.module.ts @@ -13,7 +13,8 @@ // limitations under the License. import { NgModule } from '@angular/core'; -import { CoreUserDelegate } from './providers/delegate'; +import { CoreUserDelegate } from './providers/user-delegate'; +import { CoreUserProfileFieldDelegate } from './providers/user-profile-field-delegate'; import { CoreUserProvider } from './providers/user'; import { CoreUserHelperProvider } from './providers/helper'; import { CoreUserProfileMailHandler } from './providers/user-handler'; @@ -25,6 +26,7 @@ import { CoreUserProfileMailHandler } from './providers/user-handler'; ], providers: [ CoreUserDelegate, + CoreUserProfileFieldDelegate, CoreUserProfileMailHandler, CoreUserProvider, CoreUserHelperProvider