Commit 16cf61d455479106a0e91771e6af44f6d262a4e4
Exists in
staging
Merge branch 'master' into staging
Showing
23 changed files
with
473 additions
and
338 deletions
Show diff stats
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/profile-image.component"; |
3 | import { ProfileService } from "../../../../lib/ng-noosfero-api/http/profile.service"; | 3 | import { ProfileService } from "../../../../lib/ng-noosfero-api/http/profile.service"; |
4 | import { SessionService } from "./../../../login"; | 4 | import { SessionService } from "./../../../login"; |
5 | import { NotificationService } from "../../../shared/services/notification.service"; | 5 | import { NotificationService } from "../../../shared/services/notification.service"; |
src/app/layout/blocks/profile-image/profile-image-block.html
1 | <div class="center-block text-center profile-image-block"> | 1 | <div class="center-block text-center profile-image-block"> |
2 | <a ui-sref="main.profile.info({profile: ctrl.owner.identifier})"> | 2 | <a ui-sref="main.profile.info({profile: ctrl.owner.identifier})"> |
3 | <noosfero-profile-image [profile]="ctrl.owner" [editable]="true" [edit-class]="'profile-image-block-editable'"></noosfero-profile-image> | 3 | <noosfero-profile-image [profile]="ctrl.owner" [editable]="true" [edit-class]="'profile-image-block-editable'"></noosfero-profile-image> |
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> | 4 | + </a> |
6 | <div class="actions" ng-show="ctrl.isMember!=null"> | 5 | <div class="actions" ng-show="ctrl.isMember!=null"> |
7 | <div class="organization-actions" ng-if="ctrl.displayOrganizationActions()"> | 6 | <div class="organization-actions" ng-if="ctrl.displayOrganizationActions()"> |
8 | <a ng-if="!ctrl.isMember" ng-click="ctrl.join()" class="btn btn-primary btn-sm join" href="#">{{"blocks.profile_image.join" | translate}}</a> | 7 | <a ng-if="!ctrl.isMember" ng-click="ctrl.join()" class="btn btn-primary btn-sm join" href="#">{{"blocks.profile_image.join" | translate}}</a> |
src/app/layout/blocks/profile-image/profile-image-block.scss
1 | .profile-image-block { | 1 | .profile-image-block { |
2 | - .settings-link { | ||
3 | - display: block; | 2 | + .img-responsive { |
3 | + display: initial; | ||
4 | } | 4 | } |
5 | - .upload-camera-container { | ||
6 | - top: 77%; | ||
7 | - left: 6%; | ||
8 | - } | ||
9 | -} | ||
10 | - | ||
11 | -.profile-image-block-editable { | ||
12 | - top: 68%; | ||
13 | - width: 284px; | ||
14 | - font-weight: 700; | ||
15 | - height: 43px; | ||
16 | - padding-left: 30px; | ||
17 | - padding-top: 13px; | ||
18 | } | 5 | } |
19 | - | ||
20 | - | ||
21 | - | ||
22 | - | ||
23 | - |
src/app/main/main.component.spec.ts
@@ -61,6 +61,7 @@ describe("MainComponent", function () { | @@ -61,6 +61,7 @@ describe("MainComponent", function () { | ||
61 | quickCreateComponent({ directives: [MainComponentParent], template: "<parent></parent>" }) | 61 | quickCreateComponent({ directives: [MainComponentParent], template: "<parent></parent>" }) |
62 | .then((fixture) => { | 62 | .then((fixture) => { |
63 | fixture.debugElement.getLocal("$httpBackend").expectGET("/api/v1/environments/1/boxes").respond(200, {}); | 63 | fixture.debugElement.getLocal("$httpBackend").expectGET("/api/v1/environments/1/boxes").respond(200, {}); |
64 | + fixture.debugElement.getLocal("$httpBackend").expectGET("/api/v1/tasks?all_pending=true&per_page=5&status=1").respond(200, {}); | ||
64 | localFixture = fixture; | 65 | localFixture = fixture; |
65 | // get the $state service to navigate between routes | 66 | // get the $state service to navigate between routes |
66 | $state = fixture.debugElement.getLocal("$state"); | 67 | $state = fixture.debugElement.getLocal("$state"); |
src/app/profile/image/image.component.spec.ts
@@ -1,75 +0,0 @@ | @@ -1,75 +0,0 @@ | ||
1 | -/** | ||
2 | - * @ngdoc overview | ||
3 | - * @name components.noosfero.profile-image.ProfileImageSpec | ||
4 | - * @description | ||
5 | - * This file contains the tests for the {@link components.noosfero.profile-image.ProfileImage} component. | ||
6 | - */ | ||
7 | -import { ComponentTestHelper, createClass } from '../../../spec/component-test-helper'; | ||
8 | -import { TestComponentBuilder, ComponentFixture } from 'ng-forward/cjs/testing/test-component-builder'; | ||
9 | -import { Pipe, Input, provide, Component } from 'ng-forward'; | ||
10 | -import { PersonService } from "../../../lib/ng-noosfero-api/http/person.service"; | ||
11 | - | ||
12 | -import * as helpers from "../../../spec/helpers"; | ||
13 | - | ||
14 | -import { ProfileImageComponent } from "./image.component"; | ||
15 | - | ||
16 | -const htmlTemplate: string = '<noosfero-profile-image [editable]="true" [edit-class]="editable-class" [profile]="ctrl.profile"></noosfero-profile-image>'; | ||
17 | - | ||
18 | -describe("Components", () => { | ||
19 | - | ||
20 | - describe("Profile Image Component", () => { | ||
21 | - | ||
22 | - let helper: ComponentTestHelper<ProfileImageComponent>; | ||
23 | - | ||
24 | - beforeEach(angular.mock.module("templates")); | ||
25 | - | ||
26 | - beforeEach((done) => { | ||
27 | - let scope = helpers.mocks.scopeWithEvents; | ||
28 | - let personService = jasmine.createSpyObj("personService", ["upload"]); | ||
29 | - let properties = { profile: { custom_footer: "footer" } }; | ||
30 | - let cls = createClass({ | ||
31 | - template: htmlTemplate, | ||
32 | - directives: [ProfileImageComponent], | ||
33 | - properties: properties, | ||
34 | - providers: [ | ||
35 | - helpers.createProviderToValue("PersonService", personService), | ||
36 | - helpers.createProviderToValue("$uibModal", helpers.mocks.$modal), | ||
37 | - helpers.createProviderToValue("$scope", scope) | ||
38 | - ] | ||
39 | - }); | ||
40 | - helper = new ComponentTestHelper<ProfileImageComponent>(cls, done); | ||
41 | - }); | ||
42 | - | ||
43 | - it("set modal instance when select files modal", () => { | ||
44 | - helper.component['$uibModal'].open = jasmine.createSpy("open"); | ||
45 | - helper.component.fileSelected("file", []); | ||
46 | - expect(helper.component['$uibModal'].open).toHaveBeenCalled(); | ||
47 | - }); | ||
48 | - | ||
49 | - | ||
50 | - it("show community users image if profile is not Person", (done) => { | ||
51 | - | ||
52 | - let profile = <noosfero.Profile>{ id: 1, identifier: "myprofile", type: "Community" }; | ||
53 | - helper.component.profile = profile; | ||
54 | - helper.component.ngOnInit(); | ||
55 | - | ||
56 | - // Check the attribute | ||
57 | - expect(helper.component.defaultIcon).toBe("fa-users", "The default icon should be community users"); | ||
58 | - // var elProfile = fixture.debugElement.componentViewChildren[0]; | ||
59 | - // expect(elProfile.query('div.profile-image-block').length).toEqual(1); | ||
60 | - done(); | ||
61 | - | ||
62 | - }); | ||
63 | - | ||
64 | - it("show Person image if profile is Person", (done) => { | ||
65 | - | ||
66 | - let profile = <noosfero.Profile>{ id: 1, identifier: "myprofile", type: "Person" }; | ||
67 | - helper.component.profile = profile; | ||
68 | - helper.component.ngOnInit(); | ||
69 | - // Check the attribute | ||
70 | - expect(helper.component.defaultIcon).toEqual("fa-user", "The default icon should be person user"); | ||
71 | - done(); | ||
72 | - }); | ||
73 | - | ||
74 | - }); | ||
75 | -}); |
src/app/profile/image/image.component.ts
@@ -1,91 +0,0 @@ | @@ -1,91 +0,0 @@ | ||
1 | -import { Inject, Input, Component, provide } from "ng-forward"; | ||
2 | -import { PersonService } from "../../../lib/ng-noosfero-api/http/person.service"; | ||
3 | -import { ProfileImageEditorComponent } from "./profile-image-editor.component"; | ||
4 | - | ||
5 | -/** | ||
6 | - * @ngdoc controller | ||
7 | - * @name components.noosfero.profile-image.ProfileImage | ||
8 | - * @description The component responsible for rendering the profile image | ||
9 | - * @exports ProfileImage | ||
10 | - */ | ||
11 | -@Component({ | ||
12 | - selector: "noosfero-profile-image", | ||
13 | - templateUrl: 'app/profile/image/image.html', | ||
14 | - providers: [provide('personService', { useClass: PersonService })] | ||
15 | -}) | ||
16 | -@Inject(PersonService, "$uibModal", "$scope") | ||
17 | -export class ProfileImageComponent { | ||
18 | - | ||
19 | - /** | ||
20 | - * @ngdoc property | ||
21 | - * @name profile | ||
22 | - * @propertyOf components.noosfero.profile-image.ProfileImage | ||
23 | - * @description | ||
24 | - * The Noosfero {@link models.Profile} holding the image. | ||
25 | - */ | ||
26 | - @Input() profile: noosfero.Profile; | ||
27 | - /** | ||
28 | - * @ngdoc property | ||
29 | - * @name defaultIcon | ||
30 | - * @propertyOf components.noosfero.profile-image.ProfileImage | ||
31 | - * @descritpion | ||
32 | - * The default icon used by this profile | ||
33 | - */ | ||
34 | - defaultIcon: string; | ||
35 | - | ||
36 | - @Input() editable: boolean; | ||
37 | - | ||
38 | - @Input() editClass: string; | ||
39 | - | ||
40 | - picFile: any; | ||
41 | - croppedDataUrl: any; | ||
42 | - modalInstance: any; | ||
43 | - | ||
44 | - constructor(private personService: PersonService, private $uibModal: ng.ui.bootstrap.IModalService, private $scope: ng.IScope) { | ||
45 | - } | ||
46 | - | ||
47 | - fileSelected(file: any, errFiles: any) { | ||
48 | - if (file) { | ||
49 | - this.picFile = file; | ||
50 | - this.modalInstance = this.$uibModal.open({ | ||
51 | - templateUrl: 'app/profile/image/profile-image-editor.html', | ||
52 | - controller: ProfileImageEditorComponent, | ||
53 | - controllerAs: 'ctrl', | ||
54 | - scope: this.$scope, | ||
55 | - bindToController: true, | ||
56 | - backdrop: 'static', | ||
57 | - resolve: { | ||
58 | - picFile: this.picFile, | ||
59 | - profile: this.profile, | ||
60 | - personService: this.personService | ||
61 | - } | ||
62 | - }); | ||
63 | - } | ||
64 | - } | ||
65 | - | ||
66 | - private _showCamera: boolean = false; | ||
67 | - | ||
68 | - showChange(show: boolean) { | ||
69 | - this._showCamera = show; | ||
70 | - } | ||
71 | - | ||
72 | - showCamera() { | ||
73 | - return this._showCamera; | ||
74 | - } | ||
75 | - | ||
76 | - | ||
77 | - /** | ||
78 | - * @ngdoc method | ||
79 | - * @name ngOnInit | ||
80 | - * @methodOf components.noosfero.profile-image.ProfileImage | ||
81 | - * @description | ||
82 | - * Initializes the icon names to their corresponding values depending on the profile type passed to the controller | ||
83 | - */ | ||
84 | - ngOnInit() { | ||
85 | - this.defaultIcon = 'fa-users'; | ||
86 | - if (this.profile && this.profile.type === 'Person') { | ||
87 | - this.defaultIcon = 'fa-user'; | ||
88 | - } | ||
89 | - } | ||
90 | - | ||
91 | -} |
src/app/profile/image/image.html
@@ -1,21 +0,0 @@ | @@ -1,21 +0,0 @@ | ||
1 | -<div id="profile-image-container" style=""> | ||
2 | - <div class="profile-image-wrap" title="{{ctrl.profile.name}}" ng-mouseenter="ctrl.showChange(true)" ng-mouseleave="ctrl.showChange(false)"> | ||
3 | - <img ng-if="ctrl.profile.image" ng-src="{{ctrl.profile.image.url}}" class="img-responsive profile-image"> | ||
4 | - <i ng-if="!ctrl.profile.image" class="fa {{ctrl.defaultIcon}} fa-5x profile-image"></i> | ||
5 | - <div ng-if="ctrl.editable" class="upload-camera-container"> | ||
6 | - <i id="camera" class="fa fa-camera upload-camera" aria-hidden="true"></i> | ||
7 | - </div> | ||
8 | - <div ng-if="ctrl.editable" id="select-photo-container" name="select-photo-container" class="select-photo-container container" ng-class="ctrl.editClass"> | ||
9 | - <a id="upload-container" class="upload-container" href="#" rel="dialog" role="button"> | ||
10 | - <!-- The upload button hidden behind the camera --> | ||
11 | - <div class="upload-button" ngf-select="ctrl.fileSelected($file)" | ||
12 | - ngf-pattern="'image/*'" ngf-accept="'image/*'" | ||
13 | - ngf-max-size="20MB" ngf-resize="{width: 100, height: 100}" | ||
14 | - data-toggle="modal" data-target=".crop-dialog"> | ||
15 | - {{"profile.image.upload" | translate}} | ||
16 | - </div> | ||
17 | - </a> | ||
18 | - </div> | ||
19 | - | ||
20 | - </div> | ||
21 | -</div> |
src/app/profile/image/image.scss
@@ -1,95 +0,0 @@ | @@ -1,95 +0,0 @@ | ||
1 | -i.profile-image { | ||
2 | - color: rgb(44, 62, 80); | ||
3 | - | ||
4 | - border-radius: 50%; | ||
5 | - background-clip: padding-box; | ||
6 | - margin-bottom: 15px; | ||
7 | -} | ||
8 | - | ||
9 | -.profile-image-wrap { | ||
10 | - display: inline; | ||
11 | -} | ||
12 | - | ||
13 | -#profile-image-container { | ||
14 | - display: inline; | ||
15 | -} | ||
16 | - | ||
17 | -#profile-image-container:hover { | ||
18 | - .select-photo-container { | ||
19 | - z-index: 1; | ||
20 | - } | ||
21 | - .upload-camera-container { | ||
22 | - transform: scale(.75); | ||
23 | - } | ||
24 | -} | ||
25 | - | ||
26 | -.upload-camera-container { | ||
27 | - text-align: left; | ||
28 | - position: absolute; | ||
29 | - z-index: 5; | ||
30 | -} | ||
31 | - | ||
32 | -.upload-camera { | ||
33 | - color: white; | ||
34 | - position: absolute; | ||
35 | - transition: all .3s cubic-bezier(.175, .885, .32, 1.275); | ||
36 | - opacity: 1; | ||
37 | -} | ||
38 | - | ||
39 | -.select-photo-container { | ||
40 | - position: absolute; | ||
41 | - z-index: -1; | ||
42 | - background: #000; | ||
43 | - background: rgba(0, 0, 0, .6); | ||
44 | - background: linear-gradient(transparent, rgba(0, 0, 0, .6) 70%, rgba(0, 0, 0, .6) 100%); | ||
45 | - transition: top .13s ease-out; | ||
46 | -} | ||
47 | - | ||
48 | -#upload-container { | ||
49 | - position: relative; | ||
50 | - text-decoration: none; | ||
51 | -} | ||
52 | - | ||
53 | -.upload-container a:hover { | ||
54 | - text-decoration: none; | ||
55 | -} | ||
56 | - | ||
57 | -.upload-button { | ||
58 | - -webkit-font-smoothing: antialiased; | ||
59 | - color: #fff; | ||
60 | -} | ||
61 | - | ||
62 | -.upload-container { | ||
63 | - color:#fff; | ||
64 | - display: block; | ||
65 | - overflow: hidden; | ||
66 | - position: relative; | ||
67 | - text-align: left; | ||
68 | - min-width: 89px; | ||
69 | -} | ||
70 | - | ||
71 | -.cropArea { | ||
72 | - background: #E4E4E4; | ||
73 | - overflow: hidden; | ||
74 | - width:300px; | ||
75 | - height:150px; | ||
76 | -} | ||
77 | - | ||
78 | -.crop-area { | ||
79 | - display: none; | ||
80 | -} | ||
81 | - | ||
82 | -form .progress { | ||
83 | - line-height: 15px; | ||
84 | -} | ||
85 | - | ||
86 | -.progress { | ||
87 | - display: inline-block; | ||
88 | - width: 100px; | ||
89 | - border: 3px groove #CCC; | ||
90 | -} | ||
91 | -.progress div { | ||
92 | - font-size: smaller; | ||
93 | - background: orange; | ||
94 | - width: 0; | ||
95 | -} |
src/app/profile/image/index.ts
src/app/profile/image/profile-image-editor.component.spec.ts
@@ -18,7 +18,7 @@ describe("Components", () => { | @@ -18,7 +18,7 @@ describe("Components", () => { | ||
18 | let modalInstance = jasmine.createSpyObj("$uibModalInstance", ["close"]); | 18 | let modalInstance = jasmine.createSpyObj("$uibModalInstance", ["close"]); |
19 | let picFile = { type: "png" }; | 19 | let picFile = { type: "png" }; |
20 | let $q: ng.IQService; | 20 | let $q: ng.IQService; |
21 | - let personServiceMock: any; | 21 | + let profileServiceMock: any; |
22 | let $rootScope: ng.IRootScopeService; | 22 | let $rootScope: ng.IRootScopeService; |
23 | 23 | ||
24 | beforeEach(inject((_$q_: ng.IQService, _$rootScope_: ng.IRootScopeService) => { | 24 | beforeEach(inject((_$q_: ng.IQService, _$rootScope_: ng.IRootScopeService) => { |
@@ -26,7 +26,7 @@ describe("Components", () => { | @@ -26,7 +26,7 @@ describe("Components", () => { | ||
26 | $rootScope = _$rootScope_; | 26 | $rootScope = _$rootScope_; |
27 | })); | 27 | })); |
28 | 28 | ||
29 | - let comp = new ProfileImageEditorComponent(picFile, this.profile, personServiceMock, modalInstance); | 29 | + let comp = new ProfileImageEditorComponent(picFile, this.profile, profileServiceMock, modalInstance); |
30 | 30 | ||
31 | it("get data", done => { | 31 | it("get data", done => { |
32 | 32 | ||
@@ -46,10 +46,10 @@ describe("Components", () => { | @@ -46,10 +46,10 @@ describe("Components", () => { | ||
46 | 46 | ||
47 | it("upload image", done => { | 47 | it("upload image", done => { |
48 | let imageName = "image1"; | 48 | let imageName = "image1"; |
49 | - personServiceMock = jasmine.createSpyObj("personServiceMock", ["uploadImage"]); | 49 | + profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["uploadImage"]); |
50 | let deferredUploadImage = $q.defer(); | 50 | let deferredUploadImage = $q.defer(); |
51 | - personServiceMock.uploadImage = jasmine.createSpy('uploadImage').and.returnValue(deferredUploadImage.promise); | ||
52 | - comp.personService = personServiceMock; | 51 | + profileServiceMock.uploadImage = jasmine.createSpy('uploadImage').and.returnValue(deferredUploadImage.promise); |
52 | + comp.profileService = profileServiceMock; | ||
53 | comp.uploadImage(testDataUrl, imageName); | 53 | comp.uploadImage(testDataUrl, imageName); |
54 | deferredUploadImage.resolve(); | 54 | deferredUploadImage.resolve(); |
55 | $rootScope.$apply(); | 55 | $rootScope.$apply(); |
src/app/profile/image/profile-image-editor.component.ts
1 | import { StateConfig, Component, Input, Output, Inject, provide } from 'ng-forward'; | 1 | import { StateConfig, Component, Input, Output, Inject, provide } from 'ng-forward'; |
2 | import { TranslateProfile } from "../../shared/pipes/translate-profile.filter"; | 2 | import { TranslateProfile } from "../../shared/pipes/translate-profile.filter"; |
3 | -import { PersonService } from "../../../lib/ng-noosfero-api/http/person.service"; | 3 | +import { ProfileService } from "../../../lib/ng-noosfero-api/http/profile.service"; |
4 | 4 | ||
5 | export class ProfileImageEditorComponent { | 5 | export class ProfileImageEditorComponent { |
6 | 6 | ||
7 | - activities: any; | ||
8 | croppedDataUrl: string; | 7 | croppedDataUrl: string; |
9 | - static $inject = ["picFile", "profile", "personService", "$uibModalInstance"]; | 8 | + static $inject = ["picFile", "profile", "profileService", "$uibModalInstance"]; |
10 | 9 | ||
11 | - constructor(public picFile: any, public profile: noosfero.Profile, public personService: PersonService, | 10 | + constructor(public picFile: any, public profile: noosfero.Profile, public profileService: ProfileService, |
12 | public modalInstance: ng.ui.bootstrap.IModalServiceInstance) { | 11 | public modalInstance: ng.ui.bootstrap.IModalServiceInstance) { |
13 | } | 12 | } |
14 | 13 | ||
15 | uploadImage(dataUrl: any, name: any) { | 14 | uploadImage(dataUrl: any, name: any) { |
16 | let base64ImageJson = this.getBase64ImageJson(dataUrl, name); | 15 | let base64ImageJson = this.getBase64ImageJson(dataUrl, name); |
17 | - this.personService.uploadImage(this.profile, base64ImageJson).then((result: any) => { | 16 | + this.profileService.uploadImage(this.profile, base64ImageJson).then((result: any) => { |
18 | this.modalInstance.close(name); | 17 | this.modalInstance.close(name); |
19 | }); | 18 | }); |
20 | } | 19 | } |
src/app/profile/image/profile-image-editor.html
@@ -3,18 +3,14 @@ | @@ -3,18 +3,14 @@ | ||
3 | </div> | 3 | </div> |
4 | <div class="modal-body"> | 4 | <div class="modal-body"> |
5 | <form class=""> | 5 | <form class=""> |
6 | - <div ngf-drop ng-model="ctrl.picFile" ngf-pattern="image/*" class="cropArea"> | 6 | + <div ngf-drop ng-model="ctrl.picFile" ngf-pattern="image/*" class="crop-area"> |
7 | <img-crop image="ctrl.picFile | ngfDataUrl" area-type="square" | 7 | <img-crop image="ctrl.picFile | ngfDataUrl" area-type="square" |
8 | result-image="ctrl.croppedDataUrl" ng-init="ctrl.croppedDataUrl=''"> | 8 | result-image="ctrl.croppedDataUrl" ng-init="ctrl.croppedDataUrl=''"> |
9 | </img-crop> | 9 | </img-crop> |
10 | </div> | 10 | </div> |
11 | - <div> | 11 | + <div class='cropped-image'> |
12 | <img ng-src="{{ctrl.croppedDataUrl}}" /> | 12 | <img ng-src="{{ctrl.croppedDataUrl}}" /> |
13 | - </div> | ||
14 | - <span class="progress" ng-show="progress >= 0"> | ||
15 | - <div style="width: {{progress" ng-bind="progress + '%'"></div> | ||
16 | - </span> <span ng-show="ctrl.result">Upload Successful</span> <span class="err" | ||
17 | - ng-show="ctrl.errorMsg">{{errorMsg}}</span> | 13 | + </div> |
18 | </form> | 14 | </form> |
19 | 15 | ||
20 | <div class="actions"> | 16 | <div class="actions"> |
@@ -0,0 +1,87 @@ | @@ -0,0 +1,87 @@ | ||
1 | +/** | ||
2 | + * @ngdoc overview | ||
3 | + * @name components.noosfero.profile-image.ProfileImageSpec | ||
4 | + * @description | ||
5 | + * This file contains the tests for the {@link components.noosfero.profile-image.ProfileImage} component. | ||
6 | + */ | ||
7 | +import { ComponentTestHelper, createClass } from '../../../spec/component-test-helper'; | ||
8 | +import { TestComponentBuilder, ComponentFixture } from 'ng-forward/cjs/testing/test-component-builder'; | ||
9 | +import { Pipe, Input, provide, Component } from 'ng-forward'; | ||
10 | +import { ProfileService } from "../../../lib/ng-noosfero-api/http/profile.service"; | ||
11 | + | ||
12 | +import * as helpers from "../../../spec/helpers"; | ||
13 | + | ||
14 | +import { ProfileImageComponent } from "./profile-image.component"; | ||
15 | + | ||
16 | +const htmlTemplate: string = '<noosfero-profile-image [editable]="true" [edit-class]="editable-class" [profile]="ctrl.profile"></noosfero-profile-image>'; | ||
17 | + | ||
18 | +describe("Components", () => { | ||
19 | + | ||
20 | + describe("Profile Image Component", () => { | ||
21 | + | ||
22 | + let helper: ComponentTestHelper<ProfileImageComponent>; | ||
23 | + | ||
24 | + beforeEach(angular.mock.module("templates")); | ||
25 | + | ||
26 | + beforeEach((done) => { | ||
27 | + let scope = helpers.mocks.scopeWithEvents; | ||
28 | + let profileService = jasmine.createSpyObj("profileService", ["upload"]); | ||
29 | + let permissionService = jasmine.createSpyObj("permissionService", ["isAllowed"]); | ||
30 | + let properties = { profile: { custom_footer: "footer" } }; | ||
31 | + let cls = createClass({ | ||
32 | + template: htmlTemplate, | ||
33 | + directives: [ProfileImageComponent], | ||
34 | + properties: properties, | ||
35 | + providers: [ | ||
36 | + helpers.createProviderToValue("ProfileService", profileService), | ||
37 | + helpers.createProviderToValue("PermissionService", permissionService), | ||
38 | + helpers.createProviderToValue("$uibModal", helpers.mocks.$modal), | ||
39 | + helpers.createProviderToValue("$scope", scope) | ||
40 | + ] | ||
41 | + }); | ||
42 | + helper = new ComponentTestHelper<ProfileImageComponent>(cls, done); | ||
43 | + }); | ||
44 | + | ||
45 | + it("set modal instance when select files modal", () => { | ||
46 | + helper.component['$uibModal'].open = jasmine.createSpy("open"); | ||
47 | + helper.component.fileSelected("file", []); | ||
48 | + expect(helper.component['$uibModal'].open).toHaveBeenCalled(); | ||
49 | + }); | ||
50 | + | ||
51 | + | ||
52 | + it("show community users image if profile is not Person", (done) => { | ||
53 | + let profile = <noosfero.Profile>{ id: 1, identifier: "myprofile", type: "Community" }; | ||
54 | + helper.component.profile = profile; | ||
55 | + helper.component.ngOnInit(); | ||
56 | + expect(helper.component.defaultIcon).toBe("fa-users", "The default icon should be community users"); | ||
57 | + done(); | ||
58 | + | ||
59 | + }); | ||
60 | + | ||
61 | + it("show Person image if profile is Person", (done) => { | ||
62 | + let profile = <noosfero.Profile>{ id: 1, identifier: "myprofile", type: "Person" }; | ||
63 | + helper.component.profile = profile; | ||
64 | + helper.component.ngOnInit(); | ||
65 | + expect(helper.component.defaultIcon).toEqual("fa-user", "The default icon should be person user"); | ||
66 | + done(); | ||
67 | + }); | ||
68 | + | ||
69 | + it("is editable be true in blocks that are editable", (done) => { | ||
70 | + expect(helper.component.editable).toBe(true); | ||
71 | + done(); | ||
72 | + }); | ||
73 | + | ||
74 | + it("is not editable in editable blocks but without permission", (done) => { | ||
75 | + helper.component['permissionService'].isAllowed = jasmine.createSpy("isAllowed").and.returnValue(false); | ||
76 | + expect(helper.component.isEditable()).toBe(false); | ||
77 | + done(); | ||
78 | + }); | ||
79 | + | ||
80 | + it("is editable in editable blocks with edit permission", (done) => { | ||
81 | + helper.component['permissionService'].isAllowed = jasmine.createSpy("isAllowed").and.returnValue(true); | ||
82 | + expect(helper.component.isEditable()).toBe(true); | ||
83 | + done(); | ||
84 | + }); | ||
85 | + | ||
86 | + }); | ||
87 | +}); |
@@ -0,0 +1,82 @@ | @@ -0,0 +1,82 @@ | ||
1 | +import { Inject, Input, Component, provide } from "ng-forward"; | ||
2 | +import { ProfileService } from "../../../lib/ng-noosfero-api/http/profile.service"; | ||
3 | +import { PermissionService } from "../../shared/services/permission.service"; | ||
4 | +import { ProfileImageEditorComponent } from "./profile-image-editor.component"; | ||
5 | + | ||
6 | +/** | ||
7 | + * @ngdoc controller | ||
8 | + * @name components.noosfero.profile-image.ProfileImage | ||
9 | + * @description The component responsible for rendering the profile image | ||
10 | + * @exports ProfileImage | ||
11 | + */ | ||
12 | +@Component({ | ||
13 | + selector: "noosfero-profile-image", | ||
14 | + templateUrl: 'app/profile/image/profile-image.html', | ||
15 | + providers: [provide('profileService', { useClass: ProfileService })] | ||
16 | +}) | ||
17 | +@Inject(ProfileService, PermissionService, "$uibModal", "$scope") | ||
18 | +export class ProfileImageComponent { | ||
19 | + | ||
20 | + /** | ||
21 | + * @ngdoc property | ||
22 | + * @name profile | ||
23 | + * @propertyOf components.noosfero.profile-image.ProfileImage | ||
24 | + * @description | ||
25 | + * The Noosfero {@link models.Profile} holding the image. | ||
26 | + */ | ||
27 | + @Input() profile: noosfero.Profile; | ||
28 | + /** | ||
29 | + * @ngdoc property | ||
30 | + * @name defaultIcon | ||
31 | + * @propertyOf components.noosfero.profile-image.ProfileImage | ||
32 | + * @descritpion | ||
33 | + * The default icon used by this profile | ||
34 | + */ | ||
35 | + defaultIcon: string; | ||
36 | + | ||
37 | + @Input() editable: boolean; | ||
38 | + | ||
39 | + picFile: any; | ||
40 | + modalInstance: any; | ||
41 | + | ||
42 | + constructor(private profileService: ProfileService, private permissionService: PermissionService, private $uibModal: ng.ui.bootstrap.IModalService, private $scope: ng.IScope) { | ||
43 | + } | ||
44 | + | ||
45 | + fileSelected(file: any, errFiles: any) { | ||
46 | + if (file) { | ||
47 | + this.picFile = file; | ||
48 | + this.modalInstance = this.$uibModal.open({ | ||
49 | + templateUrl: 'app/profile/image/profile-image-editor.html', | ||
50 | + controller: ProfileImageEditorComponent, | ||
51 | + controllerAs: 'ctrl', | ||
52 | + scope: this.$scope, | ||
53 | + bindToController: true, | ||
54 | + backdrop: 'static', | ||
55 | + resolve: { | ||
56 | + picFile: this.picFile, | ||
57 | + profile: this.profile, | ||
58 | + profileService: this.profileService | ||
59 | + } | ||
60 | + }); | ||
61 | + } | ||
62 | + } | ||
63 | + | ||
64 | + isEditable() { | ||
65 | + return this.editable && this.permissionService.isAllowed(this.profile, 'allow_edit'); | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * @ngdoc method | ||
70 | + * @name ngOnInit | ||
71 | + * @methodOf components.noosfero.profile-image.ProfileImage | ||
72 | + * @description | ||
73 | + * Initializes the icon names to their corresponding values depending on the profile type passed to the controller | ||
74 | + */ | ||
75 | + ngOnInit() { | ||
76 | + this.defaultIcon = 'fa-users'; | ||
77 | + if (this.profile && this.profile.type === 'Person') { | ||
78 | + this.defaultIcon = 'fa-user'; | ||
79 | + } | ||
80 | + } | ||
81 | + | ||
82 | +} |
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +<div ng-if="ctrl.isEditable()" id="profile-image-container"> | ||
2 | + <div class="profile-image-wrap" title="{{ctrl.profile.name}}" ng-mouseenter="ctrl.showChange(true)" ng-mouseleave="ctrl.showChange(false)"> | ||
3 | + <div class="hovereffect "> | ||
4 | + <i ng-if="!ctrl.profile.image" class="fa {{ctrl.defaultIcon}} fa-5x profile-image"></i> | ||
5 | + <img ng-if="ctrl.profile.image" ng-src="{{ctrl.profile.image.url}}" class="img-responsive profile-image"> | ||
6 | + <div class='container-camera'> | ||
7 | + <a ngf-select="ctrl.fileSelected($file)" | ||
8 | + ngf-pattern="'image/*'" ngf-accept="'image/*'" | ||
9 | + ngf-max-size="20MB" | ||
10 | + data-toggle="modal" data-target=".crop-dialog" href="#"><i class="fa fa-camera upload-camera" ></i> | ||
11 | + </a> | ||
12 | + </div> | ||
13 | + <div class="overlay"></div> | ||
14 | + </div> | ||
15 | + </div> | ||
16 | +</div> | ||
17 | +<span ng-if="!ctrl.isEditable()" class="profile-image-wrap" title="{{ctrl.profile.name}}"> | ||
18 | + <img ng-if="ctrl.profile.image" ng-src="{{ctrl.profile.image.url}}" class="img-responsive profile-image"> | ||
19 | + <i ng-if="!ctrl.profile.image" class="fa {{ctrl.defaultIcon}} fa-5x profile-image"></i> | ||
20 | +</span> |
@@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
1 | +.hovereffect { | ||
2 | + width:100%; | ||
3 | + height:100%; | ||
4 | + float:left; | ||
5 | + overflow:hidden; | ||
6 | + position:relative; | ||
7 | + text-align:center; | ||
8 | + cursor:default; | ||
9 | + .container-camera { | ||
10 | + position: relative; | ||
11 | + z-index: 2; | ||
12 | + .upload-camera{ | ||
13 | + right: 0px; | ||
14 | + left: 0px; | ||
15 | + position: absolute; | ||
16 | + font-size: 1.5em; | ||
17 | + bottom: 2px; | ||
18 | + text-shadow: 0px 0px 3px black; | ||
19 | + color: white; | ||
20 | + padding-top: 5px; | ||
21 | + &:hover{ | ||
22 | + font-size: 1.5em; | ||
23 | + background-color: rgba(0, 0, 0, 0.50); | ||
24 | + } | ||
25 | + | ||
26 | + } | ||
27 | + } | ||
28 | + .overlay { | ||
29 | + width:100%; | ||
30 | + height:100%; | ||
31 | + position:absolute; | ||
32 | + overflow:hidden; | ||
33 | + top:0; | ||
34 | + left:0; | ||
35 | + opacity:0; | ||
36 | + background-color:rgba(0,0,0,0.5); | ||
37 | + -webkit-transition:all .4s ease-in-out; | ||
38 | + transition:all .4s ease-in-out; | ||
39 | + z-index: 1; | ||
40 | + } | ||
41 | + img { | ||
42 | + display:block; | ||
43 | + position:relative; | ||
44 | + -webkit-transition:all .4s linear; | ||
45 | + transition:all .4s linear; | ||
46 | + width: 100%; | ||
47 | + } | ||
48 | + &:hover { | ||
49 | + img { | ||
50 | + -ms-transform:scale(1.2); | ||
51 | + -webkit-transform:scale(1.2); | ||
52 | + transform:scale(1.2); | ||
53 | + } | ||
54 | + .overlay { | ||
55 | + opacity:1; | ||
56 | + filter:alpha(opacity=100); | ||
57 | + } | ||
58 | + } | ||
59 | +} |
@@ -0,0 +1,137 @@ | @@ -0,0 +1,137 @@ | ||
1 | +import { PermissionService } from './permission.service'; | ||
2 | + | ||
3 | + | ||
4 | +describe("PermissionService", () => { | ||
5 | + | ||
6 | + // Profile TESTS | ||
7 | + it("check if a person has no permission if there is no permissions in object", (done) => { | ||
8 | + let permissionService: PermissionService = new PermissionService(); | ||
9 | + let target = <noosfero.Profile>{ id: 1, identifier: "some" }; | ||
10 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
11 | + done(); | ||
12 | + }); | ||
13 | + | ||
14 | + it("check if a person has no permission if the permissions is null", (done) => { | ||
15 | + let permissionService: PermissionService = new PermissionService(); | ||
16 | + let target = <noosfero.Profile>{ id: 1, identifier: "some", permissions: null }; | ||
17 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
18 | + done(); | ||
19 | + }); | ||
20 | + | ||
21 | + it("check if a person has no permission if the permissions is empty", (done) => { | ||
22 | + let permissionService: PermissionService = new PermissionService(); | ||
23 | + let target = <noosfero.Profile>{ id: 1, identifier: "some", permissions: [] }; | ||
24 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
25 | + done(); | ||
26 | + }); | ||
27 | + | ||
28 | + it("check person has no permission if permissions has no element named like permission desired", (done) => { | ||
29 | + let permissionService: PermissionService = new PermissionService(); | ||
30 | + let target = <noosfero.Profile>{ id: 1, identifier: "some", permissions: ['another_permission'] }; | ||
31 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(false); | ||
32 | + done(); | ||
33 | + }); | ||
34 | + | ||
35 | + it("check person has permission if permissions has the element named like permission desired", (done) => { | ||
36 | + let permissionService: PermissionService = new PermissionService(); | ||
37 | + let target = <noosfero.Profile>{ id: 1, identifier: "some", permissions: ['some_permission'] }; | ||
38 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(true); | ||
39 | + done(); | ||
40 | + }); | ||
41 | + | ||
42 | + it("check person has permission if permissions has some element named like permission desired", (done) => { | ||
43 | + let permissionService: PermissionService = new PermissionService(); | ||
44 | + let target = <noosfero.Profile>{ id: 1, identifier: "some", permissions: ['another', 'some_permission'] }; | ||
45 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(true); | ||
46 | + done(); | ||
47 | + }); | ||
48 | + | ||
49 | + | ||
50 | + // Comment TESTS | ||
51 | + it("check if a person has no permission if there is no permissions in object", (done) => { | ||
52 | + let permissionService: PermissionService = new PermissionService(); | ||
53 | + let target = <noosfero.Comment>{ id: 1 }; | ||
54 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
55 | + done(); | ||
56 | + }); | ||
57 | + | ||
58 | + it("check if a person has no permission if the permissions is null", (done) => { | ||
59 | + let permissionService: PermissionService = new PermissionService(); | ||
60 | + let target = <noosfero.Comment>{ id: 1, permissions: null }; | ||
61 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
62 | + done(); | ||
63 | + }); | ||
64 | + | ||
65 | + it("check if a person has no permission if the permissions is empty", (done) => { | ||
66 | + let permissionService: PermissionService = new PermissionService(); | ||
67 | + let target = <noosfero.Comment>{ id: 1, permissions: [] }; | ||
68 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
69 | + done(); | ||
70 | + }); | ||
71 | + | ||
72 | + it("check person has no permission if permissions has no element named like permission desired", (done) => { | ||
73 | + let permissionService: PermissionService = new PermissionService(); | ||
74 | + let target = <noosfero.Comment>{ id: 1, permissions: ['another_permission'] }; | ||
75 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(false); | ||
76 | + done(); | ||
77 | + }); | ||
78 | + | ||
79 | + it("check person has permission if permissions has the element named like permission desired", (done) => { | ||
80 | + let permissionService: PermissionService = new PermissionService(); | ||
81 | + let target = <noosfero.Comment>{ id: 1, permissions: ['some_permission'] }; | ||
82 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(true); | ||
83 | + done(); | ||
84 | + }); | ||
85 | + | ||
86 | + it("check person has permission if permissions has some element named like permission desired", (done) => { | ||
87 | + let permissionService: PermissionService = new PermissionService(); | ||
88 | + let target = <noosfero.Comment>{ id: 1, permissions: ['another', 'some_permission'] }; | ||
89 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(true); | ||
90 | + done(); | ||
91 | + }); | ||
92 | + | ||
93 | + // Article TESTS | ||
94 | + it("check if a person has no permission if there is no permissions in object", (done) => { | ||
95 | + let permissionService: PermissionService = new PermissionService(); | ||
96 | + let target = <noosfero.Article>{ id: 1 }; | ||
97 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
98 | + done(); | ||
99 | + }); | ||
100 | + | ||
101 | + it("check if a person has no permission if the permissions is null", (done) => { | ||
102 | + let permissionService: PermissionService = new PermissionService(); | ||
103 | + let target = <noosfero.Article>{ id: 1, permissions: null }; | ||
104 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
105 | + done(); | ||
106 | + }); | ||
107 | + | ||
108 | + it("check if a person has no permission if the permissions is empty", (done) => { | ||
109 | + let permissionService: PermissionService = new PermissionService(); | ||
110 | + let target = <noosfero.Article>{ id: 1, permissions: [] }; | ||
111 | + expect(permissionService.isAllowed(target, null)).toBe(false); | ||
112 | + done(); | ||
113 | + }); | ||
114 | + | ||
115 | + it("check person has no permission if permissions has no element named like permission desired", (done) => { | ||
116 | + let permissionService: PermissionService = new PermissionService(); | ||
117 | + let target = <noosfero.Article>{ id: 1, permissions: ['another_permission'] }; | ||
118 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(false); | ||
119 | + done(); | ||
120 | + }); | ||
121 | + | ||
122 | + it("check person has permission if permissions has the element named like permission desired", (done) => { | ||
123 | + let permissionService: PermissionService = new PermissionService(); | ||
124 | + let target = <noosfero.Article>{ id: 1, permissions: ['some_permission'] }; | ||
125 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(true); | ||
126 | + done(); | ||
127 | + }); | ||
128 | + | ||
129 | + it("check person has permission if permissions has some element named like permission desired", (done) => { | ||
130 | + let permissionService: PermissionService = new PermissionService(); | ||
131 | + let target = <noosfero.Article>{ id: 1, permissions: ['another', 'some_permission'] }; | ||
132 | + expect(permissionService.isAllowed(target, 'some_permission')).toBe(true); | ||
133 | + done(); | ||
134 | + }); | ||
135 | + | ||
136 | + | ||
137 | +}); |
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +import {Injectable, Inject} from "ng-forward"; | ||
2 | + | ||
3 | +type WithPermissions = noosfero.Profile | noosfero.Comment | noosfero.Article; | ||
4 | + | ||
5 | +@Injectable() | ||
6 | +export class PermissionService { | ||
7 | + isAllowed(target: WithPermissions, permission: string) { | ||
8 | + return (target.permissions || []).indexOf(permission) >= 0; | ||
9 | + } | ||
10 | + | ||
11 | +} |
src/lib/ng-noosfero-api/http/article.service.ts
@@ -58,7 +58,7 @@ export class ArticleService extends RestangularService<noosfero.Article> { | @@ -58,7 +58,7 @@ export class ArticleService extends RestangularService<noosfero.Article> { | ||
58 | } | 58 | } |
59 | 59 | ||
60 | createInProfile(profile: noosfero.Profile, article: noosfero.Article): ng.IPromise<noosfero.RestResult<noosfero.Article>> { | 60 | createInProfile(profile: noosfero.Profile, article: noosfero.Article): ng.IPromise<noosfero.RestResult<noosfero.Article>> { |
61 | - let profileElement = this.profileService.get(<number>profile.id); | 61 | + let profileElement = this.profileService.getProfileElement(<number>profile.id); |
62 | (<any>profileElement).id = profile.id; | 62 | (<any>profileElement).id = profile.id; |
63 | let headers = { | 63 | let headers = { |
64 | 'Content-Type': 'application/json' | 64 | 'Content-Type': 'application/json' |
@@ -84,13 +84,13 @@ export class ArticleService extends RestangularService<noosfero.Article> { | @@ -84,13 +84,13 @@ export class ArticleService extends RestangularService<noosfero.Article> { | ||
84 | } | 84 | } |
85 | 85 | ||
86 | getByProfile<T>(profile: noosfero.Profile, params?: any): ng.IPromise<noosfero.RestResult<noosfero.Article[]>> { | 86 | getByProfile<T>(profile: noosfero.Profile, params?: any): ng.IPromise<noosfero.RestResult<noosfero.Article[]>> { |
87 | - let profileElement = this.profileService.get(<number>profile.id); | 87 | + let profileElement = this.profileService.getProfileElement(<number>profile.id); |
88 | return this.list(profileElement, params); | 88 | return this.list(profileElement, params); |
89 | } | 89 | } |
90 | 90 | ||
91 | getArticleByProfileAndPath(profile: noosfero.Profile, path: string): ng.IPromise<noosfero.RestResult<noosfero.Article>> { | 91 | getArticleByProfileAndPath(profile: noosfero.Profile, path: string): ng.IPromise<noosfero.RestResult<noosfero.Article>> { |
92 | let deferred = this.$q.defer<noosfero.RestResult<noosfero.Article>>(); | 92 | let deferred = this.$q.defer<noosfero.RestResult<noosfero.Article>>(); |
93 | - let profileElement = this.profileService.get(<number>profile.id); | 93 | + let profileElement = this.profileService.getProfileElement(<number>profile.id); |
94 | 94 | ||
95 | let restRequest: ng.IPromise<any>; | 95 | let restRequest: ng.IPromise<any>; |
96 | 96 | ||
@@ -108,7 +108,7 @@ export class ArticleService extends RestangularService<noosfero.Article> { | @@ -108,7 +108,7 @@ export class ArticleService extends RestangularService<noosfero.Article> { | ||
108 | } | 108 | } |
109 | 109 | ||
110 | getOneByProfile<T>(profile: noosfero.Profile, params?: any): ng.IPromise<noosfero.RestResult<noosfero.Article>> { | 110 | getOneByProfile<T>(profile: noosfero.Profile, params?: any): ng.IPromise<noosfero.RestResult<noosfero.Article>> { |
111 | - let profileElement = this.profileService.get(<number>profile.id); | 111 | + let profileElement = this.profileService.getProfileElement(<number>profile.id); |
112 | return this.getSub(profileElement, params); | 112 | return this.getSub(profileElement, params); |
113 | } | 113 | } |
114 | 114 |
src/lib/ng-noosfero-api/http/profile.service.ts
1 | import { Injectable, Inject } from "ng-forward"; | 1 | import { Injectable, Inject } from "ng-forward"; |
2 | +import { RestangularService } from "./restangular_service"; | ||
3 | + | ||
2 | 4 | ||
3 | @Injectable() | 5 | @Injectable() |
4 | @Inject("Restangular", "$q") | 6 | @Inject("Restangular", "$q") |
5 | -export class ProfileService { | 7 | +export class ProfileService extends RestangularService<noosfero.Profile> { |
6 | 8 | ||
7 | private _currentProfilePromise: ng.IDeferred<noosfero.Profile>; | 9 | private _currentProfilePromise: ng.IDeferred<noosfero.Profile>; |
8 | 10 | ||
9 | - constructor(private restangular: restangular.IService, private $q: ng.IQService) { | 11 | + constructor(private restangular: restangular.IService, $q: ng.IQService, $log: ng.ILogService) { |
12 | + super(restangular, $q, $log); | ||
10 | this.resetCurrentProfile(); | 13 | this.resetCurrentProfile(); |
11 | } | 14 | } |
12 | 15 | ||
16 | + getResourcePath() { | ||
17 | + return "profiles"; | ||
18 | + } | ||
19 | + | ||
20 | + getDataKeys() { | ||
21 | + return { | ||
22 | + singular: 'profile', | ||
23 | + plural: 'profiles' | ||
24 | + }; | ||
25 | + } | ||
26 | + | ||
13 | resetCurrentProfile() { | 27 | resetCurrentProfile() { |
14 | this._currentProfilePromise = this.$q.defer(); | 28 | this._currentProfilePromise = this.$q.defer(); |
15 | } | 29 | } |
@@ -31,7 +45,7 @@ export class ProfileService { | @@ -31,7 +45,7 @@ export class ProfileService { | ||
31 | } | 45 | } |
32 | 46 | ||
33 | getHomePage(profileId: number, params?: any) { | 47 | getHomePage(profileId: number, params?: any) { |
34 | - return this.get(profileId).customGET("home_page", params); | 48 | + return this.getProfileElement(profileId).customGET("home_page", params); |
35 | } | 49 | } |
36 | 50 | ||
37 | getByIdentifier(identifier: string): ng.IPromise<noosfero.Profile> { | 51 | getByIdentifier(identifier: string): ng.IPromise<noosfero.Profile> { |
@@ -45,28 +59,28 @@ export class ProfileService { | @@ -45,28 +59,28 @@ export class ProfileService { | ||
45 | } | 59 | } |
46 | 60 | ||
47 | getProfileMembers(profileId: number, params?: any): restangular.IPromise<any> { | 61 | getProfileMembers(profileId: number, params?: any): restangular.IPromise<any> { |
48 | - return this.get(profileId).customGET("members", params); | 62 | + return this.getProfileElement(profileId).customGET("members", params); |
49 | } | 63 | } |
50 | 64 | ||
51 | getBoxes(profileId: number): restangular.IPromise<any> { | 65 | getBoxes(profileId: number): restangular.IPromise<any> { |
52 | - return this.get(profileId).customGET('boxes'); | 66 | + return this.getProfileElement(profileId).customGET('boxes'); |
53 | } | 67 | } |
54 | 68 | ||
55 | getActivities(profileId: number, params?: any): restangular.IPromise<any> { | 69 | getActivities(profileId: number, params?: any): restangular.IPromise<any> { |
56 | - return this.get(profileId).customGET("activities", params); | 70 | + return this.getProfileElement(profileId).customGET("activities", params); |
57 | } | 71 | } |
58 | 72 | ||
59 | - get(profileId: number): restangular.IElement { | 73 | + getProfileElement(profileId: number): restangular.IElement { |
60 | return this.restangular.one('profiles', profileId); | 74 | return this.restangular.one('profiles', profileId); |
61 | } | 75 | } |
62 | 76 | ||
63 | update(profile: noosfero.Profile) { | 77 | update(profile: noosfero.Profile) { |
64 | let headers = { 'Content-Type': 'application/json' }; | 78 | let headers = { 'Content-Type': 'application/json' }; |
65 | - return this.get(profile.id).customPOST({ profile: profile }, null, null, headers); | 79 | + return this.getProfileElement(profile.id).customPOST({ profile: profile }, null, null, headers); |
66 | } | 80 | } |
67 | 81 | ||
68 | getMembers(profile: noosfero.Profile, params?: any) { | 82 | getMembers(profile: noosfero.Profile, params?: any) { |
69 | - let p = this.get(profile.id); | 83 | + let p = this.getProfileElement(profile.id); |
70 | return p.customGET('members', params); | 84 | return p.customGET('members', params); |
71 | } | 85 | } |
72 | 86 | ||
@@ -83,10 +97,24 @@ export class ProfileService { | @@ -83,10 +97,24 @@ export class ProfileService { | ||
83 | } | 97 | } |
84 | 98 | ||
85 | addMember(person: noosfero.Person, profile: noosfero.Profile) { | 99 | addMember(person: noosfero.Person, profile: noosfero.Profile) { |
86 | - return this.get(profile.id).customPOST({}, "members", null, null); | 100 | + return this.getProfileElement(profile.id).customPOST({}, "members", null, null); |
87 | } | 101 | } |
88 | 102 | ||
89 | removeMember(person: noosfero.Person, profile: noosfero.Profile) { | 103 | removeMember(person: noosfero.Person, profile: noosfero.Profile) { |
90 | - return this.get(profile.id).customDELETE("members", null, null); | 104 | + return this.getProfileElement(profile.id).customDELETE("members", null, null); |
105 | + } | ||
106 | + | ||
107 | + uploadImage(profile: noosfero.Profile, base64ImageJson: any) { | ||
108 | + let headers = { 'Content-Type': 'application/json' }; | ||
109 | + let deferred = this.$q.defer<noosfero.RestResult<noosfero.Profile>>(); | ||
110 | + // TODO dynamically copy the selected attributes to update | ||
111 | + let attributesToUpdate: any = { | ||
112 | + profile: { image_builder: base64ImageJson } | ||
113 | + }; | ||
114 | + let restRequest: ng.IPromise<noosfero.RestResult<any>> = | ||
115 | + this.getProfileElement(profile.id).customPOST(attributesToUpdate, null, null, headers); | ||
116 | + restRequest.then(this.getHandleSuccessFunction(deferred)) | ||
117 | + .catch(this.getHandleErrorFunction(deferred)); | ||
118 | + return deferred.promise; | ||
91 | } | 119 | } |
92 | } | 120 | } |
src/lib/ng-noosfero-api/interfaces/article.ts
@@ -8,6 +8,8 @@ namespace noosfero { | @@ -8,6 +8,8 @@ namespace noosfero { | ||
8 | parent: Article; | 8 | parent: Article; |
9 | body: string; | 9 | body: string; |
10 | title: string; | 10 | title: string; |
11 | + | ||
12 | + | ||
11 | name: string; | 13 | name: string; |
12 | published: boolean; | 14 | published: boolean; |
13 | setting: any; | 15 | setting: any; |
src/lib/ng-noosfero-api/interfaces/comment.ts
@@ -5,6 +5,7 @@ namespace noosfero { | @@ -5,6 +5,7 @@ namespace noosfero { | ||
5 | reply_of: Comment; | 5 | reply_of: Comment; |
6 | replies: Comment[]; | 6 | replies: Comment[]; |
7 | body: string; | 7 | body: string; |
8 | + permissions: string[]; | ||
8 | } | 9 | } |
9 | 10 | ||
10 | export interface CommentViewModel extends Comment { | 11 | export interface CommentViewModel extends Comment { |