chore(react/promoted_attributes): handle URL open button

This commit is contained in:
Elian Doran 2025-11-23 12:46:06 +02:00
parent 8d4e30a2e4
commit 832d9a2ab8
No known key found for this signature in database
2 changed files with 46 additions and 20 deletions

View File

@ -8,7 +8,7 @@ import { t } from "../services/i18n";
import { DefinitionObject, LabelType } from "../services/promoted_attribute_definition_parser"; import { DefinitionObject, LabelType } from "../services/promoted_attribute_definition_parser";
import server from "../services/server"; import server from "../services/server";
import FNote from "../entities/fnote"; import FNote from "../entities/fnote";
import { HTMLInputTypeAttribute, InputHTMLAttributes, TargetedEvent, TargetedInputEvent } from "preact"; import { HTMLInputTypeAttribute, InputHTMLAttributes, MouseEventHandler, TargetedEvent, TargetedInputEvent } from "preact";
import tree from "../services/tree"; import tree from "../services/tree";
interface Cell { interface Cell {
@ -150,12 +150,19 @@ function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) {
} }
}, []); }, []);
if (definition.labelType === "number") { switch (definition.labelType) {
case "number": {
let step = 1; let step = 1;
for (let i = 0; i < (definition.numberPrecision || 0) && i < 10; i++) { for (let i = 0; i < (definition.numberPrecision || 0) && i < 10; i++) {
step /= 10; step /= 10;
} }
extraInputProps.step = step; extraInputProps.step = step;
break;
}
case "url": {
extraInputProps.placeholder = t("promoted_attributes.url_placeholder");
break;
}
} }
return ( return (
@ -175,6 +182,20 @@ function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) {
/> />
{ definition.labelType === "color" && <ColorPicker {...props} onChange={onChangeListener} inputId={inputId} />} { definition.labelType === "color" && <ColorPicker {...props} onChange={onChangeListener} inputId={inputId} />}
{ definition.labelType === "url" && (
<InputButton
className="open-external-link-button"
icon="bx bx-window-open"
title={t("promoted_attributes.open_external_link")}
onClick={(e) => {
const inputEl = document.getElementById(inputId) as HTMLInputElement | null;
const url = inputEl?.value;
if (url) {
window.open(url, "_blank");
}
}}
/>
)}
</> </>
); );
} }
@ -197,8 +218,8 @@ function ColorPicker({ cell, onChange, inputId }: CellProps & {
value={cell.valueAttr.value || defaultColor} value={cell.valueAttr.value || defaultColor}
onChange={onChange} onChange={onChange}
/> />
<span <InputButton
className="input-group-text bx bxs-tag-x" icon="bx bxs-tag-x"
title={t("promoted_attributes.remove_color")} title={t("promoted_attributes.remove_color")}
onClick={(e) => { onClick={(e) => {
// Indicate to the user the color was reset. // Indicate to the user the color was reset.
@ -292,9 +313,8 @@ function MultiplicityCell({ cell, cells, setCells, setCellToFocus, note, compone
function PromotedActionButton({ icon, title, onClick }: { function PromotedActionButton({ icon, title, onClick }: {
icon: string, icon: string,
title: string, title: string,
onClick: () => void onClick: MouseEventHandler<HTMLSpanElement>
}) }) {
{
return ( return (
<span <span
className={clsx("tn-tool-button pointer", icon)} className={clsx("tn-tool-button pointer", icon)}
@ -304,6 +324,21 @@ function PromotedActionButton({ icon, title, onClick }: {
) )
} }
function InputButton({ icon, className, title, onClick }: {
icon: string;
className?: string;
title: string;
onClick: MouseEventHandler<HTMLSpanElement>;
}) {
return (
<span
className={clsx("input-group-text", className, icon)}
title={title}
onClick={onClick}
/>
)
}
function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute, onChangeListener: TargetedEvent<HTMLInputElement, Event>) { function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute, onChangeListener: TargetedEvent<HTMLInputElement, Event>) {
// no need to await for this, can be done asynchronously // no need to await for this, can be done asynchronously
const $input = $(el); const $input = $(el);

View File

@ -30,15 +30,6 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget {
if (valueAttr.value === "true") { if (valueAttr.value === "true") {
$input.prop("checked", "checked"); $input.prop("checked", "checked");
} }
} else if (definition.labelType === "url") {
$input.prop("placeholder", t("promoted_attributes.url_placeholder"));
const $openButton = $("<span>")
.addClass("input-group-text open-external-link-button bx bx-window-open")
.prop("title", t("promoted_attributes.open_external_link"))
.on("click", () => window.open($input.val() as string, "_blank"));
$input.after($openButton);
} else { } else {
ws.logError(t("promoted_attributes.unknown_label_type", { type: definition.labelType })); ws.logError(t("promoted_attributes.unknown_label_type", { type: definition.labelType }));
} }