riddler_admin 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/riddler_admin/application.js +0 -1
- data/app/assets/javascripts/riddler_admin/preview_contexts.js +2 -0
- data/app/assets/javascripts/riddler_admin/publish_requests.js +2 -0
- data/app/assets/javascripts/riddler_admin/steps.js +36 -22
- data/app/assets/stylesheets/riddler_admin/application.scss +3 -0
- data/app/assets/stylesheets/riddler_admin/preview_contexts.css +4 -0
- data/app/assets/stylesheets/riddler_admin/publish_requests.css +4 -0
- data/app/controllers/riddler_admin/application_controller.rb +24 -2
- data/app/controllers/riddler_admin/dashboard_controller.rb +8 -0
- data/app/controllers/riddler_admin/elements_controller.rb +6 -2
- data/app/controllers/riddler_admin/preview_contexts_controller.rb +60 -0
- data/app/controllers/riddler_admin/publish_requests_controller.rb +90 -0
- data/app/controllers/riddler_admin/slugs_controller.rb +67 -0
- data/app/controllers/riddler_admin/steps_controller.rb +73 -20
- data/app/helpers/riddler_admin/application_helper.rb +19 -0
- data/app/helpers/riddler_admin/preview_contexts_helper.rb +4 -0
- data/app/helpers/riddler_admin/publish_requests_helper.rb +4 -0
- data/app/models/riddler_admin/application_record.rb +4 -4
- data/app/models/riddler_admin/content_definition.rb +87 -0
- data/app/models/riddler_admin/element.rb +52 -10
- data/app/models/riddler_admin/elements/heading.rb +6 -0
- data/app/models/riddler_admin/elements/image.rb +18 -0
- data/app/models/riddler_admin/elements/link.rb +18 -0
- data/app/models/riddler_admin/elements/{copy.rb → text.rb} +7 -1
- data/app/models/riddler_admin/elements/variant.rb +19 -0
- data/app/models/riddler_admin/preview_context.rb +83 -0
- data/app/models/riddler_admin/publish_request.rb +57 -0
- data/app/models/riddler_admin/slug.rb +90 -0
- data/app/models/riddler_admin/step.rb +66 -4
- data/app/models/riddler_admin/steps/variant.rb +19 -0
- data/app/validators/parseable_predicate_validator.rb +8 -0
- data/app/views/layouts/riddler_admin/application.html.erb +11 -4
- data/app/views/riddler_admin/_element.html.erb +14 -10
- data/app/views/riddler_admin/_element_container.html.erb +11 -0
- data/app/views/riddler_admin/_navbar.html.erb +29 -0
- data/app/views/riddler_admin/_preview_step.html.erb +39 -0
- data/app/views/riddler_admin/_step.html.erb +35 -0
- data/app/views/riddler_admin/_step_container.html.erb +11 -0
- data/app/views/riddler_admin/dashboard/index.html.erb +44 -0
- data/app/views/riddler_admin/elements/_form.html.erb +37 -0
- data/app/views/riddler_admin/elements/_new.html.erb +41 -8
- data/app/views/riddler_admin/elements/_show.html.erb +3 -1
- data/app/views/riddler_admin/elements/edit.js.erb +2 -0
- data/app/views/riddler_admin/elements/heading/_detail.html.erb +0 -0
- data/app/views/riddler_admin/elements/heading/_form.html.erb +8 -2
- data/app/views/riddler_admin/elements/image/_detail.html.erb +0 -0
- data/app/views/riddler_admin/elements/image/_form.html.erb +12 -0
- data/app/views/riddler_admin/elements/link/_detail.html.erb +0 -0
- data/app/views/riddler_admin/elements/link/_form.html.erb +12 -0
- data/app/views/riddler_admin/elements/show.js.erb +2 -2
- data/app/views/riddler_admin/elements/text/_detail.html.erb +0 -0
- data/app/views/riddler_admin/elements/text/_form.html.erb +4 -0
- data/app/views/riddler_admin/elements/variant/_detail.html.erb +6 -0
- data/app/views/riddler_admin/elements/variant/_form.html.erb +1 -0
- data/app/views/riddler_admin/preview_contexts/_form.html.erb +44 -0
- data/app/views/riddler_admin/preview_contexts/edit.html.erb +10 -0
- data/app/views/riddler_admin/preview_contexts/index.html.erb +43 -0
- data/app/views/riddler_admin/preview_contexts/new.html.erb +10 -0
- data/app/views/riddler_admin/preview_contexts/show.html.erb +45 -0
- data/app/views/riddler_admin/publish_requests/_actions.html.erb +19 -0
- data/app/views/riddler_admin/publish_requests/_form.html.erb +53 -0
- data/app/views/riddler_admin/publish_requests/approve.js.erb +2 -0
- data/app/views/riddler_admin/publish_requests/edit.html.erb +10 -0
- data/app/views/riddler_admin/publish_requests/index.html.erb +62 -0
- data/app/views/riddler_admin/publish_requests/new.html.erb +10 -0
- data/app/views/riddler_admin/publish_requests/publish.js.erb +2 -0
- data/app/views/riddler_admin/publish_requests/show.html.erb +25 -0
- data/app/views/riddler_admin/slugs/_form.html.erb +48 -0
- data/app/views/riddler_admin/slugs/edit.html.erb +10 -0
- data/app/views/riddler_admin/slugs/index.html.erb +44 -0
- data/app/views/riddler_admin/slugs/new.html.erb +10 -0
- data/app/views/riddler_admin/slugs/show.html.erb +18 -0
- data/app/views/riddler_admin/steps/_definition.html.erb +11 -0
- data/app/views/riddler_admin/steps/_form.html.erb +45 -17
- data/app/views/riddler_admin/steps/_new_sub_step.html.erb +56 -0
- data/app/views/riddler_admin/steps/_visual_preview.html.erb +24 -0
- data/app/views/riddler_admin/steps/content/_show.html.erb +53 -25
- data/app/views/riddler_admin/steps/edit.html.erb +15 -4
- data/app/views/riddler_admin/steps/index.html.erb +24 -10
- data/app/views/riddler_admin/steps/internal_preview.js.erb +5 -0
- data/app/views/riddler_admin/steps/new.html.erb +10 -5
- data/app/views/riddler_admin/steps/new.js.erb +3 -0
- data/app/views/riddler_admin/steps/preview.json.erb +1 -0
- data/app/views/riddler_admin/steps/show.html.erb +26 -11
- data/app/views/riddler_admin/steps/show.js.erb +4 -0
- data/app/views/riddler_admin/steps/variant/_show.html.erb +59 -0
- data/config/routes.rb +20 -1
- data/db/migrate/20181124201519_riddler_admin_genesis.rb +72 -0
- data/lib/riddler_admin.rb +29 -2
- data/lib/riddler_admin/configuration.rb +44 -0
- data/lib/riddler_admin/version.rb +1 -1
- metadata +75 -30
- data/app/views/riddler_admin/elements/copy/_class.html.erb +0 -3
- data/app/views/riddler_admin/elements/copy/_form.html.erb +0 -2
- data/app/views/riddler_admin/elements/heading/_class.html.erb +0 -3
- data/app/views/riddler_admin/steps/_preview.html.erb +0 -5
- data/db/migrate/20181124201519_create_riddler_admin_steps.rb +0 -20
@@ -1,4 +1,23 @@
|
|
1
1
|
module RiddlerAdmin
|
2
2
|
module ApplicationHelper
|
3
|
+
def page_title
|
4
|
+
[
|
5
|
+
::RiddlerAdmin.config.main_app_name,
|
6
|
+
::RiddlerAdmin.config.app_name
|
7
|
+
].compact.join " - "
|
8
|
+
end
|
9
|
+
|
10
|
+
def brand_link
|
11
|
+
if ::RiddlerAdmin.config.main_app_name.present?
|
12
|
+
link_to ::RiddlerAdmin.config.main_app_name, main_app.root_path, class: "navbar-brand"
|
13
|
+
else
|
14
|
+
link_to ::RiddlerAdmin.config.app_name, riddler_admin.root_path, class: "navbar-brand"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def additional_javascript_includes
|
19
|
+
return if ::RiddlerAdmin.config.javascript_includes.blank?
|
20
|
+
javascript_include_tag *::RiddlerAdmin.config.javascript_includes
|
21
|
+
end
|
3
22
|
end
|
4
23
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "ulid"
|
2
2
|
|
3
3
|
module RiddlerAdmin
|
4
4
|
class ApplicationRecord < ActiveRecord::Base
|
@@ -9,15 +9,15 @@ module RiddlerAdmin
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def id_length
|
12
|
-
return
|
12
|
+
return 16 unless self.class.const_defined? :ID_LENGTH
|
13
13
|
self.class.const_get :ID_LENGTH
|
14
14
|
end
|
15
15
|
|
16
16
|
def generate_id
|
17
17
|
return if id.present?
|
18
18
|
model_key = self.class.const_get :MODEL_KEY
|
19
|
-
|
20
|
-
id_string =
|
19
|
+
ulid = ULID.generate
|
20
|
+
id_string = ulid[0..(9+id_length)]
|
21
21
|
self.id = [model_key, id_string].join "_"
|
22
22
|
end
|
23
23
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "riddler/protobuf/content_definition_pb"
|
2
|
+
require "riddler/protobuf/content_management_services_pb"
|
3
|
+
|
4
|
+
module RiddlerAdmin
|
5
|
+
class ContentDefinition < ::RiddlerAdmin::ApplicationRecord
|
6
|
+
MODEL_KEY = "cdef".freeze
|
7
|
+
ID_LENGTH = 5 # 916_132_832 per second
|
8
|
+
|
9
|
+
DEFINITION_SCHEMA_VERSION = 1
|
10
|
+
|
11
|
+
# The Step or Element being defined
|
12
|
+
belongs_to :content, polymorphic: true
|
13
|
+
|
14
|
+
# The PublishRequest that created this
|
15
|
+
belongs_to :publish_request
|
16
|
+
|
17
|
+
validates :definition, presence: true
|
18
|
+
|
19
|
+
validates_uniqueness_of :version, scope: [:content_type, :content_id]
|
20
|
+
|
21
|
+
before_validation :add_fields
|
22
|
+
|
23
|
+
def description
|
24
|
+
publish_request.title
|
25
|
+
end
|
26
|
+
|
27
|
+
def title
|
28
|
+
"#{content.title} v#{version} - #{description}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_proto
|
32
|
+
::Riddler::Protobuf::ContentDefinition.new \
|
33
|
+
id: id,
|
34
|
+
created_at: created_at_proto,
|
35
|
+
content_type: content.content_type.upcase.to_sym,
|
36
|
+
content_id: content.id,
|
37
|
+
title: content.title,
|
38
|
+
description: description,
|
39
|
+
version: version,
|
40
|
+
definition_schema_version: DEFINITION_SCHEMA_VERSION,
|
41
|
+
definition_string: definition.to_json
|
42
|
+
end
|
43
|
+
|
44
|
+
def publish_to_remote
|
45
|
+
content_management_grpc.create_content_definition create_request_proto
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def created_at_proto
|
51
|
+
::Google::Protobuf::Timestamp.new seconds: created_at.to_i,
|
52
|
+
nanos: created_at.nsec
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_request_proto
|
56
|
+
::Riddler::Protobuf::CreateContentDefinitionRequest.new \
|
57
|
+
content_definition: self.to_proto
|
58
|
+
end
|
59
|
+
|
60
|
+
def content_management_grpc
|
61
|
+
::Riddler::Protobuf::ContentManagement::Stub.new \
|
62
|
+
::RiddlerAdmin.configuration.riddler_grpc_address,
|
63
|
+
:this_channel_is_insecure
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_fields
|
67
|
+
return if self.persisted? || content.blank?
|
68
|
+
|
69
|
+
self.definition_schema_version = DEFINITION_SCHEMA_VERSION
|
70
|
+
self.version = next_version
|
71
|
+
self.definition = generate_definition self.version
|
72
|
+
end
|
73
|
+
|
74
|
+
def next_version
|
75
|
+
previous_max = self.class.where(content: content).maximum(:version) || 0
|
76
|
+
previous_max + 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_definition version
|
80
|
+
generated_definition = content.definition_hash.merge({
|
81
|
+
"definition_id" => id,
|
82
|
+
"definition_schema_version" => DEFINITION_SCHEMA_VERSION,
|
83
|
+
"version" => version
|
84
|
+
})
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -1,28 +1,41 @@
|
|
1
1
|
module RiddlerAdmin
|
2
|
-
class Element < ApplicationRecord
|
2
|
+
class Element < ::RiddlerAdmin::ApplicationRecord
|
3
3
|
MODEL_KEY = "el".freeze
|
4
4
|
ID_LENGTH = 6 # 56_800_235_584 per second
|
5
5
|
|
6
|
+
after_initialize :set_defaults
|
7
|
+
|
6
8
|
belongs_to :container, polymorphic: true, validate: true
|
7
9
|
|
8
10
|
acts_as_list scope: [:container_type, :container_id]
|
9
11
|
|
12
|
+
validates_presence_of :name
|
13
|
+
|
14
|
+
# Alphanumeric and underscore only - no whitespace.
|
15
|
+
# We might consider doing lowercase only for snake casing.
|
16
|
+
validates_format_of :name, with: /\A[a-z][a-zA-Z0-9_]*\z/, message: "cannot start with a capital letter or a number."
|
17
|
+
validates_uniqueness_of :name, scope: [:container_type, :container_id], unless: :is_variant?
|
18
|
+
|
19
|
+
validates :include_predicate, parseable_predicate: true
|
20
|
+
|
10
21
|
def self.available_classes
|
11
|
-
[
|
22
|
+
[
|
23
|
+
Elements::Heading,
|
24
|
+
Elements::Image,
|
25
|
+
Elements::Link,
|
26
|
+
Elements::Text,
|
27
|
+
Elements::Variant
|
28
|
+
]
|
12
29
|
end
|
13
30
|
|
14
31
|
def self.default_class
|
15
|
-
Elements::
|
32
|
+
Elements::Text
|
16
33
|
end
|
17
34
|
|
18
35
|
def self.short_name
|
19
36
|
name.demodulize
|
20
37
|
end
|
21
38
|
|
22
|
-
def self.to_partial_path
|
23
|
-
"#{name.underscore}/class"
|
24
|
-
end
|
25
|
-
|
26
39
|
def to_partial_path detail=nil
|
27
40
|
[self.class.name.underscore, detail].compact.join "/"
|
28
41
|
end
|
@@ -36,20 +49,49 @@ module RiddlerAdmin
|
|
36
49
|
type.demodulize.underscore
|
37
50
|
end
|
38
51
|
|
52
|
+
def content_type
|
53
|
+
"element"
|
54
|
+
end
|
55
|
+
|
56
|
+
def content_id
|
57
|
+
id
|
58
|
+
end
|
59
|
+
|
39
60
|
def definition_hash options=nil
|
40
61
|
options ||= {}
|
41
|
-
serializable_hash options.merge(serializable_hash_options)
|
62
|
+
hash = serializable_hash options.merge(serializable_hash_options)
|
63
|
+
hash["type"] = object
|
64
|
+
hash.delete "include_predicate" if hash["include_predicate"].blank?
|
65
|
+
hash
|
42
66
|
end
|
43
67
|
|
44
68
|
def serializable_hash_options
|
45
69
|
{
|
46
|
-
methods: :
|
70
|
+
methods: [:content_type],
|
47
71
|
except: excluded_attrs
|
48
72
|
}
|
49
73
|
end
|
50
74
|
|
51
75
|
def excluded_attrs
|
52
|
-
[:created_at, :updated_at, :container_type, :container_id, :position, :
|
76
|
+
[:created_at, :updated_at, :container_type, :container_id, :position, :url, :text]
|
77
|
+
end
|
78
|
+
|
79
|
+
def step
|
80
|
+
if container.kind_of? ::RiddlerAdmin::Step
|
81
|
+
container
|
82
|
+
else
|
83
|
+
container.step
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def is_variant?
|
90
|
+
container.kind_of? ::RiddlerAdmin::Elements::Variant
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_defaults
|
94
|
+
self.name = short_name.underscore if name.blank?
|
53
95
|
end
|
54
96
|
end
|
55
97
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RiddlerAdmin
|
2
|
+
module Elements
|
3
|
+
class Image < Element
|
4
|
+
validates_presence_of :url
|
5
|
+
|
6
|
+
def self.model_name
|
7
|
+
Element.model_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def definition_hash options=nil
|
11
|
+
hash = super
|
12
|
+
hash["src"] = url
|
13
|
+
hash["alt"] = text
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RiddlerAdmin
|
2
|
+
module Elements
|
3
|
+
class Link < Element
|
4
|
+
validates_presence_of :url
|
5
|
+
|
6
|
+
def self.model_name
|
7
|
+
Element.model_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def definition_hash options=nil
|
11
|
+
hash = super
|
12
|
+
hash["href"] = url
|
13
|
+
hash["text"] = text
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,11 +1,17 @@
|
|
1
1
|
module RiddlerAdmin
|
2
2
|
module Elements
|
3
|
-
class
|
3
|
+
class Text < Element
|
4
4
|
validates_presence_of :text
|
5
5
|
|
6
6
|
def self.model_name
|
7
7
|
Element.model_name
|
8
8
|
end
|
9
|
+
|
10
|
+
def definition_hash options=nil
|
11
|
+
hash = super
|
12
|
+
hash["text"] = text
|
13
|
+
hash
|
14
|
+
end
|
9
15
|
end
|
10
16
|
end
|
11
17
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RiddlerAdmin
|
2
|
+
module Elements
|
3
|
+
class Variant < Element
|
4
|
+
has_many :elements, -> { order position: :asc },
|
5
|
+
dependent: :destroy,
|
6
|
+
as: :container
|
7
|
+
|
8
|
+
def self.model_name
|
9
|
+
Element.model_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def definition_hash options=nil
|
13
|
+
hash = super
|
14
|
+
hash["elements"] = elements.map { |e| e.definition_hash }
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RiddlerAdmin
|
2
|
+
class PreviewContext < ::RiddlerAdmin::ApplicationRecord
|
3
|
+
MODEL_KEY = "pctx".freeze
|
4
|
+
ID_LENGTH = 5 # 916_132_832 per second
|
5
|
+
|
6
|
+
validates :title, presence: true, uniqueness: true
|
7
|
+
|
8
|
+
def self.convert_headers input_headers
|
9
|
+
original_headers = input_headers.to_h.
|
10
|
+
select{|k,v| k.starts_with? "HTTP_"}.
|
11
|
+
map{|k,v| [k.downcase.gsub(/^http_/, ""), v] }
|
12
|
+
|
13
|
+
Hash[original_headers]
|
14
|
+
end
|
15
|
+
|
16
|
+
def data
|
17
|
+
yaml_string = yaml
|
18
|
+
|
19
|
+
if ::RiddlerAdmin.configuration.encrypt_preview_contexts? &&
|
20
|
+
encrypted_yaml.present?
|
21
|
+
|
22
|
+
yaml_string = decrypt encrypted_yaml
|
23
|
+
end
|
24
|
+
|
25
|
+
return {} if yaml_string.to_s.strip == ""
|
26
|
+
YAML.safe_load yaml_string
|
27
|
+
end
|
28
|
+
|
29
|
+
def refresh_data input_headers: {}
|
30
|
+
use_case_headers = merge_headers input_headers
|
31
|
+
|
32
|
+
use_case = ::Riddler::UseCases::PreviewContext.new \
|
33
|
+
params: params_hash,
|
34
|
+
headers: use_case_headers
|
35
|
+
|
36
|
+
hash = use_case.process
|
37
|
+
update_data hash
|
38
|
+
end
|
39
|
+
|
40
|
+
def params_hash
|
41
|
+
params_array = (params || "").split("\n").map do |line|
|
42
|
+
line.split(":").map &:strip
|
43
|
+
end
|
44
|
+
Hash[params_array]
|
45
|
+
end
|
46
|
+
|
47
|
+
def headers_hash
|
48
|
+
headers_array = (headers || "").split("\n").map do |line|
|
49
|
+
key, val = *line.split(":").map(&:strip)
|
50
|
+
[key.downcase.gsub(/[^0-9a-z]/i, "_"), val]
|
51
|
+
end
|
52
|
+
Hash[headers_array]
|
53
|
+
end
|
54
|
+
|
55
|
+
def merge_headers input_headers
|
56
|
+
request_headers = self.class.convert_headers input_headers
|
57
|
+
request_headers.merge headers_hash
|
58
|
+
end
|
59
|
+
|
60
|
+
def update_data hash
|
61
|
+
yaml = hash.to_yaml
|
62
|
+
|
63
|
+
if ::RiddlerAdmin.configuration.encrypt_preview_contexts?
|
64
|
+
encrypted_yaml = encrypt yaml
|
65
|
+
update_attribute :encrypted_yaml, encrypted_yaml
|
66
|
+
else
|
67
|
+
update_attribute :yaml, yaml
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def encrypt plaintext
|
74
|
+
::RiddlerAdmin.encrypt plaintext,
|
75
|
+
key: ::RiddlerAdmin.configuration.preview_context_transit_key
|
76
|
+
end
|
77
|
+
|
78
|
+
def decrypt ciphertext
|
79
|
+
::RiddlerAdmin.decrypt ciphertext,
|
80
|
+
key: ::RiddlerAdmin.configuration.preview_context_transit_key
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RiddlerAdmin
|
2
|
+
class PublishRequest < ::RiddlerAdmin::ApplicationRecord
|
3
|
+
MODEL_KEY = "pr".freeze
|
4
|
+
ID_LENGTH = 5 # 916_132_832 per second
|
5
|
+
|
6
|
+
# The Step or Element being published
|
7
|
+
belongs_to :content, polymorphic: true
|
8
|
+
|
9
|
+
# The ContentDefinition created as a result of this request
|
10
|
+
has_one :content_definition
|
11
|
+
|
12
|
+
validates :title, presence: true
|
13
|
+
|
14
|
+
after_initialize :set_defaults
|
15
|
+
|
16
|
+
scope :unapproved, -> { where "approved_at is null" }
|
17
|
+
|
18
|
+
def approve riddler_user = nil, approved_at = Time.now.utc
|
19
|
+
attrs = {status: "approved", approved_at: approved_at}
|
20
|
+
if riddler_user.present?
|
21
|
+
attrs[:approved_by_name] = ::RiddlerAdmin.config.user_name_block.call riddler_user
|
22
|
+
attrs[:approved_by_id] = riddler_user.public_send ::RiddlerAdmin.config.user_id_method
|
23
|
+
end
|
24
|
+
|
25
|
+
update_attributes attrs
|
26
|
+
end
|
27
|
+
|
28
|
+
def approved?
|
29
|
+
approved_at.present?
|
30
|
+
end
|
31
|
+
|
32
|
+
def publish published_at = Time.now.utc
|
33
|
+
raise "ERROR: Attempt to publish an unapproved definition" unless approved?
|
34
|
+
create_content_definition! content: content
|
35
|
+
content_definition.publish_to_remote
|
36
|
+
|
37
|
+
update_attributes published_at: published_at,
|
38
|
+
status: "published"
|
39
|
+
end
|
40
|
+
|
41
|
+
def published?
|
42
|
+
published_at.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def set_defaults
|
48
|
+
return if title.present? || content.blank?
|
49
|
+
|
50
|
+
if content.published?
|
51
|
+
self.title = "Update #{content.title}"
|
52
|
+
else
|
53
|
+
self.title = "Create #{content.title}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|