Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/admin.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/dark-theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/light-theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/images/alchemy/icons-sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions app/components/alchemy/admin/publish_element_button.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<alchemy-publish-element-button id="publish-element-button-<%= element.id %>">
<sl-button-group label="Example Button Group">
<sl-tooltip
content="<%= element.public? ? Alchemy.t(:hide_element) : Alchemy.t(:show_element) %>"
<%= "disabled" if element.scheduled? || cannot?(:update, element) %>
>
<%= form_tag(alchemy.publish_admin_element_path(element), method: "patch") do %>
<sl-button
variant="<%= element.public? ? "default" : "primary" %>"
type="submit"
size="small"
<%= "disabled" if element.scheduled? || cannot?(:update, element) %>
outline
pill
>
<alchemy-icon name="cloud-off" slot="prefix" size="1x"></alchemy-icon>
</sl-button>
<% end %>
</sl-tooltip>
<sl-tooltip
content="<%= element.scheduled? ? Alchemy.t(:edit_element_schedule) : Alchemy.t(:schedule_element) %>"
<%= "disabled" if cannot?(:update, element) %>
>
<sl-dropdown distance="5">
<sl-button
slot="trigger"
variant="<%= element.scheduled? ? "primary" : "default" %>"
size="small"
<%= "disabled" if cannot?(:update, element) %>
outline
pill
>
<alchemy-icon name="calendar-schedule" slot="suffix" size="1x"></alchemy-icon>
</sl-button>
<div class="alchemy-popover">
<%= render "alchemy/admin/elements/schedule", element: element %>
</div>
</sl-dropdown>
</sl-tooltip>
</sl-button-group>
</alchemy-publish-element-button>
13 changes: 13 additions & 0 deletions app/components/alchemy/admin/publish_element_button.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Alchemy
module Admin
class PublishElementButton < ViewComponent::Base
delegate :alchemy, :cannot?, :render_icon, :link_to_dialog, to: :helpers

attr_reader :element

def initialize(element:)
@element = element
end
end
end
end
27 changes: 21 additions & 6 deletions app/controllers/alchemy/admin/elements_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,23 @@ def destroy
end

def publish
@element.public = !@element.public?
@element.save(validate: false)
render json: {
public: @element.public?,
label: @element.public? ? Alchemy.t(:hide_element) : Alchemy.t(:show_element)
}.merge(pagePublicationData(@element.page))
if schedule_element_params.present?
@element.assign_attributes(schedule_element_params)
@element.skip_ingredient_validations = true
@element.save
status = @element.valid? ? 200 : 422
else
@element.public = !@element.public?
@element.save(validate: false)
status = 200
end

respond_to do |format|
format.turbo_stream do
@page = @element.page
render status:
end
end
end

def order
Expand Down Expand Up @@ -216,6 +227,10 @@ def element_params
def create_element_params
params.require(:element).permit(:name, :page_version_id, :parent_element_id)
end

