#369: updated UI for user settings, ssh_keys

This commit is contained in:
Vokhmin Alexey V 2014-11-07 01:00:23 +03:00
parent 16808549ab
commit 6a78ab4993
28 changed files with 237 additions and 204 deletions

View File

@ -1,5 +1,6 @@
class Users::SettingsController < Users::BaseController class Users::SettingsController < Users::BaseController
include AvatarHelper include AvatarHelper
layout 'bootstrap'
before_filter :set_current_user before_filter :set_current_user
def profile def profile

View File

@ -1,8 +1,9 @@
class Users::SshKeysController < Users::BaseController class Users::SshKeysController < Users::BaseController
layout 'bootstrap'
skip_before_filter :find_user skip_before_filter :find_user
def index def index
@ssh_keys = current_user.ssh_keys @ssh_key = SshKey.new
end end
def create def create
@ -10,11 +11,12 @@ class Users::SshKeysController < Users::BaseController
if @ssh_key.save if @ssh_key.save
flash[:notice] = t 'flash.ssh_keys.saved' flash[:notice] = t 'flash.ssh_keys.saved'
redirect_to ssh_keys_path
else else
flash[:error] = t 'flash.ssh_keys.save_error' flash[:error] = t 'flash.ssh_keys.save_error'
flash[:warning] = @ssh_key.errors.full_messages.join('. ') unless @ssh_key.errors.blank? # flash[:warning] = @ssh_key.errors.full_messages.join('. ') unless @ssh_key.errors.blank?
render :index
end end
redirect_to ssh_keys_path
end end
def destroy def destroy

View File

@ -51,9 +51,9 @@ class User < Avatar
validates :language, inclusion: { in: LANGUAGES }, allow_blank: true validates :language, inclusion: { in: LANGUAGES }, allow_blank: true
attr_accessible :email, :password, :password_confirmation, :current_password, :remember_me, :login, :name, :uname, :language, attr_accessible :email, :password, :password_confirmation, :current_password, :remember_me, :login, :name, :uname, :language,
:site, :company, :professional_experience, :location, :sound_notifications, :hide_email :site, :company, :professional_experience, :location, :sound_notifications, :hide_email, :delete_avatar
attr_readonly :uname attr_readonly :uname
attr_accessor :login attr_accessor :login, :delete_avatar
scope :opened, -> { where('users.role != \'system\' OR users.role IS NULL') } scope :opened, -> { where('users.role != \'system\' OR users.role IS NULL') }
scope :real, -> { where(role: ['', nil]) } scope :real, -> { where(role: ['', nil]) }

View File

@ -1,10 +0,0 @@
.leftlist= f.label :avatar, t("layout.avatars.avatar_with_size", max: number_to_human_size(Avatar::MAX_AVATAR_SIZE))
.rightlist= image_tag(avatar_url(subject, :medium))
.leftlist
.rightlist
.check
%span#niceCheckbox1.niceCheck-main= check_box_tag "delete_avatar", 1, false, class: 'niceCheckbox1'
.forcheck= t('layout.avatars.delete_avatar')
.both
= f.file_field :avatar
.both

View File

@ -0,0 +1,10 @@
= f.input :avatar,
as: :file,
hint: t("layout.avatars.avatar_with_size", max: number_to_human_size(Avatar::MAX_AVATAR_SIZE))
.form-group
label.col-sm-3.control-label
.col-sm-9
= image_tag(avatar_url(subject, :medium))
= f.input :delete_avatar, as: :boolean, input_html: { name: 'delete_avatar' }

View File

