Skip to content

Commit

Permalink
Rename Anchor Select into Dom Id Select
Browse files Browse the repository at this point in the history
It was previously a dom id - select and technically it is search for dom nodes with ids. It also adds an enabled and disabled state on the dom id - select. Also separate both dom id selects into slightly different components and add an enable and disable mechanic to alchemy-select.
  • Loading branch information
sascha-karnatz committed Mar 27, 2024
1 parent b939ee1 commit 81ad9d5
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 80 deletions.
6 changes: 3 additions & 3 deletions app/components/alchemy/admin/link_dialog/anchor_tab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def self.panel_name

def fields
[
anchor_select,
dom_id_select,
title_input
]
end
Expand All @@ -25,13 +25,13 @@ def message

private

def anchor_select
def dom_id_select
label = label_tag("anchor_link", Alchemy.t(:anchor), class: "control-label")
options = [[Alchemy.t("Please choose"), ""]]
options += [[@url, @url]] if is_selected? && @url

select = select_tag(:anchor_link, options_for_select(options, @url), is: "alchemy-select")
select_component = content_tag("alchemy-anchor-select", select, {type: "preview"})
select_component = content_tag("alchemy-dom-id-preview-select", select)

content_tag("div", label + select_component, class: "input select")
end
Expand Down
10 changes: 5 additions & 5 deletions app/components/alchemy/admin/link_dialog/internal_tab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ def page_select
end

def dom_id_select
fragment = uri.fragment if uri
fragment = "##{uri.fragment}" if uri&.fragment
label = label_tag("element_anchor", Alchemy.t(:anchor), class: "control-label")
options = [[Alchemy.t("Please choose"), ""]]
options += [["##{fragment}", fragment]] if is_selected? && fragment
options = [[page.nil? ? Alchemy.t("Select a page first") : Alchemy.t("None"), ""]]
options += [[fragment, fragment]] if is_selected? && fragment

select = select_tag("element_anchor", options_for_select(options, fragment), is: "alchemy-select")
select_component = content_tag("alchemy-anchor-select", select, {page: page&.id})
select = select_tag("element_anchor", options_for_select(options, fragment), is: "alchemy-select", disabled: page.nil?)
select_component = content_tag("alchemy-dom-id-api-select", select, {page: page&.id})

content_tag("div", label + select_component, class: "input select")
end
Expand Down
59 changes: 0 additions & 59 deletions app/javascript/alchemy_admin/components/anchor_select.js

This file was deleted.

75 changes: 75 additions & 0 deletions app/javascript/alchemy_admin/components/dom_id_select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { get } from "alchemy_admin/utils/ajax"
import { translate } from "alchemy_admin/i18n"

class DomIdSelect extends HTMLElement {
dataItem(hash) {
return {
id: `#${hash}`,
text: `#${hash}`
}
}

get selectElement() {
return this.querySelector("select")
}
}

class DomIdApiSelect extends DomIdSelect {
#pageId = undefined

connectedCallback() {
this.page = this.getAttribute("page")
}

#fetchDomIdsFromApi() {
get(Alchemy.routes.api_ingredients_path, { page_id: this.#pageId }).then(
(result) => {
this.selectElement.data = result.data.ingredients
.filter((ingredient) => ingredient.data?.dom_id)
.map((ingredient) => this.dataItem(ingredient.data.dom_id))
// this.enable()
}
)
}

enable() {
this.selectElement.options[0].text =
this.selectElement.options.length > 0
? translate("None")
: translate("No anchors found")
this.selectElement.enable()
}

disable() {
this.selectElement.options[0].text = translate("Select a page first")
this.selectElement.disable()
}

set page(pageId) {
this.#pageId = pageId
if (!!pageId) {
this.#fetchDomIdsFromApi()
} else {
this.disable()
this.selectElement.data = []
}
}
}

class DomIdPreviewSelect extends DomIdSelect {
connectedCallback() {
// wait a tick to let the browser initialize the inner select component
setTimeout(() => {
const frame = document.getElementById("alchemy_preview_window")
const elements = frame.contentDocument?.querySelectorAll("[id]") || []
if (elements.length > 0) {
this.selectElement.data = Array.from(elements).map((element) => {
return this.dataItem(element.id)
})
}
})
}
}

customElements.define("alchemy-dom-id-api-select", DomIdApiSelect)
customElements.define("alchemy-dom-id-preview-select", DomIdPreviewSelect)
2 changes: 1 addition & 1 deletion app/javascript/alchemy_admin/components/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import "alchemy_admin/components/anchor_select"
import "alchemy_admin/components/button"
import "alchemy_admin/components/char_counter"
import "alchemy_admin/components/clipboard_button"
import "alchemy_admin/components/datepicker"
import "alchemy_admin/components/dialog_link"
import "alchemy_admin/components/dom_id_select"
import "alchemy_admin/components/element_editor"
import "alchemy_admin/components/elements_window"
import "alchemy_admin/components/message"
Expand Down
26 changes: 19 additions & 7 deletions app/javascript/alchemy_admin/components/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,30 @@ class Select extends HTMLSelectElement {
})
}

enable() {
this.removeAttribute("disabled")
this.#select2Element.trigger("change")
}

disable() {
this.setAttribute("disabled", "disabled")
this.#select2Element.trigger("change")
}

set data(data) {
let selected = this.value
// remove all previous entries except the default please select entry which has no value or is selected
const emptyOption =
this.options[0]?.value === ""
? this.options[0].cloneNode(true)
: undefined
const emptyOptions = []
for (let option of this.options) {
if (option.value === "") {
emptyOptions.push(option.cloneNode(true))
}
}

// reset the old options and insert the placeholder(s) first
this.innerHTML = ""
if (emptyOption) {
this.add(emptyOption)
}
emptyOptions.forEach((option) => this.add(option))

// add the new options to the select
data.forEach((item) => {
const option = new Option(item.text, item.id, false, item.id === selected)
Expand Down
11 changes: 6 additions & 5 deletions app/javascript/alchemy_admin/link_dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ export class LinkDialog extends Alchemy.Dialog {
* @param page
*/
#updatePage(page = null) {
document.getElementById("internal_link").value =
page != null ? page.url_path : undefined
const internalLink = document.getElementById("internal_link")
const domIdSelect = document.querySelector(
'[data-link-form-type="internal"] alchemy-dom-id-api-select'
)

document.querySelector(
'[data-link-form-type="internal"] alchemy-anchor-select'
).page = page != null ? page.id : undefined
internalLink.value = page != null ? page.url_path : undefined
domIdSelect.page = page != null ? page.id : undefined
}

/**
Expand Down
3 changes: 3 additions & 0 deletions app/javascript/alchemy_admin/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export const en = {
"Uploaded bytes exceed file size": "Uploaded bytes exceed file size",
"Abort upload": "Abort upload",
"Cancel all uploads": "Cancel all uploads",
None: "None",
"No anchors found": "No anchors found",
"Select a page first": "Select a page first",
Close: "Close",
formats: {
datetime: "Y-m-d H:i",
Expand Down

0 comments on commit 81ad9d5

Please sign in to comment.