Commit a2d3b211892afefe9fe4ccd041391af45501f4b6
1 parent
54fb0f85
Exists in
master
and in
4 other branches
User profile restyle. Feed(Atom) links for commits & issues
Showing
16 changed files
with
147 additions
and
92 deletions
Show diff stats
844 Bytes
app/assets/stylesheets/application.css
app/assets/stylesheets/projects.css.scss
| @@ -639,3 +639,11 @@ h4.middle-panel { | @@ -639,3 +639,11 @@ h4.middle-panel { | ||
| 639 | background: #4A2; | 639 | background: #4A2; |
| 640 | color: white; | 640 | color: white; |
| 641 | } | 641 | } |
| 642 | + | ||
| 643 | +.rss-icon { | ||
| 644 | + margin:0 15px; | ||
| 645 | + padding:5px; | ||
| 646 | + border:1px solid #ccc; | ||
| 647 | + border-radius:3px; | ||
| 648 | + float:left; | ||
| 649 | +} |
app/controllers/keys_controller.rb
| @@ -6,6 +6,10 @@ class KeysController < ApplicationController | @@ -6,6 +6,10 @@ class KeysController < ApplicationController | ||
| 6 | @keys = current_user.keys.all | 6 | @keys = current_user.keys.all |
| 7 | end | 7 | end |
| 8 | 8 | ||
| 9 | + def show | ||
| 10 | + @key = current_user.keys.find(params[:id]) | ||
| 11 | + end | ||
| 12 | + | ||
| 9 | def new | 13 | def new |
| 10 | @key = current_user.keys.new | 14 | @key = current_user.keys.new |
| 11 | 15 |
app/models/user.rb
| @@ -46,6 +46,10 @@ class User < ActiveRecord::Base | @@ -46,6 +46,10 @@ class User < ActiveRecord::Base | ||
| 46 | admin | 46 | admin |
| 47 | end | 47 | end |
| 48 | 48 | ||
| 49 | + def require_ssh_key? | ||
| 50 | + keys.count == 0 | ||
| 51 | + end | ||
| 52 | + | ||
| 49 | def can_create_project? | 53 | def can_create_project? |
| 50 | projects_limit >= my_own_projects.count | 54 | projects_limit >= my_own_projects.count |
| 51 | end | 55 | end |
app/views/commits/index.html.haml
| 1 | - content_for(:body_class, "project-page commits-page") | 1 | - content_for(:body_class, "project-page commits-page") |
| 2 | +- if current_user.private_token | ||
| 3 | + = content_for :rss_icon do | ||
| 4 | + .rss-icon | ||
| 5 | + = link_to project_commits_path(@project, :atom, { :private_token => current_user.private_token, :ref => @ref }) do | ||
| 6 | + = image_tag "rss_icon_gray.png", :width => 16, :title => "feed" | ||
| 2 | 7 | ||
| 3 | --#%a.right.button{:href => "#"} Download | ||
| 4 | --#-if can? current_user, :admin_project, @project | ||
| 5 | - %a.right.button.blue{:href => "#"} EDIT | ||
| 6 | - if params[:path] | 8 | - if params[:path] |
| 7 | %h2.icon | 9 | %h2.icon |
| 8 | %span | 10 | %span |
app/views/issues/index.html.haml
| 1 | +- if current_user.private_token | ||
| 2 | + = content_for :rss_icon do | ||
| 3 | + .rss-icon | ||
| 4 | + = link_to project_issues_path(@project, :atom, { :private_token => current_user.private_token }) do | ||
| 5 | + = image_tag "rss_icon_gray.png", :width => 16, :title => "feed" | ||
| 6 | + | ||
| 1 | %div#issues-table-holder | 7 | %div#issues-table-holder |
| 2 | %table.round-borders#issues-table | 8 | %table.round-borders#issues-table |
| 3 | %thead | 9 | %thead |
app/views/keys/_show.html.haml
| 1 | -%tr | ||
| 2 | - %td= truncate key.title, :lenght => 12 | ||
| 3 | - %td= truncate key.key, :lenght => 1114 | ||
| 4 | - %td= link_to 'Cancel', key, :confirm => 'Are you sure?', :method => :delete, :class => "grey-button negative delete-key", :id => "destroy_key_#{key.id}", :remote => true | 1 | +%a.update-item{:href => key_path(key)} |
| 2 | + %span.update-title | ||
| 3 | + = key.title | ||
| 4 | + %span.update-author | ||
| 5 | + Added | ||
| 6 | + = time_ago_in_words(key.created_at) | ||
| 7 | + ago |
app/views/keys/create.js.haml
| 1 | - if @key.valid? | 1 | - if @key.valid? |
| 2 | :plain | 2 | :plain |
| 3 | $("#new_key_dialog").dialog("close"); | 3 | $("#new_key_dialog").dialog("close"); |
| 4 | - $("#keys-table").append("#{escape_javascript(render(:partial => 'show', :locals => {:key => @key} ))}"); | 4 | + $("#keys-table .data").append("#{escape_javascript(render(:partial => 'show', :locals => {:key => @key} ))}"); |
| 5 | $("#no_ssh_key_defined").hide(); | 5 | $("#no_ssh_key_defined").hide(); |
| 6 | - else | 6 | - else |
| 7 | :plain | 7 | :plain |
app/views/keys/index.html.haml
| 1 | -%div#new-key-holder | 1 | +%h2.icon |
| 2 | + %span> | ||
| 3 | + SSH Keys | ||
| 4 | +%div#new-key-holder.right | ||
| 2 | = link_to "Add new", new_key_path, :remote => true, :class => "grey-button" | 5 | = link_to "Add new", new_key_path, :remote => true, :class => "grey-button" |
| 3 | %br | 6 | %br |
| 4 | 7 | ||
| 5 | -%table.round-borders#keys-table | ||
| 6 | - %tr | ||
| 7 | - %th title | ||
| 8 | - %th key | ||
| 9 | - %th Actions | ||
| 10 | - - @keys.each do |key| | ||
| 11 | - = render(:partial => 'show', :locals => {:key => key}) | 8 | +%div#keys-table{ :class => "update-data ui-box ui-box-small ui-box-big" } |
| 9 | + .data | ||
| 10 | + - @keys.each do |key| | ||
| 11 | + = render(:partial => 'show', :locals => {:key => key}) | ||
| 12 | 12 | ||
| 13 | :javascript | 13 | :javascript |
| 14 | $('.delete-key').live('ajax:success', function() { | 14 | $('.delete-key').live('ajax:success', function() { |
| 15 | - $(this).closest('tr').fadeOut(); }); | 15 | + $(this).closest('.update-item').fadeOut(); }); |
| 16 | 16 |
app/views/layouts/_head_panel.html.erb
| @@ -47,7 +47,7 @@ | @@ -47,7 +47,7 @@ | ||
| 47 | <% end %> | 47 | <% end %> |
| 48 | <% end %> | 48 | <% end %> |
| 49 | 49 | ||
| 50 | -<% if current_user.keys.all.empty? %> | 50 | +<% if current_user.require_ssh_key? %> |
| 51 | <div id="no_ssh_key_defined" class="big-message error"> | 51 | <div id="no_ssh_key_defined" class="big-message error"> |
| 52 | <p>No SSH Key is defined. You won't be able to use any Git command!. Click <%=link_to( 'here', keys_path ) %> to add one! | 52 | <p>No SSH Key is defined. You won't be able to use any Git command!. Click <%=link_to( 'here', keys_path ) %> to add one! |
| 53 | </div> | 53 | </div> |
app/views/layouts/_middle_panel.html.haml
| 1 | %h4.middle-panel | 1 | %h4.middle-panel |
| 2 | - .project_name= truncate @project.name, :length => 20 | 2 | + .project_name |
| 3 | + = truncate @project.name, :length => 20 | ||
| 3 | .git_url_wrapper | 4 | .git_url_wrapper |
| 4 | %input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo, :class => "one_click_select"} | 5 | %input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo, :class => "one_click_select"} |
| 6 | + = yield :rss_icon | ||
| 7 | + | ||
| 5 | - if @project.repo_exists? | 8 | - if @project.repo_exists? |
| 6 | .right= render :partial => "projects/refs", :locals => { :destination => controller.controller_name == "commits" ? "commits" : "tree" } | 9 | .right= render :partial => "projects/refs", :locals => { :destination => controller.controller_name == "commits" ? "commits" : "tree" } |
| 7 | 10 |
app/views/profile/password.html.haml
| 1 | -%p Note: after success password update you will be redirected to login page where you should login with new password | ||
| 2 | -= form_for @user, :url => profile_password_path, :method => :put do |f| | ||
| 3 | - -if @user.errors.any? | ||
| 4 | - #error_explanation | ||
| 5 | - %h2= "#{pluralize(@user.errors.count, "error")} prohibited this password from being saved:" | ||
| 6 | - %ul | ||
| 7 | - - @user.errors.full_messages.each do |msg| | ||
| 8 | - %li= msg | 1 | +.ui-box.width-100p.append-bottom-20 |
| 2 | + %h3 Password | ||
| 3 | + = form_for @user, :url => profile_password_path, :method => :put do |f| | ||
| 4 | + .data | ||
| 5 | + %p After successfull password update you will be redirected to login page where you should login with new password | ||
| 6 | + -if @user.errors.any? | ||
| 7 | + #error_explanation | ||
| 8 | + %ul | ||
| 9 | + - @user.errors.full_messages.each do |msg| | ||
| 10 | + %li= msg | ||
| 9 | 11 | ||
| 10 | - .form-row | ||
| 11 | - = f.label :password | ||
| 12 | - %br | ||
| 13 | - = f.password_field :password | ||
| 14 | - .form-row | ||
| 15 | - = f.label :password_confirmation | ||
| 16 | - %br | ||
| 17 | - = f.password_field :password_confirmation | ||
| 18 | - .actions | ||
| 19 | - = f.submit 'Save', :class => "grey-button" | 12 | + .form-row |
| 13 | + = f.label :password | ||
| 14 | + %br | ||
| 15 | + = f.password_field :password | ||
| 16 | + .form-row | ||
| 17 | + = f.label :password_confirmation | ||
| 18 | + %br | ||
| 19 | + = f.password_field :password_confirmation | ||
| 20 | + .buttons | ||
| 21 | + = f.submit 'Save', :class => "grey-button" | ||
| 22 | +.clear | ||
| 20 | 23 | ||
| 21 | -%br | ||
| 22 | -%br | ||
| 23 | -%br | ||
| 24 | - | ||
| 25 | -= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f| | ||
| 26 | - %p | ||
| 27 | - Current private token: | ||
| 28 | - - if current_user.private_token | ||
| 29 | - %strong | ||
| 30 | - = current_user.private_token | ||
| 31 | - %em.cred | ||
| 32 | - keep it in secret! | ||
| 33 | - - else | ||
| 34 | - %strong don`t have | ||
| 35 | - .actions | ||
| 36 | - - if current_user.private_token | ||
| 37 | - = f.submit 'Reset', :confirm => "Are you sure?", :class => "grey-button" | ||
| 38 | - - else | ||
| 39 | - = f.submit 'Generate', :class => "grey-button" | 24 | +.ui-box.width-100p |
| 25 | + %h3 | ||
| 26 | + Private token | ||
| 27 | + %em.cred.right | ||
| 28 | + keep it in secret! | ||
| 29 | + = form_for @user, :url => profile_reset_private_token_path, :method => :put do |f| | ||
| 30 | + .data | ||
| 31 | + %p Private token used to access application resources without authentication. | ||
| 32 | + %p For example its required to access commits feed. | ||
| 33 | + %hr | ||
| 34 | + %p.cgray | ||
| 35 | + - if current_user.private_token | ||
| 36 | + = text_field_tag "token", current_user.private_token | ||
| 37 | + - else | ||
| 38 | + You don`t have one yet. Click generate to fix it. | ||
| 39 | + .buttons | ||
| 40 | + - if current_user.private_token | ||
| 41 | + = f.submit 'Reset', :confirm => "Are you sure?", :class => "grey-button" | ||
| 42 | + - else | ||
| 43 | + = f.submit 'Generate', :class => "positive-button" | ||
| 40 | 44 |
app/views/profile/show.html.haml
| 1 | -%h2.icon | ||
| 2 | - %span> | ||
| 3 | - = @user.name | 1 | +.ui-box.width-100p |
| 2 | + %h3= @user.name | ||
| 3 | + = form_for @user, :url => profile_edit_path, :method => :put do |f| | ||
| 4 | + .data | ||
| 5 | + -if @user.errors.any? | ||
| 6 | + #error_explanation | ||
| 7 | + %ul | ||
| 8 | + - @user.errors.full_messages.each do |msg| | ||
| 9 | + %li= msg | ||
| 4 | 10 | ||
| 5 | -.clear | ||
| 6 | - | ||
| 7 | -= form_for @user, :url => profile_edit_path, :method => :put do |f| | ||
| 8 | - -if @user.errors.any? | ||
| 9 | - #error_explanation | ||
| 10 | - %ul | ||
| 11 | - - @user.errors.full_messages.each do |msg| | ||
| 12 | - %li= msg | ||
| 13 | - | ||
| 14 | - .form-row | ||
| 15 | - = f.label :name | ||
| 16 | - %br | ||
| 17 | - = f.text_field :name | ||
| 18 | - .form-row | ||
| 19 | - = f.label :email | ||
| 20 | - %br | ||
| 21 | - = f.text_field :email | ||
| 22 | - .form-row | ||
| 23 | - = f.label :skype | ||
| 24 | - %br | ||
| 25 | - = f.text_field :skype | ||
| 26 | - .form-row | ||
| 27 | - = f.label :linkedin | ||
| 28 | - %br | ||
| 29 | - = f.text_field :linkedin | ||
| 30 | - .form-row | ||
| 31 | - = f.label :twitter | ||
| 32 | - %br | ||
| 33 | - = f.text_field :twitter | ||
| 34 | - .actions | ||
| 35 | - = f.submit 'Save', :class => "grey-button" | 11 | + .form-row |
| 12 | + = f.label :name | ||
| 13 | + %br | ||
| 14 | + = f.text_field :name | ||
| 15 | + .form-row | ||
| 16 | + = f.label :email | ||
| 17 | + %br | ||
| 18 | + = f.text_field :email | ||
| 19 | + .form-row | ||
| 20 | + = f.label :skype | ||
| 21 | + %br | ||
| 22 | + = f.text_field :skype | ||
| 23 | + .form-row | ||
| 24 | + = f.label :linkedin | ||
| 25 | + %br | ||
| 26 | + = f.text_field :linkedin | ||
| 27 | + .form-row | ||
| 28 | + = f.label :twitter | ||
| 29 | + %br | ||
| 30 | + = f.text_field :twitter | ||
| 31 | + .buttons | ||
| 32 | + = f.submit 'Save', :class => "grey-button" | ||
| 36 | 33 |
spec/requests/keys_spec.rb
| @@ -16,9 +16,11 @@ describe "Issues" do | @@ -16,9 +16,11 @@ describe "Issues" do | ||
| 16 | it { should have_content(@key.title) } | 16 | it { should have_content(@key.title) } |
| 17 | 17 | ||
| 18 | describe "Destroy" do | 18 | describe "Destroy" do |
| 19 | + before { visit key_path(@key) } | ||
| 20 | + | ||
| 19 | it "should remove entry" do | 21 | it "should remove entry" do |
| 20 | expect { | 22 | expect { |
| 21 | - click_link "destroy_key_#{@key.id}" | 23 | + click_link "Remove" |
| 22 | }.to change { @user.keys.count }.by(-1) | 24 | }.to change { @user.keys.count }.by(-1) |
| 23 | end | 25 | end |
| 24 | end | 26 | end |
| @@ -47,8 +49,17 @@ describe "Issues" do | @@ -47,8 +49,17 @@ describe "Issues" do | ||
| 47 | 49 | ||
| 48 | page.should_not have_content("Add new public key") | 50 | page.should_not have_content("Add new public key") |
| 49 | page.should have_content "laptop" | 51 | page.should have_content "laptop" |
| 50 | - page.should have_content "publickey234=" | ||
| 51 | end | 52 | end |
| 52 | end | 53 | end |
| 53 | end | 54 | end |
| 55 | + | ||
| 56 | + describe "Show page" do | ||
| 57 | + before do | ||
| 58 | + @key = Factory :key, :user => @user | ||
| 59 | + visit key_path(@key) | ||
| 60 | + end | ||
| 61 | + | ||
| 62 | + it { page.should have_content @key.title } | ||
| 63 | + it { page.should have_content @key.key[0..10] } | ||
| 64 | + end | ||
| 54 | end | 65 | end |