@ -1,44 +0,0 @@
- if current_user.admin?
.leftlist= f.label :role, t("activerecord.attributes.user.role"), class: :label
.rightlist= f.select :role, User::ROLES, {}, {name: 'role'}
- if @user.new_record?
.leftlist= f.label :uname, t("activerecord.attributes.user.uname")
.rightlist= f.text_field :uname
.leftlist= f.label :password, t("activerecord.attributes.user.password")
.rightlist= f.password_field :password
.both
.leftlist= f.label :password_confirmation, t("activerecord.attributes.user.password_confirm")
.rightlist= f.password_field :password_confirmation
.both
.leftlist= f.label :name, t("activerecord.attributes.user.name")
.rightlist= f.text_field :name
.both
.leftlist= f.label :email, t("activerecord.attributes.user.email")
.rightlist= f.text_field :email
.both
.leftlist= f.label :hide_email, t("activerecord.attributes.user.hide_email")
.rightlist= f.check_box :hide_email
.both
.leftlist= f.label :site, t("activerecord.attributes.user.site")
.rightlist= f.text_field :site
.both
.leftlist= f.label :language, t("activerecord.attributes.user.language")
.rightlist= f.select :language, User::LANGUAGES_FOR_SELECT
.both
.leftlist= f.label :company, t("activerecord.attributes.user.company")
.rightlist= f.text_field :company
.both
.leftlist= f.label :location, t("activerecord.attributes.user.location")
.rightlist= f.text_field :location
.both
= render 'shared/avatar_form', subject: @user, f: f
.leftlist= f.label :professional_experience, t("activerecord.attributes.user.professional_experience")
.rightlist= f.text_area :professional_experience
.both
.leftlist= f.label :sound_notifications, t("activerecord.attributes.user.sound_notifications")
.rightlist= f.check_box :sound_notifications
.both
.leftlist
\ 
.rightlist= submit_tag t('layout.save'), data: {'disable-with' => t('layout.saving')}
.both

View File

@ -0,0 +1,25 @@
- if current_user.admin?
= f.input :role,
collection: User::ROLES,
input_html: { name: 'role' },
include_blank: false
- if @user.new_record?
= f.input :uname
= f.input :password
= f.input :password_confirmation
= f.input :name
= f.input :email
= f.input :hide_email, as: :boolean
= f.input :site
= f.input :language, collection: User::LANGUAGES_FOR_SELECT, include_blank: false
= f.input :company
= f.input :location
= render 'shared/avatar_form', subject: @user, f: f
= f.input :professional_experience, as: :text
= f.input :sound_notifications, as: :boolean
= f.button :submit, t('layout.save')

View File

@ -1,7 +0,0 @@
%aside
.admin-preferences
%ul
%li{class: action_name == 'profile' ? 'active' : nil}= link_to t('layout.users.profile'), profile_settings_path
%li{class: action_name == 'private' ? 'active' : nil}= link_to t('layout.users.user_private_settings'), private_settings_path
%li{class: action_name == 'notifiers' ? 'active' : nil}= link_to t('layout.users.settings_notifier'), notifiers_settings_path
%li{class: controller_name == 'ssh_keys' ? 'active' : nil}= link_to t('ssh_keys'), ssh_keys_path

View File

@ -0,0 +1,26 @@
- content_for :submenu do
- act = action_name.to_sym
- contr = controller_name.to_sym
nav.navbar.navbar-default role='navigation'
.container-fluid
/ Brand and toggle get grouped for better mobile display
.navbar-header
button.navbar-toggle data-target='#submenu-navbar-collapse' data-toggle='collapse' type='button'
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
.navbar-brand
= link_to current_user.uname, current_user
/ Collect the nav links, forms, and other content for toggling
#submenu-navbar-collapse.collapse.navbar-collapse
ul.nav.navbar-nav.left-border
li class=('active' if act == :profile)
= link_to t('layout.users.profile'), profile_settings_path
li class=('active' if act == :private)
= link_to t('layout.users.user_private_settings'), private_settings_path
li class=('active' if act == :notifiers)
= link_to t('layout.users.settings_notifier'), notifiers_settings_path
li class=('active' if contr == :ssh_keys)
= link_to t('ssh_keys'), ssh_keys_path

View File

@ -1,3 +0,0 @@
.leftside.w25= f.check_box field
.leftside= f.label field, t("activerecord.attributes.settings.notifier.#{field}")
.both

