Commit c2abd5b3c556a651216f070ba6696c23f33d383c
1 parent
c1e0c406
Exists in
master
and in
30 other branches
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,12 +24,19 @@ $main-bg-color: #e7ebee; | ||
| 24 | $primary-color: #03a9f4; | 24 | $primary-color: #03a9f4; |
| 25 | $primary-color-dark: #0288d1; | 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 | //GRID - media queries breakpoints | 32 | //GRID - media queries breakpoints |
| 28 | $break-xxs-min: 420px; | 33 | $break-xxs-min: 420px; |
| 29 | $break-xs-min: 768px; | 34 | $break-xs-min: 768px; |
| 30 | 35 | ||
| 31 | $break-xxs-max: ($break-xxs-min - 1); | 36 | $break-xxs-max: ($break-xxs-min - 1); |
| 32 | $break-xs-max: ($break-xs-min - 1); | 37 | $break-xs-max: ($break-xs-min - 1); |
| 38 | + | ||
| 39 | + | ||
| 33 | @import "../../bower_components/bootswatch/flatly/_variables.scss"; | 40 | @import "../../bower_components/bootswatch/flatly/_variables.scss"; |
| 34 | 41 | ||
| 35 | /** | 42 | /** |
| @@ -68,4 +75,5 @@ h1, h2, h3, h4, h5 { | @@ -68,4 +75,5 @@ h1, h2, h3, h4, h5 { | ||
| 68 | @import "../../bower_components/bootswatch/flatly/_bootswatch.scss"; | 75 | @import "../../bower_components/bootswatch/flatly/_bootswatch.scss"; |
| 69 | @import "layout/scss/mixins"; | 76 | @import "layout/scss/mixins"; |
| 70 | @import "layout/scss/bootstrap-overrides"; | 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 | /* TABS */ | 1 | /* TABS */ |
| 40 | .nav-tabs { | 2 | .nav-tabs { |
| 41 | background: #f9f9f9; | 3 | background: #f9f9f9; |
src/app/layout/scss/_layout.scss
| @@ -0,0 +1,103 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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,6 +8,7 @@ describe("Components", () => { | ||
| 8 | let $q: ng.IQService; | 8 | let $q: ng.IQService; |
| 9 | let profileServiceMock: any; | 9 | let profileServiceMock: any; |
| 10 | let $stateParams: any; | 10 | let $stateParams: any; |
| 11 | + let amDateFormatMock: any; | ||
| 11 | 12 | ||
| 12 | beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => { | 13 | beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => { |
| 13 | $rootScope = _$rootScope_; | 14 | $rootScope = _$rootScope_; |
| @@ -17,6 +18,7 @@ describe("Components", () => { | @@ -17,6 +18,7 @@ describe("Components", () => { | ||
| 17 | beforeEach(() => { | 18 | beforeEach(() => { |
| 18 | $stateParams = jasmine.createSpyObj("$stateParams", ["profile"]); | 19 | $stateParams = jasmine.createSpyObj("$stateParams", ["profile"]); |
| 19 | profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile", "getActivities"]); | 20 | profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile", "getActivities"]); |
| 21 | + amDateFormatMock = jasmine.createSpyObj("amDateFormatMock", ["transform"]); | ||
| 20 | 22 | ||
| 21 | let getCurrentProfileResponse = $q.defer(); | 23 | let getCurrentProfileResponse = $q.defer(); |
| 22 | getCurrentProfileResponse.resolve({ id: 1 }); | 24 | getCurrentProfileResponse.resolve({ id: 1 }); |
| @@ -29,7 +31,7 @@ describe("Components", () => { | @@ -29,7 +31,7 @@ describe("Components", () => { | ||
| 29 | }); | 31 | }); |
| 30 | 32 | ||
| 31 | it("get the profile activities", done => { | 33 | it("get the profile activities", done => { |
| 32 | - let component: ProfileInfoComponent = new ProfileInfoComponent(profileServiceMock); | 34 | + let component: ProfileInfoComponent = new ProfileInfoComponent(profileServiceMock, amDateFormatMock); |
| 33 | $rootScope.$apply(); | 35 | $rootScope.$apply(); |
| 34 | expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled(); | 36 | expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled(); |
| 35 | expect(profileServiceMock.getActivities).toHaveBeenCalled(); | 37 | expect(profileServiceMock.getActivities).toHaveBeenCalled(); |
src/app/profile/info/profile-info.component.ts
| 1 | import {StateConfig, Component, Inject, provide} from 'ng-forward'; | 1 | import {StateConfig, Component, Inject, provide} from 'ng-forward'; |
| 2 | import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service"; | 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 | @Component({ | 6 | @Component({ |
| 5 | selector: 'profile', | 7 | selector: 'profile', |
| 6 | templateUrl: "app/profile/info/profile-info.html", | 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 | @Inject(ProfileService) | 13 | @Inject(ProfileService) |
| 10 | @Inject("amDateFormatFilter") | 14 | @Inject("amDateFormatFilter") |
| @@ -14,10 +18,10 @@ export class ProfileInfoComponent { | @@ -14,10 +18,10 @@ export class ProfileInfoComponent { | ||
| 14 | profile: noosfero.Profile; | 18 | profile: noosfero.Profile; |
| 15 | 19 | ||
| 16 | constructor(private profileService: ProfileService, private amDateFormatFilter: any) { | 20 | constructor(private profileService: ProfileService, private amDateFormatFilter: any) { |
| 17 | - this.activate(); | 21 | + this.init(); |
| 18 | } | 22 | } |
| 19 | 23 | ||
| 20 | - activate() { | 24 | + init() { |
| 21 | this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => { | 25 | this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => { |
| 22 | this.profile = profile; | 26 | this.profile = profile; |
| 23 | return this.profileService.getActivities(<number>this.profile.id); | 27 | return this.profileService.getActivities(<number>this.profile.id); |
src/app/profile/info/profile-info.html
| @@ -5,8 +5,9 @@ | @@ -5,8 +5,9 @@ | ||
| 5 | <header class="main-box-header clearfix"> | 5 | <header class="main-box-header clearfix"> |
| 6 | <h2>{{vm.profile.name}}</h2> | 6 | <h2>{{vm.profile.name}}</h2> |
| 7 | </header> | 7 | </header> |
| 8 | - <div class="main-box-body clearfix"> | 8 | + <div id="profile-left" class="main-box-body clearfix"> |
| 9 | <noosfero-profile-image [profile]="vm.profile" class="img-responsive center-block"></noosfero-profile-image> | 9 | <noosfero-profile-image [profile]="vm.profile" class="img-responsive center-block"></noosfero-profile-image> |
| 10 | + <span class="label" ng-class="{'label-danger': vm.profile.type == 'Community', 'label-info': vm.profile.type == 'Person'}">{{vm.profile | translateProfile}}</span> | ||
| 10 | <div class="profile-since"> | 11 | <div class="profile-since"> |
| 11 | {{"profile.member_since" | translate}}: {{vm.profile.created_at | amDateFormat:'MMMM YYYY'}} | 12 | {{"profile.member_since" | translate}}: {{vm.profile.created_at | amDateFormat:'MMMM YYYY'}} |
| 12 | </div> | 13 | </div> |
| @@ -21,7 +22,7 @@ | @@ -21,7 +22,7 @@ | ||
| 21 | <noosfero-activities [activities]="vm.activities"></noosfero-activities> | 22 | <noosfero-activities [activities]="vm.activities"></noosfero-activities> |
| 22 | </uib-tab> | 23 | </uib-tab> |
| 23 | <uib-tab index="0" heading="{{ 'profile.about' | translate }}"> | 24 | <uib-tab index="0" heading="{{ 'profile.about' | translate }}"> |
| 24 | - <!-- Profile data here --> | 25 | + <profile-data [profile]="vm.profile"></profile-data> |
| 25 | </uib-tab> | 26 | </uib-tab> |
| 26 | </uib-tabset> | 27 | </uib-tabset> |
| 27 | </div> | 28 | </div> |
src/app/profile/profile.scss
| @@ -0,0 +1,14 @@ | @@ -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,7 +10,12 @@ | ||
| 10 | "language.pt": "Portuguese", | 10 | "language.pt": "Portuguese", |
| 11 | "language.selector": "Language", | 11 | "language.selector": "Language", |
| 12 | "profile.member_since": "Member since", | 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 | "activities.title": "Activities", | 19 | "activities.title": "Activities", |
| 15 | "activities.create_article.description": "has published on", | 20 | "activities.create_article.description": "has published on", |
| 16 | "activities.add_member_in_community.description": "has joined the community", | 21 | "activities.add_member_in_community.description": "has joined the community", |
src/languages/pt.json
| @@ -9,9 +9,13 @@ | @@ -9,9 +9,13 @@ | ||
| 9 | "language.en": "Inglês", | 9 | "language.en": "Inglês", |
| 10 | "language.pt": "Português", | 10 | "language.pt": "Português", |
| 11 | "language.selector": "Idioma", | 11 | "language.selector": "Idioma", |
| 12 | - "profile.wall": "Mural do Perfil", | ||
| 13 | "profile.member_since": "Membro desde", | 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 | "activities.title": "Atividades", | 19 | "activities.title": "Atividades", |
| 16 | "activities.create_article.description": "publicou em", | 20 | "activities.create_article.description": "publicou em", |
| 17 | "activities.add_member_in_community.description": "entrou na comunidade", | 21 | "activities.add_member_in_community.description": "entrou na comunidade", |