+/**
+ * Service for helping manage common dual-list scenarios.
+ * (Shelf book manager, sort set manager).
+ */
+
+type ListActionsSet = Record<string, ((item: HTMLElement) => void)>;
+
+export function buildListActions(
+ availableList: HTMLElement,
+ configuredList: HTMLElement,
+): ListActionsSet {
+ return {
+ move_up(item) {
+ const list = item.parentNode as HTMLElement;
+ const index = Array.from(list.children).indexOf(item);
+ const newIndex = Math.max(index - 1, 0);
+ list.insertBefore(item, list.children[newIndex] || null);
+ },
+ move_down(item) {
+ const list = item.parentNode as HTMLElement;
+ const index = Array.from(list.children).indexOf(item);
+ const newIndex = Math.min(index + 2, list.children.length);
+ list.insertBefore(item, list.children[newIndex] || null);
+ },
+ remove(item) {
+ availableList.appendChild(item);
+ },
+ add(item) {
+ configuredList.appendChild(item);
+ },
+ };
+}
+
+export function sortActionClickListener(actions: ListActionsSet, onChange: () => void) {
+ return (event: MouseEvent) => {
+ const sortItemAction = (event.target as Element).closest('.scroll-box-item button[data-action]') as HTMLElement|null;
+ if (sortItemAction) {
+ const sortItem = sortItemAction.closest('.scroll-box-item') as HTMLElement;
+ const action = sortItemAction.dataset.action;
+ if (!action) {
+ throw new Error('No action defined for clicked button');
+ }
+
+ const actionFunction = actions[action];
+ actionFunction(sortItem);
+
+ onChange();
+ }
+ };
+}
+