View File

@ -1,31 +0,0 @@
-set_meta_tags title: t('layout.users.settings_notifier')
%p
= t("layout.settings.notifiers.notice_header", email: @user.email)
%br
= link_to t("layout.settings.notifiers.change_email_link"), profile_settings_path
%br
%br
= form_for @user.notifier, url: notifiers_settings_path, html: {class: :form} do |f|
= render 'notifier', f: f, field: :can_notify
%h3= t("layout.settings.notifiers.code_header")
- [:update_code, :new_comment_commit_owner, :new_comment_commit_repo_owner, :new_comment_commit_commentor].each do |field|
= render 'notifier', f: f, field: field
%h3= t("layout.settings.notifiers.tracker_header")
- [:new_comment, :new_comment_reply, :new_issue, :issue_assign].each do |field|
= render 'notifier', f: f, field: field
%h3= t("layout.settings.notifiers.build_list_header")
- [:new_build, :new_associated_build].each do |field|
= render 'notifier', f: f, field: field
%br
.leftside.w25
\ 
.leftside.w420= submit_tag t('layout.save'), data: {'disable-with' => t('layout.saving')}
.both
:javascript
disableNotifierCbx($('#settings_notifier_can_notify'));
$('article .right').addClass('bigpadding');
- content_for :sidebar, render('sidebar')

View File

@ -0,0 +1,43 @@
- set_meta_tags title: t('layout.users.settings_notifier')
= render 'users/base/submenu'
.container.col-md-offset-2.col-md-8
.row
p
= t('layout.settings.notifiers.notice_header', email: @user.email)
= link_to t("layout.settings.notifiers.change_email_link"), profile_settings_path
hr
= simple_form_for @user.notifier,
url: notifiers_settings_path,
wrapper: :horizontal_form,
wrapper_mappings: { boolean: :horizontal_boolean } do |f|
.row
.col-md-6
= f.input :can_notify, as: :boolean
.col-sm-offset-3.col-sm-9
h4
= t('layout.settings.notifiers.code_header')
- [:update_code, :new_comment_commit_owner, :new_comment_commit_repo_owner, :new_comment_commit_commentor].each do |field|
= f.input field, as: :boolean
.col-md-6
.col-sm-offset-3.col-sm-9
h4
= t('layout.settings.notifiers.tracker_header')
- [:new_comment, :new_comment_reply, :new_issue, :issue_assign].each do |field|
= f.input field, as: :boolean
.col-sm-offset-3.col-sm-9
h4
= t('layout.settings.notifiers.build_list_header')
- [:new_build, :new_associated_build].each do |field|
= f.input field, as: :boolean
.row
hr
= f.button :submit, t('layout.save')

View File

@ -1,31 +0,0 @@
-set_meta_tags title: t('layout.users.settings')
%h3.fix.bpadding10= t('layout.users.private_settings_header')
= form_for @user, url: private_settings_path, html: {class: :form} do |f|
.leftlist= f.label :current_password
.rightlist= f.password_field :current_password
.both
.leftlist= f.label :password
.rightlist= f.password_field :password
.both
.leftlist= f.label :password_confirmation
.rightlist= f.password_field :password_confirmation
.both
.leftlist
\ 
.rightlist= submit_tag t('layout.save'), data: {'disable-with' => t('layout.saving')}
.both
%br
= form_for @user, url: reset_auth_token_settings_path, html: { class: :form, method: :put } do |f|
.leftlist= f.label :authentication_token
.rightlist= @user.authentication_token
.both
.leftlist
.rightlist= submit_tag t('layout.users.reset_token'), data: {'disable-with' => t('layout.saving')}
.both
:javascript
$('article .right').addClass('middlepadding');
- content_for :sidebar, render('sidebar')

View File

