Commit c2abd5b3c556a651216f070ba6696c23f33d383c
1 parent
c1e0c406
Exists in
master
and in
1 other branch
Completed initial two columns profile-info. Needs create a unit test for new profile-data component
Showing
13 changed files
with
216 additions
and
49 deletions
Show diff stats
src/app/index.scss
... | ... | @@ -24,12 +24,19 @@ $main-bg-color: #e7ebee; |
24 | 24 | $primary-color: #03a9f4; |
25 | 25 | $primary-color-dark: #0288d1; |
26 | 26 | |
27 | +//OTHER COLORS | |
28 | +$default-bg-hover-color: #f8f8f8; | |
29 | +$red-color: #e84e40; | |
30 | +$red-color-dark: #dd191d; | |
31 | + | |
27 | 32 | //GRID - media queries breakpoints |
28 | 33 | $break-xxs-min: 420px; |
29 | 34 | $break-xs-min: 768px; |
30 | 35 | |
31 | 36 | $break-xxs-max: ($break-xxs-min - 1); |
32 | 37 | $break-xs-max: ($break-xs-min - 1); |
38 | + | |
39 | + | |
33 | 40 | @import "../../bower_components/bootswatch/flatly/_variables.scss"; |
34 | 41 | |
35 | 42 | /** |
... | ... | @@ -68,4 +75,5 @@ h1, h2, h3, h4, h5 { |
68 | 75 | @import "../../bower_components/bootswatch/flatly/_bootswatch.scss"; |
69 | 76 | @import "layout/scss/mixins"; |
70 | 77 | @import "layout/scss/bootstrap-overrides"; |
71 | -@import "layout/scss/layout" | |
78 | +@import "layout/scss/layout"; | |
79 | +@import "layout/scss/tables"; | ... | ... |
src/app/layout/scss/_bootstrap-overrides.scss
1 | -/* MAINBOX */ | |
2 | -.main-box { | |
3 | - border: 1px solid #e7ebee; | |
4 | - box-shadow: 0px 1px 1px rgba(0,0,0,0.1); | |
5 | - margin-bottom: 16px; | |
6 | - /* overflow: hidden; */ | |
7 | - @include border-radius($border-radius-base); | |
8 | - | |
9 | - @media (max-width: $break-xs-max) { | |
10 | - margin-bottom: 10px; | |
11 | - } | |
12 | - | |
13 | - h2 { | |
14 | - font-size: 1.3em; | |
15 | - line-height: 29px; | |
16 | - margin: 0; | |
17 | - padding: 0; | |
18 | - | |
19 | - @media (max-width: $break-xxs-max) { | |
20 | - margin-bottom: 5px; | |
21 | - } | |
22 | - } | |
23 | - &.no-header { | |
24 | - padding-top: 20px; | |
25 | - } | |
26 | - .main-box-header { | |
27 | - min-height: 50px; | |
28 | - padding: 10px 20px; | |
29 | - | |
30 | - &.with-border { | |
31 | - border-bottom: 1px solid #ecf0f1; | |
32 | - } | |
33 | - } | |
34 | - .main-box-body { | |
35 | - padding: 0 20px 20px 20px; | |
36 | - } | |
37 | -} | |
38 | - | |
39 | 1 | /* TABS */ |
40 | 2 | .nav-tabs { |
41 | 3 | background: #f9f9f9; | ... | ... |
src/app/layout/scss/_layout.scss
... | ... | @@ -0,0 +1,103 @@ |
1 | +/* TABLES */ | |
2 | +.table-hover > tbody > tr:hover > td, | |
3 | +.table-hover > tbody > tr:hover > th { | |
4 | + background-color: $default-bg-hover-color; | |
5 | +} | |
6 | +.table { | |
7 | + thead > tr { | |
8 | + > th { | |
9 | + border-bottom: 2px solid $main-bg-color; | |
10 | + text-transform: uppercase; | |
11 | + font-size: 0.875em; | |
12 | + | |
13 | + > a span { | |
14 | + color: $text-color; | |
15 | + } | |
16 | + } | |
17 | + } | |
18 | + tbody > tr { | |
19 | + > td { | |
20 | + font-size: 0.875em; | |
21 | + vertical-align: middle; | |
22 | + border-top: 1px solid $main-bg-color; | |
23 | + padding: 12px 8px; | |
24 | + | |
25 | + &:first-child { | |
26 | + font-size: 1.125em; | |
27 | + font-weight: bold; | |
28 | + } | |
29 | + } | |
30 | + td { | |
31 | + .call-type { | |
32 | + display: block; | |
33 | + font-size: 0.75em; | |
34 | + text-align: center; | |
35 | + } | |
36 | + .first-line { | |
37 | + line-height: 1.5; | |
38 | + font-weight: 400; | |
39 | + font-size: 1.125em; | |
40 | + | |
41 | + span { | |
42 | + font-size: 0.875em; | |
43 | + color: #969696; | |
44 | + font-weight: 300; | |
45 | + } | |
46 | + } | |
47 | + .second-line { | |
48 | + font-size: 0.875em; | |
49 | + line-height: 1.2; | |
50 | + } | |
51 | + } | |
52 | + &.table-line-fb > td { | |
53 | + background-color: #9daccb; | |
54 | + color: #262525; | |
55 | + } | |
56 | + &.table-line-twitter > td { | |
57 | + background-color: #9fccff; | |
58 | + color: #262525; | |
59 | + } | |
60 | + &.table-line-plus > td { | |
61 | + background-color: #eea59c; | |
62 | + color: #262525; | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + a { | |
67 | + &.table-link { | |
68 | + margin: 0 5px; | |
69 | + font-size: 1.125em; | |
70 | + | |
71 | + &:hover { | |
72 | + text-decoration: none; | |
73 | + color: #2980b9; | |
74 | + } | |
75 | + &.danger { | |
76 | + color: $red-color; | |
77 | + | |
78 | + &:hover { | |
79 | + color: $red-color-dark; | |
80 | + } | |
81 | + } | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + &.table-condensed { | |
86 | + tbody > tr { | |
87 | + > td { | |
88 | + padding: 8px 5px; | |
89 | + } | |
90 | + } | |
91 | + } | |
92 | +} | |
93 | + | |
94 | +.table-striped { | |
95 | + tbody > tr { | |
96 | + > td { | |
97 | + width: 50%; | |
98 | + background: none; | |
99 | + border: none; | |
100 | + border-bottom: 1px solid #ebebeb; | |
101 | + } | |
102 | + } | |
103 | +} | ... | ... |
... | ... | @@ -0,0 +1,15 @@ |
1 | +import {StateConfig, Component, Inject, Input, provide} from 'ng-forward'; | |
2 | +import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service"; | |
3 | +import {TranslateProfile} from "../../shared/pipes/translate-profile.filter"; | |
4 | + | |
5 | +@Component({ | |
6 | + selector: 'profile-data', | |
7 | + templateUrl: "app/profile/data/profile-data.html", | |
8 | + pipes: [TranslateProfile] | |
9 | +}) | |
10 | +export class ProfileDataComponent { | |
11 | + | |
12 | + @Input() | |
13 | + profile: noosfero.Profile; | |
14 | + | |
15 | +} | ... | ... |
... | ... | @@ -0,0 +1,45 @@ |
1 | +<!-- Basic data --> | |
2 | +<div class="main-box clearfix"> | |
3 | + <header class="main-box-header clearfix"> | |
4 | + <h2>{{"profile.basic_info" | translate}}</h2> | |
5 | + </header> | |
6 | + <div class="main-box-body clearfix"> | |
7 | + <div class="table-responsive"> | |
8 | + <table class="table table-striped table-hover"> | |
9 | + <tbody> | |
10 | + <tr> | |
11 | + <td> | |
12 | + {{"profile.type" | translate}} | |
13 | + </td> | |
14 | + <td> | |
15 | + <span class="label" ng-class="{'label-danger': ctrl.profile.type == 'Community', 'label-info': ctrl.profile.type == 'Person'}">{{ctrl.profile | translateProfile}}</span> | |
16 | + </td> | |
17 | + </tr> | |
18 | + </tbody> | |
19 | + </table> | |
20 | + </div> | |
21 | + </div> | |
22 | +</div> | |
23 | + | |
24 | +<!-- Custom Fields --> | |
25 | +<div class="main-box clearfix"> | |
26 | + <header class="main-box-header clearfix"> | |
27 | + <h2>{{"profile.others_info" | translate}}</h2> | |
28 | + </header> | |
29 | + <div class="main-box-body clearfix"> | |
30 | + <div class="table-responsive"> | |
31 | + <table class="table table-striped table-hover"> | |
32 | + <tbody> | |
33 | + <tr ng-repeat="(field, value) in ctrl.profile.additional_data"> | |
34 | + <td> | |
35 | + {{ field }} | |
36 | + </td> | |
37 | + <td> | |
38 | + {{ value }} | |
39 | + </td> | |
40 | + </tr> | |
41 | + </tbody> | |
42 | + </table> | |
43 | + </div> | |
44 | + </div> | |
45 | +</div> | ... | ... |
src/app/profile/info/profile-info.component.spec.ts
... | ... | @@ -8,6 +8,7 @@ describe("Components", () => { |
8 | 8 | let $q: ng.IQService; |
9 | 9 | let profileServiceMock: any; |
10 | 10 | let $stateParams: any; |
11 | + let amDateFormatMock: any; | |
11 | 12 | |
12 | 13 | beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => { |
13 | 14 | $rootScope = _$rootScope_; |
... | ... | @@ -17,6 +18,7 @@ describe("Components", () => { |
17 | 18 | beforeEach(() => { |
18 | 19 | $stateParams = jasmine.createSpyObj("$stateParams", ["profile"]); |
19 | 20 | profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile", "getActivities"]); |
21 | + amDateFormatMock = jasmine.createSpyObj("amDateFormatMock", ["transform"]); | |
20 | 22 | |
21 | 23 | let getCurrentProfileResponse = $q.defer(); |
22 | 24 | getCurrentProfileResponse.resolve({ id: 1 }); |
... | ... | @@ -29,7 +31,7 @@ describe("Components", () => { |
29 | 31 | }); |
30 | 32 | |
31 | 33 | it("get the profile activities", done => { |
32 | - let component: ProfileInfoComponent = new ProfileInfoComponent(profileServiceMock); | |
34 | + let component: ProfileInfoComponent = new ProfileInfoComponent(profileServiceMock, amDateFormatMock); | |
33 | 35 | $rootScope.$apply(); |
34 | 36 | expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled(); |
35 | 37 | expect(profileServiceMock.getActivities).toHaveBeenCalled(); | ... | ... |
src/app/profile/info/profile-info.component.ts
1 | 1 | import {StateConfig, Component, Inject, provide} from 'ng-forward'; |
2 | 2 | import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service"; |
3 | +import {ProfileDataComponent} from "../data/profile-data.component"; | |
4 | +import {TranslateProfile} from "../../shared/pipes/translate-profile.filter"; | |
3 | 5 | |
4 | 6 | @Component({ |
5 | 7 | selector: 'profile', |
6 | 8 | templateUrl: "app/profile/info/profile-info.html", |
7 | - providers: [provide('profileService', { useClass: ProfileService })] | |
9 | + providers: [provide('profileService', { useClass: ProfileService })], | |
10 | + directives: [ProfileDataComponent], | |
11 | + pipes: [TranslateProfile] | |
8 | 12 | }) |
9 | 13 | @Inject(ProfileService) |
10 | 14 | @Inject("amDateFormatFilter") |
... | ... | @@ -14,10 +18,10 @@ export class ProfileInfoComponent { |
14 | 18 | profile: noosfero.Profile; |
15 | 19 | |
16 | 20 | constructor(private profileService: ProfileService, private amDateFormatFilter: any) { |
17 | - this.activate(); | |
21 | + this.init(); | |
18 | 22 | } |
19 | 23 | |
20 | - activate() { | |
24 | + init() { | |
21 | 25 | this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => { |
22 | 26 | this.profile = profile; |
23 | 27 | return this.profileService.getActivities(<number>this.profile.id); | ... | ... |
src/app/profile/info/profile-info.html
... | ... | @@ -5,8 +5,9 @@ |
5 | 5 | <header class="main-box-header clearfix"> |
6 | 6 | <h2>{{vm.profile.name}}</h2> |
7 | 7 | </header> |
8 | - <div class="main-box-body clearfix"> | |
8 | + <div id="profile-left" class="main-box-body clearfix"> | |
9 | 9 | <noosfero-profile-image [profile]="vm.profile" class="img-responsive center-block"></noosfero-profile-image> |
10 | + <span class="label" ng-class="{'label-danger': vm.profile.type == 'Community', 'label-info': vm.profile.type == 'Person'}">{{vm.profile | translateProfile}}</span> | |
10 | 11 | <div class="profile-since"> |
11 | 12 | {{"profile.member_since" | translate}}: {{vm.profile.created_at | amDateFormat:'MMMM YYYY'}} |
12 | 13 | </div> |
... | ... | @@ -21,7 +22,7 @@ |
21 | 22 | <noosfero-activities [activities]="vm.activities"></noosfero-activities> |
22 | 23 | </uib-tab> |
23 | 24 | <uib-tab index="0" heading="{{ 'profile.about' | translate }}"> |
24 | - <!-- Profile data here --> | |
25 | + <profile-data [profile]="vm.profile"></profile-data> | |
25 | 26 | </uib-tab> |
26 | 27 | </uib-tabset> |
27 | 28 | </div> | ... | ... |
src/app/profile/profile.scss
... | ... | @@ -0,0 +1,14 @@ |
1 | +import {Pipe, Inject} from "ng-forward"; | |
2 | + | |
3 | +@Pipe("translateProfile") | |
4 | +@Inject("translateFilter") | |
5 | +export class TranslateProfile { | |
6 | + | |
7 | + constructor(private translateFilter: any) { } | |
8 | + | |
9 | + transform(profile: noosfero.Profile, options: any) { | |
10 | + | |
11 | + return this.translateFilter("profile." + profile.type.toLowerCase() + ".title"); | |
12 | + } | |
13 | + | |
14 | +} | ... | ... |
src/languages/en.json
... | ... | @@ -10,7 +10,12 @@ |
10 | 10 | "language.pt": "Portuguese", |
11 | 11 | "language.selector": "Language", |
12 | 12 | "profile.member_since": "Member since", |
13 | - "profile.about": "About me", | |
13 | + "profile.type": "Tipo", | |
14 | + "profile.about": "About", | |
15 | + "profile.basic_info": "Basic Information", | |
16 | + "profile.others_info": "Others", | |
17 | + "profile.community.title": "Community", | |
18 | + "profile.person.title": "Person", | |
14 | 19 | "activities.title": "Activities", |
15 | 20 | "activities.create_article.description": "has published on", |
16 | 21 | "activities.add_member_in_community.description": "has joined the community", | ... | ... |
src/languages/pt.json
... | ... | @@ -9,9 +9,13 @@ |
9 | 9 | "language.en": "Inglês", |
10 | 10 | "language.pt": "Português", |
11 | 11 | "language.selector": "Idioma", |
12 | - "profile.wall": "Mural do Perfil", | |
13 | 12 | "profile.member_since": "Membro desde", |
14 | - "profile.about": "Meus dados", | |
13 | + "profile.type": "Tipo", | |
14 | + "profile.about": "Sobre", | |
15 | + "profile.basic_info": "Dados básicos", | |
16 | + "profile.others_info": "Outras informações", | |
17 | + "profile.community.title": "Comunidade", | |
18 | + "profile.person.title": "Pessoa", | |
15 | 19 | "activities.title": "Atividades", |
16 | 20 | "activities.create_article.description": "publicou em", |
17 | 21 | "activities.add_member_in_community.description": "entrou na comunidade", | ... | ... |