From 79291fb999d642a63ebceaa4cd6ac6cf6f9315d6 Mon Sep 17 00:00:00 2001
From: Justin Coyne
Date: Fri, 5 Jun 2020 16:39:38 -0500
Subject: [PATCH] Add display messages
---
.rubocop_todo.yml | 10 +-
app/controllers/catalog_controller.rb | 4 +
app/controllers/content_blocks_controller.rb | 42 ++++++
app/javascript/argo.js | 5 +
.../controllers/content_block_edit.js | 43 ++++++
.../controllers/content_block_new.js | 23 ++++
app/javascript/style/application.scss | 5 +
app/javascript/style/bootstrap-overrides.scss | 11 ++
app/javascript/style/variables.scss | 1 +
app/models/content_block.rb | 28 ++++
app/presenters/home_text_presenter.rb | 4 +
app/views/catalog/_home_text.html.erb | 19 +++
app/views/content_blocks/index.html.erb | 124 ++++++++++++++++++
app/views/shared/_user_util_links.html.erb | 13 +-
config/routes.rb | 2 +
.../20200514171819_create_content_blocks.rb | 12 ++
db/schema.rb | 11 +-
package.json | 1 +
spec/factories/content_blocks.rb | 10 ++
spec/models/content_block_spec.rb | 64 +++++++++
spec/requests/content_blocks_spec.rb | 64 +++++++++
spec/support/factory_bot.rb | 11 +-
.../views/catalog/_home_text.html.erb_spec.rb | 8 +-
yarn.lock | 5 +
24 files changed, 505 insertions(+), 15 deletions(-)
create mode 100644 app/controllers/content_blocks_controller.rb
create mode 100644 app/javascript/controllers/content_block_edit.js
create mode 100644 app/javascript/controllers/content_block_new.js
create mode 100644 app/models/content_block.rb
create mode 100644 app/views/content_blocks/index.html.erb
create mode 100644 db/migrate/20200514171819_create_content_blocks.rb
create mode 100644 spec/factories/content_blocks.rb
create mode 100644 spec/models/content_block_spec.rb
create mode 100644 spec/requests/content_blocks_spec.rb
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 8f7cf5b5e..ac7ede816 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2020-07-06 17:37:04 UTC using RuboCop version 0.86.0.
+# on 2020-07-06 18:37:58 UTC using RuboCop version 0.86.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -41,7 +41,7 @@ Lint/UnusedBlockArgument:
- 'lib/tasks/argo.rake'
- 'lib/tasks/argo_testing.rake'
-# Offense count: 96
+# Offense count: 97
# Configuration parameters: IgnoredMethods.
Metrics/AbcSize:
Max: 82
@@ -49,7 +49,7 @@ Metrics/AbcSize:
# Offense count: 5
# Configuration parameters: CountComments.
Metrics/ClassLength:
- Max: 173
+ Max: 177
# Offense count: 11
# Configuration parameters: IgnoredMethods.
@@ -301,7 +301,7 @@ Style/CommentedKeyword:
- 'lib/tasks/argo.rake'
- 'lib/tasks/argo_testing.rake'
-# Offense count: 63
+# Offense count: 65
Style/Documentation:
Enabled: false
@@ -328,7 +328,7 @@ Style/NumericPredicate:
- 'spec/**/*'
- 'app/jobs/descmetadata_download_job.rb'
-# Offense count: 291
+# Offense count: 292
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb
index 8f6664c69..f84507171 100644
--- a/app/controllers/catalog_controller.rb
+++ b/app/controllers/catalog_controller.rb
@@ -174,6 +174,10 @@ class CatalogController < ApplicationController
def index
@presenter = HomeTextPresenter.new(current_user)
+ unless has_search_parameters?
+ @presenter.primary_messages = ContentBlock.active.primary
+ @presenter.secondary_messages = ContentBlock.active.secondary
+ end
super
end
diff --git a/app/controllers/content_blocks_controller.rb b/app/controllers/content_blocks_controller.rb
new file mode 100644
index 000000000..2d4b6bc5a
--- /dev/null
+++ b/app/controllers/content_blocks_controller.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+class ContentBlocksController < ApplicationController
+ before_action :set_content_block, only: %i[create update destroy]
+ authorize_resource
+
+ # GET /content_blocks
+ def index
+ @unexpired_blocks = ContentBlock.unexpired
+ @expired_blocks = ContentBlock.expired
+ end
+
+ # POST /content_blocks
+ def create
+ @content_block.save!
+ redirect_to content_blocks_path
+ end
+
+ # PATCH/PUT /content_blocks/1
+ def update
+ @content_block.save!
+ redirect_to content_blocks_path
+ end
+
+ # DELETE /content_blocks/1
+ def destroy
+ @content_block.destroy
+ redirect_to content_blocks_path
+ end
+
+ private
+
+ # Use callbacks to share common setup or constraints between actions.
+ def set_content_block
+ @content_block = params[:id] ? ContentBlock.find(params[:id]) : ContentBlock.new
+ return unless params[:content_block]
+
+ start_at = params[:content_block][:start_at].in_time_zone('America/Los_Angeles')
+ end_at = params[:content_block][:end_at].in_time_zone('America/Los_Angeles').end_of_day
+ @content_block.attributes = { end_at: end_at, start_at: start_at, ordinal: params[:content_block][:ordinal], value: params[:content_block][:value] }
+ end
+end
diff --git a/app/javascript/argo.js b/app/javascript/argo.js
index 0caf6cabd..f8bf66184 100644
--- a/app/javascript/argo.js
+++ b/app/javascript/argo.js
@@ -1,5 +1,8 @@
import Form from 'modules/apo_form'
import CollectionEditor from 'controllers/collection_editor'
+import ContentBlockNew from 'controllers/content_block_new'
+import ContentBlockEdit from 'controllers/content_block_edit'
+
import BulkActions from 'controllers/bulk_actions'
import BulkUpload from 'controllers/bulk_upload'
import FacetFilter from 'controllers/facet_filter'
@@ -46,6 +49,8 @@ export default class Argo {
application.register("facet-filter", FacetFilter)
application.register("workflow-grid", WorkflowGrid)
application.register("collection-editor", CollectionEditor)
+ application.register("content-block-new", ContentBlockNew)
+ application.register("content-block-edit", ContentBlockEdit)
application.register("tokens", Tokens)
}
diff --git a/app/javascript/controllers/content_block_edit.js b/app/javascript/controllers/content_block_edit.js
new file mode 100644
index 000000000..2bb83e8f3
--- /dev/null
+++ b/app/javascript/controllers/content_block_edit.js
@@ -0,0 +1,43 @@
+import { Controller } from 'stimulus'
+
+export default class extends Controller {
+ static targets = [ "value", "ordinal", "startAt", "endAt" ]
+
+ display(event) {
+ event.preventDefault()
+
+ // Save the old HTML so we can cancel.
+ this.existingHTML = this.element.innerHTML
+
+ // Display the editor
+ let template = document.getElementById('edit-row')
+ this.element.innerHTML = template.innerHTML
+
+ // Populate the form with the values for this row
+ this.valueTarget.value = this.data.get('value')
+ this.ordinalTarget.value = this.data.get('ordinal')
+ this.startAtTarget.value = this.data.get('start_at')
+ this.endAtTarget.value = this.data.get('end_at')
+ }
+
+ save(event) {
+ // remove the new form fields
+ document.querySelector('[data-target="content-block-new.form"').remove()
+
+ // Update the form so it updates the current item.
+ let form = document.querySelector('[data-target="content-block-form"]')
+ form.action = this.data.get('url')
+
+ // Set the patch method on the form
+ var input = document.createElement("input");
+ input.type = 'hidden'
+ input.name = '_method'
+ input.value = 'patch'
+ form.appendChild(input)
+ }
+
+ cancel(event) {
+ event.preventDefault()
+ this.element.innerHTML = this.existingHTML
+ }
+}
diff --git a/app/javascript/controllers/content_block_new.js b/app/javascript/controllers/content_block_new.js
new file mode 100644
index 000000000..d482009fc
--- /dev/null
+++ b/app/javascript/controllers/content_block_new.js
@@ -0,0 +1,23 @@
+import { Controller } from 'stimulus'
+
+export default class extends Controller {
+ static targets = [ "button", "form", "headerRow" ]
+
+ display(event) {
+ event.preventDefault()
+ this.formTarget.classList.remove('d-none')
+ // The header row doesn't display if there are no existing records, so display it now.
+ this.headerRowTarget.classList.remove('d-none')
+ this.buttonTarget.classList.add('d-none')
+ }
+
+ cancel(event) {
+ event.preventDefault()
+ this.hideForm()
+ }
+
+ hideForm() {
+ this.formTarget.classList.add('d-none')
+ this.buttonTarget.classList.remove('d-none')
+ }
+}
diff --git a/app/javascript/style/application.scss b/app/javascript/style/application.scss
index 396458158..cd4a9033a 100644
--- a/app/javascript/style/application.scss
+++ b/app/javascript/style/application.scss
@@ -3,6 +3,11 @@
@import 'variables';
@import 'bootstrap/scss/bootstrap';
@import 'bootstrap-overrides';
+
+$fa-font-path: '~@fortawesome/fontawesome-free/webfonts';
+@import "@fortawesome/fontawesome-free/scss/fontawesome.scss";
+@import "@fortawesome/fontawesome-free/scss/solid.scss";
+
// Override before importing Blacklight
$logo-image: "../images/logo.png";
@import 'blacklight-frontend/app/assets/stylesheets/blacklight/blacklight';
diff --git a/app/javascript/style/bootstrap-overrides.scss b/app/javascript/style/bootstrap-overrides.scss
index c82f32654..902e505ce 100644
--- a/app/javascript/style/bootstrap-overrides.scss
+++ b/app/javascript/style/bootstrap-overrides.scss
@@ -32,3 +32,14 @@
color: $body-color;
opacity: 1.0;
}
+
+.alert-warning {
+ @include alert-variant(theme-color-level('warning', $alert-bg-level), $gamboge, $body-color);
+
+ .fa-exclamation-circle {
+ color: $gamboge;
+ font-size: 2em;
+ margin-right: .5em;
+ vertical-align: middle;
+ }
+}
diff --git a/app/javascript/style/variables.scss b/app/javascript/style/variables.scss
index 732135ba1..05bc4637b 100644
--- a/app/javascript/style/variables.scss
+++ b/app/javascript/style/variables.scss
@@ -8,6 +8,7 @@
$barley-corn: #b3995d;
$floral-white: #f9f6ef;
$tahuna-sands: #d2c295;
+$gamboge: #eaab01;
$tea: #b6b1a9;
$silver: #c5c5c5;
diff --git a/app/models/content_block.rb b/app/models/content_block.rb
new file mode 100644
index 000000000..7eccd3567
--- /dev/null
+++ b/app/models/content_block.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class ContentBlock < ApplicationRecord
+ ORDINAL_STRING = { 1 => 'Primary', 2 => 'Secondary' }.freeze
+ scope :expired, -> { where('end_at < ?', current_time) }
+ scope :unexpired, -> { where('end_at >= ?', current_time) }
+ scope :active, -> { where('start_at < ? AND end_at >= ?', current_time, current_time) }
+ scope :primary, -> { where(ordinal: 1) }
+ scope :secondary, -> { where(ordinal: 2) }
+
+ validates :ordinal, presence: true, inclusion: { in: [1, 2] }
+
+ def self.current_time
+ Time.now.in_time_zone('America/Los_Angeles')
+ end
+
+ def ordinal_string
+ ORDINAL_STRING.fetch(ordinal)
+ end
+
+ def pacific_start
+ start_at.in_time_zone('America/Los_Angeles')
+ end
+
+ def pacific_end
+ end_at.in_time_zone('America/Los_Angeles')
+ end
+end
diff --git a/app/presenters/home_text_presenter.rb b/app/presenters/home_text_presenter.rb
index a58a3c983..77c6473db 100644
--- a/app/presenters/home_text_presenter.rb
+++ b/app/presenters/home_text_presenter.rb
@@ -4,6 +4,8 @@
class HomeTextPresenter
def initialize(current_user)
@current_user = current_user
+ @primary_messages = []
+ @secondary_messages = []
end
# @return [Boolean] true if this user has permissions to see anything in Argo
@@ -11,6 +13,8 @@ def view_something?
admin? || manager? || viewer? || permitted_apos.any?
end
+ attr_accessor :primary_messages, :secondary_messages
+
private
attr_reader :current_user
diff --git a/app/views/catalog/_home_text.html.erb b/app/views/catalog/_home_text.html.erb
index 4453c43bb..0637a06cd 100644
--- a/app/views/catalog/_home_text.html.erb
+++ b/app/views/catalog/_home_text.html.erb
@@ -9,4 +9,23 @@
You do not appear to have permission to view any items in Argo. Please contact an administrator.
<% end %>
+
+ <% @presenter.primary_messages.each do |block| %>
+
+
+ <%= block.value %>
+
+
+ <% end %>
+
+ <% if @presenter.secondary_messages.present? %>
+
Messages from the Argo team
+
+ <% @presenter.secondary_messages.each do |block| %>
+
<%= block.value %>
+ <% end %>
+
+ <% end %>
diff --git a/app/views/content_blocks/index.html.erb b/app/views/content_blocks/index.html.erb
new file mode 100644
index 000000000..eed4e1b71
--- /dev/null
+++ b/app/views/content_blocks/index.html.erb
@@ -0,0 +1,124 @@
+
Message alerts
+
+
Primary messages will appear in a yellow box at the top of the homepage. Secondary messages
+ will display below the yellow primary messages boxes in a bulleted list. Max 1,000 characters per message.