@ -0,0 +1,24 @@
- set_meta_tags title: t('layout.users.settings')
= render 'users/base/submenu'
.container.col-md-offset-2.col-md-8
.row
h3
= t('layout.users.private_settings_header')
= simple_form_for @user, url: private_settings_path do |f|
= f.input :current_password
= f.input :password
= f.input :password_confirmation
= f.button :submit, t('layout.save')
hr
= simple_form_for @user,
url: reset_auth_token_settings_path,
html: { method: :put } do |f|
= f.input :authentication_token, disabled: true
= f.button :submit, t('layout.users.reset_token')

View File

@ -1,15 +0,0 @@
-set_meta_tags title: t('.title')
%h3.fix.bpadding10= @user.uname
= form_for @user, url: profile_settings_path, html: {class: :form} do |f|
= render 'form', f: f
.notify
%p= t('layout.users.public_data_edit_warning')
.notify
%p= t('layout.avatars.avatar_notice')
:javascript
$('article .right').addClass('middlepadding');
- content_for :sidebar, render('sidebar')

View File

@ -0,0 +1,22 @@
- set_meta_tags title: t('.title')
= render 'users/base/submenu'
.container.col-md-offset-2.col-md-8
.row
h3
= @user.uname
= simple_form_for @user,
url: profile_settings_path,
wrapper: :horizontal_form,
wrapper_mappings: { boolean: :horizontal_boolean } do |f|
= render 'form', f: f
.row
hr
.alert.alert-danger
= t('layout.users.public_data_edit_warning')
.alert.alert-danger
= t('layout.avatars.avatar_notice')

View File

@ -0,0 +1,15 @@
table.table.table-striped
thead
tr
th= t('ssh_keys')
th= t('layout.delete')
tbody
- current_user.ssh_keys.each do |key|
tr
td= "#{key.name} (#{key.fingerprint})"
td.buttons
= link_to ssh_key_path(key),
method: :delete,
data: { confirm: t('layout.confirm') } do
span.glyphicon.glyphicon-remove

View File

@ -0,0 +1,7 @@
h3
= t("layout.key_pairs.header")
= simple_form_for @ssh_key, url: ssh_keys_path do |f|
= f.input :name
= f.input :key, as: :text
= f.button :submit, t('layout.save')

View File

@ -1,26 +0,0 @@
= form_tag ssh_keys_path, id: 'ssh_keys_form' do
= hidden_field_tag "_method", "post"
%table.tablesorter{cellpadding: "0", cellspacing: "0"}
%thead
%tr
%th= title t('ssh_keys')
%th{colspan: "2"}= t 'layout.delete'
%tbody
- @ssh_keys.each do |key|
%tr
%td="#{key.name} (#{key.fingerprint})"
%td= link_to image_tag('x.png'), ssh_key_path(key), method: :delete, data: { confirm: t('layout.confirm') }
.both
%h3.fix.bpadding10= t 'add_key'
= form_for SshKey.new, url: ssh_keys_path, html: {class: :form} do |f|
.leftlist= f.label :name, t('activerecord.attributes.ssh_key.name')
.rightlist= f.text_field :name
.both
.leftlist= f.label :key, t('activerecord.attributes.ssh_key.key')
.rightlist= f.text_area :key
%br
= f.submit t('layout.add'), data: {'disable-with' => t('layout.processing')}
- content_for :sidebar, render('sidebar')

View File

@ -0,0 +1,7 @@
= render 'users/base/submenu'
.container.col-md-offset-2.col-md-8
.row
= render 'new'
hr
= render 'list'

View File

@ -169,20 +169,6 @@ en:
product_build_list: Product build list product_build_list: Product build list
attributes: attributes:
settings:
notifier:
can_notify: Notifications by email
new_comment: New task comment notifications
new_comment_reply: New reply of comment notifications
new_issue: New task notifications
issue_assign: New task assignment notifications
update_code: Notify about changes of code in my projects
new_comment_commit_owner: Notify about comments to my commit
new_comment_commit_repo_owner: Notify about comments to my repository commits
new_comment_commit_commentor: Notify about comments after my commit
new_build: Notify about my build tasks
new_associated_build: Notify about associated with me build tasks
arch: arch:
name: Name name: Name
created_at: Created created_at: Created

