Files
MajoorWaldi-ComfyUI-Majoor-…/js/features/collections/contextmenu/addToCollectionMenu.js
T
MajoorWaldi 834ef1fef3 feat(docs): comprehensive AI features guide and new documentation
- Added new AI_FEATURES.md guide covering all AI-powered capabilities
- Updated DOCUMENTATION_INDEX.md to include new AI features guide
- Added AI Features section to README.md with overview and models used
- Improved backfill warning information in README.md
- Updated reset index / delete DB procedures in DB_MAINTENANCE.md
- Added configuration options for AI features in README.md
2026-03-06 12:43:46 +01:00

152 lines
5.9 KiB
JavaScript

import { comfyPrompt } from "../../../app/dialogs.js";
import { comfyToast } from "../../../app/toast.js";
import { listCollections, createCollection, addAssetsToCollection } from "../../../api/client.js";
import { t } from "../../../app/i18n.js";
import {
getOrCreateMenu as getOrCreateMenuCore,
createMenuItem,
createMenuSeparator,
showMenuAt,
clearMenu,
hideMenu,
hideAllMenus,
MENU_Z_INDEX,
} from "../../../components/contextmenu/MenuCore.js";
import { pickRootId } from "../../../utils/ids.js";
const MENU_SELECTOR = ".mjr-collections-context-menu";
function getOrCreateCollectionsMenu() {
return getOrCreateMenuCore({
selector: MENU_SELECTOR,
className: "mjr-collections-context-menu",
minWidth: 240,
zIndex: MENU_Z_INDEX.COLLECTIONS,
onHide: null,
});
}
function separator() {
return createMenuSeparator();
}
const createItem = (label, iconClass, onClick, opts) => createMenuItem(label, iconClass, null, onClick, opts);
const showAt = showMenuAt;
function simplifyAsset(a) {
if (!a || typeof a !== "object") return null;
const filepath = a.filepath || a.path || a?.file_info?.filepath || "";
if (!filepath) return null;
return {
filepath,
filename: a.filename || "",
subfolder: a.subfolder || "",
type: (a.type || "output").toLowerCase(),
root_id: pickRootId(a),
kind: a.kind || "",
};
}
function formatAddResultMessage({ collectionName, selectedCount, addRes }) {
const added = Number(addRes?.data?.added ?? 0) || 0;
const skippedExisting = Number(addRes?.data?.skipped_existing ?? 0) || 0;
const skippedDuplicate = Number(addRes?.data?.skipped_duplicate ?? 0) || 0;
const name = String(collectionName || "").trim() || t("label.collection", "collection");
let msg = t("msg.collectionAdd.added", "Added {added} item(s) to \"{name}\".", { added, name });
if (skippedExisting > 0) {
msg += `\n\n${t("msg.collectionAdd.skippedExisting", "Skipped {count} item(s): already present in the collection.", { count: skippedExisting })}`;
}
if (skippedDuplicate > 0) {
msg += `\n\n${t("msg.collectionAdd.skippedDuplicate", "Ignored {count} duplicate(s) in selection.", { count: skippedDuplicate })}`;
}
if (added === 0 && skippedExisting > 0 && selectedCount > 0) {
msg = t("msg.collectionAdd.noneAddedExisting", "No new items added to \"{name}\" (all exist).", { name });
}
return msg;
}
export async function showAddToCollectionMenu({ x, y, assets }) {
try {
window.dispatchEvent(new CustomEvent("mjr-close-all-menus"));
} catch (e) { console.debug?.(e); }
hideAllMenus();
const selected = Array.isArray(assets) ? assets.map(simplifyAsset).filter(Boolean) : [];
if (!selected.length) {
comfyToast(t("toast.noValidAssetsSelected", "No valid assets selected."), "warning");
return;
}
const listRes = await listCollections();
const collections = Array.isArray(listRes?.data) ? listRes.data : [];
// If none exist, directly prompt creation.
if (!collections.length) {
const name = await comfyPrompt(
t("dialog.createCollection", "Create collection"),
t("dialog.collectionPlaceholder", "My collection")
);
if (!name) return;
const created = await createCollection(name);
if (!created?.ok) {
comfyToast(created?.error || t("toast.failedCreateCollectionDot", "Failed to create collection."), "error");
return;
}
const cid = created.data?.id;
const addRes = await addAssetsToCollection(cid, selected);
if (!addRes?.ok) {
comfyToast(addRes?.error || t("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error");
return;
}
comfyToast(formatAddResultMessage({ collectionName: created.data?.name || name, selectedCount: selected.length, addRes }), "success", 4000);
return;
}
const menu = getOrCreateCollectionsMenu();
clearMenu(menu);
const createIt = createItem(`${t("dialog.createCollection", "Create collection")}...`, "pi pi-plus", async () => {
hideMenu(menu);
const name = await comfyPrompt(
t("dialog.createCollection", "Create collection"),
t("dialog.collectionPlaceholder", "My collection")
);
if (!name) return;
const created = await createCollection(name);
if (!created?.ok) {
comfyToast(created?.error || t("toast.failedCreateCollectionDot", "Failed to create collection."), "error");
return;
}
const cid = created.data?.id;
const addRes = await addAssetsToCollection(cid, selected);
if (!addRes?.ok) {
comfyToast(addRes?.error || t("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error");
return;
}
comfyToast(formatAddResultMessage({ collectionName: created.data?.name || name, selectedCount: selected.length, addRes }), "success", 4000);
});
menu.appendChild(createIt);
menu.appendChild(separator());
for (const c of collections) {
const cid = String(c?.id || "");
const name = String(c?.name || cid);
if (!cid) continue;
menu.appendChild(
createItem(name, "pi pi-bookmark", async () => {
hideMenu(menu);
const addRes = await addAssetsToCollection(cid, selected);
if (!addRes?.ok) {
comfyToast(addRes?.error || t("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error");
return;
}
comfyToast(formatAddResultMessage({ collectionName: name, selectedCount: selected.length, addRes }), "success", 4000);
})
);
}
showAt(menu, Number(x) || 0, Number(y) || 0);
}