diff --git a/Gemfile b/Gemfile index 98feafb..39ba4b6 100644 --- a/Gemfile +++ b/Gemfile @@ -111,3 +111,5 @@ group :test do gem 'vcr' gem 'webmock' end + +gem "administrate", "~> 0.20.1" diff --git a/Gemfile.lock b/Gemfile.lock index 360902d..edfc3aa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -86,6 +86,14 @@ GEM tzinfo (~> 2.0) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) + administrate (0.20.1) + actionpack (>= 6.0, < 8.0) + actionview (>= 6.0, < 8.0) + activerecord (>= 6.0, < 8.0) + jquery-rails (~> 4.6.0) + kaminari (~> 1.2.2) + sassc-rails (~> 2.1) + selectize-rails (~> 0.6) aes_key_wrap (1.1.0) annotate (3.2.0) activerecord (>= 3.2, < 8.0) @@ -178,6 +186,10 @@ GEM jbuilder (2.12.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) + jquery-rails (4.6.0) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) json (2.7.2) json-jwt (1.16.6) activesupport (>= 4.2) @@ -186,6 +198,18 @@ GEM bindata faraday (~> 2.0) faraday-follow_redirects + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) language_server-protocol (3.17.0.3) llhttp-ffi (0.5.0) ffi-compiler (~> 1.0) @@ -349,6 +373,7 @@ GEM sprockets (> 3.0) sprockets-rails tilt + selectize-rails (0.12.6) selenium-webdriver (4.23.0) base64 (~> 0.2) logger (~> 1.4) @@ -429,6 +454,7 @@ PLATFORMS x86_64-linux DEPENDENCIES + administrate (~> 0.20.1) annotate bootsnap cancancan diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb new file mode 100644 index 0000000..8449926 --- /dev/null +++ b/app/controllers/admin/application_controller.rb @@ -0,0 +1,36 @@ +# All Administrate controllers inherit from this +# `Administrate::ApplicationController`, making it the ideal place to put +# authentication logic or other before_actions. +# +# If you want to add pagination or other controller-level concerns, +# you're free to overwrite the RESTful controller actions. +module Admin + class ApplicationController < Administrate::ApplicationController + before_action :require_user + before_action :authorize_user + + private + + def authorize_user + return if authorize_action?(resource_name, action_name) + + redirect_to root_path, alert: 'Not authorized' + end + + def authorize_action?(resource, action) + can? action, resource + end + + def require_user + return if current_user + + redirect_to root_path, alert: 'Please sign in to continue' + end + + # Override this value to specify the number of elements to display at a time + # on index pages. Defaults to 20. + # def records_per_page + # params[:per_page] || 20 + # end + end +end diff --git a/app/controllers/admin/detector/suggested_resources_controller.rb b/app/controllers/admin/detector/suggested_resources_controller.rb new file mode 100644 index 0000000..9cebe16 --- /dev/null +++ b/app/controllers/admin/detector/suggested_resources_controller.rb @@ -0,0 +1,48 @@ +module Admin + module Detector + class SuggestedResourcesController < Admin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes(action_name)). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-demo.herokuapp.com/customizing_controller_actions + # for more information + end + end +end diff --git a/app/controllers/admin/search_events_controller.rb b/app/controllers/admin/search_events_controller.rb new file mode 100644 index 0000000..de79091 --- /dev/null +++ b/app/controllers/admin/search_events_controller.rb @@ -0,0 +1,46 @@ +module Admin + class SearchEventsController < Admin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes(action_name)). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-demo.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/terms_controller.rb b/app/controllers/admin/terms_controller.rb new file mode 100644 index 0000000..9f2780c --- /dev/null +++ b/app/controllers/admin/terms_controller.rb @@ -0,0 +1,46 @@ +module Admin + class TermsController < Admin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes(action_name)). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-demo.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb new file mode 100644 index 0000000..2c4ab7d --- /dev/null +++ b/app/controllers/admin/users_controller.rb @@ -0,0 +1,46 @@ +module Admin + class UsersController < Admin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes(action_name)). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-demo.herokuapp.com/customizing_controller_actions + # for more information + end +end diff --git a/app/dashboards/detector/suggested_resource_dashboard.rb b/app/dashboards/detector/suggested_resource_dashboard.rb new file mode 100644 index 0000000..7fd3240 --- /dev/null +++ b/app/dashboards/detector/suggested_resource_dashboard.rb @@ -0,0 +1,73 @@ +require "administrate/base_dashboard" + +module Detector + class Detector::SuggestedResourceDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + fingerprint: Field::String, + phrase: Field::String, + title: Field::String, + url: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + id + fingerprint + phrase + title + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + id + fingerprint + phrase + title + url + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + phrase + title + url + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how suggested resources are displayed + # across all pages of the admin dashboard. + # + # def display_resource(suggested_resource) + # "Detector::SuggestedResource ##{suggested_resource.id}" + # end + end +end diff --git a/app/dashboards/search_event_dashboard.rb b/app/dashboards/search_event_dashboard.rb new file mode 100644 index 0000000..cd4e096 --- /dev/null +++ b/app/dashboards/search_event_dashboard.rb @@ -0,0 +1,66 @@ +require "administrate/base_dashboard" + +class SearchEventDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + source: Field::String, + term: Field::BelongsTo, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + id + source + term + created_at + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + id + source + term + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + source + term + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how search events are displayed + # across all pages of the admin dashboard. + # + # def display_resource(search_event) + # "SearchEvent ##{search_event.id}" + # end +end diff --git a/app/dashboards/term_dashboard.rb b/app/dashboards/term_dashboard.rb new file mode 100644 index 0000000..b75dbff --- /dev/null +++ b/app/dashboards/term_dashboard.rb @@ -0,0 +1,66 @@ +require "administrate/base_dashboard" + +class TermDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + phrase: Field::String, + search_events: Field::HasMany, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + id + phrase + search_events + created_at + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + id + phrase + search_events + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + phrase + search_events + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how terms are displayed + # across all pages of the admin dashboard. + # + # def display_resource(term) + # "Term ##{term.id}" + # end +end diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb new file mode 100644 index 0000000..7fe9659 --- /dev/null +++ b/app/dashboards/user_dashboard.rb @@ -0,0 +1,69 @@ +require "administrate/base_dashboard" + +class UserDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + admin: Field::Boolean, + email: Field::String, + uid: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + id + admin + email + uid + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + id + admin + email + uid + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + admin + email + uid + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how users are displayed + # across all pages of the admin dashboard. + # + # def display_resource(user) + # "User ##{user.id}" + # end +end diff --git a/app/views/layouts/_site_nav.html.erb b/app/views/layouts/_site_nav.html.erb index 1a4f038..a777138 100644 --- a/app/views/layouts/_site_nav.html.erb +++ b/app/views/layouts/_site_nav.html.erb @@ -9,6 +9,11 @@