107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
import { getGlobalOptions } from "@/lib/globals";
|
|
import {
|
|
printError,
|
|
printErrorMessageWithReason,
|
|
printObject,
|
|
printSuccess,
|
|
} from "@/lib/output";
|
|
import { getAPIClient } from "@/lib/trpc";
|
|
import { Command } from "@commander-js/extra-typings";
|
|
import { getBorderCharacters, table } from "table";
|
|
|
|
export const categoriesCmd = new Command()
|
|
.name("categories")
|
|
.description("Manipulate categories");
|
|
|
|
categoriesCmd
|
|
.command("list")
|
|
.description("lists all defined categories")
|
|
.action(async () => {
|
|
const api = getAPIClient();
|
|
|
|
try {
|
|
const categories = (await api.categories.list.query()).categories;
|
|
// colors.sort((a, b) => b.numCategories - a.numCategories);
|
|
if (getGlobalOptions().json) {
|
|
printObject(categories);
|
|
} else {
|
|
const data: string[][] = [["Code", "Name", "Description", "Color"]];
|
|
|
|
categories.forEach((c) => {
|
|
data.push([c.code.toString(), c.name, c.description ?? "none", c.color.name]);
|
|
});
|
|
console.log(
|
|
data.length <= 1 ?
|
|
"No categories found. Add one with `lifetracker categories create <code> <name> <description> <color>`" :
|
|
table(data, {
|
|
// border: getBorderCharacters("ramac"),
|
|
// singleLine: true,
|
|
drawVerticalLine: (lineIndex, columnCount) => {
|
|
return lineIndex === 0 || lineIndex === columnCount;
|
|
},
|
|
drawHorizontalLine: (lineIndex, rowCount) => {
|
|
return lineIndex < 2 || lineIndex === rowCount;
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
} catch (error) {
|
|
printErrorMessageWithReason("Failed to list all categories", error as object);
|
|
}
|
|
});
|
|
|
|
categoriesCmd
|
|
.command("create")
|
|
.description("create a category")
|
|
.argument("<code>", "the code of the category")
|
|
.argument("<name>", "the name of the category")
|
|
.argument("<description>", "the description of the category")
|
|
.argument("[color]", "the color of the category")
|
|
.option('-p, --parent <CODE>', "specify a parent category by code")
|
|
.action(async (codeStr: string, name: string, description: string, colorName?: string, flags?) => {
|
|
const api = getAPIClient();
|
|
|
|
const color = flags?.parent === undefined ?
|
|
(await api.colors.get.query({ colorName: colorName! }))
|
|
:
|
|
(await api.categories.get.query({ categoryCode: parseInt(flags.parent) })).color
|
|
|
|
|
|
try {
|
|
await api.categories.create
|
|
.mutate({
|
|
code: parseFloat(codeStr),
|
|
name: name,
|
|
description: description,
|
|
color: color,
|
|
})
|
|
.then(printSuccess(`Successfully created the category "${name}"`))
|
|
.catch(printError(`Failed to create the category "${name}"`));
|
|
api.categories.list
|
|
}
|
|
catch (e) {
|
|
console.log(e);
|
|
}
|
|
});
|
|
|
|
|
|
categoriesCmd
|
|
.command("delete")
|
|
.description("delete a category")
|
|
.argument("<code>", "the code of the category")
|
|
.action(async (codeStr: string) => {
|
|
const api = getAPIClient();
|
|
|
|
try {
|
|
await api.categories.delete
|
|
.mutate({
|
|
categoryCode: parseInt(codeStr),
|
|
})
|
|
.then(printSuccess(`Successfully deleted category "${codeStr}"`))
|
|
.catch(printError(`Failed to delete category "${codeStr}"`));
|
|
}
|
|
catch (e) {
|
|
console.log(e);
|
|
}
|
|
});
|