286 lines
11 KiB
TypeScript
286 lines
11 KiB
TypeScript
import { t } from "../../../app/i18n.js";
|
|
|
|
const _safeText = (v: any) => {
|
|
try {
|
|
return String(v ?? "");
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
const _labelSort = (key: any) => {
|
|
const k = String(key || "");
|
|
if (k === "name_asc") return t("sort.nameAZ");
|
|
if (k === "name_desc") return t("sort.nameZA");
|
|
if (k === "mtime_asc") return t("sort.oldest");
|
|
return t("sort.newest");
|
|
};
|
|
|
|
const _labelScope = (scope: any) => {
|
|
const s = String(scope || "").toLowerCase();
|
|
if (s === "similar") return t("scope.similar", "Similar");
|
|
if (s === "custom") return t("scope.customBrowser");
|
|
if (s === "workflow") return t("scope.workflow", "Workflow");
|
|
if (s === "all") return t("tab.all");
|
|
if (s === "input" || s === "inputs") return t("scope.input");
|
|
return t("scope.output");
|
|
};
|
|
|
|
function _createPill({ label, value, onClear }: Record<string, any> = {}) {
|
|
const pill = document.createElement("div");
|
|
pill.className = "mjr-context-pill";
|
|
|
|
const txt = document.createElement("span");
|
|
txt.className = "mjr-context-pill-text";
|
|
txt.textContent =
|
|
value != null && String(value).length ? `${label}: ${String(value)}` : String(label || "");
|
|
pill.appendChild(txt);
|
|
|
|
if (typeof onClear === "function") {
|
|
const x = document.createElement("button");
|
|
x.type = "button";
|
|
x.className = "mjr-context-pill-x";
|
|
x.title = t("tooltip.clearFilter", { label: label || t("label.filters") });
|
|
x.setAttribute(
|
|
"aria-label",
|
|
t("tooltip.clearFilter", { label: label || t("label.filters") }),
|
|
);
|
|
x.textContent = "x";
|
|
x.addEventListener("click", (e) => {
|
|
try {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
} catch (e) {
|
|
console.debug?.(e);
|
|
}
|
|
try {
|
|
onClear();
|
|
} catch (e) {
|
|
console.debug?.(e);
|
|
}
|
|
});
|
|
pill.appendChild(x);
|
|
}
|
|
|
|
return pill;
|
|
}
|
|
|
|
export function createContextPillsView(): Record<string, any> {
|
|
const root = document.createElement("div");
|
|
root.className = "mjr-am-context-pills";
|
|
|
|
const update = ({ state, rawQuery = "", actions = null }: Record<string, any> = {}) => {
|
|
const safeActions = actions && typeof actions === "object" ? actions : {};
|
|
|
|
const query = _safeText(rawQuery || "").trim();
|
|
const isQueryActive = query.length > 0 && query !== "*";
|
|
|
|
const isFilterActive = !!(
|
|
_safeText(state?.kindFilter || "").trim() ||
|
|
!!state?.workflowOnly ||
|
|
(Number(state?.minRating || 0) || 0) > 0 ||
|
|
(Number(state?.minSizeMB || 0) || 0) > 0 ||
|
|
(Number(state?.maxSizeMB || 0) || 0) > 0 ||
|
|
(Number(state?.minWidth || 0) || 0) > 0 ||
|
|
(Number(state?.minHeight || 0) || 0) > 0 ||
|
|
(Number(state?.maxWidth || 0) || 0) > 0 ||
|
|
(Number(state?.maxHeight || 0) || 0) > 0 ||
|
|
_safeText(state?.workflowType || "").trim() ||
|
|
_safeText(state?.workflowId || "").trim() ||
|
|
_safeText(state?.workflowModelFilter || "").trim() ||
|
|
_safeText(state?.workflowRunsOnFilter || "").trim() ||
|
|
_safeText(state?.dateRangeFilter || "").trim() ||
|
|
_safeText(state?.dateExactFilter || "").trim()
|
|
);
|
|
const isSortActive = _safeText(state?.sort || "mtime_desc").trim() !== "mtime_desc";
|
|
const isCollectionActive = _safeText(state?.collectionId || "").trim().length > 0;
|
|
const scopeValue = String(state?.viewScope || state?.scope || "output").toLowerCase();
|
|
const isSimilarScope = scopeValue === "similar";
|
|
const isBrowserScope = scopeValue === "custom";
|
|
const isScopeActive = scopeValue !== "output";
|
|
const similarSourceId = _safeText(state?.similarSourceAssetId || "").trim();
|
|
|
|
const anyContext =
|
|
isQueryActive ||
|
|
isFilterActive ||
|
|
isSortActive ||
|
|
isCollectionActive ||
|
|
isScopeActive ||
|
|
isSimilarScope;
|
|
if (!anyContext && !root.childElementCount) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
root.replaceChildren();
|
|
} catch (e) {
|
|
console.debug?.(e);
|
|
}
|
|
|
|
if (!isBrowserScope && isCollectionActive) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.collections"),
|
|
value: _safeText(state?.collectionName || state?.collectionId || "").trim(),
|
|
onClear: () => safeActions?.clearCollection?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (isSimilarScope) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("search.findSimilar", "Find Similar"),
|
|
value: similarSourceId
|
|
? t("search.similarReference", "Reference #{id}", { id: similarSourceId })
|
|
: t("scope.similar", "Similar"),
|
|
onClear: () => safeActions?.clearSimilarScope?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (isScopeActive) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.scope"),
|
|
value: _labelScope(scopeValue || "output"),
|
|
onClear: () =>
|
|
isSimilarScope
|
|
? safeActions?.clearSimilarScope?.()
|
|
: safeActions?.clearScope?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (isQueryActive) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.query"),
|
|
value: query,
|
|
onClear: () => safeActions?.clearQuery?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.kindFilter || "").trim()) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.type"),
|
|
value: _safeText(state?.kindFilter || "").trim(),
|
|
onClear: () => safeActions?.clearKind?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (Number(state?.minRating || 0) > 0) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.rating"),
|
|
value: `>= ${Number(state?.minRating || 0)}`,
|
|
onClear: () => safeActions?.clearMinRating?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (state?.workflowOnly) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.workflow"),
|
|
value: t("label.only"),
|
|
onClear: () => safeActions?.clearWorkflowOnly?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.workflowType || "").trim()) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.workflowType"),
|
|
value: _safeText(state?.workflowType || "").trim(),
|
|
onClear: () => safeActions?.clearWorkflowType?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.workflowId || "").trim()) {
|
|
const workflowId = _safeText(state?.workflowId || "").trim();
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.sameWorkflow", "Generated with Same Workflow"),
|
|
value: workflowId.length > 18 ? `${workflowId.slice(0, 8)}...${workflowId.slice(-6)}` : workflowId,
|
|
onClear: () => safeActions?.clearWorkflowId?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.workflowModelFilter || "").trim()) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.workflowModelFamily", "Model family"),
|
|
value: _safeText(state?.workflowModelFilter || "").trim(),
|
|
onClear: () => safeActions?.clearWorkflowModel?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.workflowRunsOnFilter || "").trim()) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.workflowRunsOn", "Runs on"),
|
|
value: _safeText(state?.workflowRunsOnFilter || "").trim(),
|
|
onClear: () => safeActions?.clearWorkflowRunsOn?.(),
|
|
}),
|
|
);
|
|
}
|
|
if ((Number(state?.minSizeMB || 0) || 0) > 0 || (Number(state?.maxSizeMB || 0) || 0) > 0) {
|
|
const min = Number(state?.minSizeMB || 0) || 0;
|
|
const max = Number(state?.maxSizeMB || 0) || 0;
|
|
const label =
|
|
min > 0 && max > 0 ? `${min}-${max} MB` : min > 0 ? `>= ${min} MB` : `<= ${max} MB`;
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("sidebar.size"),
|
|
value: label,
|
|
onClear: () => safeActions?.clearSize?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (
|
|
(Number(state?.minWidth || 0) || 0) > 0 ||
|
|
(Number(state?.minHeight || 0) || 0) > 0 ||
|
|
(Number(state?.maxWidth || 0) || 0) > 0 ||
|
|
(Number(state?.maxHeight || 0) || 0) > 0
|
|
) {
|
|
const isLte = String(state?.resolutionCompare || "gte") === "lte";
|
|
const w = Number(isLte ? state?.maxWidth : state?.minWidth || 0) || 0;
|
|
const h = Number(isLte ? state?.maxHeight : state?.minHeight || 0) || 0;
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.resolution"),
|
|
value: `${isLte ? "<=" : ">="} ${w || 0}x${h || 0} px`,
|
|
onClear: () => safeActions?.clearResolution?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.dateRangeFilter || "").trim()) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("sidebar.date"),
|
|
value: _safeText(state?.dateRangeFilter || "").trim(),
|
|
onClear: () => safeActions?.clearDateRange?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (_safeText(state?.dateExactFilter || "").trim()) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.day"),
|
|
value: _safeText(state?.dateExactFilter || "").trim(),
|
|
onClear: () => safeActions?.clearDateExact?.(),
|
|
}),
|
|
);
|
|
}
|
|
if (isSortActive) {
|
|
root.appendChild(
|
|
_createPill({
|
|
label: t("label.sort"),
|
|
value: _labelSort(state?.sort),
|
|
onClear: () => safeActions?.clearSort?.(),
|
|
}),
|
|
);
|
|
}
|
|
};
|
|
|
|
return { wrap: root, update };
|
|
}
|