Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-select categories from context menu feature #918

Closed
cazendium opened this issue Nov 25, 2023 · 3 comments
Closed

Multi-select categories from context menu feature #918

cazendium opened this issue Nov 25, 2023 · 3 comments

Comments

@cazendium
Copy link

cazendium commented Nov 25, 2023

I think this feature will be extremely nice to have (well for me at least). I want to be able to quickly organize my archives anywhere I am or triage my queue from the reading list into the right categories without needing to look in "remove from category" before going to "add to category", and that's if I remember which category it's already in.

Marked checkboxes also prevent selecting the same category more than once.

I managed to get it working now with the code below. I'm hoping for an official implementation.

Demo video of the context menu with multi-select categories, FYI the video is sped up

index.html.tt2

			// Initialize context menu
			$.contextMenu({
				selector: '.context-menu',
				build: ($trigger, e) => {
					function addToList() {
						catList = [];
									[% IF categories.size > 0 %][% FOREACH categories %]
									catList.push("[% name %]");
									catListId.push("[% id %]");
									[% END %]
									[% ELSE %]
									catList.push("None");
									[% END %]
					}
					addToList();
					return {
						callback: function (key, options) {
								Index.handleContextMenu(key, $(this).attr("id"));
						},
						items: {
							"collections": {
								"name": "Add to a Category",
								"icon": "fas fa-search-plus",
								"items": Index.loadContextMenuCategories($trigger.attr("id"))
							},
							"edit": { name: "Edit Metadata", icon: "fas fa-pencil-alt" },
							"delete": { name: "Delete", icon: "fas fa-trash-alt" },
							"sep1": "---------",
							"read": { name: "Read", icon: "fas fa-book" },
							"download": { name: "Download", icon: "fas fa-save" },
							[% IF userlogged %]
							[% END %]
						},
					}
				}
			});

index.js

let catList = [];
let catListId = [];

/**
 * Load the categories a given ID belongs to.
 * @param {*} id The ID of the archive to check
 * @returns Categories
 */
Index.loadContextMenuCategories = function (id) {
    return Server.callAPI(`/api/archives/${id}/categories`, "GET", null, `Error finding categories for ${id}!`,
        (data) => {
            const items = {};

            for (let i = 0; i < catList.length; i++) {
                const catId = `category-${catListId[i]}`;
                items[catId] = { name: catList[i], "type": "checkbox" };

                items[catId].events = {
                    click: function () {
                        if ($(this).is(':checked')) {
                            Index.handleContextMenu(`category-${catListId[i]}`, id);
                        } else {
                            Index.handleContextMenu(`delcat-${catListId[i]}`,id);
                        }
                    },
                };
            }

            for (let i = 0; i < data.categories.length; i++) {
                const cat = data.categories[i];
                const index = catList.indexOf(cat.name);

                if (index !== -1) {
                    const catId = `category-${catListId[index]}`;
                    items[catId] = { name: cat.name, "type": "checkbox", "selected": "yes" };

                    items[catId].events = {
                        click: function () {
                            if ($(this).is(':checked')) {
                                Index.handleContextMenu(`category-${cat.id}`, id);
                            } else {
                                Index.handleContextMenu(`delcat-${cat.id}`,id);
                            }
                        },
                    };
                }
            }
            return items;
        },
    );
};

Thank you.

@cazendium cazendium changed the title Multi-select categories from Multi-select categories from context menu feature Nov 25, 2023
@Difegue
Copy link
Owner

Difegue commented Nov 27, 2023

Nice work -- Checkbox-style UI for categories is quite better and I wouldn't mind adding this in, yeah!
The existing implementation just fits with the rest of the item-callback way the context menu library we use is built, but I hadn't thought of just overriding the callback by giving the items their own click events... I think this approach is good.

The only drawback I can think of is that the API call is now made everytime you want to add/remove a category to an ID (previously it was only needed for removal), but I don't think it's that big of a deal ¯\_(ツ)_/¯

I'd approve a PR with those changes (or I guess I'll copy-paste it in myself eventually but don't have the time for it rn) -- just a few notes from me:

  • It'd be cleaner to move addToList out of $.contextMenu -- It doesn't even really need to be in a function, you could just have the catList building code before/after the contextMenu init in that template-provided javascript.
  • If we're handling categories that way the specific code for it in handleContextMenu isn't really necessary anymore; It can be removed and you could just call Server.addArchiveToCategory(id, catId);/Server.removeArchiveFromCategory(id, catId);.

@cazendium
Copy link
Author

Thanks for the tips! I haven't noticed anything wrong spamming the checkboxes so far.

And I don't mind if anything I share just gets copy/pasted, since I still need to make time on learning how to do pull requests.

@Difegue
Copy link
Owner

Difegue commented Dec 16, 2023

Cleaned up and implemented.

@Difegue Difegue closed this as completed Dec 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants