Skip to content

Commit

Permalink
(Feat) Element deprecations
Browse files Browse the repository at this point in the history
Elements can be marked as deprecated.

They will be visually displayed with a warning. The deprecation notice can
be localized.
  • Loading branch information
tvdeyen committed Dec 23, 2020
1 parent ab85d1f commit 0a8c1ea
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 6 deletions.
25 changes: 20 additions & 5 deletions app/assets/stylesheets/alchemy/elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,32 @@
}
}

&.deprecated {
border-color: #fdafaf;

> .element-header {
// background-color: rgba(253, 175, 175, 0.5);
background-image: linear-gradient(
45deg,
rgba(253, 175, 175, 0.25) 25%,
$element-header-bg-color 25%,
$element-header-bg-color 50%,
rgba(253, 175, 175, 0.25) 50%,
rgba(253, 175, 175, 0.25) 75%,
$element-header-bg-color 75%,
$element-header-bg-color 100%
);
background-size: 28.28px 28.28px;
}
}

&.selected:not(.is-fixed), &:hover {
&:not(.hidden) {
box-shadow: 0 2px 8px rgba(#9b9b9b, 0.75);
}
}

&.selected:not(.is-fixed):not(.folded):not(.dirty):not(.hidden) {
&.selected:not(.is-fixed):not(.folded):not(.dirty):not(.hidden):not(.deprecated) {
> .element-header {
background-color: $element-header-active-bg-color;
color: $element-header-active-color;
Expand Down Expand Up @@ -802,10 +821,6 @@ textarea.has_tinymce {
}
}

.element-handle .hint-with-icon {
top: -1px;
}

.is-fixed {
&.with-contents {
>.element-footer {
Expand Down
42 changes: 42 additions & 0 deletions app/decorators/alchemy/element_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def css_classes
taggable? ? "taggable" : "not-taggable",
folded ? "folded" : "expanded",
compact? ? "compact" : nil,
deprecated? ? "deprecated" : nil,
fixed? ? "is-fixed" : "not-fixed",
public? ? "visible" : "hidden",
].join(" ")
Expand All @@ -36,5 +37,46 @@ def respond_to?(method_name)

super
end

# Returns a deprecation notice for elements marked deprecated
#
# You can either use localizations or pass a String as notice
# in the element definition.
#
# == Custom deprecation notices
#
# Use general element deprecation notice
#
# - name: old_element
# deprecated: true
#
# Add a translation to your locale file for a per element notice.
#
# en:
# alchemy:
# element_deprecation_notices:
# old_element: Foo baz widget is deprecated
#
# or use the global translation that apply to all deprecated elements.
#
# en:
# alchemy:
# element_deprecation_notice: Foo baz widget is deprecated
#
# or pass string as deprecation notice.
#
# - name: old_element
# deprecated: This element will be removed soon.
#
def deprecation_notice
case definition["deprecated"]
when String
definition["deprecated"]
when TrueClass
Alchemy.t(name,
scope: :element_deprecation_notices,
default: Alchemy.t(:element_deprecated))
end
end
end
end
33 changes: 33 additions & 0 deletions app/models/alchemy/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Element < BaseRecord
"taggable",
"compact",
"message",
"deprecated",
].freeze

SKIPPED_ATTRIBUTES_ON_COPY = [
Expand Down Expand Up @@ -252,6 +253,38 @@ def compact?
definition["compact"] == true
end

# Defined as deprecated element?
#
# You can either set true or a String on your elements definition.
#
# == Passing true
#
# - name: old_element
# deprecated: true
#
# The deprecation notice can be translated. Either as global notice for all deprecated elements.
#
# en:
# alchemy:
# element_deprecation_notice: Foo baz widget is deprecated
#
# Or add a translation to your locale file for a per element notice.
#
# en:
# alchemy:
# element_deprecation_notices:
# old_element: Foo baz widget is deprecated
#
# == Pass a String
#
# - name: old_element
# deprecated: This element will be removed soon.
#
# @return Boolean
def deprecated?
!!definition["deprecated"]
end

# The element's view partial is dependent from its name
#
# == Define elements
Expand Down
2 changes: 2 additions & 0 deletions app/views/alchemy/admin/elements/_element_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<span class="element-handle">
<% if element.definition.blank? %>
<%= hint_with_tooltip Alchemy.t(:element_definition_missing) %>
<% elsif element.deprecated? %>
<%= hint_with_tooltip element.deprecation_notice %>
<% else %>
<% if element.public? %>
<%= render_icon('window-maximize', style: 'regular', class: 'element') %>
Expand Down
1 change: 1 addition & 0 deletions config/locales/alchemy.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ en:
"Warning!": "Warning!"
content_definition_missing: "Warning: Content is missing its definition. Please check the elements.yml"
element_definition_missing: "WARNING! Missing element definition. Please check your elements.yml file."
element_deprecated: "WARNING! This element is deprecated and will be removed soon. Please do not use it anymore."
page_definition_missing: "WARNING! Missing page layout definition. Please check your page_layouts.yml file."
"Welcome to Alchemy": "Welcome to Alchemy"
"Who else is online": "Who else is online"
Expand Down
59 changes: 59 additions & 0 deletions spec/decorators/alchemy/element_editor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@

it { is_expected.to include("not-nestable") }
end

context "with element being deprecated" do
before do
allow(element).to receive(:deprecated?) { true }
end

it { is_expected.to include("deprecated") }
end
end

describe "#editable?" do
Expand Down Expand Up @@ -141,4 +149,55 @@

it { is_expected.to be(false) }
end

describe "deprecation_notice" do
subject { element_editor.deprecation_notice }

context "when element is not deprecated" do
let(:element) { build(:alchemy_element, name: "article") }

it { is_expected.to be_nil }
end

context "when element is deprecated" do
let(:element) { build(:alchemy_element, name: "old") }

context "with custom element translation" do
it { is_expected.to eq("Old element is deprecated") }
end

context "without custom element translation" do
let(:element) { build(:alchemy_element, name: "old_too") }

before do
allow(element).to receive(:definition) do
{
"name" => "old_too",
"deprecated" => true,
}
end
end

it do
is_expected.to eq(
"WARNING! This element is deprecated and will be removed soon. " \
"Please do not use it anymore."
)
end
end

context "with String as deprecation" do
before do
allow(element).to receive(:definition) do
{
"name" => "old",
"deprecated" => "Foo baz widget",
}
end
end

it { is_expected.to eq("Foo baz widget") }
end
end
end
end
8 changes: 8 additions & 0 deletions spec/dummy/config/alchemy/elements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,11 @@
contents:
- name: menu
type: EssenceNode

- name: old
deprecated: true
contents:
- name: title
type: EssenceText
- name: text
type: EssenceRichtext
2 changes: 1 addition & 1 deletion spec/dummy/config/alchemy/page_layouts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
autogenerate: [header, article, download]

- name: everything
elements: [text, all_you_can_eat, gallery, right_column, left_column]
elements: [text, all_you_can_eat, gallery, right_column, left_column, old]
autogenerate: [all_you_can_eat, right_column, left_column]

- name: news
Expand Down
2 changes: 2 additions & 0 deletions spec/dummy/config/locales/alchemy.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ en:
resource_help_texts:
party:
name: Party
element_deprecation_notices:
old: Old element is deprecated

activemodel:
models:
Expand Down
25 changes: 25 additions & 0 deletions spec/models/alchemy/element_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,31 @@ module Alchemy
end
end

describe "#deprecated?" do
subject { element.deprecated? }

let(:element) { build(:alchemy_element) }

before do
expect(element).to receive(:definition) { definition }
end

context "definition has 'deprecated' key with true value" do
let(:definition) { { "deprecated" => true } }
it { is_expected.to be(true) }
end

context "definition has 'deprecated' key with foo value" do
let(:definition) { { "deprecated" => "This is deprecated" } }
it { is_expected.to be(true) }
end

context "definition has no 'deprecated' key" do
let(:definition) { { "name" => "article" } }
it { is_expected.to be(false) }
end
end

describe "#trash!" do
let(:element) { create(:alchemy_element) }

Expand Down

0 comments on commit 0a8c1ea

Please sign in to comment.