Commit 4b151aa3f841c62ad465feb808af0e52e683912c
1 parent
e6bb091b
Exists in
master
and in
4 other branches
change image component name to profile image component
Showing
11 changed files
with
245 additions
and
251 deletions
Show diff stats
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/profile/image/image.component.spec.ts
... | ... | @@ -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 { ProfileService } from "../../../lib/ng-noosfero-api/http/profile.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 profileService = jasmine.createSpyObj("profileService", ["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("ProfileService", profileService), | |
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,94 +0,0 @@ |
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/image.html', | |
15 | - providers: [provide('profileService', { useClass: ProfileService })] | |
16 | -}) | |
17 | -@Inject(ProfileService, PermissionService, "$uibModal", "$scope") | |
18 | -export class ProfileImageComponent { | |
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 profileService: ProfileService, private permissionService: PermissionService, 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 | - profileService: this.profileService | |
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 | - isEditable() { | |
77 | - return this.editable && this.permissionService.isAllowed(this.profile, 'allow_edit'); | |
78 | - } | |
79 | - | |
80 | - /** | |
81 | - * @ngdoc method | |
82 | - * @name ngOnInit | |
83 | - * @methodOf components.noosfero.profile-image.ProfileImage | |
84 | - * @description | |
85 | - * Initializes the icon names to their corresponding values depending on the profile type passed to the controller | |
86 | - */ | |
87 | - ngOnInit() { | |
88 | - this.defaultIcon = 'fa-users'; | |
89 | - if (this.profile && this.profile.type === 'Person') { | |
90 | - this.defaultIcon = 'fa-user'; | |
91 | - } | |
92 | - } | |
93 | - | |
94 | -} |
src/app/profile/image/image.html
... | ... | @@ -1,20 +0,0 @@ |
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/image.scss
... | ... | @@ -1,59 +0,0 @@ |
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/profile/image/index.ts
src/app/profile/image/profile-image-editor.component.ts
... | ... | @@ -10,7 +10,7 @@ export class ProfileImageEditorComponent { |
10 | 10 | constructor(public picFile: any, public profile: noosfero.Profile, public profileService: ProfileService, |
11 | 11 | public modalInstance: ng.ui.bootstrap.IModalServiceInstance) { |
12 | 12 | } |
13 | - | |
13 | + | |
14 | 14 | uploadImage(dataUrl: any, name: any) { |
15 | 15 | let base64ImageJson = this.getBase64ImageJson(dataUrl, name); |
16 | 16 | this.profileService.uploadImage(this.profile, base64ImageJson).then((result: any) => { | ... | ... |
... | ... | @@ -0,0 +1,68 @@ |
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 properties = { profile: { custom_footer: "footer" } }; | |
30 | + let cls = createClass({ | |
31 | + template: htmlTemplate, | |
32 | + directives: [ProfileImageComponent], | |
33 | + properties: properties, | |
34 | + providers: [ | |
35 | + helpers.createProviderToValue("ProfileService", profileService), | |
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 | + let profile = <noosfero.Profile>{ id: 1, identifier: "myprofile", type: "Community" }; | |
52 | + helper.component.profile = profile; | |
53 | + helper.component.ngOnInit(); | |
54 | + expect(helper.component.defaultIcon).toBe("fa-users", "The default icon should be community users"); | |
55 | + done(); | |
56 | + | |
57 | + }); | |
58 | + | |
59 | + it("show Person image if profile is Person", (done) => { | |
60 | + let profile = <noosfero.Profile>{ id: 1, identifier: "myprofile", type: "Person" }; | |
61 | + helper.component.profile = profile; | |
62 | + helper.component.ngOnInit(); | |
63 | + expect(helper.component.defaultIcon).toEqual("fa-user", "The default icon should be person user"); | |
64 | + done(); | |
65 | + }); | |
66 | + | |
67 | + }); | |
68 | +}); | ... | ... |
... | ... | @@ -0,0 +1,95 @@ |
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 | + @Input() editClass: string; | |
40 | + | |
41 | + picFile: any; | |
42 | + croppedDataUrl: any; | |
43 | + modalInstance: any; | |
44 | + | |
45 | + constructor(private profileService: ProfileService, private permissionService: PermissionService, private $uibModal: ng.ui.bootstrap.IModalService, private $scope: ng.IScope) { | |
46 | + } | |
47 | + | |
48 | + fileSelected(file: any, errFiles: any) { | |
49 | + if (file) { | |
50 | + this.picFile = file; | |
51 | + this.modalInstance = this.$uibModal.open({ | |
52 | + templateUrl: 'app/profile/image/profile-image-editor.html', | |
53 | + controller: ProfileImageEditorComponent, | |
54 | + controllerAs: 'ctrl', | |
55 | + scope: this.$scope, | |
56 | + bindToController: true, | |
57 | + backdrop: 'static', | |
58 | + resolve: { | |
59 | + picFile: this.picFile, | |
60 | + profile: this.profile, | |
61 | + profileService: this.profileService | |
62 | + } | |
63 | + }); | |
64 | + } | |
65 | + } | |
66 | + | |
67 | + private _showCamera: boolean = false; | |
68 | + | |
69 | + showChange(show: boolean) { | |
70 | + this._showCamera = show; | |
71 | + } | |
72 | + | |
73 | + showCamera() { | |
74 | + return this._showCamera; | |
75 | + } | |
76 | + | |
77 | + isEditable() { | |
78 | + return this.editable && this.permissionService.isAllowed(this.profile, 'allow_edit'); | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * @ngdoc method | |
83 | + * @name ngOnInit | |
84 | + * @methodOf components.noosfero.profile-image.ProfileImage | |
85 | + * @description | |
86 | + * Initializes the icon names to their corresponding values depending on the profile type passed to the controller | |
87 | + */ | |
88 | + ngOnInit() { | |
89 | + this.defaultIcon = 'fa-users'; | |
90 | + if (this.profile && this.profile.type === 'Person') { | |
91 | + this.defaultIcon = 'fa-user'; | |
92 | + } | |
93 | + } | |
94 | + | |
95 | +} | ... | ... |
... | ... | @@ -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 @@ |
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 | +} | ... | ... |