Add functions for creation selection commands

This commit is contained in:
Robert
2023-04-13 15:53:22 +01:00
parent be3efd79a8
commit 08eb7f811e

View File

@@ -0,0 +1,51 @@
import { showAndLogErrorMessage } from "../helpers";
import {
ExplorerSelectionCommandFunction,
TreeViewContextMultiSelectionCommandFunction,
TreeViewContextSingleSelectionCommandFunction,
} from "./commands";
// A hack to match types that are not an array, which is useful to help avoid
// misusing createSingleSelectionCommand, e.g. where T accidentally gets instantiated
// as DatabaseItem[] instead of DatabaseItem.
type NotArray = object & { length?: never };
// A way to get the type system to help assert that one type is a supertype of another.
type CreateSupertypeOf<Super, Sub extends Super> = Sub;
// This asserts that SelectionCommand is assignable to all of the different types of
// SelectionCommand defined in commands.ts. The intention is the output from the helpers
// in this file can be used with any of the select command types and cna handle any of
// the inputs.
type SelectionCommand<T extends NotArray> = CreateSupertypeOf<
TreeViewContextMultiSelectionCommandFunction<T> &
TreeViewContextSingleSelectionCommandFunction<T> &
ExplorerSelectionCommandFunction<T>,
(singleItem: T, multiSelect?: T[] | undefined) => Promise<void>
>;
export function createSingleSelectionCommand<T extends NotArray>(
f: (argument: T) => Promise<void>,
itemName: string,
): SelectionCommand<T> {
return async (singleItem, multiSelect) => {
if (multiSelect === undefined || multiSelect.length === 1) {
return f(singleItem);
} else {
void showAndLogErrorMessage(`Please select a single ${itemName}.`);
return;
}
};
}
export function createMultiSelectionCommand<T extends NotArray>(
f: (argument: T[]) => Promise<void>,
): SelectionCommand<T> {
return async (singleItem, multiSelect) => {
if (multiSelect !== undefined && multiSelect.length > 0) {
return f(multiSelect);
} else {
return f([singleItem]);
}
};
}