Merge Request #63

Merged
noosfero-themes/angular-theme!63
Created by Leandro Santos

Refactoring image upload

Assignee: None
Milestone: None

Merged by Victor Costa

Source branch has been removed
Commits (4)
2 participants
src/app/layout/blocks/profile-image/profile-image-block.component.ts
1 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 3 import { ProfileService } from "../../../../lib/ng-noosfero-api/http/profile.service";
4 4 import { SessionService } from "./../../../login";
5 5 import { NotificationService } from "../../../shared/services/notification.service";
... ...
src/app/layout/blocks/profile-image/profile-image-block.html
1 1 <div class="center-block text-center profile-image-block">
2 2 <a ui-sref="main.profile.info({profile: ctrl.owner.identifier})">
3 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 5 <div class="actions" ng-show="ctrl.isMember!=null">
7 6 <div class="organization-actions" ng-if="ctrl.displayOrganizationActions()">
8 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 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/profile/image/index.ts
1 1 /* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./image.component";
  2 +export * from "./profile-image.component";
... ...
src/app/profile/image/profile-image-editor.component.spec.ts
... ... @@ -18,7 +18,7 @@ describe(&quot;Components&quot;, () =&gt; {
18 18 let modalInstance = jasmine.createSpyObj("$uibModalInstance", ["close"]);
19 19 let picFile = { type: "png" };
20 20 let $q: ng.IQService;
21   - let personServiceMock: any;
  21 + let profileServiceMock: any;
22 22 let $rootScope: ng.IRootScopeService;
23 23  
24 24 beforeEach(inject((_$q_: ng.IQService, _$rootScope_: ng.IRootScopeService) => {
... ... @@ -26,7 +26,7 @@ describe(&quot;Components&quot;, () =&gt; {
26 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 31 it("get data", done => {
32 32  
... ... @@ -46,10 +46,10 @@ describe(&quot;Components&quot;, () =&gt; {
46 46  
47 47 it("upload image", done => {
48 48 let imageName = "image1";
49   - personServiceMock = jasmine.createSpyObj("personServiceMock", ["uploadImage"]);
  49 + profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["uploadImage"]);
50 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 53 comp.uploadImage(testDataUrl, imageName);
54 54 deferredUploadImage.resolve();
55 55 $rootScope.$apply();
... ...
src/app/profile/image/profile-image-editor.component.ts
1 1 import { StateConfig, Component, Input, Output, Inject, provide } from 'ng-forward';
2 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 5 export class ProfileImageEditorComponent {
6 6  
7   - activities: any;
8 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 11 public modalInstance: ng.ui.bootstrap.IModalServiceInstance) {
13 12 }
14 13  
15 14 uploadImage(dataUrl: any, name: any) {
16 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 17 this.modalInstance.close(name);
19 18 });
20 19 }
... ...
src/app/profile/image/profile-image-editor.html
... ... @@ -3,18 +3,14 @@
3 3 </div>
4 4 <div class="modal-body">
5 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 7 <img-crop image="ctrl.picFile | ngfDataUrl" area-type="square"
8 8 result-image="ctrl.croppedDataUrl" ng-init="ctrl.croppedDataUrl=''">
9 9 </img-crop>
10 10 </div>
11   - <div>
  11 + <div class='cropped-image'>
12 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 14 </form>
19 15  
20 16 <div class="actions">
... ...
src/app/profile/image/profile-image-editor.scss 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +.crop-area{
  2 + background: #E4E4E4;
  3 + height: 200px;
  4 +}
  5 +.cropped-image {
  6 + margin-top: 10px;
  7 + text-align: center;
  8 +}
  9 +
  10 +.modal-body .actions{
  11 + text-align: center;
  12 +
  13 +}
... ...
src/app/profile/image/profile-image.component.spec.ts 0 → 100644
... ... @@ -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 +});
... ...
src/app/profile/image/profile-image.component.ts 0 → 100644
... ... @@ -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 +}
... ...
src/app/profile/image/profile-image.html 0 → 100644
... ... @@ -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>
... ...
src/app/profile/image/profile-image.scss 0 → 100644
... ... @@ -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 +}
... ...
src/app/shared/services/permission.service.spec.ts 0 → 100644
... ... @@ -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 +});
... ...
src/app/shared/services/permission.service.ts 0 → 100644
... ... @@ -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&lt;noosfero.Article&gt; {
58 58 }
59 59  
60 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 62 (<any>profileElement).id = profile.id;
63 63 let headers = {
64 64 'Content-Type': 'application/json'
... ... @@ -84,13 +84,13 @@ export class ArticleService extends RestangularService&lt;noosfero.Article&gt; {
84 84 }
85 85  
86 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 88 return this.list(profileElement, params);
89 89 }
90 90  
91 91 getArticleByProfileAndPath(profile: noosfero.Profile, path: string): ng.IPromise<noosfero.RestResult<noosfero.Article>> {
92 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 95 let restRequest: ng.IPromise<any>;
96 96  
... ... @@ -108,7 +108,7 @@ export class ArticleService extends RestangularService&lt;noosfero.Article&gt; {
108 108 }
109 109  
110 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 112 return this.getSub(profileElement, params);
113 113 }
114 114  
... ...
src/lib/ng-noosfero-api/http/profile.service.ts
1 1 import { Injectable, Inject } from "ng-forward";
  2 +import { RestangularService } from "./restangular_service";
  3 +
2 4  
3 5 @Injectable()
4 6 @Inject("Restangular", "$q")
5   -export class ProfileService {
  7 +export class ProfileService extends RestangularService<noosfero.Profile> {
6 8  
7 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 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 27 resetCurrentProfile() {
14 28 this._currentProfilePromise = this.$q.defer();
15 29 }
... ... @@ -31,7 +45,7 @@ export class ProfileService {
31 45 }
32 46  
33 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 51 getByIdentifier(identifier: string): ng.IPromise<noosfero.Profile> {
... ... @@ -45,28 +59,28 @@ export class ProfileService {
45 59 }
46 60  
47 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 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 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 74 return this.restangular.one('profiles', profileId);
61 75 }
62 76  
63 77 update(profile: noosfero.Profile) {
64 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 82 getMembers(profile: noosfero.Profile, params?: any) {
69   - let p = this.get(profile.id);
  83 + let p = this.getProfileElement(profile.id);
70 84 return p.customGET('members', params);
71 85 }
72 86  
... ... @@ -83,10 +97,24 @@ export class ProfileService {
83 97 }
84 98  
85 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 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 8 parent: Article;
9 9 body: string;
10 10 title: string;
  11 +
  12 +
11 13 name: string;
12 14 published: boolean;
13 15 setting: any;
... ...
src/lib/ng-noosfero-api/interfaces/comment.ts
... ... @@ -5,6 +5,7 @@ namespace noosfero {
5 5 reply_of: Comment;
6 6 replies: Comment[];
7 7 body: string;
  8 + permissions: string[];
8 9 }
9 10  
10 11 export interface CommentViewModel extends Comment {
... ...