Compare View
Commits (43)
-
…T_NAMES to be an array of strings
-
Events hub Added a service called EventsHubService to serve as central point for events propagated through the Noosfero Angular Application. See merge request !53
-
Adjusts the style of the component according with its prototype Translates messages of the signup page. Fixes the post request, using the 2nd parameter as string instead of object. Signed-off-by: DylanGuedes <djmgguedes@gmail.com> Signed-off-by: Omar Junior <omarroinuj@gmail.com> Signed-off-by: Sabryna Sousa <sabryna.sousa1323@gmail.com> Signed-off-by: Victor Arnaud <victorhad@gmail.com>
-
Signed-off-by: DylanGuedes <djmgguedes@gmail.com> Signed-off-by: ArthurJahn <stutrzbecher@gmail.com> Signed-off-by: Fábio Teixeira <fabio1079@gmail.com>
-
Signed-off-by: DylanGuedes <djmgguedes@gmail.com> Signed-off-by: ArthurJahn <stutrzbecher@gmail.com>
-
Also added link to register on login modal
-
See merge request !47
-
Add scrap in profile's timeline  See merge request !56
-
…t' aligned to right of screen
-
Join community Add a button to join/leave communities. See merge request !54
-
Signed-off-by: Tallys Martins <tallysmartins@gmail.com>
-
- Profile activities are now loaded on main block - Adds css style to profile page Signed-off-by: Tallys Martins <tallysmartins@gmail.com> Conflicts: src/app/profile/profile.component.ts
-
Signed-off-by: Tallys Martins <tallysmartins@gmail.com> Signed-off-by: Paulo Tada <paulohtfs@gmail.com>
-
Signed-off-by: Tallys Martins <tallysmartins@gmail.com>
-
Signed-off-by: Tallys Martins <tallysmartins@gmail.com>
-
Signed-off-by: Tallys Martins <tallysmartins@gmail.com>
-
Signed-off-by: Tallys Martins <tallysmartins@gmail.com>
Showing
81 changed files
Show diff stats
bower.json
@@ -38,8 +38,9 @@ | @@ -38,8 +38,9 @@ | ||
38 | "angular-bind-html-compile": "^1.2.1", | 38 | "angular-bind-html-compile": "^1.2.1", |
39 | "angular-click-outside": "^2.7.1", | 39 | "angular-click-outside": "^2.7.1", |
40 | "ng-ckeditor": "^0.2.1", | 40 | "ng-ckeditor": "^0.2.1", |
41 | - "angular-bootstrap-toggle-switch": "^0.5.6", | ||
42 | - "angular-tag-cloud": "^0.3.0" | 41 | + "angular-tag-cloud": "^0.3.0", |
42 | + "angular-ui-switch": "^0.1.1", | ||
43 | + "angular-password": "^1.0.1" | ||
43 | }, | 44 | }, |
44 | "devDependencies": { | 45 | "devDependencies": { |
45 | "angular-mocks": "~1.5.0" | 46 | "angular-mocks": "~1.5.0" |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +export * from "./register.component"; |
@@ -0,0 +1,77 @@ | @@ -0,0 +1,77 @@ | ||
1 | +<div class="register-page"> | ||
2 | + <div class="welcome-message"> | ||
3 | + <h1>{{"account.register.welcomeMessageTitle" | translate }}</h1> | ||
4 | + <div class="environment-signup-intro" ng-bind-html="ctrl.environment.signup_intro"></div> | ||
5 | + </div> | ||
6 | + <form name="signupForm"> | ||
7 | + <div class="row"> | ||
8 | + <div class="col-md-12 register-field"> | ||
9 | + <div class="input-group"> | ||
10 | + <span class="input-group-addon"><i class="fa fa-male"></i><i class="fa fa-female"></i></span> | ||
11 | + <input type="text" class="form-control" id="name" name="fullName" placeholder="{{'account.register.fullNameLabel' | translate }}" ng-model="ctrl.account.name"> | ||
12 | + </div> | ||
13 | + </div> | ||
14 | + | ||
15 | + <div class="form-group col-md-12 register-field" ng-class="ctrl.isInvalid(signupForm.username)"> | ||
16 | + <div class="input-group"> | ||
17 | + <span class="input-group-addon" style="font-weight: bold;"><i class="fa fa-globe"></i> {{ ctrl.environment.host }}</span> | ||
18 | + <input type="text" id="username" name="username" class="form-control" placeholder="{{'account.register.usernameLabel' | translate }}" ng-model="ctrl.account.login" required> | ||
19 | + </div> | ||
20 | + <div class="help-block" ng-show="signupForm.username.$touched" ng-messages="signupForm.username.$error"> | ||
21 | + <ul class="list-unstyled"> | ||
22 | + <li ng-messages-include="languages/messages.html"></li> | ||
23 | + </ul> | ||
24 | + </div> | ||
25 | + </div> | ||
26 | + | ||
27 | + <div class="form-group col-md-12 register-field" ng-class="ctrl.isInvalid(signupForm.email)"> | ||
28 | + <div class="input-group"> | ||
29 | + <span class="input-group-addon"><i class="fa fa-envelope"></i></span> | ||
30 | + <input type="email" class="form-control" id="email" name="email" placeholder="{{'account.register.emailLabel' | translate }}" ng-model="ctrl.account.email" required> | ||
31 | + </div> | ||
32 | + <div class="help-block" ng-show="signupForm.email.$touched" ng-messages="signupForm.email.$error"> | ||
33 | + <ul class="list-unstyled"> | ||
34 | + <li ng-messages-include="languages/messages.html"></li> | ||
35 | + </ul> | ||
36 | + </div> | ||
37 | + </div> | ||
38 | + | ||
39 | + <div class="form-group col-md-6 register-field" ng-class="ctrl.isInvalid(signupForm.password)"> | ||
40 | + <div class="input-group"> | ||
41 | + <span class="input-group-addon"><i class="fa fa-lock"></i></span> | ||
42 | + <input type="password" class="form-control" id="password" name="password" placeholder="{{'account.register.passwordLabel' | translate }}" ng-model="ctrl.account.password" required> | ||
43 | + </div> | ||
44 | + <div class="help-block" ng-show="signupForm.password.$touched" ng-messages="signupForm.password.$error"> | ||
45 | + <ul class="list-unstyled"> | ||
46 | + <li ng-messages-include="languages/messages.html"></li> | ||
47 | + </ul> | ||
48 | + </div> | ||
49 | + </div> | ||
50 | + | ||
51 | + <div class="form-group col-md-6 register-field" ng-class="ctrl.isInvalid(signupForm.passwordConfirm)"> | ||
52 | + <div class="input-group"> | ||
53 | + <span class="input-group-addon"><i class="fa fa-unlock-alt"></i></span> | ||
54 | + <input type="password" class="form-control" id="passwordConfirm" name="passwordConfirm" match-password="password" placeholder="{{'account.register.passwordConfirmationLabel' | translate}}" ng-model="ctrl.account.passwordConfirmation" required> | ||
55 | + </div> | ||
56 | + <div class="help-block" ng-show="signupForm.passwordConfirm.$touched" ng-messages="signupForm.passwordConfirm.$error"> | ||
57 | + <ul class="list-unstyled"> | ||
58 | + <li ng-messages-include="languages/messages.html"></li> | ||
59 | + <li ng-message="passwordMatch" translate="messages.invalid.passwordMatch"></li> | ||
60 | + </ul> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + | ||
64 | + <div class="col-md-12"> | ||
65 | + <p class="terms-info">{{"account.register.accountCreatingMessage" | translate}} <a (click)="ctrl.openTerms()" href="#">{{"account.register.termsOfUseMessage" | translate}}</a>.</p> | ||
66 | + </div> | ||
67 | + | ||
68 | + <div class="col-md-12"> | ||
69 | + <button type="submit" class="btn btn-default" ng-disabled="signupForm.$invalid" ng-click="ctrl.signup()">{{"account.register.signupMessage" | translate}}</button> | ||
70 | + </div> | ||
71 | + | ||
72 | + </div> | ||
73 | + </form> | ||
74 | + | ||
75 | + <p class="already-registered-message">{{"account.register.haveAccountMessage" | translate}}</p> | ||
76 | + | ||
77 | +</div> |
@@ -0,0 +1,7 @@ | @@ -0,0 +1,7 @@ | ||
1 | +<div class="modal-header"> | ||
2 | + <h3 class="modal-title">Register terms</h3> | ||
3 | +</div> | ||
4 | +<div class="modal-body modal-body-overflow" ng-bind-html="ctrl.environment.terms_of_use"></div> | ||
5 | +<div class="modal-footer"> | ||
6 | + <button class="btn btn-primary" type="button" (click)="vm.closeTerms()">OK</button> | ||
7 | +</div> |
@@ -0,0 +1,52 @@ | @@ -0,0 +1,52 @@ | ||
1 | +import { ComponentTestHelper, createClass } from "../../spec/component-test-helper"; | ||
2 | +import * as helpers from "../../spec/helpers"; | ||
3 | +import { RegisterComponent } from "./register.component"; | ||
4 | +// import {RegisterService} from "../../lib/ng-noosfero-api/http/register.service" | ||
5 | + | ||
6 | + | ||
7 | +describe("Register Component", () => { | ||
8 | + const htmlTemplate: string = '<noosfero-register></noosfero-register>'; | ||
9 | + | ||
10 | + let helper: ComponentTestHelper<RegisterComponent>; | ||
11 | + let registerService = helpers.mocks.registerService; | ||
12 | + let stateService = jasmine.createSpyObj("$state", ["transitionTo"]); | ||
13 | + let notificationService = helpers.mocks.notificationService; | ||
14 | + notificationService.success = jasmine.createSpy('success'); | ||
15 | + notificationService.error = jasmine.createSpy('error'); | ||
16 | + | ||
17 | + | ||
18 | + let account: any = { | ||
19 | + id: 1, | ||
20 | + login: 'test', | ||
21 | + email: 'test@email.com', | ||
22 | + password: 'xxx', | ||
23 | + passwordConfirmation: 'xxx' | ||
24 | + }; | ||
25 | + | ||
26 | + beforeEach(() => { | ||
27 | + angular.mock.module('templates'); | ||
28 | + angular.mock.module('ngSanitize'); | ||
29 | + angular.mock.module('ngMessages'); | ||
30 | + angular.mock.module('ngPassword'); | ||
31 | + }); | ||
32 | + | ||
33 | + beforeEach((done) => { | ||
34 | + let cls = createClass({ | ||
35 | + template: htmlTemplate, | ||
36 | + directives: [RegisterComponent], | ||
37 | + providers: [ | ||
38 | + helpers.createProviderToValue('$state', stateService), | ||
39 | + helpers.createProviderToValue('$uibModal', helpers.mocks.$modal), | ||
40 | + helpers.createProviderToValue('RegisterService', registerService), | ||
41 | + helpers.createProviderToValue('NotificationService', notificationService), | ||
42 | + helpers.createProviderToValue('EnvironmentService', helpers.mocks.environmentService) | ||
43 | + ] | ||
44 | + }); | ||
45 | + helper = new ComponentTestHelper<RegisterComponent>(cls, done); | ||
46 | + }); | ||
47 | + | ||
48 | + it('register page was rendered', () => { | ||
49 | + expect(helper.debugElement.query('div.register-page').length).toEqual(1); | ||
50 | + }); | ||
51 | + | ||
52 | +}); |
@@ -0,0 +1,66 @@ | @@ -0,0 +1,66 @@ | ||
1 | +import { Inject, Input, Component, Output, EventEmitter, provide } from 'ng-forward'; | ||
2 | +import { RegisterService } from "./../../lib/ng-noosfero-api/http/register.service"; | ||
3 | +import { NotificationService } from "./../shared/services/notification.service"; | ||
4 | +import { EnvironmentService } from "../../lib/ng-noosfero-api/http/environment.service"; | ||
5 | +import { RegisterController } from "./register.controller"; | ||
6 | +import { IModalComponent } from "../shared/components/interfaces"; | ||
7 | + | ||
8 | +@Component({ | ||
9 | + selector: 'noosfero-register', | ||
10 | + templateUrl: 'app/account/register-component.html', | ||
11 | + providers: [ | ||
12 | + provide('registerService', { useClass: RegisterService }) | ||
13 | + ] | ||
14 | +}) | ||
15 | + | ||
16 | +@Inject('$state', '$uibModal', '$scope', RegisterService, NotificationService, EnvironmentService) | ||
17 | +export class RegisterComponent { | ||
18 | + @Input() account: any; | ||
19 | + environment: noosfero.Environment; | ||
20 | + | ||
21 | + modalInstance: ng.ui.bootstrap.IModalServiceInstance; | ||
22 | + | ||
23 | + constructor( | ||
24 | + private $state: ng.ui.IStateService, | ||
25 | + private $uibModal: ng.ui.bootstrap.IModalService, | ||
26 | + private $scope: ng.IScope, | ||
27 | + public registerService: RegisterService, | ||
28 | + private notificationService: NotificationService, | ||
29 | + private environmentService: EnvironmentService | ||
30 | + ) { | ||
31 | + this.account = {}; | ||
32 | + this.environment = environmentService.getCurrentEnvironment(); | ||
33 | + } | ||
34 | + | ||
35 | + signup() { | ||
36 | + if (this.account.password === this.account.passwordConfirmation) { | ||
37 | + this.registerService.createAccount(this.account).then((response) => { | ||
38 | + | ||
39 | + if (response.status === 201) { | ||
40 | + this.$state.transitionTo('main.environment'); | ||
41 | + this.notificationService.success({ title: "account.register.success.title", message: "account.register.success.message" }); | ||
42 | + } else { | ||
43 | + throw new Error('Invalid attributes'); | ||
44 | + } | ||
45 | + }); | ||
46 | + } else { | ||
47 | + this.notificationService.error({ message: "account.register.passwordConfirmation.failed" }); | ||
48 | + } | ||
49 | + } | ||
50 | + | ||
51 | + isInvalid(field: any): any { | ||
52 | + return { 'has-error': field['$touched'] && field['$invalid'] }; | ||
53 | + } | ||
54 | + | ||
55 | + openTerms() { | ||
56 | + | ||
57 | + this.modalInstance = this.$uibModal.open({ | ||
58 | + templateUrl: 'app/account/register-terms.html', | ||
59 | + size: 'lg', | ||
60 | + controller: RegisterController, | ||
61 | + controllerAs: 'vm', | ||
62 | + bindToController: true, | ||
63 | + scope: this.$scope | ||
64 | + }); | ||
65 | + } | ||
66 | +} |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +import { Input } from "ng-forward"; | ||
2 | +import { IModalComponent } from "../shared/components/interfaces"; | ||
3 | + | ||
4 | +export class RegisterController { | ||
5 | + | ||
6 | + static $inject = ["$log", "$stateParams", "$scope"]; | ||
7 | + ctrl: IModalComponent; | ||
8 | + | ||
9 | + constructor( | ||
10 | + private $log: ng.ILogService, | ||
11 | + private $stateParams: any | ||
12 | + ) { } | ||
13 | + | ||
14 | + closeTerms() { | ||
15 | + this.ctrl.modalInstance.dismiss('ok'); | ||
16 | + } | ||
17 | +} |
@@ -0,0 +1,44 @@ | @@ -0,0 +1,44 @@ | ||
1 | +.modal .modal-body-overflow { | ||
2 | + max-height: 420px; | ||
3 | + overflow-y: auto; | ||
4 | +} | ||
5 | + | ||
6 | +.register-page button { | ||
7 | + width: 100%; | ||
8 | + text-transform: uppercase; | ||
9 | + font-weight: 600; | ||
10 | +} | ||
11 | + | ||
12 | +.register-page .light-text { | ||
13 | + color: #BBB; | ||
14 | + margin-top: 0px; | ||
15 | + margin-bottom: 0px; | ||
16 | + font-weight: 600; | ||
17 | +} | ||
18 | + | ||
19 | +.register-page .terms-info { | ||
20 | + margin-top: 30px; | ||
21 | + margin-bottom: 30px; | ||
22 | + font-weight: bold; | ||
23 | +} | ||
24 | + | ||
25 | +.register-page .welcome-message { | ||
26 | + text-align: center; | ||
27 | +} | ||
28 | + | ||
29 | +.register-page .already-registered-message { | ||
30 | + margin-top: 60px; | ||
31 | + text-align: center; | ||
32 | +} | ||
33 | + | ||
34 | +.register-page input { | ||
35 | + height: 40px; | ||
36 | +} | ||
37 | + | ||
38 | +.register-page .register-field { | ||
39 | + margin-bottom: 25px; | ||
40 | +} | ||
41 | + | ||
42 | +.register-page input:focus { | ||
43 | + border: 2px solid #bbb; | ||
44 | +} |
src/app/admin/layout-edit/designModeToggler.component.spec.ts
1 | import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; | 1 | import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; |
2 | +import {INgForwardJQuery} from 'ng-forward/cjs/util/jqlite-extensions'; | ||
2 | import * as helpers from '../../../spec/helpers'; | 3 | import * as helpers from '../../../spec/helpers'; |
3 | import {DesignModeTogglerComponent} from './designModeToggler.component'; | 4 | import {DesignModeTogglerComponent} from './designModeToggler.component'; |
4 | import {DesignModeService} from './designMode.service'; | 5 | import {DesignModeService} from './designMode.service'; |
5 | import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; | 6 | import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; |
6 | 7 | ||
7 | describe('DesignModeToggler Component', () => { | 8 | describe('DesignModeToggler Component', () => { |
8 | - const htmlTemplate: string = '<noosfero-design-toggler></noosfero-design-toggler>'; | 9 | + const htmlTemplate: string = '<design-toggler></design-toggler>'; |
9 | 10 | ||
10 | let helper: ComponentTestHelper<DesignModeTogglerComponent>; | 11 | let helper: ComponentTestHelper<DesignModeTogglerComponent>; |
11 | beforeEach(() => { | 12 | beforeEach(() => { |
12 | angular.mock.module('templates'); | 13 | angular.mock.module('templates'); |
13 | angular.mock.module('ngSanitize'); | 14 | angular.mock.module('ngSanitize'); |
14 | - angular.mock.module('toggle-switch'); | 15 | + angular.mock.module('uiSwitch'); |
15 | }); | 16 | }); |
16 | 17 | ||
17 | let designModeService: DesignModeService; | 18 | let designModeService: DesignModeService; |
@@ -30,12 +31,12 @@ describe('DesignModeToggler Component', () => { | @@ -30,12 +31,12 @@ describe('DesignModeToggler Component', () => { | ||
30 | }); | 31 | }); |
31 | 32 | ||
32 | it('changes css classes representing the switch is on or off', () => { | 33 | it('changes css classes representing the switch is on or off', () => { |
33 | - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeTruthy(); | ||
34 | - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeFalsy(); | 34 | + let switchEl: INgForwardJQuery = helper.debugElement.query('span.switch'); |
35 | + | ||
36 | + expect(switchEl.hasClass('checked')).toBeFalsy(); | ||
35 | helper.component.inDesignMode = true; | 37 | helper.component.inDesignMode = true; |
36 | helper.detectChanges(); | 38 | helper.detectChanges(); |
37 | - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeTruthy(); | ||
38 | - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeFalsy(); | 39 | + expect(switchEl.hasClass('checked')).toBeTruthy(); |
39 | }); | 40 | }); |
40 | 41 | ||
41 | it('emits event with value "true" when changing inDesignMode to On', (done) => { | 42 | it('emits event with value "true" when changing inDesignMode to On', (done) => { |
@@ -60,4 +61,4 @@ describe('DesignModeToggler Component', () => { | @@ -60,4 +61,4 @@ describe('DesignModeToggler Component', () => { | ||
60 | helper.component.inDesignMode = false; | 61 | helper.component.inDesignMode = false; |
61 | helper.detectChanges(); | 62 | helper.detectChanges(); |
62 | }); | 63 | }); |
63 | -}); | ||
64 | \ No newline at end of file | 64 | \ No newline at end of file |
65 | +}); |
src/app/admin/layout-edit/designModeToggler.component.ts
1 | -import {Component, Inject} from 'ng-forward'; | 1 | +import {Component, Inject, Input} from 'ng-forward'; |
2 | import {DesignModeService} from './designMode.service'; | 2 | import {DesignModeService} from './designMode.service'; |
3 | import {AuthService, AuthEvents} from '../../login'; | 3 | import {AuthService, AuthEvents} from '../../login'; |
4 | 4 | ||
5 | @Component({ | 5 | @Component({ |
6 | - selector: 'noosfero-design-toggler', | 6 | + selector: 'design-toggler', |
7 | templateUrl: 'app/admin/layout-edit/designModeToggler.html' | 7 | templateUrl: 'app/admin/layout-edit/designModeToggler.html' |
8 | }) | 8 | }) |
9 | -@Inject(DesignModeService, AuthService) | 9 | +@Inject(DesignModeService, AuthService, '$sce') |
10 | export class DesignModeTogglerComponent { | 10 | export class DesignModeTogglerComponent { |
11 | 11 | ||
12 | - icon: string = " <i class='glyphicon glyphicon-wrench'></i> "; | 12 | + private _inDesignMode: boolean = false; |
13 | 13 | ||
14 | - constructor(private designModeService: DesignModeService, private authService: AuthService) { | 14 | + constructor(private designModeService: DesignModeService, private authService: AuthService, private $sce: ng.ISCEService) { |
15 | this.authService.subscribe(AuthEvents[AuthEvents.logoutSuccess], () => { | 15 | this.authService.subscribe(AuthEvents[AuthEvents.logoutSuccess], () => { |
16 | this.designModeService.destroy(); | 16 | this.designModeService.destroy(); |
17 | }); | 17 | }); |
18 | } | 18 | } |
19 | 19 | ||
20 | - private _inDesignMode: boolean = false; | ||
21 | - | ||
22 | get inDesignMode(): boolean { | 20 | get inDesignMode(): boolean { |
23 | return this.designModeService.isInDesignMode(); | 21 | return this.designModeService.isInDesignMode(); |
24 | }; | 22 | }; |
src/app/admin/layout-edit/designModeToggler.html
1 | -<toggle-switch | ||
2 | - html="true" | ||
3 | - ng-model="ctrl.inDesignMode" | ||
4 | - on-label="{{'designMode.toggle.ON' | translate}}" | ||
5 | - off-label="{{'designMode.toggle.OFF' | translate}}" | ||
6 | - class="switch-small" | ||
7 | - knob-label="{{ ctrl.icon + ('designMode.label' | translate) }}"> | ||
8 | -</toggle-switch> | ||
9 | \ No newline at end of file | 1 | \ No newline at end of file |
2 | +<switch id="enabled" name="enabled" ng-model="ctrl.inDesignMode" on="ON" off="OFF" class="green"></switch> |
@@ -0,0 +1,55 @@ | @@ -0,0 +1,55 @@ | ||
1 | +$off-text: #949494; | ||
2 | +$off-color: #EFEFEF; | ||
3 | +$blue-color: #36B4F6; | ||
4 | +$red-color: #DF3B3A; | ||
5 | + | ||
6 | +body.noosfero-design-on { | ||
7 | + | ||
8 | + div.content-wrapper { | ||
9 | + opacity: 0.5; | ||
10 | + } | ||
11 | +} | ||
12 | + | ||
13 | +.switch { | ||
14 | + @include not-select(); | ||
15 | + background-color: $off-color; | ||
16 | + | ||
17 | + &[on][off] { | ||
18 | + width: 60px; | ||
19 | + } | ||
20 | + | ||
21 | + &:focus { | ||
22 | + outline: none; | ||
23 | + } | ||
24 | + | ||
25 | + &.checked small { | ||
26 | + left: initial; | ||
27 | + right: 0px; | ||
28 | + } | ||
29 | + | ||
30 | + &.blue.checked { | ||
31 | + background: $blue-color; | ||
32 | + border-color: $blue-color; | ||
33 | + } | ||
34 | + | ||
35 | + &.red.checked { | ||
36 | + background: $red-color; | ||
37 | + border-color: $red-color; | ||
38 | + } | ||
39 | + | ||
40 | + %switch-label { | ||
41 | + font-weight: bold; | ||
42 | + } | ||
43 | + | ||
44 | + .on { | ||
45 | + @extend %switch-label; | ||
46 | + } | ||
47 | + | ||
48 | + .off { | ||
49 | + @extend %switch-label; | ||
50 | + right: 2px; | ||
51 | + top: 25%; | ||
52 | + color: $off-text; | ||
53 | + text-align: center; | ||
54 | + } | ||
55 | +} |
src/app/index.scss
@@ -39,6 +39,12 @@ $break-sm-min: 992px; | @@ -39,6 +39,12 @@ $break-sm-min: 992px; | ||
39 | $break-xxs-max: ($break-xxs-min - 1); | 39 | $break-xxs-max: ($break-xxs-min - 1); |
40 | $break-sm-max: ($break-sm-min - 1); | 40 | $break-sm-max: ($break-sm-min - 1); |
41 | $break-xs-max: ($break-xs-min - 1); | 41 | $break-xs-max: ($break-xs-min - 1); |
42 | +// TODO: improve this method to collect all the paddings with a single var | ||
43 | +$wrapper-padding: 15px 15px 35px 15px; | ||
44 | +$wrapper-padding-top: 15px; | ||
45 | +$wrapper-padding-right: 15px; | ||
46 | +$wrapper-padding-bottom: 35px; | ||
47 | +$wrapper-padding-left: 15px; | ||
42 | 48 | ||
43 | 49 | ||
44 | @import "../../bower_components/bootswatch/flatly/_variables.scss"; | 50 | @import "../../bower_components/bootswatch/flatly/_variables.scss"; |
src/app/index.ts
1 | -import {bootstrap} from "ng-forward"; | 1 | +import {bootstrap, provide} from "ng-forward"; |
2 | import {noosferoModuleConfig} from "./index.config"; | 2 | import {noosferoModuleConfig} from "./index.config"; |
3 | import {noosferoAngularRunBlock} from "./index.run"; | 3 | import {noosferoAngularRunBlock} from "./index.run"; |
4 | import {MainComponent} from "./main/main.component"; | 4 | import {MainComponent} from "./main/main.component"; |
@@ -22,4 +22,13 @@ angular.module('noosfero.init', ['noosfero.templates.app', 'noosfero.templates.p | @@ -22,4 +22,13 @@ angular.module('noosfero.init', ['noosfero.templates.app', 'noosfero.templates.p | ||
22 | run(noosferoAngularRunBlock). | 22 | run(noosferoAngularRunBlock). |
23 | constant("moment", moment). | 23 | constant("moment", moment). |
24 | constant("AuthEvents", AuthEvents); | 24 | constant("AuthEvents", AuthEvents); |
25 | -bootstrap(MainComponent); | 25 | + |
26 | + | ||
27 | +import { EVENTS_HUB_KNOW_EVENT_NAMES } from './shared/services/events-hub.service'; | ||
28 | +import { NoosferoKnownEvents } from './known-events'; | ||
29 | + | ||
30 | +bootstrap(MainComponent, | ||
31 | + [ | ||
32 | + provide(EVENTS_HUB_KNOW_EVENT_NAMES, { useClass: NoosferoKnownEvents }) | ||
33 | + ] | ||
34 | +); |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +import { EventsHubKnownEventNames } from './shared/services/events-hub.service'; | ||
2 | + | ||
3 | +export class NoosferoKnownEvents implements EventsHubKnownEventNames { | ||
4 | + IMAGE_PROFILE_UPDATED: string = 'IMAGE_PROFILE_UPDATED'; | ||
5 | + PROFILE_INFO_UPDATED: string = 'PROFILE_INFO_UPDATED'; | ||
6 | + ARTICLE_UPDATED: string = 'ARTICLE_UPDATED'; | ||
7 | + | ||
8 | + constructor() { | ||
9 | + } | ||
10 | + | ||
11 | + getNames() { | ||
12 | + return Object.getOwnPropertyNames(this); | ||
13 | + } | ||
14 | +} | ||
0 | \ No newline at end of file | 15 | \ No newline at end of file |
src/app/layout/blocks/block.component.ts
@@ -18,7 +18,7 @@ export class BlockComponent { | @@ -18,7 +18,7 @@ export class BlockComponent { | ||
18 | @Input() block: noosfero.Block; | 18 | @Input() block: noosfero.Block; |
19 | @Input() owner: noosfero.Profile | noosfero.Environment; | 19 | @Input() owner: noosfero.Profile | noosfero.Environment; |
20 | 20 | ||
21 | - private modalInstance: any = null; | 21 | + private modalInstance: ng.ui.bootstrap.IModalServiceInstance; |
22 | originalBlock: noosfero.Block; | 22 | originalBlock: noosfero.Block; |
23 | 23 | ||
24 | currentUser: noosfero.User; | 24 | currentUser: noosfero.User; |
@@ -26,7 +26,8 @@ export class BlockComponent { | @@ -26,7 +26,8 @@ export class BlockComponent { | ||
26 | editionMode = false; | 26 | editionMode = false; |
27 | designMode = false; | 27 | designMode = false; |
28 | 28 | ||
29 | - constructor(private $uibModal: any, | 29 | + constructor( |
30 | + private $uibModal: ng.ui.bootstrap.IModalService, | ||
30 | private $scope: ng.IScope, | 31 | private $scope: ng.IScope, |
31 | private $state: ng.ui.IStateService, | 32 | private $state: ng.ui.IStateService, |
32 | private $rootScope: ng.IRootScopeService, | 33 | private $rootScope: ng.IRootScopeService, |
src/app/layout/blocks/communities/communities-block.html
1 | -<div class="communities-block"> | ||
2 | - <a ng-repeat="profile in ctrl.profiles" ui-sref="main.profile.home({profile: profile.identifier})" class="profile"> | 1 | +<div ng-repeat="profile in ctrl.profiles" class="col-xs-2 col-md-4 block-item"> |
2 | + <a ui-sref="main.profile.home({profile: profile.identifier})"> | ||
3 | <noosfero-profile-image [profile]="profile"></noosfero-profile-image> | 3 | <noosfero-profile-image [profile]="profile"></noosfero-profile-image> |
4 | </a> | 4 | </a> |
5 | + <p>{{profile.name}}</p> | ||
5 | </div> | 6 | </div> |
src/app/layout/blocks/communities/communities-block.scss
1 | -.communities-block { | ||
2 | - .profile { | 1 | +.communitiesblock { |
2 | + .panel-body { | ||
3 | + text-align: center; | ||
3 | margin: 10px; | 4 | margin: 10px; |
4 | - img, i.profile-image { | ||
5 | - width: 60px; | ||
6 | - } | ||
7 | img { | 5 | img { |
8 | display: inline-block; | 6 | display: inline-block; |
9 | vertical-align: top; | 7 | vertical-align: top; |
10 | } | 8 | } |
11 | i.profile-image { | 9 | i.profile-image { |
12 | text-align: center; | 10 | text-align: center; |
13 | - font-size: 4.5em; | 11 | + font-size: 7rem; |
12 | + } | ||
13 | + p { | ||
14 | + overflow: hidden; | ||
15 | + font-size: 1rem; | ||
16 | + } | ||
17 | + .block-item { | ||
18 | + padding: 0px; | ||
14 | } | 19 | } |
15 | } | 20 | } |
16 | } | 21 | } |
src/app/layout/blocks/container-block-plugin-container-block/container-block-plugin-container-block.component.ts
0 → 100644
@@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
1 | +import { Input, Inject, Component } from 'ng-forward'; | ||
2 | +import {BlockService} from "../../../../lib/ng-noosfero-api/http/block.service"; | ||
3 | +import {Arrays} from "./../../../../lib/util/arrays"; | ||
4 | + | ||
5 | +@Component({ | ||
6 | + selector: 'noosfero-container-block-plugin-container-block', | ||
7 | + templateUrl: 'app/layout/blocks/container-block-plugin-container-block/container-block-plugin-container-block.html' | ||
8 | +}) | ||
9 | +@Inject(BlockService, "$state") | ||
10 | +export class ContainerBlockPluginContainerBlockComponent { | ||
11 | + | ||
12 | + @Input() block: any; | ||
13 | + @Input() owner: any; | ||
14 | + | ||
15 | + profile: any; | ||
16 | + blocks: any; | ||
17 | + | ||
18 | + constructor(private blockService: BlockService, private $state: any) { } | ||
19 | + | ||
20 | + ngOnInit() { | ||
21 | + this.profile = this.owner; | ||
22 | + this.blocks = []; | ||
23 | + this.blockService.getApiContent(this.block).then((content: any) => { | ||
24 | + this.blocks = content.blocks; | ||
25 | + }); | ||
26 | + } | ||
27 | +} |
src/app/layout/blocks/container-block-plugin-container-block/container-block-plugin-container-block.html
0 → 100644
src/app/layout/blocks/container-block-plugin-container-block/container-block-plugin-container-block.scss
0 → 100644
src/app/layout/blocks/container-block-plugin-container-block/index.ts
0 → 100644
src/app/layout/blocks/profile-image/profile-image-block.component.spec.ts
@@ -15,11 +15,18 @@ describe("Components", () => { | @@ -15,11 +15,18 @@ describe("Components", () => { | ||
15 | 15 | ||
16 | beforeEach(angular.mock.module("templates")); | 16 | beforeEach(angular.mock.module("templates")); |
17 | 17 | ||
18 | + let profileService = jasmine.createSpyObj("ProfileService", ["isMember", "addMember", "removeMember"]); | ||
19 | + profileService.isMember = jasmine.createSpy("isMember").and.returnValue(Promise.resolve(false)); | ||
20 | + | ||
18 | @Component({ | 21 | @Component({ |
19 | selector: 'test-container-component', | 22 | selector: 'test-container-component', |
20 | template: htmlTemplate, | 23 | template: htmlTemplate, |
21 | directives: [ProfileImageBlockComponent], | 24 | directives: [ProfileImageBlockComponent], |
22 | - providers: helpers.provideFilters("translateFilter") | 25 | + providers: [ |
26 | + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})), | ||
27 | + helpers.createProviderToValue('ProfileService', profileService), | ||
28 | + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService) | ||
29 | + ].concat(helpers.provideFilters("translateFilter")) | ||
23 | }) | 30 | }) |
24 | class BlockContainerComponent { | 31 | class BlockContainerComponent { |
25 | block = { type: 'Block' }; | 32 | block = { type: 'Block' }; |
@@ -42,5 +49,42 @@ describe("Components", () => { | @@ -42,5 +49,42 @@ describe("Components", () => { | ||
42 | }); | 49 | }); |
43 | }); | 50 | }); |
44 | 51 | ||
52 | + it("display button to join community", (done: Function) => { | ||
53 | + helpers.tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
54 | + let elProfile = fixture.debugElement.componentViewChildren[0]; | ||
55 | + expect(elProfile.query('.actions .join').length).toEqual(1); | ||
56 | + done(); | ||
57 | + }); | ||
58 | + }); | ||
59 | + | ||
60 | + it("display button to leave community", (done: Function) => { | ||
61 | + helpers.tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
62 | + let elProfile = fixture.debugElement.componentViewChildren[0]; | ||
63 | + elProfile.componentInstance['isMember'] = true; | ||
64 | + fixture.detectChanges(); | ||
65 | + expect(elProfile.query('.actions .leave').length).toEqual(1); | ||
66 | + done(); | ||
67 | + }); | ||
68 | + }); | ||
69 | + | ||
70 | + it("join community", (done: Function) => { | ||
71 | + helpers.tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
72 | + let elProfile = fixture.debugElement.componentViewChildren[0]; | ||
73 | + profileService.addMember = jasmine.createSpy("addMember").and.returnValue(Promise.resolve({ data: {} })); | ||
74 | + elProfile.componentInstance.join(); | ||
75 | + expect(profileService.addMember).toHaveBeenCalled(); | ||
76 | + done(); | ||
77 | + }); | ||
78 | + }); | ||
79 | + | ||
80 | + it("leave community", (done: Function) => { | ||
81 | + helpers.tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
82 | + let elProfile = fixture.debugElement.componentViewChildren[0]; | ||
83 | + profileService.removeMember = jasmine.createSpy("removeMember").and.returnValue(Promise.resolve({ data: {} })); | ||
84 | + elProfile.componentInstance.leave(); | ||
85 | + expect(profileService.removeMember).toHaveBeenCalled(); | ||
86 | + done(); | ||
87 | + }); | ||
88 | + }); | ||
45 | }); | 89 | }); |
46 | }); | 90 | }); |
src/app/layout/blocks/profile-image/profile-image-block.component.ts
1 | import {Inject, Input, Component} from "ng-forward"; | 1 | import {Inject, Input, Component} from "ng-forward"; |
2 | import {ProfileImageComponent} from "./../../../profile/image/image.component"; | 2 | import {ProfileImageComponent} from "./../../../profile/image/image.component"; |
3 | +import {ProfileService} from "../../../../lib/ng-noosfero-api/http/profile.service"; | ||
4 | +import {SessionService} from "./../../../login"; | ||
5 | +import {NotificationService} from "../../../shared/services/notification.service"; | ||
3 | 6 | ||
4 | @Component({ | 7 | @Component({ |
5 | selector: "noosfero-profile-image-block", | 8 | selector: "noosfero-profile-image-block", |
6 | templateUrl: 'app/layout/blocks/profile-image/profile-image-block.html', | 9 | templateUrl: 'app/layout/blocks/profile-image/profile-image-block.html', |
7 | directives: [ProfileImageComponent] | 10 | directives: [ProfileImageComponent] |
8 | }) | 11 | }) |
12 | +@Inject(ProfileService, SessionService, NotificationService) | ||
9 | export class ProfileImageBlockComponent { | 13 | export class ProfileImageBlockComponent { |
10 | 14 | ||
11 | @Input() block: noosfero.Block; | 15 | @Input() block: noosfero.Block; |
12 | @Input() owner: noosfero.Profile; | 16 | @Input() owner: noosfero.Profile; |
13 | 17 | ||
18 | + private isMember: boolean; | ||
19 | + | ||
20 | + constructor(private profileService: ProfileService, private session: SessionService, private notificationService: NotificationService) { | ||
21 | + } | ||
22 | + | ||
23 | + ngOnInit() { | ||
24 | + this.loadMembership(); | ||
25 | + } | ||
26 | + | ||
27 | + loadMembership() { | ||
28 | + let person = this.session.currentUser() ? this.session.currentUser().person : null; | ||
29 | + this.profileService.isMember(person, this.owner).then((val: boolean) => { | ||
30 | + this.isMember = val; | ||
31 | + }); | ||
32 | + } | ||
33 | + | ||
34 | + join() { | ||
35 | + let person = this.session.currentUser() ? this.session.currentUser().person : null; | ||
36 | + this.profileService.addMember(person, this.owner).then((result: any) => { | ||
37 | + if (result.data.pending) { | ||
38 | + this.notificationService.success({ title: "blocks.profile_image.join.moderation.title", message: "blocks.profile_image.join.moderation.message" }); | ||
39 | + } else { | ||
40 | + this.loadMembership(); | ||
41 | + } | ||
42 | + }); | ||
43 | + } | ||
44 | + | ||
45 | + leave() { | ||
46 | + let person = this.session.currentUser() ? this.session.currentUser().person : null; | ||
47 | + this.profileService.removeMember(person, this.owner).then(() => { | ||
48 | + this.loadMembership(); | ||
49 | + }); | ||
50 | + } | ||
14 | } | 51 | } |
src/app/layout/blocks/profile-image/profile-image-block.html
@@ -3,4 +3,8 @@ | @@ -3,4 +3,8 @@ | ||
3 | <noosfero-profile-image [profile]="ctrl.owner"></noosfero-profile-image> | 3 | <noosfero-profile-image [profile]="ctrl.owner"></noosfero-profile-image> |
4 | </a> | 4 | </a> |
5 | <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: ctrl.owner.identifier})">{{"blocks.profile_image.control_panel" | translate}}</a> | 5 | <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: ctrl.owner.identifier})">{{"blocks.profile_image.control_panel" | translate}}</a> |
6 | + <div class="actions" ng-show="ctrl.isMember!=null"> | ||
7 | + <a ng-if="!ctrl.isMember" ng-click="ctrl.join()" class="btn btn-primary btn-sm join" href="#">{{"blocks.profile_image.join" | translate}}</a> | ||
8 | + <a ng-if="ctrl.isMember" ng-click="ctrl.leave()" class="btn btn-warning btn-sm leave" href="#">{{"blocks.profile_image.leave" | translate}}</a> | ||
9 | + </div> | ||
6 | </div> | 10 | </div> |
src/app/layout/blocks/profile-images-plugin-profile-images/index.ts
0 → 100644
src/app/layout/blocks/profile-images-plugin-profile-images/profile-images-plugin-profile-images-block.component.spec.ts
0 → 100644
@@ -0,0 +1,65 @@ | @@ -0,0 +1,65 @@ | ||
1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | ||
2 | +import {Provider, Input, provide, Component} from 'ng-forward'; | ||
3 | +import {provideFilters} from '../../../../spec/helpers'; | ||
4 | +import {ProfileImagesPluginProfileImagesBlockComponent} from './profile-images-plugin-profile-images-block.component'; | ||
5 | +import * as helpers from "./../../../../spec/helpers"; | ||
6 | + | ||
7 | +const htmlTemplate: string = '<noosfero-profile-images-plugin-profile-images-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-profile-images-plugin-profile-images-block>'; | ||
8 | + | ||
9 | +const tcb = new TestComponentBuilder(); | ||
10 | + | ||
11 | +const images = [ | ||
12 | + { | ||
13 | + title: 'Test', | ||
14 | + id: 1, | ||
15 | + view_url: { host: 'localhost', page: ['image'] }, | ||
16 | + path: '/articles/0000/0001/test.png' | ||
17 | + } | ||
18 | +]; | ||
19 | + | ||
20 | +describe("Components", () => { | ||
21 | + describe("Profile Images Block Component", () => { | ||
22 | + | ||
23 | + let settingsObj = {}; | ||
24 | + let person = <noosfero.Person>{ name: "Person" }; | ||
25 | + let mockedService = { | ||
26 | + getApiContent: (block: noosfero.Block): any => { | ||
27 | + return Promise.resolve({ images: images, headers: (name: string) => { return name; } }); | ||
28 | + } | ||
29 | + }; | ||
30 | + beforeEach(angular.mock.module("templates")); | ||
31 | + | ||
32 | + let state = jasmine.createSpyObj("state", ["go"]); | ||
33 | + | ||
34 | + | ||
35 | + function getProviders() { | ||
36 | + return [ | ||
37 | + new Provider('$state', { useValue: state }), | ||
38 | + new Provider('BlockService', { | ||
39 | + useValue: mockedService | ||
40 | + }) | ||
41 | + ].concat(provideFilters("truncateFilter", "stripTagsFilter")); | ||
42 | + } | ||
43 | + let componentClass: any = null; | ||
44 | + | ||
45 | + function getComponent() { | ||
46 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ProfileImagesPluginProfileImagesBlockComponent], providers: getProviders() }) | ||
47 | + class BlockContainerComponent { | ||
48 | + block = { type: 'Block', settings: settingsObj }; | ||
49 | + owner = person; | ||
50 | + constructor() { | ||
51 | + } | ||
52 | + } | ||
53 | + return BlockContainerComponent; | ||
54 | + } | ||
55 | + | ||
56 | + it("get images from the block service", done => { | ||
57 | + tcb.createAsync(getComponent()).then(fixture => { | ||
58 | + let ProfileImagesPluginProfileImagesBlock: ProfileImagesPluginProfileImagesBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
59 | + expect(ProfileImagesPluginProfileImagesBlock.images).toEqual(images); | ||
60 | + done(); | ||
61 | + }); | ||
62 | + }); | ||
63 | + | ||
64 | + }); | ||
65 | +}); |
src/app/layout/blocks/profile-images-plugin-profile-images/profile-images-plugin-profile-images-block.component.ts
0 → 100644
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +import {Component, Inject, Input} from "ng-forward"; | ||
2 | +import {BlockService} from "./../../../../lib/ng-noosfero-api/http/block.service"; | ||
3 | +import {Arrays} from "./../../../../lib/util/arrays"; | ||
4 | + | ||
5 | +@Component({ | ||
6 | + selector: "noosfero-profile-images-plugin-profile-images-block", | ||
7 | + templateUrl: 'app/layout/blocks/profile-images-plugin-profile-images/profile-images-plugin-profile-images-block.html' | ||
8 | +}) | ||
9 | +@Inject(BlockService, "$state") | ||
10 | +export class ProfileImagesPluginProfileImagesBlockComponent { | ||
11 | + | ||
12 | + @Input() block: any; | ||
13 | + @Input() owner: any; | ||
14 | + | ||
15 | + profile: any; | ||
16 | + images: any; | ||
17 | + | ||
18 | + constructor(private blockService: BlockService, private $state: any) { } | ||
19 | + | ||
20 | + urlFor(params: any) { | ||
21 | + let url = '//' + params.host; | ||
22 | + if (params.port) { | ||
23 | + url += ':' + params.port; | ||
24 | + } | ||
25 | + url += '/' + params.profile + '/'; | ||
26 | + if (params.page) { | ||
27 | + url += params.page.join('/'); | ||
28 | + } | ||
29 | + return url; | ||
30 | + } | ||
31 | + | ||
32 | + ngOnInit() { | ||
33 | + this.profile = this.owner; | ||
34 | + this.images = []; | ||
35 | + this.blockService.getApiContent(this.block).then((content: any) => { | ||
36 | + this.images = content.images; | ||
37 | + }); | ||
38 | + } | ||
39 | +} |
src/app/layout/blocks/profile-images-plugin-profile-images/profile-images-plugin-profile-images-block.html
0 → 100644
@@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
1 | +<ul class="profile-images-plugin-profile-images"> | ||
2 | + <li ng-repeat="image in ctrl.images"> | ||
3 | + <a ng-href="{{ctrl.urlFor(image.view_url)}}" ng-style="{'background-image': 'url(' + image.path + ')'}"> | ||
4 | + <span>{{image.title}}</span> | ||
5 | + </a> | ||
6 | + </li> | ||
7 | +</ul> | ||
8 | +<br style="clear: both;" /> |
src/app/layout/blocks/profile-images-plugin-profile-images/profile-images-plugin-profile-images-block.scss
0 → 100644
@@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
1 | +.profile-images-plugin-profile-images { | ||
2 | + padding: 0; | ||
3 | + margin: 0; | ||
4 | + display: block; | ||
5 | + width: 100%; | ||
6 | + | ||
7 | + li { | ||
8 | + list-style: none; | ||
9 | + } | ||
10 | + | ||
11 | + a { | ||
12 | + display: block; | ||
13 | + width: 53px; | ||
14 | + height: 53px; | ||
15 | + float: left; | ||
16 | + padding: 1px; | ||
17 | + border: 1px solid #ccc; | ||
18 | + margin: 4px; | ||
19 | + background-size: cover; | ||
20 | + | ||
21 | + &:hover { | ||
22 | + border: 1px solid #000; | ||
23 | + } | ||
24 | + | ||
25 | + span { | ||
26 | + display: none; | ||
27 | + } | ||
28 | + } | ||
29 | +} |
src/app/layout/blocks/recent-activities-plugin-activities/activities/event.html
0 → 100644
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.component.ts
@@ -18,7 +18,12 @@ export class RecentActivitiesPluginActivitiesBlockComponent { | @@ -18,7 +18,12 @@ export class RecentActivitiesPluginActivitiesBlockComponent { | ||
18 | constructor(private blockService: BlockService, private $state: any) { } | 18 | constructor(private blockService: BlockService, private $state: any) { } |
19 | 19 | ||
20 | getActivityTemplate(activity: any) { | 20 | getActivityTemplate(activity: any) { |
21 | - return 'app/layout/blocks/recent-activities-plugin-activities/activities/' + activity.verb + '.html'; | 21 | + if (activity.label === 'events') { |
22 | + return 'app/layout/blocks/recent-activities-plugin-activities/activities/event.html'; | ||
23 | + } | ||
24 | + else { | ||
25 | + return 'app/layout/blocks/recent-activities-plugin-activities/activities/' + activity.verb + '.html'; | ||
26 | + } | ||
22 | } | 27 | } |
23 | 28 | ||
24 | urlFor(params: any) { | 29 | urlFor(params: any) { |
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.html
1 | <div class="deckgrid recent-activities-block"> | 1 | <div class="deckgrid recent-activities-block"> |
2 | <div ng-repeat="activity in ctrl.activities" class="a-card panel media"> | 2 | <div ng-repeat="activity in ctrl.activities" class="a-card panel media"> |
3 | + | ||
4 | + <div class="subheader"> | ||
5 | + <p ng-if="activity.label === 'events'"> | ||
6 | + {{ 'activities.event.description' | translate }} <b>{{ activity.start_date | date:longDate }}</b> {{ 'time.at' | translate }} {{ activity.start_date | date:'HH:mm' }} - <a ng-href="/{{activity.user.identifier}}">{{activity.user.name}}</a> <span class="activity-label">{{activity.label}}</span> | ||
7 | + </p> | ||
8 | + | ||
9 | + <p ng-if="activity.label !== 'events'"> | ||
10 | + {{ 'date.on' | translate }} <b>{{ activity.created_at | date:longDate }}</b> {{ 'time.at' | translate }} {{ activity.created_at | date:'HH:mm' }} - <a ng-href="/{{activity.user.identifier}}">{{activity.user.name}}</a> <span class="activity-label">{{activity.label}}</span> | ||
11 | + </p> | ||
12 | + </div> | ||
13 | + | ||
3 | <div class="header media-body"> | 14 | <div class="header media-body"> |
4 | <h5 class="title media-heading"> | 15 | <h5 class="title media-heading"> |
5 | - <a ng-href="/{{activity.user.identifier}}">{{activity.user.name}}</a> <ng-include src="ctrl.getActivityTemplate(activity)"></ng-include> | 16 | + <ng-include src="ctrl.getActivityTemplate(activity)"></ng-include> |
6 | </h5> | 17 | </h5> |
7 | </div> | 18 | </div> |
8 | - <div class="subheader"> | ||
9 | - <span class="time"> | ||
10 | - <i class="fa fa-clock-o"></i> <span am-time-ago="activity.created_at | dateFormat"></span> | ||
11 | - </span> | ||
12 | - </div> | 19 | + |
20 | + <hr /> | ||
13 | </div> | 21 | </div> |
14 | </div> | 22 | </div> |
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.scss
@@ -20,4 +20,53 @@ | @@ -20,4 +20,53 @@ | ||
20 | display: none; | 20 | display: none; |
21 | } | 21 | } |
22 | } | 22 | } |
23 | + | ||
24 | + .panel { | ||
25 | + margin-bottom: 15px; | ||
26 | + box-shadow: none; | ||
27 | + border-radius: 0; | ||
28 | + } | ||
29 | + | ||
30 | + h5 { | ||
31 | + text-transform: capitalize; | ||
32 | + } | ||
33 | + | ||
34 | + .subheader { | ||
35 | + p { | ||
36 | + margin: 2px 0; | ||
37 | + font-size: 11px; | ||
38 | + } | ||
39 | + } | ||
40 | + | ||
41 | + hr { | ||
42 | + border: 0; | ||
43 | + height: 1px; | ||
44 | + background: #ccc; | ||
45 | + margin: 0; | ||
46 | + margin-top: 15px; | ||
47 | + } | ||
48 | + | ||
49 | + .activity-label { | ||
50 | + @include border-radius(2px); | ||
51 | + font-size: 11px; | ||
52 | + text-transform: capitalize; | ||
53 | + background: #333; | ||
54 | + color: #fff; | ||
55 | + padding: 2px; | ||
56 | + margin-left: 5px; | ||
57 | + display: inline-block; | ||
58 | + } | ||
59 | + | ||
60 | + .event-image { | ||
61 | + width: 15%; | ||
62 | + height: auto; | ||
63 | + float: left; | ||
64 | + } | ||
65 | + | ||
66 | + .event-description { | ||
67 | + width: 83%; | ||
68 | + margin: 2px 0 0 2px; | ||
69 | + float: left; | ||
70 | + display: block; | ||
71 | + } | ||
23 | } | 72 | } |
src/app/layout/boxes/display-boxes.filter.ts
@@ -11,6 +11,8 @@ export class DisplayBoxes { | @@ -11,6 +11,8 @@ export class DisplayBoxes { | ||
11 | 11 | ||
12 | if (layout === "rightbar") { | 12 | if (layout === "rightbar") { |
13 | valid_boxes = this.visible_on_right_bar(); | 13 | valid_boxes = this.visible_on_right_bar(); |
14 | + }else if(layout === "topleft") { | ||
15 | + valid_boxes = this.visible_on_top_right_bar(); | ||
14 | }else { | 16 | }else { |
15 | valid_boxes = this.visible_on_default(); | 17 | valid_boxes = this.visible_on_default(); |
16 | } | 18 | } |
@@ -31,5 +33,9 @@ export class DisplayBoxes { | @@ -31,5 +33,9 @@ export class DisplayBoxes { | ||
31 | return [1, 3]; | 33 | return [1, 3]; |
32 | } | 34 | } |
33 | 35 | ||
36 | + private visible_on_top_right_bar() { | ||
37 | + return [1, 2, 3]; | ||
38 | + } | ||
39 | + | ||
34 | } | 40 | } |
35 | 41 |
src/app/layout/boxes/set-box-layout.filter.ts
@@ -6,6 +6,8 @@ export class SetBoxLayout { | @@ -6,6 +6,8 @@ export class SetBoxLayout { | ||
6 | transform(pos: number, layout: string) { | 6 | transform(pos: number, layout: string) { |
7 | if (layout === "rightbar") { | 7 | if (layout === "rightbar") { |
8 | return this.right_bar(pos); | 8 | return this.right_bar(pos); |
9 | + }else if(layout === "topleft") { | ||
10 | + return this.top_right_bar(pos); | ||
9 | }else { | 11 | }else { |
10 | return this.default(pos); | 12 | return this.default(pos); |
11 | } | 13 | } |
@@ -29,4 +31,14 @@ export class SetBoxLayout { | @@ -29,4 +31,14 @@ export class SetBoxLayout { | ||
29 | } | 31 | } |
30 | } | 32 | } |
31 | 33 | ||
34 | + private top_right_bar(position: number) { | ||
35 | + if (position === 1) { | ||
36 | + return "col-sm-12 col-md-8"; | ||
37 | + }else if(position == 2) { | ||
38 | + return "col-sm-12 col-md-4"; | ||
39 | + }else { | ||
40 | + return "col-sm-12 col-md-12"; | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
32 | } | 44 | } |
src/app/layout/navbar/navbar.html
@@ -20,6 +20,12 @@ | @@ -20,6 +20,12 @@ | ||
20 | <a ng-href="#" ng-click="ctrl.openLogin()">{{"navbar.login" | translate}}</a> | 20 | <a ng-href="#" ng-click="ctrl.openLogin()">{{"navbar.login" | translate}}</a> |
21 | </li> | 21 | </li> |
22 | 22 | ||
23 | + <li ng-show="!ctrl.currentUser"> | ||
24 | + <a ui-sref="main.register"> | ||
25 | + Sign Up | ||
26 | + </a> | ||
27 | + </li> | ||
28 | + | ||
23 | <li class="dropdown profile-menu" ng-show="ctrl.currentUser" uib-dropdown> | 29 | <li class="dropdown profile-menu" ng-show="ctrl.currentUser" uib-dropdown> |
24 | <a href="#" class="dropdown-toggle" aria-expanded="false" uib-dropdown-toggle> | 30 | <a href="#" class="dropdown-toggle" aria-expanded="false" uib-dropdown-toggle> |
25 | <noosfero-profile-image [profile]="ctrl.currentUser.person" class="profile-image"></noosfero-profile-image> | 31 | <noosfero-profile-image [profile]="ctrl.currentUser.person" class="profile-image"></noosfero-profile-image> |
src/app/layout/navbar/navbar.ts
1 | -import {Component, Inject, EventEmitter, Input} from "ng-forward"; | ||
2 | -import {LanguageSelectorComponent} from "../language-selector/language-selector.component"; | ||
3 | -import {SessionService, AuthService, AuthController, AuthEvents} from "./../../login"; | ||
4 | -import {EnvironmentService} from "./../../../lib/ng-noosfero-api/http/environment.service"; | ||
5 | -import {SidebarNotificationService} from "../sidebar/sidebar.notification.service"; | ||
6 | -import {BodyStateClassesService} from '../services/body-state-classes.service'; | ||
7 | -import {DesignModeTogglerComponent} from './../../admin/layout-edit/designModeToggler.component'; | ||
8 | -import {BootstrapSwitcherComponent, BootstrapSwitcherItem} from './../../shared/components/bootstrap-switcher/bootstrap-switcher.component'; | 1 | +import { Component, Inject, EventEmitter, Input } from "ng-forward"; |
2 | +import { LanguageSelectorComponent } from "../language-selector/language-selector.component"; | ||
3 | +import { SessionService, AuthService, AuthController, AuthEvents } from "./../../login"; | ||
4 | +import { EnvironmentService } from "./../../../lib/ng-noosfero-api/http/environment.service"; | ||
5 | +import { SidebarNotificationService } from "../sidebar/sidebar.notification.service"; | ||
6 | +import { BodyStateClassesService } from '../services/body-state-classes.service'; | ||
7 | +import { DesignModeTogglerComponent } from './../../admin/layout-edit/designModeToggler.component'; | ||
8 | +import { BootstrapSwitcherComponent, BootstrapSwitcherItem } from './../../shared/components/bootstrap-switcher/bootstrap-switcher.component'; | ||
9 | 9 | ||
10 | @Component({ | 10 | @Component({ |
11 | selector: "acme-navbar", | 11 | selector: "acme-navbar", |
@@ -17,14 +17,14 @@ import {BootstrapSwitcherComponent, BootstrapSwitcherItem} from './../../shared/ | @@ -17,14 +17,14 @@ import {BootstrapSwitcherComponent, BootstrapSwitcherItem} from './../../shared/ | ||
17 | export class Navbar { | 17 | export class Navbar { |
18 | 18 | ||
19 | private currentUser: noosfero.User; | 19 | private currentUser: noosfero.User; |
20 | - private modalInstance: any = null; | 20 | + private modalInstance: ng.ui.bootstrap.IModalServiceInstance; |
21 | public showHamburger: boolean = false; | 21 | public showHamburger: boolean = false; |
22 | public currentEnvironment: noosfero.Environment = <any>{ name: '' }; | 22 | public currentEnvironment: noosfero.Environment = <any>{ name: '' }; |
23 | /** | 23 | /** |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | constructor( | 26 | constructor( |
27 | - private $uibModal: any, | 27 | + private $uibModal: ng.ui.bootstrap.IModalService, |
28 | public authService: AuthService, | 28 | public authService: AuthService, |
29 | private session: SessionService, | 29 | private session: SessionService, |
30 | private $state: ng.ui.IStateService, | 30 | private $state: ng.ui.IStateService, |
src/app/layout/scss/_forms.scss
src/app/layout/scss/_layout.scss
@@ -34,17 +34,4 @@ | @@ -34,17 +34,4 @@ | ||
34 | .main-box-body { | 34 | .main-box-body { |
35 | padding: 0 20px 20px 20px; | 35 | padding: 0 20px 20px 20px; |
36 | } | 36 | } |
37 | -} | ||
38 | - | ||
39 | -ul.nav > li.toggler-container { | ||
40 | - position: relative; | ||
41 | - padding-top: 12px; | ||
42 | -} | ||
43 | - | ||
44 | -.noosfero-main-toolbar { | ||
45 | - padding: 5px; | ||
46 | - @include make-row(); | ||
47 | - margin-left: 0px; | ||
48 | - margin-right: 0px; | ||
49 | - background-color: #edecec; | ||
50 | -} | 37 | +} |
51 | \ No newline at end of file | 38 | \ No newline at end of file |
src/app/layout/scss/_mixins.scss
@@ -4,6 +4,12 @@ | @@ -4,6 +4,12 @@ | ||
4 | background-clip: padding-box; /* stops bg color from leaking outside the border: */ | 4 | background-clip: padding-box; /* stops bg color from leaking outside the border: */ |
5 | } | 5 | } |
6 | 6 | ||
7 | +@mixin box-shadow($args...) { | ||
8 | + -webkit-box-shadow: $args; | ||
9 | + -moz-box-shadow: $args; | ||
10 | + box-shadow: $args; | ||
11 | +} | ||
12 | + | ||
7 | @mixin checkbox-mark($width, $height, $top, $left, $bg, $border, $content: "", $cursor: pointer, $position: absolute) { | 13 | @mixin checkbox-mark($width, $height, $top, $left, $bg, $border, $content: "", $cursor: pointer, $position: absolute) { |
8 | width: $width; | 14 | width: $width; |
9 | height: $height; | 15 | height: $height; |
@@ -48,3 +54,31 @@ | @@ -48,3 +54,31 @@ | ||
48 | outline-width: $width; | 54 | outline-width: $width; |
49 | } | 55 | } |
50 | } | 56 | } |
57 | + | ||
58 | +@mixin not-select() { | ||
59 | + -webkit-touch-callout: none; /* iOS Safari */ | ||
60 | + -webkit-user-select: none; /* Chrome/Safari/Opera */ | ||
61 | + -khtml-user-select: none; /* Konqueror */ | ||
62 | + -moz-user-select: none; /* Firefox */ | ||
63 | + -ms-user-select: none; /* Internet Explorer/Edge */ | ||
64 | + user-select: none; /* Non-prefixed version, currently | ||
65 | + not supported by any browser */ | ||
66 | +} | ||
67 | + | ||
68 | +@mixin keyframes($animation-name) { | ||
69 | + @-webkit-keyframes #{$animation-name} { | ||
70 | + @content; | ||
71 | + } | ||
72 | + @-moz-keyframes #{$animation-name} { | ||
73 | + @content; | ||
74 | + } | ||
75 | + @-ms-keyframes #{$animation-name} { | ||
76 | + @content; | ||
77 | + } | ||
78 | + @-o-keyframes #{$animation-name} { | ||
79 | + @content; | ||
80 | + } | ||
81 | + @keyframes #{$animation-name} { | ||
82 | + @content; | ||
83 | + } | ||
84 | +} |
src/app/layout/scss/skins/_whbl.scss
@@ -122,7 +122,7 @@ $whbl-font-color: #16191c; | @@ -122,7 +122,7 @@ $whbl-font-color: #16191c; | ||
122 | margin-bottom: 0; | 122 | margin-bottom: 0; |
123 | position: relative; | 123 | position: relative; |
124 | min-height: 1200px; | 124 | min-height: 1200px; |
125 | - padding: 15px 15px 35px 15px; | 125 | + padding: $wrapper-padding; |
126 | margin-left: 220px; | 126 | margin-left: 220px; |
127 | // border-left: 2px solid #e7ebee; | 127 | // border-left: 2px solid #e7ebee; |
128 | } | 128 | } |
@@ -291,11 +291,7 @@ $whbl-font-color: #16191c; | @@ -291,11 +291,7 @@ $whbl-font-color: #16191c; | ||
291 | background-color: #fff; | 291 | background-color: #fff; |
292 | } | 292 | } |
293 | 293 | ||
294 | - noosfero-design-toggler .ats-switch .knob i { | ||
295 | - color: #999999; | ||
296 | - } | ||
297 | - | ||
298 | - .ats-switch .knob { | 294 | + .ats-switch .knob { |
299 | padding-right: 15px; | 295 | padding-right: 15px; |
300 | } | 296 | } |
301 | 297 |
src/app/layout/services/body-state-classes.service.spec.ts
@@ -193,7 +193,6 @@ describe("BodyStateClasses Service", () => { | @@ -193,7 +193,6 @@ describe("BodyStateClasses Service", () => { | ||
193 | 193 | ||
194 | service.start(); | 194 | service.start(); |
195 | 195 | ||
196 | - debugger; | ||
197 | designModeService.setInDesignMode(true); | 196 | designModeService.setInDesignMode(true); |
198 | 197 | ||
199 | 198 |
src/app/login/login.html
@@ -21,4 +21,7 @@ | @@ -21,4 +21,7 @@ | ||
21 | </div> | 21 | </div> |
22 | <button type="submit" class="btn btn-default btn-block" ng-click="vm.login()">{{"auth.form.login_button" | translate}}</button> | 22 | <button type="submit" class="btn btn-default btn-block" ng-click="vm.login()">{{"auth.form.login_button" | translate}}</button> |
23 | </form> | 23 | </form> |
24 | + <div class="text-center"> | ||
25 | + <a ui-sref="main.register" ng-click="$close()">{{"auth.createAccount" | translate}}</a> | ||
26 | + </div> | ||
24 | </div> | 27 | </div> |
src/app/login/session.service.ts
src/app/main/main.component.spec.ts
@@ -4,8 +4,9 @@ import {TestComponentBuilder, ComponentFixture} from "ng-forward/cjs/testing/tes | @@ -4,8 +4,9 @@ import {TestComponentBuilder, ComponentFixture} from "ng-forward/cjs/testing/tes | ||
4 | 4 | ||
5 | import {quickCreateComponent} from "../../spec/helpers"; | 5 | import {quickCreateComponent} from "../../spec/helpers"; |
6 | import {getAngularServiceFactory} from "../../spec/helpers"; | 6 | import {getAngularServiceFactory} from "../../spec/helpers"; |
7 | +import { EVENTS_HUB_KNOW_EVENT_NAMES } from "../shared/services/events-hub.service"; | ||
7 | 8 | ||
8 | -describe("MainComponent", function() { | 9 | +describe("MainComponent", function () { |
9 | 10 | ||
10 | let localFixture: ComponentFixture; | 11 | let localFixture: ComponentFixture; |
11 | let $state: angular.ui.IStateService; | 12 | let $state: angular.ui.IStateService; |
@@ -34,6 +35,14 @@ describe("MainComponent", function() { | @@ -34,6 +35,14 @@ describe("MainComponent", function() { | ||
34 | { | 35 | { |
35 | useValue: environmentService | 36 | useValue: environmentService |
36 | }), | 37 | }), |
38 | + provide(EVENTS_HUB_KNOW_EVENT_NAMES, | ||
39 | + { | ||
40 | + useValue: [ | ||
41 | + 'IMAGE_PROFILE_UPDATED', | ||
42 | + 'PROFILE_INFO_UPDATED', | ||
43 | + 'ARTICLE_UPDATED' | ||
44 | + ] | ||
45 | + }), | ||
37 | ] | 46 | ] |
38 | }) | 47 | }) |
39 | class MainComponentParent { | 48 | class MainComponentParent { |
@@ -57,7 +66,7 @@ describe("MainComponent", function() { | @@ -57,7 +66,7 @@ describe("MainComponent", function() { | ||
57 | // navigates to the environment home | 66 | // navigates to the environment home |
58 | $state.go("main.environment.home"); | 67 | $state.go("main.environment.home"); |
59 | localFixture.detectChanges(); | 68 | localFixture.detectChanges(); |
60 | - // after changes were detected it checks the current $state route | 69 | + // after changes were detected it checks the current $state route |
61 | expect($state.current.name).toEqual("main.environment.home"); | 70 | expect($state.current.name).toEqual("main.environment.home"); |
62 | done(); | 71 | done(); |
63 | }); | 72 | }); |
src/app/main/main.component.ts
1 | import * as plugins from "../../plugins"; | 1 | import * as plugins from "../../plugins"; |
2 | -import {bundle, Component, StateConfig, Inject} from "ng-forward"; | ||
3 | -import {ArticleBlogComponent} from "./../article/types/blog/blog.component"; | ||
4 | - | ||
5 | -import {ArticleViewComponent} from "./../article/article-default-view.component"; | ||
6 | - | ||
7 | -import {ProfileComponent} from "../profile/profile.component"; | ||
8 | -import {BoxesComponent} from "../layout/boxes/boxes.component"; | ||
9 | -import {BlockContentComponent} from "../layout/blocks/block-content.component"; | ||
10 | -import {BlockComponent} from "../layout/blocks/block.component"; | ||
11 | -import {EnvironmentComponent} from "../environment/environment.component"; | ||
12 | -import {EnvironmentHomeComponent} from "../environment/environment-home.component"; | ||
13 | -import {PeopleBlockComponent} from "../layout/blocks/people/people-block.component"; | ||
14 | -import {DisplayContentBlockComponent} from "../layout/blocks/display-content/display-content-block.component"; | ||
15 | -import {LinkListBlockComponent} from "../layout/blocks/link-list/link-list-block.component"; | ||
16 | -import {RecentDocumentsBlockComponent} from "../layout/blocks/recent-documents/recent-documents-block.component"; | ||
17 | -import {ProfileImageBlockComponent} from "../layout/blocks/profile-image/profile-image-block.component"; | ||
18 | -import {RawHTMLBlockComponent} from "../layout/blocks/raw-html/raw-html-block.component"; | ||
19 | -import {StatisticsBlockComponent} from "../layout/blocks/statistics/statistics-block.component"; | ||
20 | -import {PersonTagsPluginInterestsBlockComponent} from "../layout/blocks/person-tags-plugin-interests/person-tags-plugin-interests-block.component"; | ||
21 | -import {TagsBlockComponent} from "../layout/blocks/tags/tags-block.component"; | ||
22 | -import {CustomContentComponent} from "../profile/custom-content/custom-content.component"; | ||
23 | -import {RecentActivitiesPluginActivitiesBlockComponent} from "../layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.component"; | ||
24 | - | ||
25 | -import {MembersBlockComponent} from "../layout/blocks/members/members-block.component"; | ||
26 | -import {CommunitiesBlockComponent} from "../layout/blocks/communities/communities-block.component"; | ||
27 | - | ||
28 | -import {LoginBlockComponent} from "../layout/blocks/login-block/login-block.component"; | ||
29 | - | ||
30 | -import {NoosferoTemplate} from "../shared/pipes/noosfero-template.filter"; | ||
31 | -import {DateFormat} from "../shared/pipes/date-format.filter"; | ||
32 | - | ||
33 | -import {AuthService} from "../login/auth.service"; | ||
34 | -import {SessionService} from "../login/session.service"; | ||
35 | -import {EnvironmentService} from "./../../lib/ng-noosfero-api/http/environment.service"; | ||
36 | -import {NotificationService} from "../shared/services/notification.service"; | ||
37 | - | ||
38 | -import {BodyStateClassesService} from "./../layout/services/body-state-classes.service"; | ||
39 | - | ||
40 | -import {Navbar} from "../layout/navbar/navbar"; | ||
41 | - | ||
42 | -import {SidebarComponent} from "../layout/sidebar/sidebar.component"; | ||
43 | - | ||
44 | -import {MainBlockComponent} from "../layout/blocks/main/main-block.component"; | ||
45 | -import {HtmlEditorComponent} from "../shared/components/html-editor/html-editor.component"; | ||
46 | -import {PermissionDirective} from "../shared/components/permission/permission.directive"; | ||
47 | -import {SearchComponent} from "../search/search.component"; | ||
48 | -import {SearchFormComponent} from "../search/search-form/search-form.component"; | ||
49 | - | 2 | +import { bundle, Component, StateConfig, Inject } from "ng-forward"; |
3 | +import { ArticleBlogComponent } from "./../article/types/blog/blog.component"; | ||
4 | + | ||
5 | +import { ArticleViewComponent } from "./../article/article-default-view.component"; | ||
6 | + | ||
7 | +import { ProfileComponent } from "../profile/profile.component"; | ||
8 | +import { BoxesComponent } from "../layout/boxes/boxes.component"; | ||
9 | +import { BlockContentComponent } from "../layout/blocks/block-content.component"; | ||
10 | +import { BlockComponent } from "../layout/blocks/block.component"; | ||
11 | +import { EnvironmentComponent } from "../environment/environment.component"; | ||
12 | +import { EnvironmentHomeComponent } from "../environment/environment-home.component"; | ||
13 | +import { PeopleBlockComponent } from "../layout/blocks/people/people-block.component"; | ||
14 | +import { DisplayContentBlockComponent } from "../layout/blocks/display-content/display-content-block.component"; | ||
15 | +import { LinkListBlockComponent } from "../layout/blocks/link-list/link-list-block.component"; | ||
16 | +import { RecentDocumentsBlockComponent } from "../layout/blocks/recent-documents/recent-documents-block.component"; | ||
17 | +import { ProfileImageBlockComponent } from "../layout/blocks/profile-image/profile-image-block.component"; | ||
18 | +import { RawHTMLBlockComponent } from "../layout/blocks/raw-html/raw-html-block.component"; | ||
19 | +import { StatisticsBlockComponent } from "../layout/blocks/statistics/statistics-block.component"; | ||
20 | +import { PersonTagsPluginInterestsBlockComponent } from "../layout/blocks/person-tags-plugin-interests/person-tags-plugin-interests-block.component"; | ||
21 | +import { TagsBlockComponent } from "../layout/blocks/tags/tags-block.component"; | ||
22 | +import { CustomContentComponent } from "../profile/custom-content/custom-content.component"; | ||
23 | +import { RecentActivitiesPluginActivitiesBlockComponent } from "../layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.component"; | ||
24 | +import { ContainerBlockPluginContainerBlockComponent } from "../layout/blocks/container-block-plugin-container-block/container-block-plugin-container-block.component"; | ||
25 | +import { ProfileImagesPluginProfileImagesBlockComponent } from "../layout/blocks/profile-images-plugin-profile-images/profile-images-plugin-profile-images-block.component"; | ||
26 | +import { RegisterComponent } from "../account/register.component"; | ||
27 | + | ||
28 | +import { MembersBlockComponent } from "../layout/blocks/members/members-block.component"; | ||
29 | +import { CommunitiesBlockComponent } from "../layout/blocks/communities/communities-block.component"; | ||
30 | + | ||
31 | +import { LoginBlockComponent } from "../layout/blocks/login-block/login-block.component"; | ||
32 | + | ||
33 | +import { NoosferoTemplate } from "../shared/pipes/noosfero-template.filter"; | ||
34 | +import { DateFormat } from "../shared/pipes/date-format.filter"; | ||
35 | + | ||
36 | +import { AuthService } from "../login/auth.service"; | ||
37 | +import { SessionService } from "../login/session.service"; | ||
38 | +import { EnvironmentService } from "./../../lib/ng-noosfero-api/http/environment.service"; | ||
39 | +import { NotificationService } from "../shared/services/notification.service"; | ||
40 | +import { RegisterService } from "./../../lib/ng-noosfero-api/http/register.service"; | ||
41 | + | ||
42 | +import { BodyStateClassesService } from "./../layout/services/body-state-classes.service"; | ||
43 | + | ||
44 | +import { Navbar } from "../layout/navbar/navbar"; | ||
45 | + | ||
46 | +import { SidebarComponent } from "../layout/sidebar/sidebar.component"; | ||
47 | + | ||
48 | +import { MainBlockComponent } from "../layout/blocks/main/main-block.component"; | ||
49 | +import { HtmlEditorComponent } from "../shared/components/html-editor/html-editor.component"; | ||
50 | +import { PermissionDirective } from "../shared/components/permission/permission.directive"; | ||
51 | +import { SearchComponent } from "../search/search.component"; | ||
52 | +import { SearchFormComponent } from "../search/search-form/search-form.component"; | ||
53 | + | ||
54 | +import { EVENTS_HUB_KNOW_EVENT_NAMES, EventsHubService } from "../shared/services/events-hub.service"; | ||
55 | +import { NoosferoKnownEvents } from "../known-events"; | ||
50 | /** | 56 | /** |
51 | * @ngdoc controller | 57 | * @ngdoc controller |
52 | * @name main.MainContentComponent | 58 | * @name main.MainContentComponent |
@@ -62,12 +68,16 @@ import {SearchFormComponent} from "../search/search-form/search-form.component"; | @@ -62,12 +68,16 @@ import {SearchFormComponent} from "../search/search-form/search-form.component"; | ||
62 | templateUrl: "app/main/main.html", | 68 | templateUrl: "app/main/main.html", |
63 | providers: [AuthService, SessionService] | 69 | providers: [AuthService, SessionService] |
64 | }) | 70 | }) |
65 | -@Inject(BodyStateClassesService) | 71 | +@Inject(BodyStateClassesService, EVENTS_HUB_KNOW_EVENT_NAMES) |
66 | export class MainContentComponent { | 72 | export class MainContentComponent { |
67 | 73 | ||
68 | public themeSkin: string = 'skin-whbl'; | 74 | public themeSkin: string = 'skin-whbl'; |
69 | 75 | ||
70 | - constructor(private bodyStateClassesService: BodyStateClassesService) { | 76 | + constructor( |
77 | + private bodyStateClassesService: BodyStateClassesService, | ||
78 | + eventsNames: NoosferoKnownEvents, | ||
79 | + eventsHubService: EventsHubService | ||
80 | + ) { | ||
71 | bodyStateClassesService.start({ | 81 | bodyStateClassesService.start({ |
72 | skin: this.themeSkin | 82 | skin: this.themeSkin |
73 | }); | 83 | }); |
@@ -88,7 +98,8 @@ export class EnvironmentContent { | @@ -88,7 +98,8 @@ export class EnvironmentContent { | ||
88 | * @name main.Main | 98 | * @name main.Main |
89 | * @requires AuthService, Session, Notification, ArticleBlog, ArticleView, Boxes, Block, LinkListBlock, | 99 | * @requires AuthService, Session, Notification, ArticleBlog, ArticleView, Boxes, Block, LinkListBlock, |
90 | * MainBlock, RecentDocumentsBlock, Navbar, ProfileImageBlock, MembersBlock, | 100 | * MainBlock, RecentDocumentsBlock, Navbar, ProfileImageBlock, MembersBlock, |
91 | - * NoosferoTemplate, DateFormat, RawHTMLBlock, PersonTagsPluginInterestsBlock, RecentActivitiesPluginActivitiesBlock, | 101 | + * NoosferoTemplate, DateFormat, RawHTMLBlock, PersonTagsPluginInterestsBlock, |
102 | + * RecentActivitiesPluginActivitiesBlock, ContainerBlockPluginContainerBlockComponent, ProfileImagesPluginProfileImages | ||
92 | * @description | 103 | * @description |
93 | * The Main controller for the Noosfero Angular Theme application. | 104 | * The Main controller for the Noosfero Angular Theme application. |
94 | * | 105 | * |
@@ -107,16 +118,18 @@ export class EnvironmentContent { | @@ -107,16 +118,18 @@ export class EnvironmentContent { | ||
107 | MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent, | 118 | MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent, |
108 | MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent, StatisticsBlockComponent, | 119 | MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent, StatisticsBlockComponent, |
109 | LoginBlockComponent, CustomContentComponent, PermissionDirective, SearchFormComponent, SearchComponent, | 120 | LoginBlockComponent, CustomContentComponent, PermissionDirective, SearchFormComponent, SearchComponent, |
110 | - PersonTagsPluginInterestsBlockComponent, TagsBlockComponent, RecentActivitiesPluginActivitiesBlockComponent, BlockComponent | 121 | + PersonTagsPluginInterestsBlockComponent, TagsBlockComponent, RecentActivitiesPluginActivitiesBlockComponent, |
122 | + ContainerBlockPluginContainerBlockComponent, | ||
123 | + ProfileImagesPluginProfileImagesBlockComponent, BlockComponent, RegisterComponent | ||
111 | ].concat(plugins.mainComponents).concat(plugins.hotspots), | 124 | ].concat(plugins.mainComponents).concat(plugins.hotspots), |
112 | - providers: [AuthService, SessionService, NotificationService, BodyStateClassesService, | 125 | + providers: [AuthService, SessionService, NotificationService, BodyStateClassesService, RegisterService, |
113 | "ngAnimate", "ngCookies", "ngStorage", "ngTouch", | 126 | "ngAnimate", "ngCookies", "ngStorage", "ngTouch", |
114 | "ngSanitize", "ngMessages", "ngAria", "restangular", | 127 | "ngSanitize", "ngMessages", "ngAria", "restangular", |
115 | "ui.router", "ui.bootstrap", "toastr", "ngCkeditor", | 128 | "ui.router", "ui.bootstrap", "toastr", "ngCkeditor", |
116 | "angular-bind-html-compile", "angularMoment", "angular.filter", "akoenig.deckgrid", | 129 | "angular-bind-html-compile", "angularMoment", "angular.filter", "akoenig.deckgrid", |
117 | "angular-timeline", "duScroll", "oitozero.ngSweetAlert", | 130 | "angular-timeline", "duScroll", "oitozero.ngSweetAlert", |
118 | "pascalprecht.translate", "tmh.dynamicLocale", "angularLoad", | 131 | "pascalprecht.translate", "tmh.dynamicLocale", "angularLoad", |
119 | - "angular-click-outside", "toggle-switch", "ngTagCloud", "noosfero.init"] | 132 | + "angular-click-outside", "ngTagCloud", "noosfero.init", "uiSwitch", "ngPassword"] |
120 | }) | 133 | }) |
121 | @StateConfig([ | 134 | @StateConfig([ |
122 | { | 135 | { |
@@ -137,7 +150,6 @@ export class EnvironmentContent { | @@ -137,7 +150,6 @@ export class EnvironmentContent { | ||
137 | url: '/', | 150 | url: '/', |
138 | component: EnvironmentComponent, | 151 | component: EnvironmentComponent, |
139 | name: 'main.environment', | 152 | name: 'main.environment', |
140 | - abstract: true, | ||
141 | views: { | 153 | views: { |
142 | "content": { | 154 | "content": { |
143 | templateUrl: "app/environment/environment.html", | 155 | templateUrl: "app/environment/environment.html", |
@@ -147,6 +159,18 @@ export class EnvironmentContent { | @@ -147,6 +159,18 @@ export class EnvironmentContent { | ||
147 | } | 159 | } |
148 | }, | 160 | }, |
149 | { | 161 | { |
162 | + url: '/account/signup', | ||
163 | + component: RegisterComponent, | ||
164 | + name: 'main.register', | ||
165 | + views: { | ||
166 | + "content": { | ||
167 | + templateUrl: "app/account/register.html", | ||
168 | + controller: RegisterComponent, | ||
169 | + controllerAs: "vm" | ||
170 | + } | ||
171 | + } | ||
172 | + }, | ||
173 | + { | ||
150 | url: "^/:profile", | 174 | url: "^/:profile", |
151 | abstract: true, | 175 | abstract: true, |
152 | component: ProfileComponent, | 176 | component: ProfileComponent, |
src/app/profile/activities/activities.html
1 | -<timeline> | ||
2 | - <timeline-event ng-repeat="activity in ctrl.activities | orderBy: 'created_at':true"> | ||
3 | - <noosfero-activity [activity]="activity"></noosfero-activity> | ||
4 | - </timeline-event> | ||
5 | -</timeline> | 1 | +<div class="row"> |
2 | + <hr class="divider"/> | ||
3 | + <div id="atividades"> | ||
4 | + <h4>Atividades Recentes</h4> | ||
5 | + <timeline> | ||
6 | + <timeline-event ng-repeat="activity in vm.activities | orderBy: 'created_at':true"> | ||
7 | + <hr class="divider"/> | ||
8 | + <noosfero-activity [activity]="activity"></noosfero-activity> | ||
9 | + </timeline-event> | ||
10 | + </timeline> | ||
11 | + <button type="button" class="btn btn-sm btn-block">Carregar mais</button> | ||
12 | + </div> | ||
13 | +</div> |
src/app/profile/activities/activity/activity.component.spec.ts
@@ -12,6 +12,7 @@ const htmlTemplate: string = '<noosfero-activity [activity]="ctrl.activity"></no | @@ -12,6 +12,7 @@ const htmlTemplate: string = '<noosfero-activity [activity]="ctrl.activity"></no | ||
12 | describe("Components", () => { | 12 | describe("Components", () => { |
13 | 13 | ||
14 | describe("Noosfero Activity", () => { | 14 | describe("Noosfero Activity", () => { |
15 | + let activity = { name: "activity1", verb: "create_article" }; | ||
15 | 16 | ||
16 | beforeEach(angular.mock.module("templates")); | 17 | beforeEach(angular.mock.module("templates")); |
17 | 18 | ||
@@ -21,18 +22,54 @@ describe("Components", () => { | @@ -21,18 +22,54 @@ describe("Components", () => { | ||
21 | directives: [ActivityComponent], | 22 | directives: [ActivityComponent], |
22 | providers: provideFilters("truncateFilter", "stripTagsFilter", "translateFilter") | 23 | providers: provideFilters("truncateFilter", "stripTagsFilter", "translateFilter") |
23 | }) | 24 | }) |
25 | + | ||
24 | class BlockContainerComponent { | 26 | class BlockContainerComponent { |
25 | - activity = { name: "activity1", verb: "create_article" }; | 27 | + activity = activity; |
26 | } | 28 | } |
27 | 29 | ||
28 | it("render the specific template for an activity verb", done => { | 30 | it("render the specific template for an activity verb", done => { |
29 | tcb.createAsync(BlockContainerComponent).then(fixture => { | 31 | tcb.createAsync(BlockContainerComponent).then(fixture => { |
30 | let component: ActivityComponent = fixture.debugElement.componentViewChildren[0].componentInstance; | 32 | let component: ActivityComponent = fixture.debugElement.componentViewChildren[0].componentInstance; |
31 | expect(component.getActivityTemplate()).toEqual('app/profile/activities/activity/create_article.html'); | 33 | expect(component.getActivityTemplate()).toEqual('app/profile/activities/activity/create_article.html'); |
34 | + done(); | ||
35 | + }); | ||
36 | + }); | ||
37 | + | ||
38 | + it("render create article template correctly", done => { | ||
39 | + activity = { name: "activity1", verb: "create_article" }; | ||
40 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
41 | + let component: ActivityComponent = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
32 | expect(fixture.debugElement.queryAll(".activity.create_article").length).toEqual(1); | 42 | expect(fixture.debugElement.queryAll(".activity.create_article").length).toEqual(1); |
33 | done(); | 43 | done(); |
34 | }); | 44 | }); |
35 | }); | 45 | }); |
46 | + | ||
47 | + it("render add_member_in_community template correctly", done => { | ||
48 | + activity = { name: "add_member_in_community1", verb: "add_member_in_community" }; | ||
49 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
50 | + let component: ActivityComponent = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
51 | + expect(fixture.debugElement.queryAll(".activity.add_member_in_community").length).toEqual(1); | ||
52 | + done(); | ||
53 | + }); | ||
54 | + }); | ||
55 | + | ||
56 | + it("render new_friendship template correctly", done => { | ||
57 | + activity = { name: "new_friendship1", verb: "new_friendship" }; | ||
58 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
59 | + let component: ActivityComponent = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
60 | + expect(fixture.debugElement.queryAll(".activity.new_friendship").length).toEqual(1); | ||
61 | + done(); | ||
62 | + }); | ||
63 | + }); | ||
64 | + | ||
65 | + it("render leave scrap template correctly", done => { | ||
66 | + activity = { name: "scrap1", verb: "leave_scrap" }; | ||
67 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
68 | + let component: ActivityComponent = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
69 | + expect(fixture.debugElement.queryAll(".activity.leave_scrap").length).toEqual(1); | ||
70 | + done(); | ||
71 | + }); | ||
72 | + }); | ||
36 | }); | 73 | }); |
37 | 74 | ||
38 | }); | 75 | }); |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +<timeline-badge class="success"> | ||
2 | + <i class="fa fa-commenting-o"></i> | ||
3 | +</timeline-badge> | ||
4 | +<timeline-panel> | ||
5 | + <timeline-heading> | ||
6 | + <h4 class="timeline-title"> | ||
7 | + <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a> | ||
8 | + <span> {{"activities.scrap.description" | translate}} </span> | ||
9 | + </h4> | ||
10 | + <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p> | ||
11 | + </timeline-heading> | ||
12 | + <div class="timeline-body"> | ||
13 | + <div class="scrap"> | ||
14 | + <div ng-bind-html="ctrl.activity.content | stripTags | truncate: 100 : '...': true"></div> | ||
15 | + </div> | ||
16 | + </div> | ||
17 | +</timeline-panel> |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +import {Component, Inject, provide} from "ng-forward"; | ||
2 | +import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service"; | ||
3 | + | ||
4 | +@Component({ | ||
5 | + selector: "configbar", | ||
6 | + templateUrl: "app/profile/configbar.html", | ||
7 | + providers: [ | ||
8 | + provide('profileService', { useClass: ProfileService }) | ||
9 | + ] | ||
10 | +}) | ||
11 | +@Inject(ProfileService) | ||
12 | +export class ConfigBarComponent { | ||
13 | + profile: noosfero.Profile; | ||
14 | + parentId: number; | ||
15 | + | ||
16 | + constructor(profileService: ProfileService) { | ||
17 | + profileService.getCurrentProfile().then((profile: noosfero.Profile) => { | ||
18 | + this.profile = profile; | ||
19 | + }); | ||
20 | + } | ||
21 | +} |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +<div id="config-tool" ng-class="{'closed': !showConfig}"> | ||
2 | + <a id="config-tool-cog" ng-click="showConfig = !showConfig"> | ||
3 | + <i class="fa fa-cog" ng-class="{'anim-icon': showConfig}"></i> | ||
4 | + </a> | ||
5 | + | ||
6 | + <div id="config-tool-options"> | ||
7 | + <h4>{{ 'configbar.label' | translate }}</h4> | ||
8 | + <div class="section-title">{{ 'configbar.section.layout' | translate }}</div> | ||
9 | + <ul> | ||
10 | + <li> | ||
11 | + <label class="pull-left"> | ||
12 | + <i class="fa fa-th-large"></i> | ||
13 | + <span class="item-label">{{ 'designMode.label' | translate }}</span> | ||
14 | + </label> | ||
15 | + <label class="pull-right"> | ||
16 | + <design-toggler></design-toggler> | ||
17 | + </label> | ||
18 | + </li> | ||
19 | + </ul> | ||
20 | + </div> | ||
21 | +</div> |
@@ -0,0 +1,110 @@ | @@ -0,0 +1,110 @@ | ||
1 | +@import "../layout/scss/mixins"; | ||
2 | + | ||
3 | +@include keyframes(rotating) { | ||
4 | + from { | ||
5 | + transform: rotate(0deg); | ||
6 | + } | ||
7 | + to { | ||
8 | + transform: rotate(360deg); | ||
9 | + } | ||
10 | +} | ||
11 | + | ||
12 | +/* CONFIG TOOLS */ | ||
13 | +#config-tool { | ||
14 | + @include transition(all 0.2s ease-in-out 0s); | ||
15 | + @include box-shadow(0px 1px 4px rgba(0, 0, 0, 0.3)); | ||
16 | + position: fixed; | ||
17 | + right: 0; | ||
18 | + top: 120px; | ||
19 | + min-width: 200px; | ||
20 | + z-index: 1000; | ||
21 | + | ||
22 | + #config-tool-cog { | ||
23 | + @include border-radius($border-radius-base 0 0 $border-radius-base); | ||
24 | + @include transition(all 0.1s ease-in-out 0s); | ||
25 | + @include box-shadow(-3px 3px 3px -2px rgba(0, 0, 0, 0.1)); | ||
26 | + background: #fff; | ||
27 | + cursor: pointer; | ||
28 | + left: -50px; | ||
29 | + padding: 10px; | ||
30 | + position: absolute; | ||
31 | + text-align: center; | ||
32 | + width: 50px; | ||
33 | + top: 0; | ||
34 | + | ||
35 | + i { | ||
36 | + font-size: 2.2em; | ||
37 | + } | ||
38 | + | ||
39 | + .anim-icon { | ||
40 | + @include animation(rotating 0.7s ease-in-out 0s); | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
44 | + &.closed { | ||
45 | + right: -280px; | ||
46 | + box-shadow: none; | ||
47 | + | ||
48 | + #config-tool-cog { | ||
49 | + &:hover { | ||
50 | + background-color: $primary-color; | ||
51 | + color: #fff; | ||
52 | + } | ||
53 | + } | ||
54 | + } | ||
55 | + | ||
56 | + &.opened { | ||
57 | + right: 0; | ||
58 | + } | ||
59 | + | ||
60 | + .section-title { | ||
61 | + margin: 30px 0 5px; | ||
62 | + font: { | ||
63 | + size: 15px; | ||
64 | + weight: bold; | ||
65 | + } | ||
66 | + | ||
67 | + } | ||
68 | + | ||
69 | + #config-tool-options { | ||
70 | + @include box-shadow(-3px 3px 3px -2px rgba(0, 0, 0, 0.1)); | ||
71 | + background: #fff; | ||
72 | + padding: 15px; | ||
73 | + | ||
74 | + h4 { | ||
75 | + margin: 0; | ||
76 | + font-size: 1.3em; | ||
77 | + } | ||
78 | + | ||
79 | + ul { | ||
80 | + list-style: none; | ||
81 | + border-radius: 2px; | ||
82 | + padding: 0; | ||
83 | + | ||
84 | + background: { | ||
85 | + clip: padding-box; | ||
86 | + color: #f1f3f2; | ||
87 | + } | ||
88 | + | ||
89 | + li { | ||
90 | + padding: 10px; | ||
91 | + width: 250px; | ||
92 | + min-height: 50px; | ||
93 | + font: { | ||
94 | + size: 13px; | ||
95 | + weight: 300; | ||
96 | + } | ||
97 | + | ||
98 | + .checkbox { | ||
99 | + margin: 0; | ||
100 | + } | ||
101 | + | ||
102 | + .pull-left { | ||
103 | + margin-top: 8px; | ||
104 | + font-weight: normal; | ||
105 | + } | ||
106 | + | ||
107 | + } | ||
108 | + } | ||
109 | + } | ||
110 | +} |
src/app/profile/custom-content/custom-content.component.ts
1 | -import {Component, Input, Inject} from 'ng-forward'; | ||
2 | -import {ProfileService} from '../../../lib/ng-noosfero-api/http/profile.service'; | ||
3 | -import {NotificationService} from '../../shared/services/notification.service'; | ||
4 | -import {PermissionDirective} from '../../shared/components/permission/permission.directive'; | ||
5 | -import {DesignModeService} from '../../admin/layout-edit/designMode.service'; | 1 | +import { Component, Input, Inject } from 'ng-forward'; |
2 | +import { ProfileService } from '../../../lib/ng-noosfero-api/http/profile.service'; | ||
3 | +import { NotificationService } from '../../shared/services/notification.service'; | ||
4 | +import { PermissionDirective } from '../../shared/components/permission/permission.directive'; | ||
5 | +import { DesignModeService } from '../../admin/layout-edit/designMode.service'; | ||
6 | 6 | ||
7 | @Component({ | 7 | @Component({ |
8 | selector: 'custom-content', | 8 | selector: 'custom-content', |
@@ -21,9 +21,10 @@ export class CustomContentComponent { | @@ -21,9 +21,10 @@ export class CustomContentComponent { | ||
21 | 21 | ||
22 | content: string; | 22 | content: string; |
23 | originalContent: string; | 23 | originalContent: string; |
24 | - private modalInstance: any = null; | 24 | + private modalInstance: ng.ui.bootstrap.IModalServiceInstance; |
25 | 25 | ||
26 | - constructor(private $uibModal: any, | 26 | + constructor( |
27 | + private $uibModal: ng.ui.bootstrap.IModalService, | ||
27 | private $scope: ng.IScope, | 28 | private $scope: ng.IScope, |
28 | private profileService: ProfileService, | 29 | private profileService: ProfileService, |
29 | private notificationService: NotificationService, | 30 | private notificationService: NotificationService, |
src/app/profile/image/image.html
1 | <span class="profile-image-wrap" title="{{ctrl.profile.name}}"> | 1 | <span class="profile-image-wrap" title="{{ctrl.profile.name}}"> |
2 | - <img ng-if="ctrl.profile.image" ng-src="{{ctrl.profile.image.url}}" class="img-responsive profile-image"> | ||
3 | - <i ng-if="!ctrl.profile.image" class="fa {{ctrl.defaultIcon}} fa-5x profile-image"></i> | 2 | + <img ng-if="ctrl.profile.image" ng-src="{{ctrl.profile.image.url}}" class=""> |
3 | + <i ng-if="!ctrl.profile.image" class="fa {{ctrl.defaultIcon}} fa-5x profile-image img-avatar"></i> | ||
4 | </span> | 4 | </span> |
src/app/profile/info/profile-info.component.ts
@@ -16,17 +16,23 @@ export class ProfileInfoComponent { | @@ -16,17 +16,23 @@ export class ProfileInfoComponent { | ||
16 | 16 | ||
17 | activities: any; | 17 | activities: any; |
18 | profile: noosfero.Profile; | 18 | profile: noosfero.Profile; |
19 | + showInformation: boolean = false; | ||
19 | 20 | ||
20 | constructor(private profileService: ProfileService, private amDateFormatFilter: any) { | 21 | constructor(private profileService: ProfileService, private amDateFormatFilter: any) { |
21 | this.init(); | 22 | this.init(); |
23 | + this.showInformation = false; | ||
24 | + } | ||
25 | + | ||
26 | + toggleInformation() { | ||
27 | + console.log(this.showInformation); | ||
28 | + console.log("argila"); | ||
29 | + this.showInformation = !this.showInformation; | ||
30 | + console.log(this.showInformation); | ||
22 | } | 31 | } |
23 | 32 | ||
24 | init() { | 33 | init() { |
25 | this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => { | 34 | this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => { |
26 | this.profile = profile; | 35 | this.profile = profile; |
27 | - return this.profileService.getActivities(<number>this.profile.id); | ||
28 | - }).then((response: restangular.IResponse) => { | ||
29 | - this.activities = response.data.activities; | ||
30 | }); | 36 | }); |
31 | } | 37 | } |
32 | } | 38 | } |
src/app/profile/info/profile-info.html
1 | -<div class="profile-wall"> | 1 | +<!-- <div class="profile-wall mainbox clearfix"> |
2 | 2 | ||
3 | <div class="col-lg-3 col-md-4 col-sm-4"> | 3 | <div class="col-lg-3 col-md-4 col-sm-4"> |
4 | <div class="main-box clearfix"> | 4 | <div class="main-box clearfix"> |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <div id="profile-left" class="main-box-body clearfix"> | 8 | <div id="profile-left" class="main-box-body clearfix"> |
9 | <noosfero-profile-image [profile]="vm.profile" class="img-responsive center-block"></noosfero-profile-image> | 9 | <noosfero-profile-image [profile]="vm.profile" class="img-responsive center-block"></noosfero-profile-image> |
10 | <span class="label" ng-class="{'label-danger': vm.profile.type == 'Community', 'label-info': vm.profile.type == 'Person'}">{{vm.profile | translateProfile}}</span> | 10 | <span class="label" ng-class="{'label-danger': vm.profile.type == 'Community', 'label-info': vm.profile.type == 'Person'}">{{vm.profile | translateProfile}}</span> |
11 | + | ||
11 | <div class="profile-since"> | 12 | <div class="profile-since"> |
12 | {{"profile.member_since" | translate}}: {{vm.profile.created_at | amDateFormat:'MMMM YYYY'}} | 13 | {{"profile.member_since" | translate}}: {{vm.profile.created_at | amDateFormat:'MMMM YYYY'}} |
13 | </div> | 14 | </div> |
@@ -27,4 +28,38 @@ | @@ -27,4 +28,38 @@ | ||
27 | </uib-tabset> | 28 | </uib-tabset> |
28 | </div> | 29 | </div> |
29 | </div> | 30 | </div> |
31 | +</div> --> | ||
32 | + | ||
33 | +<div class="bg-image"></div> | ||
34 | + | ||
35 | +<div class="container" id="noosfero-profile"> | ||
36 | + <div class="col-sm-2"> | ||
37 | + <noosfero-profile-image [profile]="vm.profile" class="img-responsive center-block" data-pin-nopin="true"></noosfero-profile-image> | ||
38 | + <div class="social-links"> | ||
39 | + <ul> | ||
40 | + <li>Facebook</li> | ||
41 | + <li>Linkdin</li> | ||
42 | + </ul> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | + <div class="col-sm-10"> | ||
46 | + <h3>{{ vm.profile.name }}</h3> | ||
47 | + <div ng-switch="description"> | ||
48 | + <p ng-if="vm.profile.additional_data['description']"> | ||
49 | + {{ 'profile.person.description' | translate }}: {{ vm.profile.additional_data['description'] }} | ||
50 | + </p> | ||
51 | + <p class="pull-left">www.noosfero.gov.br/<strong>{{ vm.profile.identifier }}</strong></p> | ||
52 | + <div class="pull-right info-contato"> | ||
53 | + <button ng-click="vm.toggleInformation()" class="btn btn-sm">{{ 'profile.person.contact_info' | translate }}</button> | ||
54 | + <div clas="profile-contact" ng-show="vm.showInformation"> | ||
55 | + <p class="email" ng-if="vm.profile.additional_data['contact_email']">Email: {{ vm.profile.additional_data['contact_email'] }}</p> | ||
56 | + <p class="phone" ng-if="vm.profile.additional_data['contact_phone']"> | ||
57 | + {{ 'profile.person.contact_phone' | translate }}: {{ vm.profile.additional_data['contact_phone'] }} | ||
58 | + </p> | ||
59 | + <p class="phone" ng-if="(!vm.profile.additional_data['contact_phone'] && !vm.profile.additional_data['contact_email'])"> | ||
60 | + {{ 'profile.person.no_contact_info' | translate }} | ||
61 | + </p> | ||
62 | + </div> | ||
63 | + </div> | ||
64 | + </div> | ||
30 | </div> | 65 | </div> |
src/app/profile/profile.component.ts
@@ -6,22 +6,22 @@ import {CmsComponent} from '../article/cms/cms.component'; | @@ -6,22 +6,22 @@ import {CmsComponent} from '../article/cms/cms.component'; | ||
6 | import {ContentViewerComponent} from "../article/content-viewer/content-viewer.component"; | 6 | import {ContentViewerComponent} from "../article/content-viewer/content-viewer.component"; |
7 | import {ContentViewerActionsComponent} from "../article/content-viewer/content-viewer-actions.component"; | 7 | import {ContentViewerActionsComponent} from "../article/content-viewer/content-viewer-actions.component"; |
8 | import {ActivitiesComponent} from "./activities/activities.component"; | 8 | import {ActivitiesComponent} from "./activities/activities.component"; |
9 | +import {ActivityComponent} from "./activities/activity/activity.component"; | ||
9 | import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service"; | 10 | import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service"; |
10 | import {NotificationService} from "../shared/services/notification.service"; | 11 | import {NotificationService} from "../shared/services/notification.service"; |
11 | import {MyProfileComponent} from "./myprofile.component"; | 12 | import {MyProfileComponent} from "./myprofile.component"; |
12 | import {ProfileActionsComponent} from "./profile-actions.component"; | 13 | import {ProfileActionsComponent} from "./profile-actions.component"; |
13 | -import {ProfileToolbarComponent} from "./profile-toolbar.component"; | 14 | +import {ConfigBarComponent} from "./config-bar.component"; |
14 | /** | 15 | /** |
15 | * @ngdoc controller | 16 | * @ngdoc controller |
16 | - * @name profile.Profile | ||
17 | - * @description | 17 | + * @name profile.Profile * @description |
18 | * This is the profile controller. It provide routes to supported Noosfero Profiles. | 18 | * This is the profile controller. It provide routes to supported Noosfero Profiles. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | @Component({ | 21 | @Component({ |
22 | selector: 'profile', | 22 | selector: 'profile', |
23 | templateUrl: "app/profile/profile.html", | 23 | templateUrl: "app/profile/profile.html", |
24 | - directives: [ActivitiesComponent], | 24 | + directives: [ActivityComponent], |
25 | providers: [ | 25 | providers: [ |
26 | provide('profileService', { useClass: ProfileService }), | 26 | provide('profileService', { useClass: ProfileService }), |
27 | provide('notificationService', { useClass: NotificationService }) | 27 | provide('notificationService', { useClass: NotificationService }) |
@@ -33,19 +33,19 @@ import {ProfileToolbarComponent} from "./profile-toolbar.component"; | @@ -33,19 +33,19 @@ import {ProfileToolbarComponent} from "./profile-toolbar.component"; | ||
33 | url: "^/profile/:profile", | 33 | url: "^/profile/:profile", |
34 | component: ProfileInfoComponent, | 34 | component: ProfileInfoComponent, |
35 | views: { | 35 | views: { |
36 | - "mainBlockContent": { | ||
37 | - templateUrl: "app/profile/info/profile-info.html", | ||
38 | - controller: ProfileInfoComponent, | ||
39 | - controllerAs: "vm" | ||
40 | - }, | ||
41 | "actions@main": { | 36 | "actions@main": { |
42 | templateUrl: "app/profile/navbar-actions.html", | 37 | templateUrl: "app/profile/navbar-actions.html", |
43 | controller: ProfileActionsComponent, | 38 | controller: ProfileActionsComponent, |
44 | controllerAs: "vm" | 39 | controllerAs: "vm" |
45 | }, | 40 | }, |
46 | "toolbar@main": { | 41 | "toolbar@main": { |
47 | - templateUrl: "app/profile/toolbar.html", | ||
48 | - controller: ProfileToolbarComponent, | 42 | + templateUrl: "app/profile/configbar.html", |
43 | + controller: ConfigBarComponent, | ||
44 | + controllerAs: "vm" | ||
45 | + }, | ||
46 | + "mainBlockContent": { | ||
47 | + templateUrl: "app/profile/activities/activities.html", | ||
48 | + controller: ProfileInfoComponent, | ||
49 | controllerAs: "vm" | 49 | controllerAs: "vm" |
50 | } | 50 | } |
51 | } | 51 | } |
@@ -61,8 +61,8 @@ import {ProfileToolbarComponent} from "./profile-toolbar.component"; | @@ -61,8 +61,8 @@ import {ProfileToolbarComponent} from "./profile-toolbar.component"; | ||
61 | controllerAs: "vm" | 61 | controllerAs: "vm" |
62 | }, | 62 | }, |
63 | "toolbar@main": { | 63 | "toolbar@main": { |
64 | - templateUrl: "app/profile/toolbar.html", | ||
65 | - controller: ProfileToolbarComponent, | 64 | + templateUrl: "app/profile/configbar.html", |
65 | + controller: ConfigBarComponent, | ||
66 | controllerAs: "vm" | 66 | controllerAs: "vm" |
67 | } | 67 | } |
68 | } | 68 | } |
@@ -118,8 +118,8 @@ import {ProfileToolbarComponent} from "./profile-toolbar.component"; | @@ -118,8 +118,8 @@ import {ProfileToolbarComponent} from "./profile-toolbar.component"; | ||
118 | controllerAs: "vm" | 118 | controllerAs: "vm" |
119 | }, | 119 | }, |
120 | "toolbar@main": { | 120 | "toolbar@main": { |
121 | - templateUrl: "app/profile/toolbar.html", | ||
122 | - controller: ProfileToolbarComponent, | 121 | + templateUrl: "app/profile/configbar.html", |
122 | + controller: ConfigBarComponent, | ||
123 | controllerAs: "vm" | 123 | controllerAs: "vm" |
124 | } | 124 | } |
125 | } | 125 | } |
@@ -142,4 +142,6 @@ export class ProfileComponent { | @@ -142,4 +142,6 @@ export class ProfileComponent { | ||
142 | notificationService.error({ message: "notification.profile.not_found" }); | 142 | notificationService.error({ message: "notification.profile.not_found" }); |
143 | }); | 143 | }); |
144 | } | 144 | } |
145 | + | ||
146 | + | ||
145 | } | 147 | } |
src/app/profile/profile.html
@@ -4,10 +4,14 @@ | @@ -4,10 +4,14 @@ | ||
4 | [attribute]="'custom_header'" | 4 | [attribute]="'custom_header'" |
5 | [profile]="vm.profile"> | 5 | [profile]="vm.profile"> |
6 | </custom-content> | 6 | </custom-content> |
7 | - <noosfero-boxes ng-if="vm.boxes" | ||
8 | - [layout]="vm.profile.layout_template" | ||
9 | - [boxes]="vm.boxes" | ||
10 | - [owner]="vm.profile" class="row"> | ||
11 | - </noosfero-boxes> | 7 | + <div class="row" ui-view="profile-info"></div> |
8 | + | ||
9 | + <div class="wrapper-container"> | ||
10 | + <noosfero-boxes ng-if="vm.boxes" | ||
11 | + [layout]="vm.profile.layout_template" | ||
12 | + [boxes]="vm.boxes" | ||
13 | + [owner]="vm.profile" class="row"> | ||
14 | + </noosfero-boxes> | ||
15 | + </div> | ||
12 | <custom-content class="profile-footer" [label]="'profile.custom_footer.label'" [attribute]="'custom_footer'" [profile]="vm.profile"></custom-content> | 16 | <custom-content class="profile-footer" [label]="'profile.custom_footer.label'" [attribute]="'custom_footer'" [profile]="vm.profile"></custom-content> |
13 | </div> | 17 | </div> |
src/app/profile/profile.scss
1 | + | ||
2 | +@mixin padding-sides { | ||
3 | + padding-right: 15px; | ||
4 | + padding-left: 15px; | ||
5 | +} | ||
6 | + | ||
7 | +@mixin profile-img { | ||
8 | + text-align: center; | ||
9 | + margin: 10px; | ||
10 | + border: 1px solid #eee; | ||
11 | +} | ||
12 | + | ||
13 | +@media (min-width: 768px) { | ||
14 | + .container {max-width: 980px;} | ||
15 | +} | ||
16 | + | ||
1 | .profile-container { | 17 | .profile-container { |
2 | @extend .container-fluid; | 18 | @extend .container-fluid; |
3 | - padding: 0 1%; | ||
4 | - @media (max-width: 978px) { | ||
5 | - padding: 0 2%; | 19 | + margin-top: -$wrapper-padding-top; |
20 | + margin-left: -$wrapper-padding-left; | ||
21 | + margin-bottom: -$wrapper-padding-bottom; | ||
22 | + margin-right: -$wrapper-padding-right; | ||
23 | + @media (max-width: 978px) {padding: 0 2%;} | ||
24 | +} | ||
25 | + | ||
26 | +.wrapper-container { | ||
27 | + margin: auto; | ||
28 | + max-width: 980px; | ||
29 | +} | ||
30 | + | ||
31 | +.dropdown-menu { | ||
32 | + >li { | ||
33 | + margin:5px 0; | ||
34 | + >a { | ||
35 | + padding:3px 10px 3px 0 !important; | ||
36 | + &:hover {background-color:transparent !important;} | ||
37 | + } | ||
6 | } | 38 | } |
7 | } | 39 | } |
8 | 40 | ||
9 | -#profile-left { | ||
10 | - text-align: center; | ||
11 | - margin-top: 15px; | 41 | +.bg-image { |
42 | + background-color:#eee; | ||
43 | + height: 260px; | ||
44 | +} | ||
45 | + | ||
46 | +.social-links { | ||
47 | + ul { | ||
48 | + list-style:none; | ||
49 | + text-align:center; | ||
50 | + padding:0; | ||
51 | + margin:0; | ||
52 | + } | ||
53 | +} | ||
54 | + | ||
55 | +#noosfero-profile { | ||
56 | + background:#fff; | ||
57 | + margin: -200px auto auto; | ||
58 | + z-index:9999; | ||
59 | + left:0; | ||
60 | + right:0; | ||
61 | + border:1px solid #eee; | ||
62 | + padding:20px 0; | ||
63 | + font-size: 14px; | ||
64 | + | ||
65 | + img, | ||
66 | + i {@include profile-img;} | ||
67 | + | ||
68 | + .col-sm-2 {text-align: center;} | ||
69 | + | ||
70 | + h3 {margin-top: 16px;} | ||
71 | + | ||
72 | + .btn { | ||
73 | + font-size: 12px; | ||
74 | + padding: 5px 10px; | ||
75 | + } | ||
76 | + | ||
77 | + .profile-contact { | ||
78 | + padding-top: 10px; | ||
79 | + p {margin: 0px;} | ||
80 | + } | ||
12 | } | 81 | } |
src/app/shared/components/interfaces.ts
1 | - | ||
2 | - | ||
3 | export interface IComponentWithPermissions { | 1 | export interface IComponentWithPermissions { |
4 | permissions: () => string[]; | 2 | permissions: () => string[]; |
5 | -} | ||
6 | \ No newline at end of file | 3 | \ No newline at end of file |
4 | +} | ||
5 | + | ||
6 | +export interface IModalComponent { | ||
7 | + $uibModal: ng.ui.bootstrap.IModalService; | ||
8 | + modalInstance: ng.ui.bootstrap.IModalServiceInstance; | ||
9 | +} |
@@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
1 | +import { OpaqueToken } from 'ng-forward'; | ||
2 | +import { EventsHubService, EventsHubKnownEventNames } from './events-hub.service'; | ||
3 | + | ||
4 | + | ||
5 | +describe("EventsHubService", () => { | ||
6 | + let eventsHubService: EventsHubService; | ||
7 | + let event1 = 'Event 1'; | ||
8 | + let eventsHubKnownEventNames = <EventsHubKnownEventNames>{ getNames: () => { return [ event1]; }}; | ||
9 | + it("emits events for the known events", (done) => { | ||
10 | + | ||
11 | + let eventListener = () => { | ||
12 | + }; | ||
13 | + // creates the events hub service which known the event "Event1" | ||
14 | + eventsHubService = new EventsHubService(eventsHubKnownEventNames); | ||
15 | + // subscribe to the event passing the done Function as the eventListener | ||
16 | + // if the event emits works the done function is called and the | ||
17 | + // test will pass | ||
18 | + eventsHubService.subscribeToEvent<any>(event1, done); | ||
19 | + // emits the event | ||
20 | + eventsHubService.emitEvent(event1, null); | ||
21 | + }); | ||
22 | + | ||
23 | + it("throws error when trying to emit an unknow event", () => { | ||
24 | + let eventListener = () => { | ||
25 | + }; | ||
26 | + // creates the events hub service which known the event "Event1" | ||
27 | + eventsHubService = new EventsHubService(eventsHubKnownEventNames); | ||
28 | + | ||
29 | + // emits the event | ||
30 | + expect( | ||
31 | + () => { eventsHubService.emitEvent('NotKnownEvent', null); } | ||
32 | + ).toThrowError('Unknown event named NotKnownEvent'); | ||
33 | + }); | ||
34 | + | ||
35 | + it("throws error when trying to subscribe to an unknow event", () => { | ||
36 | + let eventListener = () => { | ||
37 | + }; | ||
38 | + // creates the events hub service which known the event "Event1" | ||
39 | + eventsHubService = new EventsHubService(eventsHubKnownEventNames); | ||
40 | + | ||
41 | + // emits the event | ||
42 | + expect( | ||
43 | + () => { eventsHubService.subscribeToEvent<void>('NotKnownEvent', () => {}); } | ||
44 | + ).toThrowError('Unknown event named NotKnownEvent'); | ||
45 | + }); | ||
46 | +}); | ||
0 | \ No newline at end of file | 47 | \ No newline at end of file |
@@ -0,0 +1,56 @@ | @@ -0,0 +1,56 @@ | ||
1 | +import { Injectable, Inject, OpaqueToken, EventEmitter } from 'ng-forward'; | ||
2 | + | ||
3 | +export const EVENTS_HUB_KNOW_EVENT_NAMES = new OpaqueToken('EVENTS_HUB_KNOW_EVENT_NAMES'); | ||
4 | + | ||
5 | +export interface EventsHubKnownEventNames { | ||
6 | + getNames(): string[]; | ||
7 | +} | ||
8 | + | ||
9 | +function isEventsHubKnownEventNames(object: any): object is EventsHubKnownEventNames { | ||
10 | + return 'getNames' in object; | ||
11 | +} | ||
12 | + | ||
13 | +@Injectable() | ||
14 | +@Inject(EVENTS_HUB_KNOW_EVENT_NAMES) | ||
15 | +export class EventsHubService { | ||
16 | + | ||
17 | + private emitters: Map<string, EventEmitter<any>>; | ||
18 | + private knownEvents: string[] = []; | ||
19 | + | ||
20 | + constructor(private eventsHubKnownEventNames: EventsHubKnownEventNames | string[]) { | ||
21 | + if (isEventsHubKnownEventNames(eventsHubKnownEventNames)) { | ||
22 | + this.knownEvents = eventsHubKnownEventNames.getNames(); | ||
23 | + } else if (Array.isArray(eventsHubKnownEventNames)) { | ||
24 | + this.knownEvents = eventsHubKnownEventNames; | ||
25 | + } | ||
26 | + | ||
27 | + this.emitters = new Map<string, EventEmitter<any>>(); | ||
28 | + this.setupEmitters(); | ||
29 | + } | ||
30 | + | ||
31 | + emitEvent(eventType: string, payload?: any) { | ||
32 | + this.checkKnownEvent(eventType); | ||
33 | + let event = this.emitters.get(eventType); | ||
34 | + if ( event ) this.emitters.get(eventType).next(payload); | ||
35 | + } | ||
36 | + | ||
37 | + subscribeToEvent<T>(eventType: string, generatorOrNext?: ((p?: T) => void), error?: any, complete?: any) { | ||
38 | + this.checkKnownEvent(eventType); | ||
39 | + let event = this.emitters.get(eventType); | ||
40 | + if (event) event.subscribe(generatorOrNext, error, complete); | ||
41 | + } | ||
42 | + | ||
43 | + private setupEmitters() { | ||
44 | + for (let i: number = 0; i < this.knownEvents.length; i++) { | ||
45 | + this.emitters.set(this.knownEvents[i], new EventEmitter<any>()); | ||
46 | + } | ||
47 | + } | ||
48 | + | ||
49 | + private checkKnownEvent(eventType: string) { | ||
50 | + if (!this.emitters.has(eventType)) { | ||
51 | + throw new Error('Unknown event named ' + eventType.toString()); | ||
52 | + } | ||
53 | + } | ||
54 | + | ||
55 | + | ||
56 | +} | ||
0 | \ No newline at end of file | 57 | \ No newline at end of file |
src/languages/en.json
1 | { | 1 | { |
2 | "noosfero.name" : "Noosfero", | 2 | "noosfero.name" : "Noosfero", |
3 | "blocks.profile_image.control_panel": "Control Panel", | 3 | "blocks.profile_image.control_panel": "Control Panel", |
4 | + "blocks.profile_image.join": "Join community", | ||
5 | + "blocks.profile_image.leave": "Leave community", | ||
6 | + "blocks.profile_image.join.moderation.title": "Good job!", | ||
7 | + "blocks.profile_image.join.moderation.message": "Your membership is waiting for approval", | ||
4 | "navbar.profile": "Profile", | 8 | "navbar.profile": "Profile", |
5 | "navbar.settings": "Settings", | 9 | "navbar.settings": "Settings", |
6 | "navbar.logout": "Log Out", | 10 | "navbar.logout": "Log Out", |
7 | "navbar.login": "Login", | 11 | "navbar.login": "Login", |
8 | "navbar.toggle_menu": "Toggle navigation", | 12 | "navbar.toggle_menu": "Toggle navigation", |
13 | + "configbar.label": "Configuration", | ||
14 | + "configbar.section.layout": "Layout", | ||
9 | "language.all": "All languages", | 15 | "language.all": "All languages", |
10 | "language.en": "English", | 16 | "language.en": "English", |
11 | "language.pt": "Portuguese", | 17 | "language.pt": "Portuguese", |
@@ -17,8 +23,13 @@ | @@ -17,8 +23,13 @@ | ||
17 | "profile.others_info": "Others", | 23 | "profile.others_info": "Others", |
18 | "profile.community.title": "Community", | 24 | "profile.community.title": "Community", |
19 | "profile.person.title": "Person", | 25 | "profile.person.title": "Person", |
26 | + "profile.person.description": "Description", | ||
27 | + "profile.person.contact_info": "Contact Informations", | ||
28 | + "profile.person.contact_phone": "Phone", | ||
29 | + "profile.person.no_contact_info": "No contact informations", | ||
20 | "activities.title": "Activities", | 30 | "activities.title": "Activities", |
21 | "activities.create_article.description": "has published on", | 31 | "activities.create_article.description": "has published on", |
32 | + "activities.scrap.description": "wrote in its timeline", | ||
22 | "activities.add_member_in_community.description": "has joined the community", | 33 | "activities.add_member_in_community.description": "has joined the community", |
23 | "activities.new_friendship.description": "has made {friends, plural, one{one new friend} other{# new friends}}:", | 34 | "activities.new_friendship.description": "has made {friends, plural, one{one new friend} other{# new friends}}:", |
24 | "auth.title": "Great to have you back!", | 35 | "auth.title": "Great to have you back!", |
@@ -26,6 +37,7 @@ | @@ -26,6 +37,7 @@ | ||
26 | "auth.form.password": "Password", | 37 | "auth.form.password": "Password", |
27 | "auth.form.keepLoggedIn": "Keep me logged in", | 38 | "auth.form.keepLoggedIn": "Keep me logged in", |
28 | "auth.form.login_button": "Login", | 39 | "auth.form.login_button": "Login", |
40 | + "auth.createAccount": "Create account", | ||
29 | "navbar.content_viewer_actions.new_item": "New Item", | 41 | "navbar.content_viewer_actions.new_item": "New Item", |
30 | "navbar.profile_actions.new_item": "New Item", | 42 | "navbar.profile_actions.new_item": "New Item", |
31 | "navbar.content_viewer_actions.new_post": "New Post", | 43 | "navbar.content_viewer_actions.new_post": "New Post", |
@@ -77,9 +89,7 @@ | @@ -77,9 +89,7 @@ | ||
77 | "custom_content.title": "Edit content", | 89 | "custom_content.title": "Edit content", |
78 | "profile.custom_header.label": "Header", | 90 | "profile.custom_header.label": "Header", |
79 | "profile.custom_footer.label": "Footer", | 91 | "profile.custom_footer.label": "Footer", |
80 | - "designMode.label": "In Design", | ||
81 | - "designMode.toggle.ON": "ON", | ||
82 | - "designMode.toggle.OFF": "OFF", | 92 | + "designMode.label": "Design mode", |
83 | "search.results.summary": "{results, plural, one{result} other{# results}}", | 93 | "search.results.summary": "{results, plural, one{result} other{# results}}", |
84 | "search.results.query.label": "Search therm:", | 94 | "search.results.query.label": "Search therm:", |
85 | "search.label": "Search", | 95 | "search.label": "Search", |
@@ -97,5 +107,26 @@ | @@ -97,5 +107,26 @@ | ||
97 | "block.edition.display_user.all": "All users", | 107 | "block.edition.display_user.all": "All users", |
98 | "block.edition.display_user.logged": "Logged", | 108 | "block.edition.display_user.logged": "Logged", |
99 | "block.edition.display_user.not_logged": "Not logged", | 109 | "block.edition.display_user.not_logged": "Not logged", |
100 | - "block.edition.language.label": "Show for:" | 110 | + "block.edition.language.label": "Show for:", |
111 | + "activities.event.description": "Event on", | ||
112 | + "time.at": "at", | ||
113 | + "date.on": "On", | ||
114 | + "account.register.welcomeMessageTitle": "Nice to have you there!", | ||
115 | + "account.register.fullNameLabel": "Full name", | ||
116 | + "account.register.usernameLabel": "Username", | ||
117 | + "account.register.emailLabel": "Email", | ||
118 | + "account.register.passwordLabel": "Password", | ||
119 | + "account.register.passwordConfirmationLabel": "Password confirmation", | ||
120 | + "account.register.accountCreatingMessage": "By creating an account, you are agreeing with the ", | ||
121 | + "account.register.signupMessage": "Register", | ||
122 | + "account.register.haveAccountMessage": "Already have an account?", | ||
123 | + "account.register.termsOfUseMessage": "terms of use", | ||
124 | + "account.register.success.title": "Good job!", | ||
125 | + "account.register.success.message": "Account created!", | ||
126 | + "account.register.passwordConfirmation.failed": "Wrong password confirmation", | ||
127 | + "messages.invalid.required": "This field is required", | ||
128 | + "messages.invalid.maxlength": "This field is too long", | ||
129 | + "messages.invalid.minlength": "This field is too short", | ||
130 | + "messages.invalid.email": "This needs to be a valid email", | ||
131 | + "messages.invalid.passwordMatch": "Your passwords did not match" | ||
101 | } | 132 | } |
@@ -0,0 +1,4 @@ | @@ -0,0 +1,4 @@ | ||
1 | +<li ng-message="required" translate="messages.invalid.required"></li> | ||
2 | +<li ng-message="minlength" translate="messages.invalid.minlength"></li> | ||
3 | +<li ng-message="maxlength" translate="messages.invalid.maxlength"></li> | ||
4 | +<li ng-message="email" translate="messages.invalid.email"></li> |
src/languages/pt.json
1 | { | 1 | { |
2 | "noosfero.name" : "Noosfero", | 2 | "noosfero.name" : "Noosfero", |
3 | "blocks.profile_image.control_panel": "Painel de Controle", | 3 | "blocks.profile_image.control_panel": "Painel de Controle", |
4 | + "blocks.profile_image.join": "Entrar na comunidade", | ||
5 | + "blocks.profile_image.leave": "Sair da comunidade", | ||
6 | + "blocks.profile_image.join.moderation.title": "Bom trabalho!", | ||
7 | + "blocks.profile_image.join.moderation.message": "Sua participação está pendente de aprovação", | ||
4 | "navbar.profile": "Perfil", | 8 | "navbar.profile": "Perfil", |
5 | "navbar.settings": "Configurações", | 9 | "navbar.settings": "Configurações", |
6 | "navbar.logout": "Sair", | 10 | "navbar.logout": "Sair", |
7 | "navbar.login": "Login", | 11 | "navbar.login": "Login", |
8 | "navbar.toggle_menu": "Abrir Menu", | 12 | "navbar.toggle_menu": "Abrir Menu", |
13 | + "configbar.label": "Configurações", | ||
14 | + "configbar.section.layout": "Visual", | ||
9 | "language.all": "Todos os idiomas", | 15 | "language.all": "Todos os idiomas", |
10 | "language.en": "Inglês", | 16 | "language.en": "Inglês", |
11 | "language.pt": "Português", | 17 | "language.pt": "Português", |
@@ -17,8 +23,13 @@ | @@ -17,8 +23,13 @@ | ||
17 | "profile.others_info": "Outras informações", | 23 | "profile.others_info": "Outras informações", |
18 | "profile.community.title": "Comunidade", | 24 | "profile.community.title": "Comunidade", |
19 | "profile.person.title": "Pessoa", | 25 | "profile.person.title": "Pessoa", |
26 | + "profile.person.description": "Descrição", | ||
27 | + "profile.person.contact_info": "Informações de Contato", | ||
28 | + "profile.person.contact_phone": "Telefone", | ||
29 | + "profile.person.no_contact_info": "Sem informações de contato", | ||
20 | "activities.title": "Atividades", | 30 | "activities.title": "Atividades", |
21 | "activities.create_article.description": "publicou em", | 31 | "activities.create_article.description": "publicou em", |
32 | + "activities.scrap.description": "escreveu em sua linha do tempo", | ||
22 | "activities.add_member_in_community.description": "entrou na comunidade", | 33 | "activities.add_member_in_community.description": "entrou na comunidade", |
23 | "activities.new_friendship.description": "fez {friends, plural, one{um novo amigo} other{# novos amigos}}:", | 34 | "activities.new_friendship.description": "fez {friends, plural, one{um novo amigo} other{# novos amigos}}:", |
24 | "auth.title": "Legal ter você de volta!", | 35 | "auth.title": "Legal ter você de volta!", |
@@ -26,10 +37,11 @@ | @@ -26,10 +37,11 @@ | ||
26 | "auth.form.password": "Senha", | 37 | "auth.form.password": "Senha", |
27 | "auth.form.keepLoggedIn": "Continuar logado", | 38 | "auth.form.keepLoggedIn": "Continuar logado", |
28 | "auth.form.login_button": "Login", | 39 | "auth.form.login_button": "Login", |
40 | + "auth.createAccount": "Criar conta", | ||
29 | "navbar.content_viewer_actions.new_item": "Novo Item", | 41 | "navbar.content_viewer_actions.new_item": "Novo Item", |
30 | "navbar.profile_actions.new_item": "Novo Item", | 42 | "navbar.profile_actions.new_item": "Novo Item", |
31 | - "navbar.content_viewer_actions.new_post": "Novo Artigo", | ||
32 | - "navbar.content_viewer_actions.new_discussion": "Nova Discussão", | 43 | + "navbar.content_viewer_actions.new_post": "Novo Post", |
44 | + "navbar.content_viewer_actions.new_discussion": "Nova Consulta", | ||
33 | "navbar.profile_actions.new_discussion": "Nova Discussão", | 45 | "navbar.profile_actions.new_discussion": "Nova Discussão", |
34 | "notification.error.default.message": "Algo deu errado!", | 46 | "notification.error.default.message": "Algo deu errado!", |
35 | "notification.error.default.title": "Oops...", | 47 | "notification.error.default.title": "Oops...", |
@@ -77,9 +89,7 @@ | @@ -77,9 +89,7 @@ | ||
77 | "custom_content.title": "Editar conteúdo", | 89 | "custom_content.title": "Editar conteúdo", |
78 | "profile.custom_header.label": "Cabeçalho", | 90 | "profile.custom_header.label": "Cabeçalho", |
79 | "profile.custom_footer.label": "Rodapé", | 91 | "profile.custom_footer.label": "Rodapé", |
80 | - "designMode.label": "Modo de Edição", | ||
81 | - "designMode.toggle.ON": "Ligado", | ||
82 | - "designMode.toggle.OFF": "Desligado", | 92 | + "designMode.label": "Alterar design", |
83 | "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}", | 93 | "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}", |
84 | "search.results.query.label": "Termo da busca:", | 94 | "search.results.query.label": "Termo da busca:", |
85 | "search.label": "Pesquisar", | 95 | "search.label": "Pesquisar", |
@@ -97,5 +107,29 @@ | @@ -97,5 +107,29 @@ | ||
97 | "block.edition.display_user.all": "Todos os usuários", | 107 | "block.edition.display_user.all": "Todos os usuários", |
98 | "block.edition.display_user.logged": "Logados", | 108 | "block.edition.display_user.logged": "Logados", |
99 | "block.edition.display_user.not_logged": "Não logados", | 109 | "block.edition.display_user.not_logged": "Não logados", |
100 | - "block.edition.language.label": "Exibir para:" | 110 | + "block.edition.language.label": "Exibir para:", |
111 | + "activities.event.description": "Evento em", | ||
112 | + "time.at": "às", | ||
113 | + "date.on": "Em", | ||
114 | + "account.register.welcomeMessageTitle": "Ótimo ter você aqui!", | ||
115 | + "account.register.seeMoreMessage": "Saiba mais ", | ||
116 | + "account.register.informationsMessage": "informações", | ||
117 | + "account.register.fullNameLabel": "Nome completo", | ||
118 | + "account.register.lastNameLabel": "Sobrenome", | ||
119 | + "account.register.usernameLabel": "Nome de usuário", | ||
120 | + "account.register.emailLabel": "Email", | ||
121 | + "account.register.passwordLabel": "Senha", | ||
122 | + "account.register.passwordConfirmationLabel": "Confirmar senha", | ||
123 | + "account.register.accountCreatingMessage": "Ao criar uma conta, você está concordando com os ", | ||
124 | + "account.register.termsOfUseMessage": "termos de uso", | ||
125 | + "account.register.signupMessage": "Criar Conta", | ||
126 | + "account.register.haveAccountMessage": "Já possui uma conta?", | ||
127 | + "account.register.success.title": "Bom trabalho!", | ||
128 | + "account.register.success.message": "Conta criada com sucesso!", | ||
129 | + "account.register.passwordConfirmation.failed": "A confirmação de senha não corresponde à senha", | ||
130 | + "messages.invalid.required": "Campo obrigatório", | ||
131 | + "messages.invalid.maxlength": "O valor é muito longo", | ||
132 | + "messages.invalid.minlength": "O valor é muito curto", | ||
133 | + "messages.invalid.email": "Informe um email válido", | ||
134 | + "messages.invalid.passwordMatch": "As senhas não coincidem" | ||
101 | } | 135 | } |
src/lib/ng-noosfero-api/http/article.service.spec.ts
@@ -17,7 +17,6 @@ describe("Services", () => { | @@ -17,7 +17,6 @@ describe("Services", () => { | ||
17 | articleService = _ArticleService_; | 17 | articleService = _ArticleService_; |
18 | })); | 18 | })); |
19 | 19 | ||
20 | - | ||
21 | describe("Succesfull requests", () => { | 20 | describe("Succesfull requests", () => { |
22 | 21 | ||
23 | it("should remove article", (done) => { | 22 | it("should remove article", (done) => { |
@@ -92,6 +91,5 @@ describe("Services", () => { | @@ -92,6 +91,5 @@ describe("Services", () => { | ||
92 | }); | 91 | }); |
93 | }); | 92 | }); |
94 | 93 | ||
95 | - | ||
96 | }); | 94 | }); |
97 | }); | 95 | }); |
src/lib/ng-noosfero-api/http/profile.service.spec.ts
@@ -111,6 +111,56 @@ describe("Services", () => { | @@ -111,6 +111,56 @@ describe("Services", () => { | ||
111 | }); | 111 | }); |
112 | $httpBackend.flush(); | 112 | $httpBackend.flush(); |
113 | }); | 113 | }); |
114 | + | ||
115 | + it("should return the profile members", (done) => { | ||
116 | + let profileId = 1; | ||
117 | + $httpBackend.expectGET(`/api/v1/profiles/${profileId}/members`).respond(200, { people: [{ id: 2 }] }); | ||
118 | + profileService.getMembers(<any>{ id: profileId }).then((response: restangular.IResponse) => { | ||
119 | + expect(response.data.people).toEqual([{ id: 2 }]); | ||
120 | + done(); | ||
121 | + }); | ||
122 | + $httpBackend.flush(); | ||
123 | + }); | ||
124 | + | ||
125 | + it("should return true if the person is a profile member", (done) => { | ||
126 | + let profileId = 1; | ||
127 | + $httpBackend.expectGET(`/api/v1/profiles/${profileId}/members`).respond(200, { people: [{ id: 2 }] }); | ||
128 | + profileService.isMember(<any>{ id: 2 }, <any>{ id: profileId }).then((response: restangular.IResponse) => { | ||
129 | + expect(response).toEqual(true); | ||
130 | + done(); | ||
131 | + }); | ||
132 | + $httpBackend.flush(); | ||
133 | + }); | ||
134 | + | ||
135 | + it("should return false if the person is a profile member", (done) => { | ||
136 | + let profileId = 1; | ||
137 | + $httpBackend.expectGET(`/api/v1/profiles/${profileId}/members`).respond(200, { people: [] }); | ||
138 | + profileService.isMember(<any>{ id: 2 }, <any>{ id: profileId }).then((response: restangular.IResponse) => { | ||
139 | + expect(response).toEqual(false); | ||
140 | + done(); | ||
141 | + }); | ||
142 | + $httpBackend.flush(); | ||
143 | + }); | ||
144 | + | ||
145 | + it("should add member to profile", (done) => { | ||
146 | + let profileId = 1; | ||
147 | + $httpBackend.expectPOST(`/api/v1/profiles/${profileId}/members`).respond(200, { pending: false }); | ||
148 | + profileService.addMember(<any>{ id: 2 }, <any>{ id: profileId }).then((response: restangular.IResponse) => { | ||
149 | + expect(response.data.pending).toEqual(false); | ||
150 | + done(); | ||
151 | + }); | ||
152 | + $httpBackend.flush(); | ||
153 | + }); | ||
154 | + | ||
155 | + it("should remove member from profile", (done) => { | ||
156 | + let profileId = 1; | ||
157 | + $httpBackend.expectDELETE(`/api/v1/profiles/${profileId}/members`).respond(200, { person: { id: 2 } }); | ||
158 | + profileService.removeMember(<any>{ id: 2 }, <any>{ id: profileId }).then((response: restangular.IResponse) => { | ||
159 | + expect(response.data.person).toEqual({ id: 2 }); | ||
160 | + done(); | ||
161 | + }); | ||
162 | + $httpBackend.flush(); | ||
163 | + }); | ||
114 | }); | 164 | }); |
115 | 165 | ||
116 | 166 |
src/lib/ng-noosfero-api/http/profile.service.ts
@@ -64,4 +64,29 @@ export class ProfileService { | @@ -64,4 +64,29 @@ export class ProfileService { | ||
64 | let headers = { 'Content-Type': 'application/json' }; | 64 | let headers = { 'Content-Type': 'application/json' }; |
65 | return this.get(profile.id).customPOST({ profile: profile }, null, null, headers); | 65 | return this.get(profile.id).customPOST({ profile: profile }, null, null, headers); |
66 | } | 66 | } |
67 | + | ||
68 | + getMembers(profile: noosfero.Profile, params?: any) { | ||
69 | + let p = this.get(profile.id); | ||
70 | + return p.customGET('members', params); | ||
71 | + } | ||
72 | + | ||
73 | + isMember(person: noosfero.Person, profile: noosfero.Profile) { | ||
74 | + let deferred = this.$q.defer(); | ||
75 | + if (person) { | ||
76 | + this.getMembers(profile, { identifier: person.identifier }).then((result: any) => { | ||
77 | + deferred.resolve(result.data.people.length > 0); | ||
78 | + }); | ||
79 | + } else { | ||
80 | + deferred.resolve(false); | ||
81 | + } | ||
82 | + return deferred.promise; | ||
83 | + } | ||
84 | + | ||
85 | + addMember(person: noosfero.Person, profile: noosfero.Profile) { | ||
86 | + return this.get(profile.id).customPOST({}, "members", null, null); | ||
87 | + } | ||
88 | + | ||
89 | + removeMember(person: noosfero.Person, profile: noosfero.Profile) { | ||
90 | + return this.get(profile.id).customDELETE("members", null, null); | ||
91 | + } | ||
67 | } | 92 | } |
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +import { RegisterService } from "./register.service"; | ||
2 | + | ||
3 | +describe("Services", () => { | ||
4 | + | ||
5 | + describe("Register Service", () => { | ||
6 | + | ||
7 | + let $httpBackend: ng.IHttpBackendService; | ||
8 | + let registerService: RegisterService; | ||
9 | + let $rootScope: ng.IRootScopeService; | ||
10 | + let user: any = { | ||
11 | + id: 1, | ||
12 | + login: 'test', | ||
13 | + email: 'test@email.com' | ||
14 | + }; | ||
15 | + | ||
16 | + beforeEach(angular.mock.module("main", ($translateProvider: angular.translate.ITranslateProvider) => { | ||
17 | + $translateProvider.translations('en', {}); | ||
18 | + })); | ||
19 | + | ||
20 | + beforeEach(inject((_$httpBackend_: ng.IHttpBackendService, _RegisterService_: RegisterService, _$rootScope_: ng.IRootScopeService) => { | ||
21 | + $httpBackend = _$httpBackend_; | ||
22 | + registerService = _RegisterService_; | ||
23 | + $rootScope = _$rootScope_; | ||
24 | + })); | ||
25 | + | ||
26 | + describe("Succesfull requests", () => { | ||
27 | + | ||
28 | + it("should creaet a new account", (done) => { | ||
29 | + | ||
30 | + $httpBackend.expectPOST(`/api/v1/register?email=${user.email}&id=${user.id}&login=${user.login}`).respond(201, [{ login: "test" }]); | ||
31 | + registerService.createAccount(user).then((response: restangular.IResponse) => { | ||
32 | + expect(response.data[0].login).toEqual("test"); | ||
33 | + done(); | ||
34 | + }); | ||
35 | + $httpBackend.flush(); | ||
36 | + }); | ||
37 | + }); | ||
38 | + }); | ||
39 | +}); |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +import { Injectable, Inject } from "ng-forward"; | ||
2 | +import { RestangularService } from "./restangular_service"; | ||
3 | + | ||
4 | +@Injectable() | ||
5 | +@Inject("Restangular") | ||
6 | +export class RegisterService { | ||
7 | + constructor(private Restangular: restangular.IService) { | ||
8 | + this.Restangular = Restangular; | ||
9 | + } | ||
10 | + | ||
11 | + createAccount(user: noosfero.User): ng.IPromise<noosfero.RestResult<noosfero.User>> { | ||
12 | + return this.Restangular.all("").customPOST(user, "register", user); | ||
13 | + } | ||
14 | +} |
src/lib/ng-noosfero-api/http/restangular_service.ts
@@ -80,14 +80,16 @@ export abstract class RestangularService<T extends noosfero.RestModel> { | @@ -80,14 +80,16 @@ export abstract class RestangularService<T extends noosfero.RestModel> { | ||
80 | } | 80 | } |
81 | return { | 81 | return { |
82 | data: (response.data[dataKey] || response.data), | 82 | data: (response.data[dataKey] || response.data), |
83 | - headers: response.headers | 83 | + headers: response.headers, |
84 | + status: response.status | ||
84 | }; | 85 | }; |
85 | }; | 86 | }; |
86 | 87 | ||
87 | protected buildResult(response: restangular.IResponse): noosfero.RestResult<T> { | 88 | protected buildResult(response: restangular.IResponse): noosfero.RestResult<T> { |
88 | return { | 89 | return { |
89 | data: response.data, | 90 | data: response.data, |
90 | - headers: response.headers | 91 | + headers: response.headers, |
92 | + status: response.status | ||
91 | }; | 93 | }; |
92 | }; | 94 | }; |
93 | /** | 95 | /** |
src/lib/ng-noosfero-api/interfaces/environment.ts
@@ -5,7 +5,7 @@ namespace noosfero { | @@ -5,7 +5,7 @@ namespace noosfero { | ||
5 | * @name noofero.Environment | 5 | * @name noofero.Environment |
6 | * @description | 6 | * @description |
7 | * A representation of a Noosfero Environment. | 7 | * A representation of a Noosfero Environment. |
8 | - */ | 8 | + */ |
9 | export interface Environment extends RestModel { | 9 | export interface Environment extends RestModel { |
10 | /** | 10 | /** |
11 | * @ngdoc property | 11 | * @ngdoc property |
@@ -23,6 +23,21 @@ namespace noosfero { | @@ -23,6 +23,21 @@ namespace noosfero { | ||
23 | * @returns {string} The Environment layout (e.g. default, rightbar) | 23 | * @returns {string} The Environment layout (e.g. default, rightbar) |
24 | */ | 24 | */ |
25 | layout_template: string; | 25 | layout_template: string; |
26 | + | ||
27 | + /** | ||
28 | + * @ngdoc property | ||
29 | + * @name signup_intro | ||
30 | + * @propertyOf noofero.Environment | ||
31 | + * @returns {string} The Environment signup introduction HTML (e.g. Welcome to Noosfero...!!) | ||
32 | + */ | ||
33 | + signup_intro: string; | ||
34 | + | ||
35 | + /** | ||
36 | + * @ngdoc property | ||
37 | + * @name host | ||
38 | + * @propertyOf noofero.Environment | ||
39 | + * @returns {string} The Environment default domain address with 'http://' prefix (e.g. http://localhost) | ||
40 | + */ | ||
41 | + host: string; | ||
26 | } | 42 | } |
27 | } | 43 | } |
28 | - |
src/lib/ng-noosfero-api/interfaces/rest_result.ts
@@ -3,5 +3,6 @@ namespace noosfero { | @@ -3,5 +3,6 @@ namespace noosfero { | ||
3 | export interface RestResult<T> { | 3 | export interface RestResult<T> { |
4 | data: T; | 4 | data: T; |
5 | headers: Function; | 5 | headers: Function; |
6 | + status: Number; | ||
6 | } | 7 | } |
7 | -} | ||
8 | \ No newline at end of file | 8 | \ No newline at end of file |
9 | +} |
src/spec/mocks.ts
@@ -40,6 +40,11 @@ export var mocks: any = { | @@ -40,6 +40,11 @@ export var mocks: any = { | ||
40 | return this.modalInstance; | 40 | return this.modalInstance; |
41 | } | 41 | } |
42 | }, | 42 | }, |
43 | + registerService: { | ||
44 | + createAccount: (user: noosfero.User) => { | ||
45 | + return Promise.resolve({ status: 201 }); | ||
46 | + } | ||
47 | + }, | ||
43 | authService: { | 48 | authService: { |
44 | loginSuccess: { | 49 | loginSuccess: { |
45 | event: Function, | 50 | event: Function, |
@@ -145,6 +150,15 @@ export var mocks: any = { | @@ -145,6 +150,15 @@ export var mocks: any = { | ||
145 | return mocks.promiseResultTemplate({ | 150 | return mocks.promiseResultTemplate({ |
146 | people: {} | 151 | people: {} |
147 | }); | 152 | }); |
153 | + }, | ||
154 | + getCurrentEnvironment: (): any => { | ||
155 | + return { | ||
156 | + id: 1, | ||
157 | + settings: {}, | ||
158 | + layout_template: '', | ||
159 | + signup_intro: 'Welcome to Noosfero', | ||
160 | + host: 'http://localhost' | ||
161 | + }; | ||
148 | } | 162 | } |
149 | }, | 163 | }, |
150 | profileService: { | 164 | profileService: { |
@@ -240,6 +254,7 @@ export var mocks: any = { | @@ -240,6 +254,7 @@ export var mocks: any = { | ||
240 | }, | 254 | }, |
241 | notificationService: { | 255 | notificationService: { |
242 | success: () => { }, | 256 | success: () => { }, |
243 | - confirmation: () => { } | 257 | + confirmation: () => { }, |
258 | + error: () => { } | ||
244 | } | 259 | } |
245 | }; | 260 | }; |
themes/angular-participa-consulta/app/layout/scss/skins/_yellow.scss
1 | +$yellow-hover: #f5b025; | ||
2 | +$yellow-base: #f9c404; | ||
3 | + | ||
1 | .skin-yellow { | 4 | .skin-yellow { |
2 | @extend %skin-base; | 5 | @extend %skin-base; |
3 | 6 | ||
@@ -49,7 +52,7 @@ | @@ -49,7 +52,7 @@ | ||
49 | 52 | ||
50 | .container-fluid .navbar-header .navbar-toggle { | 53 | .container-fluid .navbar-header .navbar-toggle { |
51 | &:hover, &:focus { | 54 | &:hover, &:focus { |
52 | - background-color: #f5b025; | 55 | + background-color: $yellow-hover; |
53 | } | 56 | } |
54 | } | 57 | } |
55 | 58 | ||
@@ -61,4 +64,26 @@ | @@ -61,4 +64,26 @@ | ||
61 | } | 64 | } |
62 | } | 65 | } |
63 | 66 | ||
67 | + #config-tool { | ||
68 | + | ||
69 | + #config-tool-cog { | ||
70 | + color: $yellow-hover; | ||
71 | + } | ||
72 | + | ||
73 | + #config-tool-options { | ||
74 | + h4 { | ||
75 | + color: #2c3e50; | ||
76 | + font-weight: bold; | ||
77 | + } | ||
78 | + } | ||
79 | + | ||
80 | + &.closed { | ||
81 | + #config-tool-cog { | ||
82 | + &:hover { | ||
83 | + background-color: $yellow-hover; | ||
84 | + } | ||
85 | + } | ||
86 | + } | ||
87 | + } | ||
88 | + | ||
64 | } | 89 | } |
typings.json
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | "angular-mocks": "github:DefinitelyTyped/DefinitelyTyped/angularjs/angular-mocks.d.ts", | 8 | "angular-mocks": "github:DefinitelyTyped/DefinitelyTyped/angularjs/angular-mocks.d.ts", |
9 | "angular-translate": "github:DefinitelyTyped/DefinitelyTyped/angular-translate/angular-translate.d.ts#19850bf86c876e0c2544842114878ece4664941a", | 9 | "angular-translate": "github:DefinitelyTyped/DefinitelyTyped/angular-translate/angular-translate.d.ts#19850bf86c876e0c2544842114878ece4664941a", |
10 | "angular-ui-router": "github:DefinitelyTyped/DefinitelyTyped/angular-ui-router/angular-ui-router.d.ts#655f8c1bf3c71b0e1ba415b36309604f79326ac8", | 10 | "angular-ui-router": "github:DefinitelyTyped/DefinitelyTyped/angular-ui-router/angular-ui-router.d.ts#655f8c1bf3c71b0e1ba415b36309604f79326ac8", |
11 | + "angular-ui-bootstrap": "github:DefinitelyTyped/DefinitelyTyped/angular-ui-bootstrap/angular-ui-bootstrap.d.ts", | ||
11 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", | 12 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", |
12 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4", | 13 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4", |
13 | "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8", | 14 | "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8", |