View File

@ -2,5 +2,4 @@ en:
layout: layout:
avatars: avatars:
avatar_notice: Without uploaded avatar will be used avatar from gravar web service. avatar_notice: Without uploaded avatar will be used avatar from gravar web service.
delete_avatar: Delete avatar
avatar_with_size: Avatar (less than %{max}) avatar_with_size: Avatar (less than %{max})

View File

@ -2,5 +2,4 @@ ru:
layout: layout:
avatars: avatars:
avatar_notice: При отсутствии загруженного аватара будет использован Ваш аватар на сервисе gravatar. avatar_notice: При отсутствии загруженного аватара будет использован Ваш аватар на сервисе gravatar.
delete_avatar: Удалить аватар
avatar_with_size: Аватар (менее %{max}) avatar_with_size: Аватар (менее %{max})

View File

@ -0,0 +1,18 @@
en:
simple_form:
labels:
settings_notifier:
can_notify: Notifications by email
new_comment: New task comment notifications
new_comment_reply: New reply of comment notifications
new_issue: New task notifications
issue_assign: New task assignment notifications
update_code: Notify about changes of code in my projects
new_comment_commit_owner: Notify about comments to my commit
new_comment_commit_repo_owner: Notify about comments to my repository commits
new_comment_commit_commentor: Notify about comments after my commit
new_build: Notify about my build tasks
new_associated_build: Notify about associated with me build tasks
placeholders:
settings_notifier:

View File

@ -0,0 +1,18 @@
ru:
simple_form:
labels:
settings_notifier:
can_notify: Включить оповещения по электронной почте
new_comment: Оповещать о новом комментарии в задаче
new_comment_reply: Оповещать о новом ответе на мой комментарий
new_issue: Оповещать о новых задачах в моих проектах
issue_assign: Оповещать, когда на меня выставляют задачу
update_code: Оповещать об изменении кода в моих проектах
new_comment_commit_owner: Оповещать о комментариях к моему коммиту
new_comment_commit_repo_owner: Оповещать о комментариях к коммитам в моем репозитории
new_comment_commit_commentor: Оповещать о комментариях к коммиту после моего
new_build: Оповещать о моих сборочных заданиях
new_associated_build: Оповещать о связанных со мной сборочных заданиях
placeholders:
settings_notifier:

View File

@ -167,22 +167,6 @@ ru:
models: models:
product_build_list: Сборочный лист продукта product_build_list: Сборочный лист продукта
attributes:
settings:
notifier:
can_notify: Включить оповещения по электронной почте
new_comment: Оповещать о новом комментарии в задаче
new_comment_reply: Оповещать о новом ответе на мой комментарий
new_issue: Оповещать о новых задачах в моих проектах
issue_assign: Оповещать, когда на меня выставляют задачу
update_code: Оповещать об изменении кода в моих проектах
new_comment_commit_owner: Оповещать о комментариях к моему коммиту
new_comment_commit_repo_owner: Оповещать о комментариях к коммитам в моем репозитории
new_comment_commit_commentor: Оповещать о комментариях к коммиту после моего
new_build: Оповещать о моих сборочных заданиях
new_associated_build: Оповещать о связанных со мной сборочных заданиях
arch: arch:
name: Название name: Название
created_at: Создана created_at: Создана

View File

@ -55,3 +55,10 @@ en:
avatar: Avatar avatar: Avatar
avatar_file_size: Avatar file size avatar_file_size: Avatar file size
authentication_token: API token authentication_token: API token
simple_form:
labels:
user:
delete_avatar: Delete avatar
placeholders:
user:

View File

@ -55,3 +55,10 @@ ru:
avatar: Аватар avatar: Аватар
avatar_file_size: Размер аватара avatar_file_size: Размер аватара
authentication_token: API токен authentication_token: API токен
simple_form:
labels:
user:
delete_avatar: Удалить аватар
placeholders:
user: