]> cat aescling's git repositories - mastodon.git/commitdiff
Improved admin UI
authorEugen Rochko <eugen@zeonfederated.com>
Tue, 13 Dec 2016 12:42:10 +0000 (13:42 +0100)
committerEugen Rochko <eugen@zeonfederated.com>
Tue, 13 Dec 2016 12:42:10 +0000 (13:42 +0100)
23 files changed:
Gemfile
Gemfile.lock
app/assets/javascripts/components/features/notifications/index.jsx
app/assets/stylesheets/admin.scss [new file with mode: 0644]
app/assets/stylesheets/application.scss
app/assets/stylesheets/tables.scss
app/controllers/admin/accounts_controller.rb
app/controllers/admin/domain_blocks_controller.rb [new file with mode: 0644]
app/controllers/admin/pubsubhubbub_controller.rb
app/helpers/admin/accounts_helper.rb
app/helpers/admin/domain_blocks_helper.rb [new file with mode: 0644]
app/helpers/admin/pubsubhubbub_helper.rb
app/views/admin/accounts/index.html.haml
app/views/admin/domain_blocks/index.html.haml [new file with mode: 0644]
app/views/admin/pubsubhubbub/index.html.haml
app/views/layouts/admin.html.haml [new file with mode: 0644]
config/navigation.rb [new file with mode: 0644]
config/routes.rb
spec/controllers/admin/domain_blocks_controller_spec.rb [new file with mode: 0644]
spec/helpers/admin/accounts_helper_spec.rb
spec/helpers/admin/domain_blocks_helper_spec.rb [new file with mode: 0644]
spec/helpers/admin/pubsubhubbub_helper_spec.rb
spec/lib/formatter_spec.rb

diff --git a/Gemfile b/Gemfile
index 95fd046295118c955473289459b20f19d7953cf7..db6cb7f44895997e08a2d785c68c53a06c4c884e 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -45,6 +45,7 @@ gem 'rack-timeout-puma'
 gem 'sidekiq'
 gem 'ledermann-rails-settings'
 gem 'pg_search'
+gem 'simple-navigation'
 
 gem 'react-rails'
 gem 'browserify-rails'
index cc7751ae19b4c05f1d11f3bef2a9af7dc364708e..c3ddf33fcaab66359a675a017dd4949e1ec642a8 100644 (file)
@@ -353,6 +353,8 @@ GEM
       connection_pool (~> 2.2, >= 2.2.0)
       rack-protection (>= 1.5.0)
       redis (~> 3.2, >= 3.2.1)
+    simple-navigation (4.0.3)
+      activesupport (>= 2.3.2)
     simple_form (3.2.1)
       actionpack (> 4, < 5.1)
       activemodel (> 4, < 5.1)
@@ -458,6 +460,7 @@ DEPENDENCIES
   sass-rails (~> 5.0)
   sdoc (~> 0.4.0)
   sidekiq
+  simple-navigation
   simple_form
   simplecov
   uglifier (>= 1.3.0)
index 00feeece78f24136dbacbd961636c404f0806ac5..218196cfd30904df92840a41acc8a02988072aa4 100644 (file)
@@ -26,6 +26,12 @@ const Notifications = React.createClass({
     trackScroll: React.PropTypes.bool
   },
 
+  getDefaultProps () {
+    return {
+      trackScroll: true
+    };
+  },
+
   mixins: [PureRenderMixin],
 
   componentWillMount () {
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
new file mode 100644 (file)
index 0000000..6e4234d
--- /dev/null
@@ -0,0 +1,105 @@
+.admin-wrapper {
+  width: 100%;
+  height: 100%;
+  position: fixed;
+  background: #1a1c23;
+  overflow-y: scroll;
+
+  .sidebar {
+    width: 240px;
+    position: fixed;
+    left: 0;
+    height: 100%;
+    background: #282c37;
+
+    .logo {
+      display: block;
+      margin: 40px auto;
+      width: 100px;
+      height: 100px;
+    }
+
+    ul {
+      list-style: none;
+
+      a {
+        display: block;
+        padding: 15px 25px;
+        color: rgba(255, 255, 255, 0.7);
+        text-decoration: none;
+        transition: all 200ms linear;
+
+        i.fa {
+          margin-right: 5px;
+        }
+
+        &:hover {
+          color: #fff;
+          background-color: darken(#282c37, 5%);
+          transition: all 100ms linear;
+        }
+
+        &.selected {
+          color: #fff;
+          background-color: #2b90d9;
+
+          &:hover {
+            background-color: lighten(#2b90d9, 5%);
+          }
+        }
+      }
+    }
+  }
+
+  .content {
+    margin-left: 240px;
+    padding: 15px;
+  }
+}
+
+.filters {
+  display: flex;
+  margin-bottom: 20px;
+  padding-left: 8px;
+
+  .filter-subset {
+    flex: 0 0 auto;
+    margin-right: 40px;
+
+    ul {
+      margin-top: 5px;
+      list-style: none;
+
+      li {
+        display: inline-block;
+        margin-right: 5px;
+      }
+    }
+
+    strong {
+      font-weight: 500;
+      text-transform: uppercase;
+      font-size: 12px;
+    }
+
+    a {
+      display: inline-block;
+      color: rgba(255, 255, 255, 0.7);
+      text-decoration: none;
+      text-transform: uppercase;
+      font-size: 12px;
+      font-weight: 500;
+      border-bottom: 2px solid #282c37;
+
+      &:hover {
+        color: #fff;
+        border-bottom: 2px solid lighten(#282c37, 5%);
+      }
+
+      &.selected {
+        color: #2b90d9;
+        border-bottom: 2px solid #2b90d9;
+      }
+    }
+  }
+}
index bbbeafefe35c20f5f63d187ea44b8a1395d2af58..609b3072649243e7dbc8bbf947b0e73fd56361ae 100644 (file)
@@ -235,3 +235,4 @@ body {
 @import 'components';
 @import 'about';
 @import 'tables';
+@import 'admin';
index b28b911912f6a5c306a67a2c8552a19f910b2207..a378707867291eb745c8cc109d57fde54f6cc91e 100644 (file)
@@ -7,15 +7,15 @@
 
   th, td {
     padding: 8px;
-    line-height: 1.42857143;
+    line-height: 18px;
     vertical-align: top;
-    border-top: 1px solid #ddd;
+    border-top: 1px solid #282c37;
     text-align: left;
   }
 
   & > thead > tr > th {
     vertical-align: bottom;
-    border-bottom: 2px solid #ddd;
+    border-bottom: 2px solid #282c37;
     border-top: 0;
     font-weight: 500;
   }
     font-weight: 500;
   }
 
+  & > tbody > tr:nth-child(odd) > td, & > tbody > tr:nth-child(odd) > th {
+    background: lighten(#1a1c23, 2%);
+  }
+
   a {
     color: #2b90d9;
     text-decoration: underline;
@@ -38,20 +42,20 @@ samp {
   font-family: 'Roboto Mono', monospace;
 }
 
-.filters {
-  list-style: none;
-  margin-bottom: 20px;
+a.table-action-link {
+  text-decoration: none;
+  display: inline-block;
+  margin-right: 5px;
+  padding: 0 10px;
+  color: rgba(255, 255, 255, 0.7);
+  font-weight: 500;
 
-  li {
-    display: inline-block;
+  &:hover {
+    color: #fff;
   }
 
-  a {
-    color: #2b90d9;
-    text-decoration: underline;
-
-    &:hover {
-      text-decoration: none;
-    }
+  i.fa {
+    font-weight: 400;
+    margin-right: 5px;
   }
 }
index 55436d253b72b90a052c6645d6c52bdac0a46566..95107b3dc579f8f50ba90ba4f8049873c3aab146 100644 (file)
@@ -4,7 +4,7 @@ class Admin::AccountsController < ApplicationController
   before_action :require_admin!
   before_action :set_account, except: :index
 
-  layout 'public'
+  layout 'admin'
 
   def index
     @accounts = Account.alphabetic.paginate(page: params[:page], per_page: 40)
diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb
new file mode 100644 (file)
index 0000000..e362957
--- /dev/null
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class Admin::DomainBlocksController < ApplicationController
+  before_action :require_admin!
+
+  layout 'admin'
+
+  def index
+    @blocks = DomainBlock.paginate(page: params[:page], per_page: 40)
+  end
+
+  def create
+  end
+end
index 7e6bc75ea344b45738dad8f71adf3632f58861e8..b9e840ffe48e5328f09089c6bc198e1a4f61e351 100644 (file)
@@ -3,7 +3,7 @@
 class Admin::PubsubhubbubController < ApplicationController
   before_action :require_admin!
 
-  layout 'public'
+  layout 'admin'
 
   def index
     @subscriptions = Subscription.order('id desc').includes(:account).paginate(page: params[:page], per_page: 40)
index 5b9cbbacdce84660864765ff1fed8a8c9e0590d1..57cd972fa18927627c45121f4526a61133fa7363 100644 (file)
@@ -1,2 +1,15 @@
+# frozen_string_literal: true
+
 module Admin::AccountsHelper
+  def filter_params(more_params)
+    params.permit(:local, :remote, :by_domain, :silenced, :suspended, :recent).merge(more_params)
+  end
+
+  def filter_link_to(text, more_params)
+    link_to text, filter_params(more_params), class: params.merge(more_params).compact == params.compact ? 'selected' : ''
+  end
+
+  def table_link_to(icon, text, path)
+    link_to safe_join([fa_icon(icon), text]), path, class: 'table-action-link'
+  end
 end
diff --git a/app/helpers/admin/domain_blocks_helper.rb b/app/helpers/admin/domain_blocks_helper.rb
new file mode 100644 (file)
index 0000000..d66c8d5
--- /dev/null
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+module Admin::DomainBlocksHelper
+end
index 41c874a62f827c2aa8c6b74643269435f0ad1aa9..c2fc2e7da50f289ad9c7128228a6dfc48f44b2d4 100644 (file)
@@ -1,2 +1,4 @@
+# frozen_string_literal: true
+
 module Admin::PubsubhubbubHelper
 end
index a2a3628d67bfcbe6acf4e33f313b9cc3c9b2df28..99c2af576f61cc6d5fbe761011f1d1fc97c65676 100644 (file)
@@ -1,9 +1,24 @@
-%ul.filters
-  %li= link_to 'Local', admin_accounts_path(local: '1')
-  %li= link_to 'Remote', admin_accounts_path(remote: '1')
-  %li= link_to 'Silenced', admin_accounts_path(silenced: '1')
-  %li= link_to 'Suspended', admin_accounts_path(suspended: '1')
-  %li= link_to 'Most recent', admin_accounts_path(recent: '1')
+- content_for :page_title do
+  Accounts
+
+.filters
+  .filter-subset
+    %strong Location
+    %ul
+      %li= filter_link_to 'All', local: nil, remote: nil
+      %li= filter_link_to 'Local', local: '1', remote: nil
+      %li= filter_link_to 'Remote', remote: '1', local: nil
+  .filter-subset
+    %strong Moderation
+    %ul
+      %li= filter_link_to 'All', silenced: nil, suspended: nil
+      %li= filter_link_to 'Silenced', silenced: '1'
+      %li= filter_link_to 'Suspended', suspended: '1'
+  .filter-subset
+    %strong Order
+    %ul
+      %li= filter_link_to 'Alphabetic', recent: nil
+      %li= filter_link_to 'Most recent', recent: '1'
 
 %table.table
   %thead
@@ -38,6 +53,9 @@
             %i.fa.fa-check
           - else
             %i.fa.fa-times
-        %td= link_to 'Edit', admin_account_path(account.id)
+        %td
+          = table_link_to 'circle', 'Open in web', web_path("accounts/#{account.id}")
+          = table_link_to 'globe', 'Open public', TagManager.instance.url_for(account)
+          = table_link_to 'pencil', 'Edit', admin_account_path(account.id)
 
 = will_paginate @accounts, pagination_options
diff --git a/app/views/admin/domain_blocks/index.html.haml b/app/views/admin/domain_blocks/index.html.haml
new file mode 100644 (file)
index 0000000..aedf163
--- /dev/null
@@ -0,0 +1,14 @@
+- content_for :page_title do
+  Domain Blocks
+
+%table.table
+  %thead
+    %tr
+      %th Domain
+  %tbody
+    - @blocks.each do |block|
+      %tr
+        %td
+          %samp= block.domain
+
+= will_paginate @blocks, pagination_options
index ad8cf519831db30fffd9a5a157e9de44cb389500..cb11a502c9ea34e7a630d4d79867ae9ba17804ad 100644 (file)
@@ -1,3 +1,6 @@
+- content_for :page_title do
+  PubSubHubbub
+
 %table.table
   %thead
     %tr
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
new file mode 100644 (file)
index 0000000..2fc116f
--- /dev/null
@@ -0,0 +1,11 @@
+- content_for :content do
+  .admin-wrapper
+    .sidebar
+      = link_to root_path do
+        = image_tag 'logo.png', class: 'logo'
+
+      = render_navigation
+    .content
+      = yield
+
+= render template: "layouts/application"
diff --git a/config/navigation.rb b/config/navigation.rb
new file mode 100644 (file)
index 0000000..1b6615e
--- /dev/null
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+SimpleNavigation::Configuration.run do |navigation|
+  navigation.items do |primary|
+    primary.item :accounts, safe_join([fa_icon('users fw'), 'Accounts']), admin_accounts_url
+    primary.item :pubsubhubbubs, safe_join([fa_icon('paper-plane-o fw'), 'PubSubHubbub']), admin_pubsubhubbub_index_url
+    primary.item :domain_blocks, safe_join([fa_icon('lock fw'), 'Domain Blocks']), admin_domain_blocks_url
+    primary.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url
+    primary.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url
+  end
+end
index cde84d3bc84fd4391b9394ee3083eff043833af4..2d70bdcea6ed15526e9b444e6e0c244996df106b 100644 (file)
@@ -6,8 +6,8 @@ Rails.application.routes.draw do
   mount ActionCable.server, at: 'cable'
 
   authenticate :user, lambda { |u| u.admin? } do
-    mount Sidekiq::Web, at: 'sidekiq'
-    mount PgHero::Engine, at: 'pghero'
+    mount Sidekiq::Web, at: 'sidekiq', as: :sidekiq
+    mount PgHero::Engine, at: 'pghero', as: :pghero
   end
 
   use_doorkeeper do
@@ -46,6 +46,7 @@ Rails.application.routes.draw do
 
   namespace :admin do
     resources :pubsubhubbub, only: [:index]
+    resources :domain_blocks, only: [:index, :create]
 
     resources :accounts, only: [:index, :show, :update] do
       member do
diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb
new file mode 100644 (file)
index 0000000..9d8735e
--- /dev/null
@@ -0,0 +1,14 @@
+require 'rails_helper'
+
+RSpec.describe Admin::DomainBlocksController, type: :controller do
+  before do
+    sign_in Fabricate(:user, admin: true), scope: :user
+  end
+
+  describe 'GET #index' do
+    it 'returns http success' do
+      get :index
+      expect(response).to have_http_status(:success)
+    end
+  end
+end
index 92e29a2229c676fe46a37089a3ba2a6bd811bd9a..b91f258b3a513720147b39bd02ebdfcc2217c4d9 100644 (file)
@@ -1,15 +1,5 @@
 require 'rails_helper'
 
-# Specs in this file have access to a helper object that includes
-# the Admin::AccountsHelper. For example:
-#
-# describe Admin::AccountsHelper do
-#   describe "string concat" do
-#     it "concats two strings with spaces" do
-#       expect(helper.concat_strings("this","that")).to eq("this that")
-#     end
-#   end
-# end
 RSpec.describe Admin::AccountsHelper, type: :helper do
-  pending "add some examples to (or delete) #{__FILE__}"
+
 end
diff --git a/spec/helpers/admin/domain_blocks_helper_spec.rb b/spec/helpers/admin/domain_blocks_helper_spec.rb
new file mode 100644 (file)
index 0000000..cc7ead8
--- /dev/null
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Admin::DomainBlocksHelper, type: :helper do
+
+end
index 6603e6dc0ea8590a7e3c3ec6d496314cbe1786b4..673236a7ec206312eaf6dff6470f05986a3b10b2 100644 (file)
@@ -1,15 +1,5 @@
 require 'rails_helper'
 
-# Specs in this file have access to a helper object that includes
-# the Admin::PubsubhubbubHelper. For example:
-#
-# describe Admin::PubsubhubbubHelper do
-#   describe "string concat" do
-#     it "concats two strings with spaces" do
-#       expect(helper.concat_strings("this","that")).to eq("this that")
-#     end
-#   end
-# end
 RSpec.describe Admin::PubsubhubbubHelper, type: :helper do
-  pending "add some examples to (or delete) #{__FILE__}"
+
 end
index 927211938a1e3278c96817f676e9a302b35d251c..7b8259fa62c3a3d463738c9b0dc7830ac35a7ed6 100644 (file)
@@ -17,7 +17,7 @@ RSpec.describe Formatter do
     end
 
     it 'contains a link' do
-      expect(subject).to match('<a rel="nofollow noopener" href="http://google.com">google.com</a>')
+      expect(subject).to match('<a rel="nofollow noopener" target="_blank" href="http://google.com">google.com</a>')
     end
   end