From 5f9d299624c15a295538054582ba15e8f5c06a2f Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 10:01:37 -0500 Subject: [PATCH 01/14] refactor: move down to two states --- app/models/content_item.rb | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/app/models/content_item.rb b/app/models/content_item.rb index 451b14c26..abd4db2cc 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -3,23 +3,9 @@ class ContentItem < ApplicationRecord include Elasticsearch::Model include Elasticsearch::Model::Callbacks - state_machine :initial => :default do + state_machine do + state :default state :draft - state :scheduled, :enter => lambda { |content_item| content_item.schedule_publish } - state :published - state :default #the default state that is given to an object - this should only ever exist on ContentItems where the ContentType is not publishable - - event :publish do - transitions :to => :published, :from => [:default, :draft, :scheduled] - end - - event :schedule do - transitions :to => :scheduled, :from => [:default, :draft] - end - - event :draft do - transitions :to => :draft, :from => [:default, :published, :scheduled] - end end acts_as_paranoid From 1e0dd4116a3a560895a64346ded0cc779f747426 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 10:03:39 -0500 Subject: [PATCH 02/14] refactor: remove unused publishing method and job --- app/jobs/publish_content_item_job.rb | 7 ------- app/models/content_item.rb | 5 ----- 2 files changed, 12 deletions(-) delete mode 100644 app/jobs/publish_content_item_job.rb diff --git a/app/jobs/publish_content_item_job.rb b/app/jobs/publish_content_item_job.rb deleted file mode 100644 index 1512a98a8..000000000 --- a/app/jobs/publish_content_item_job.rb +++ /dev/null @@ -1,7 +0,0 @@ -class PublishContentItemJob < ApplicationJob - queue_as :default - - def perform(content_item) - content_item.publish! - end -end diff --git a/app/models/content_item.rb b/app/models/content_item.rb index abd4db2cc..5d762ca33 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -36,11 +36,6 @@ def publish_state state.titleize end - def schedule_publish - timestamp = field_items.find { |field_item| field_item.field.name == "Publish Date" }.data["timestamp"] - PublishContentItemJob.set(wait_until: DateTime.parse(timestamp)).perform_later(self) - end - def rss_url(base_url, slug_field_id) slug = field_items.find_by_field_id(slug_field_id).data.values.join "#{base_url}#{slug}" From 506d8caebbb8747c6ff4bf2d8ca887ca40511a76 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 11:16:08 -0500 Subject: [PATCH 03/14] feat: build custom content approach to publishing workflow --- app/models/content_item.rb | 4 ++-- app/services/publish_state_service.rb | 23 +++++++++++++++++++++++ lib/tasks/employer/blog.rake | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 app/services/publish_state_service.rb diff --git a/app/models/content_item.rb b/app/models/content_item.rb index 5d762ca33..3d296a4cf 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -4,7 +4,6 @@ class ContentItem < ApplicationRecord include Elasticsearch::Model::Callbacks state_machine do - state :default state :draft end @@ -33,7 +32,8 @@ def author_email end def publish_state - state.titleize + sorted_field_items = field_items.select { |fi| fi.field.field_type_instance.is_a?(DateTimeFieldType) && !fi.field.metadata["state"].nil? }.sort_by{ |a| a.data["timestamp"] } + PublishStateService.new.perform(sorted_field_items, self) end def rss_url(base_url, slug_field_id) diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb new file mode 100644 index 000000000..8e28d7651 --- /dev/null +++ b/app/services/publish_state_service.rb @@ -0,0 +1,23 @@ +class PublishStateService < ApplicationController + def perform(sorted_field_items, content_item) + @sorted_field_items = sorted_field_items + @content_item = content_item + + Rails.cache.fetch("PublishStateService/#{content_item.id}", expires_in: 30.minutes) do + active_state + end + end + + private + + def active_state + @sorted_field_items.each do |field_item| + if DateTime.now > DateTime.parse(field_item.data["timestamp"]) + return field_item.field.metadata["state"] + break + end + end + + return @content_item.state.titleize + end +end diff --git a/lib/tasks/employer/blog.rake b/lib/tasks/employer/blog.rake index 3effa229f..9e52fc7b3 100644 --- a/lib/tasks/employer/blog.rake +++ b/lib/tasks/employer/blog.rake @@ -65,7 +65,7 @@ namespace :employer do blog.fields.new(name: 'Slug', field_type: 'text_field_type', validations: {presence: true, uniqueness: true, length: { maximum: 75, minimum: 30} }) blog.fields.new(name: 'Author', field_type: 'author_field_type') blog.fields.new(name: 'Tags', field_type: 'tag_field_type') - blog.fields.new(name: 'Publish Date', field_type: 'date_time_field_type') + blog.fields.new(name: 'Publish Date', field_type: 'date_time_field_type', metadata: {state: 'Published'}) blog.fields.new(name: 'Expiration Date', field_type: 'date_time_field_type') blog.fields.new(name: 'SEO Title', field_type: 'text_field_type', validations: {presence: true, length: {maximum: 70}, uniqueness: true }) blog.fields.new(name: 'SEO Description', field_type: 'text_field_type', validations: {presence: true, length: {maximum: 160} }) From ae224f0604896b43379c3bbd18d4d28a85ce8d64 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 14:37:22 -0500 Subject: [PATCH 04/14] feat: handle timezone through DatePicker --- app/assets/javascripts/datepicker_init.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/app/assets/javascripts/datepicker_init.js b/app/assets/javascripts/datepicker_init.js index d89435ca6..79149aba1 100644 --- a/app/assets/javascripts/datepicker_init.js +++ b/app/assets/javascripts/datepicker_init.js @@ -4,20 +4,7 @@ var datepicker_init = function() { if (datepicker.length) { datepicker.datetimepicker({ dateFormat: 'dd/mm/yy', - onSelect: function (date) { - var button = $('.new_publish_state_button'); - var currentDate = new Date(); - var selectedDate = moment(date, 'DD-MM-YYYY HH:mm'); - - if (button.length > 0 && selectedDate > currentDate) { - button.val('schedule'); - button.text('Schedule Post'); - } - else if (button.length > 0 && selectedDate <= currentDate) { - button.val('published'); - button.text('Publish Now'); - } - } + timeFormat: 'HH:mm Z' }); datepicker.on('focusout', function(ev){ From 49f221b9269d76ca37f9db98cf065437e341ef4c Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 14:37:43 -0500 Subject: [PATCH 05/14] fix: clear state cache on update --- app/services/content_item_service.rb | 2 +- app/services/publish_state_service.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/content_item_service.rb b/app/services/content_item_service.rb index 14dbcb487..dd71982ef 100644 --- a/app/services/content_item_service.rb +++ b/app/services/content_item_service.rb @@ -34,6 +34,7 @@ def update transact_and_refresh do @content_item.update(content_item_attributes) + PublishStateService.clear(@content_item) end end @@ -55,7 +56,6 @@ def transact_and_refresh yield parse_field_items! @content_item.save! - execute_state_change(@content_item) update_search! end end diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb index 8e28d7651..cf92debf7 100644 --- a/app/services/publish_state_service.rb +++ b/app/services/publish_state_service.rb @@ -8,6 +8,10 @@ def perform(sorted_field_items, content_item) end end + def self.clear(content_item) + Rails.cache.delete("PublishStateService/#{content_item.id}") + end + private def active_state From cfac6ca76dad26ea77736780bbbf119e238ce57a Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 14:38:23 -0500 Subject: [PATCH 06/14] refactor: remove previous button logic for publish --- app/views/content_items/_form.html.haml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/app/views/content_items/_form.html.haml b/app/views/content_items/_form.html.haml index fd7dce0b6..3ac37997e 100644 --- a/app/views/content_items/_form.html.haml +++ b/app/views/content_items/_form.html.haml @@ -4,18 +4,5 @@ = cell('wizard', @wizard, context: { content_item: @content_item, form: form }).() %footer.mdl-grid .mdl-cell.mdl-cell--12-col - - if @content_type.publishable - - case @content_item.state - - when 'published' - = form.submit "Update Post", class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect' - = form.button 'Save as Draft', value: 'draft', name: 'content_item[state]', class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect', type: 'submit' - - when 'scheduled' - = form.button 'Schedule Post', value: 'schedule', name: 'content_item[state]', class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect', type: 'submit' - = form.button 'Publish Now', value: 'publish', name: 'content_item[state]', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect', type: 'submit' - = form.button 'Save as Draft', value: 'draft', name: 'content_item[state]', class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect', type: 'submit' - - else - = form.button 'Publish Now', value: 'publish', name: 'content_item[state]', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect new_publish_state_button', type: 'submit' - = form.button 'Save as Draft', value: 'draft', name: 'content_item[state]', class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect', type: 'submit' - - else - = form.submit 'Submit', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect' + = form.submit 'Submit', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect' = link_to 'Cancel', content_type_content_items_path(@content_type), class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect' From 4856669a36906d4889cbb18945d266173d1d4dd3 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 14:53:52 -0500 Subject: [PATCH 07/14] feat: add working expiration date to content_item --- app/models/content_item.rb | 2 +- lib/tasks/employer/blog.rake | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/models/content_item.rb b/app/models/content_item.rb index 3d296a4cf..0e44fc889 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -32,7 +32,7 @@ def author_email end def publish_state - sorted_field_items = field_items.select { |fi| fi.field.field_type_instance.is_a?(DateTimeFieldType) && !fi.field.metadata["state"].nil? }.sort_by{ |a| a.data["timestamp"] } + sorted_field_items = field_items.select { |fi| fi.field.field_type_instance.is_a?(DateTimeFieldType) && !fi.field.metadata["state"].nil? }.sort_by{ |a| a.data["timestamp"] }.reverse PublishStateService.new.perform(sorted_field_items, self) end diff --git a/lib/tasks/employer/blog.rake b/lib/tasks/employer/blog.rake index 9e52fc7b3..1e542c5cc 100644 --- a/lib/tasks/employer/blog.rake +++ b/lib/tasks/employer/blog.rake @@ -66,7 +66,7 @@ namespace :employer do blog.fields.new(name: 'Author', field_type: 'author_field_type') blog.fields.new(name: 'Tags', field_type: 'tag_field_type') blog.fields.new(name: 'Publish Date', field_type: 'date_time_field_type', metadata: {state: 'Published'}) - blog.fields.new(name: 'Expiration Date', field_type: 'date_time_field_type') + blog.fields.new(name: 'Expiration Date', field_type: 'date_time_field_type', metadata: {state: 'Expired'}) blog.fields.new(name: 'SEO Title', field_type: 'text_field_type', validations: {presence: true, length: {maximum: 70}, uniqueness: true }) blog.fields.new(name: 'SEO Description', field_type: 'text_field_type', validations: {presence: true, length: {maximum: 160} }) blog.fields.new(name: 'SEO Keywords', field_type: 'tag_field_type') @@ -140,7 +140,7 @@ namespace :employer do "id": blog.fields.find_by_name('Publish Date').id }, { - "id": blog.fields.find_by_name('Author').id + "id": blog.fields.find_by_name('Expiration Date').id } ] }, @@ -153,6 +153,9 @@ namespace :employer do { "id": blog.fields.find_by_name('Slug').id, "tooltip": "This is your post's URL. Between each word, place a hyphen. Best if between 35-50 characters and don't include years/dates." + }, + { + "id": blog.fields.find_by_name('Author').id } ] } From 0eb39aaefb29cd2fc9974578ddcabaabd247ee2f Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 15:03:00 -0500 Subject: [PATCH 08/14] refactor: limit cache time on state --- app/services/publish_state_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb index cf92debf7..27a6847f0 100644 --- a/app/services/publish_state_service.rb +++ b/app/services/publish_state_service.rb @@ -3,7 +3,7 @@ def perform(sorted_field_items, content_item) @sorted_field_items = sorted_field_items @content_item = content_item - Rails.cache.fetch("PublishStateService/#{content_item.id}", expires_in: 30.minutes) do + Rails.cache.fetch("PublishStateService/#{content_item.id}", expires_in: 10.minutes) do active_state end end From 6d8f066689b89c868f100c4123b8e8873153baef Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 15:05:41 -0500 Subject: [PATCH 09/14] chore: add categories - per @justin3thompson --- lib/tasks/employer/blog.rake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/tasks/employer/blog.rake b/lib/tasks/employer/blog.rake index 1e542c5cc..b169948c2 100644 --- a/lib/tasks/employer/blog.rake +++ b/lib/tasks/employer/blog.rake @@ -14,7 +14,10 @@ namespace :employer do def category_tree tree = Tree.new - tree.add_node({ name: "Recruitment Solutions" }) + tree.add_node({ name: "Product News" }) + tree.add_node({ name: "Company News, Research and Trends" }) + tree.add_node({ name: "Client Success Stories" }) + tree.add_node({ name: "Recruiting Solutions" }) tree.add_node({ name: "Employment Screening" }) tree.add_node({ name: "Human Capital Management" }) From 5f64af6f8d50e26b50f99fedf4e7876252d5c857 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Mon, 24 Apr 2017 15:18:32 -0500 Subject: [PATCH 10/14] chore: change save button text - per @justin3thompson --- app/views/content_items/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/content_items/_form.html.haml b/app/views/content_items/_form.html.haml index 3ac37997e..af2958970 100644 --- a/app/views/content_items/_form.html.haml +++ b/app/views/content_items/_form.html.haml @@ -4,5 +4,5 @@ = cell('wizard', @wizard, context: { content_item: @content_item, form: form }).() %footer.mdl-grid .mdl-cell.mdl-cell--12-col - = form.submit 'Submit', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect' + = form.submit 'Save Now', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect' = link_to 'Cancel', content_type_content_items_path(@content_type), class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect' From dbd7f93c04ca1a2691c6426f263c08cca72a81c7 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Tue, 25 Apr 2017 17:05:00 -0500 Subject: [PATCH 11/14] feat: create DSL for content_items with #method_missing --- app/models/content_item.rb | 8 ++++++++ app/services/content_item_service.rb | 1 - app/services/publish_state_service.rb | 8 +------- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/models/content_item.rb b/app/models/content_item.rb index 0e44fc889..74d856dc7 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -96,4 +96,12 @@ def update_tag_lists ContentItemService.update_tags(self, tags) end end + + def method_missing(*args) + if args[0].to_s.include?("?") + "#{publish_state.downcase}?" == args[0].to_s + else + field_items.select { |field_item| field_item.field.name.parameterize({ separator: '_' }) == args[0].to_s }.first.data.values[0] + end + end end diff --git a/app/services/content_item_service.rb b/app/services/content_item_service.rb index dd71982ef..4a84600d1 100644 --- a/app/services/content_item_service.rb +++ b/app/services/content_item_service.rb @@ -34,7 +34,6 @@ def update transact_and_refresh do @content_item.update(content_item_attributes) - PublishStateService.clear(@content_item) end end diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb index 27a6847f0..54ca01d62 100644 --- a/app/services/publish_state_service.rb +++ b/app/services/publish_state_service.rb @@ -3,13 +3,7 @@ def perform(sorted_field_items, content_item) @sorted_field_items = sorted_field_items @content_item = content_item - Rails.cache.fetch("PublishStateService/#{content_item.id}", expires_in: 10.minutes) do - active_state - end - end - - def self.clear(content_item) - Rails.cache.delete("PublishStateService/#{content_item.id}") + active_state end private From b32cd67c73e37ce965cc03a839a9d33d365672b6 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Wed, 26 Apr 2017 09:10:16 -0500 Subject: [PATCH 12/14] refactor: necessary pub system renamings and refactors --- app/models/content_item.rb | 2 +- app/services/publish_state_service.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/content_item.rb b/app/models/content_item.rb index 74d856dc7..b56d66c9d 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -33,7 +33,7 @@ def author_email def publish_state sorted_field_items = field_items.select { |fi| fi.field.field_type_instance.is_a?(DateTimeFieldType) && !fi.field.metadata["state"].nil? }.sort_by{ |a| a.data["timestamp"] }.reverse - PublishStateService.new.perform(sorted_field_items, self) + PublishStateService.new.content_item_state(sorted_field_items, self) end def rss_url(base_url, slug_field_id) diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb index 54ca01d62..503fb251e 100644 --- a/app/services/publish_state_service.rb +++ b/app/services/publish_state_service.rb @@ -1,5 +1,5 @@ -class PublishStateService < ApplicationController - def perform(sorted_field_items, content_item) +class PublishStateService < ApplicationService + def content_item_state(sorted_field_items, content_item) @sorted_field_items = sorted_field_items @content_item = content_item From ea21a4f3d3ad89b8ee367ac44b4435e17bedf184 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Wed, 26 Apr 2017 12:58:13 -0500 Subject: [PATCH 13/14] refactor: clean publish service and add method_missing comments --- app/models/content_item.rb | 7 +++++-- app/services/publish_state_service.rb | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/content_item.rb b/app/models/content_item.rb index b56d66c9d..68b290ed6 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -32,8 +32,7 @@ def author_email end def publish_state - sorted_field_items = field_items.select { |fi| fi.field.field_type_instance.is_a?(DateTimeFieldType) && !fi.field.metadata["state"].nil? }.sort_by{ |a| a.data["timestamp"] }.reverse - PublishStateService.new.content_item_state(sorted_field_items, self) + PublishStateService.new.content_item_state(self) end def rss_url(base_url, slug_field_id) @@ -97,10 +96,14 @@ def update_tag_lists end end + # Metaprograms a number of convenience methods for content_items def method_missing(*args) if args[0].to_s.include?("?") + # Used to check state - allows for methods such as #published? and #expired? + # Will return true if the active_state corresponds to the name of the method "#{publish_state.downcase}?" == args[0].to_s else + # Used to query for any field on the relevant ContentType and return data from the content_item field_items.select { |field_item| field_item.field.name.parameterize({ separator: '_' }) == args[0].to_s }.first.data.values[0] end end diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb index 503fb251e..83d5acbd5 100644 --- a/app/services/publish_state_service.rb +++ b/app/services/publish_state_service.rb @@ -1,6 +1,5 @@ class PublishStateService < ApplicationService - def content_item_state(sorted_field_items, content_item) - @sorted_field_items = sorted_field_items + def content_item_state(content_item) @content_item = content_item active_state @@ -9,7 +8,7 @@ def content_item_state(sorted_field_items, content_item) private def active_state - @sorted_field_items.each do |field_item| + sorted_field_items.each do |field_item| if DateTime.now > DateTime.parse(field_item.data["timestamp"]) return field_item.field.metadata["state"] break @@ -18,4 +17,8 @@ def active_state return @content_item.state.titleize end + + def sorted_field_items + @sorted_field_items ||= @content_item.field_items.select { |fi| fi.field.field_type_instance.is_a?(DateTimeFieldType) && !fi.field.metadata["state"].nil? }.sort_by{ |a| a.data["timestamp"] }.reverse + end end From 79006001548207b5177dbdbffc1b7a8233c07297 Mon Sep 17 00:00:00 2001 From: ElliottAYoung Date: Wed, 26 Apr 2017 16:19:04 -0500 Subject: [PATCH 14/14] feat: implement hybrid approach for state system --- app/assets/javascripts/datepicker_init.js | 12 +++++++++++- app/models/content_item.rb | 9 +++++++++ app/services/content_item_service.rb | 1 + app/services/publish_state_service.rb | 2 +- app/views/content_items/_form.html.haml | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/datepicker_init.js b/app/assets/javascripts/datepicker_init.js index 79149aba1..2f890d3fc 100644 --- a/app/assets/javascripts/datepicker_init.js +++ b/app/assets/javascripts/datepicker_init.js @@ -4,11 +4,21 @@ var datepicker_init = function() { if (datepicker.length) { datepicker.datetimepicker({ dateFormat: 'dd/mm/yy', - timeFormat: 'HH:mm Z' + timeFormat: 'HH:mm Z', + onSelect: function (date) { + var button = $('.form-button--submission'); + button.text('Schedule Post'); + button.val('schedule'); + } }); datepicker.on('focusout', function(ev){ if ($(this).val() === "") { + var button = $('.form-button--submission'); + + button.text('Save Now'); + button.val('draft'); + $(this).closest('div').addClass('is-dirty'); } }); diff --git a/app/models/content_item.rb b/app/models/content_item.rb index 68b290ed6..f40017e91 100644 --- a/app/models/content_item.rb +++ b/app/models/content_item.rb @@ -5,6 +5,15 @@ class ContentItem < ApplicationRecord state_machine do state :draft + state :scheduled + + event :schedule do + transitions :to => :scheduled, :from => [:draft] + end + + event :draft do + transitions :to => :draft, :from => [:scheduled] + end end acts_as_paranoid diff --git a/app/services/content_item_service.rb b/app/services/content_item_service.rb index 4a84600d1..14dbcb487 100644 --- a/app/services/content_item_service.rb +++ b/app/services/content_item_service.rb @@ -55,6 +55,7 @@ def transact_and_refresh yield parse_field_items! @content_item.save! + execute_state_change(@content_item) update_search! end end diff --git a/app/services/publish_state_service.rb b/app/services/publish_state_service.rb index 83d5acbd5..9b0ee590e 100644 --- a/app/services/publish_state_service.rb +++ b/app/services/publish_state_service.rb @@ -9,7 +9,7 @@ def content_item_state(content_item) def active_state sorted_field_items.each do |field_item| - if DateTime.now > DateTime.parse(field_item.data["timestamp"]) + if !field_item.data['timestamp'].blank? && DateTime.now > DateTime.parse(field_item.data["timestamp"]) return field_item.field.metadata["state"] break end diff --git a/app/views/content_items/_form.html.haml b/app/views/content_items/_form.html.haml index af2958970..4230f54ee 100644 --- a/app/views/content_items/_form.html.haml +++ b/app/views/content_items/_form.html.haml @@ -4,5 +4,5 @@ = cell('wizard', @wizard, context: { content_item: @content_item, form: form }).() %footer.mdl-grid .mdl-cell.mdl-cell--12-col - = form.submit 'Save Now', class: 'mdl-button mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect' + = form.button 'Save Now', value: @content_item.state || 'draft', name: 'content_item[state]', class: 'mdl-button form-button--submission mdl-js-button mdl-button--raised mdl-button--success mdl-js-ripple-effect', type: 'submit' = link_to 'Cancel', content_type_content_items_path(@content_type), class: 'mdl-button mdl-js-button mdl-button--cb mdl-js-ripple-effect'