def schedule_element_params
params[:element]&.permit(:public_on, :public_until)
end
end
end
end
13 changes: 11 additions & 2 deletions app/javascript/alchemy_admin/components/element_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class ElementEditor extends HTMLElement {

// Dirty observer still needs to be jQuery
// in order to support select2.
$(this).on("change", this.onChange)
$(this.form).on("change", this.onChange)

this.header?.addEventListener("dblclick", () => {
this.toggle()
Expand Down Expand Up @@ -87,7 +87,7 @@ export class ElementEditor extends HTMLElement {
if (target.classList.contains("nested-elements")) {
return
}
this.setDirty(target)
this.closest("alchemy-element-editor").setDirty(target)
event.stopPropagation()
return false
}
Expand Down Expand Up @@ -555,6 +555,15 @@ export class ElementEditor extends HTMLElement {
return this.querySelector("alchemy-element-editor")
}

/**
* The form element if present
*
* @returns {HTMLFormElement|undefined}
*/
get form() {
return this.querySelector("form.element-body")
}

/**
* The parent element editor if present
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
import { patch } from "alchemy_admin/utils/ajax"
import { reloadPreview } from "alchemy_admin/components/preview_window"
import { growl } from "alchemy_admin/growler"
import { dispatchPageDirtyEvent } from "alchemy_admin/components/element_editor"

export class PublishElementButton extends HTMLElement {
constructor() {
super()
#scheduleButtonVariant

connectedCallback() {
this.#scheduleButtonVariant = this.scheduleButton.getAttribute("variant")
this.publishButton.addEventListener("click", this)
this.dropdown.addEventListener("sl-show", this)
this.dropdown.addEventListener("sl-hide", this)
}

this.addEventListener("sl-change", this)
disconnectedCallback() {
this.publishButton.removeEventListener("click", this)
this.dropdown.removeEventListener("sl-show", this)
this.dropdown.removeEventListener("sl-hide", this)
}

handleEvent(event) {
const elementEditor = event.target.closest("alchemy-element-editor")
if (elementEditor === this.elementEditor) {
patch(Alchemy.routes.publish_admin_element_path(this.elementId))
.then((response) => {
const data = response.data
this.elementEditor.published = data.public
this.tooltip.setAttribute("content", data.label)
reloadPreview()
if (data.pageHasUnpublishedChanges) {
dispatchPageDirtyEvent(data)
}
})
.catch((error) => growl(error.message, "error"))
switch (event.type) {
case "click":
this.publishButton.loading = true
break
case "sl-show":
this.scheduleButton.setAttribute("variant", "primary")
break
case "sl-hide":
this.scheduleButton.setAttribute("variant", this.#scheduleButtonVariant)
break
}
}

get elementEditor() {
return this.closest("alchemy-element-editor")
get publishButton() {
return this.querySelector("sl-button[type='submit']")
}

get tooltip() {
return this.closest("sl-tooltip")
get dropdown() {
return this.querySelector("sl-dropdown")
}

get elementId() {
return this.elementEditor.elementId
get scheduleButton() {
return this.querySelector("sl-button[slot='trigger']")
}
}

Expand Down
6 changes: 5 additions & 1 deletion app/javascript/alchemy_admin/components/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Message extends HTMLElement {
return this.hasAttribute("dismissable")
}

get icon() {
return this.getAttribute("icon")
}

get type() {
return this.getAttribute("type") || "notice"
}
Expand All @@ -50,7 +54,7 @@ class Message extends HTMLElement {
}

get iconName() {
switch (this.type) {
switch (this.icon || this.type) {
case "warning":
case "warn":
case "alert":
Expand Down
8 changes: 6 additions & 2 deletions app/javascript/alchemy_admin/shoelace_theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ const spriteUrl = document
.getAttribute("href")

const iconMap = {
"x-lg": "close"
"x-lg": "close",
caret: "arrow-down-s"
}

const options = {
resolver: (name) => `${spriteUrl}#ri-${iconMap[name] || name}-line`,
mutator: (svg) => svg.setAttribute("fill", "currentColor"),
mutator: (svg) => {
svg.setAttribute("fill", "currentColor")
svg.setAttribute("viewBox", "0 0 24 24")
},
spriteSheet: true
}

Expand Down
2 changes: 2 additions & 0 deletions app/models/alchemy/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class Element < BaseRecord
include Alchemy::Taggable
include Publishable

attr_accessor :skip_ingredient_validations

FORBIDDEN_DEFINITION_ATTRIBUTES = [
"amount",
"autogenerate",
Expand Down
2 changes: 2 additions & 0 deletions app/models/alchemy/ingredient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ def partial_name

# @return [Boolean]
def has_validations?
return false if element.skip_ingredient_validations

definition.validate.any?
end

Expand Down
12 changes: 12 additions & 0 deletions app/models/concerns/alchemy/publishable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ module Publishable
where("#{table_name}.public_until > :at", at:)
)
}

validate do
if public_on.present? && public_until.present?
if public_until <= public_on
errors.add(:public_until, :must_be_after_public_on)
end
end
end
end

# Determines if this record is public
Expand All @@ -28,6 +36,10 @@ def public?(time = Time.current)
end
alias_method :public, :public?

def scheduled?
public_on&.future? || public_until&.future?
end

# Determines if this record is publishable
#
# A record is publishable if a +public_on+ timestamp is set and not expired yet.
Expand Down
2 changes: 1 addition & 1 deletion app/stylesheets/alchemy/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
border-color: $border-color;
border-radius: $border-radius;
box-shadow: $box-shadow;
outline: none;
outline: 0 none;

&::-moz-focus-inner {
border: none !important;
Expand Down
2 changes: 2 additions & 0 deletions app/stylesheets/alchemy/_themes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
--button-secondary-hover-bg-color: var(--a-dark-grey);
--button-secondary-hover-border-color: var(--a-grey);
--button-secondary-text-color: var(--color-white);
--button-primary-text-color: var(--a-darker-grey);

--code-background-color: var(--a-darkest-grey);
--code-border-color: var(--a-grey);
Expand Down Expand Up @@ -309,6 +310,7 @@
--button-secondary-hover-bg-color: var(--color-white);
--button-secondary-hover-border-color: var(--color-grey_medium);
--button-secondary-text-color: var(--text-color);
--button-primary-text-color: var(--color-white);

--code-background-color: var(--color-grey_light);
--code-border-color: var(--border-color);
Expand Down
1 change: 1 addition & 0 deletions app/stylesheets/alchemy/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
@use "admin/nodes";
@use "admin/notices";
@use "admin/pagination";
@use "admin/popover";
@use "admin/preview_window";
@use "admin/resource_info";
@use "admin/search";
Expand Down
3 changes: 2 additions & 1 deletion app/stylesheets/alchemy/admin/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ a img {
width: 100%;
}

.hidden {
.hidden,
[hidden] {
display: none !important;
}

Expand Down
31 changes: 12 additions & 19 deletions app/stylesheets/alchemy/admin/elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -237,21 +237,17 @@ button.element-toggle {
.element-toggle {
margin-left: 0;
}

.element-hidden-icon {
display: inline-flex;
align-items: center;
gap: var(--spacing-1);
margin-left: auto;
}

.element-hidden-label {
line-height: 1;
font-size: var(--font-size_small);
}
}
}

.element-status-icons {
display: inline-flex;
align-items: center;
gap: var(--spacing-1);
margin-left: auto;
font-size: var(--font-size_small);
}

&.is-fixed {
border-width: 0;
border-radius: 0;
Expand Down Expand Up @@ -355,10 +351,6 @@ button.element-toggle {
}

&.compact {
.element-hidden-label {
display: none;
}

.element-toolbar {
visibility: hidden;
position: absolute;
Expand Down Expand Up @@ -449,7 +441,7 @@ button.element-toggle {
text-align: left;
}

alchemy-message {
> alchemy-message {
margin: var(--spacing-2);
}

Expand Down Expand Up @@ -538,7 +530,7 @@ button.element-toggle {
}
}

.element-hidden-icon {
.element-status-icons {
display: none;
white-space: nowrap;
flex-shrink: 0;
Expand Down Expand Up @@ -1075,7 +1067,8 @@ select.long {
.picture_thumbnail,
.select2-container,
.tinymce_container {
outline: 1px solid var(--element-dirty-border-color);
box-shadow: 0 0 0 1px var(--element-dirty-border-color);
border-color: var(--element-dirty-border-color);
}
}

Expand Down
Loading
Loading