mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 12:43:09 -05:00
Don't allow duplicate category names (per group) (#1833)
* Remove author from electron package.json * Don't allow dupes in cat names (per group) * Release Notes * Handle reorders and moves * Fix linter warnings * Fix typecheck * Show the name of the duplicate category * missed func call * Upper case before compare * lint fixes --------- Co-authored-by: Shazib Hussain <contact@shazib.com>
This commit is contained in:
@@ -92,6 +92,7 @@ type BudgetProps = {
|
||||
moveCategory: BoundActions['moveCategory'];
|
||||
moveCategoryGroup: BoundActions['moveCategoryGroup'];
|
||||
loadPrefs: BoundActions['loadPrefs'];
|
||||
addNotification: BoundActions['addNotification'];
|
||||
};
|
||||
|
||||
function Budget(props: BudgetProps) {
|
||||
@@ -241,7 +242,28 @@ function Budget(props: BudgetProps) {
|
||||
setIsAddingGroup(false);
|
||||
};
|
||||
|
||||
const categoryNameAlreadyExistsNotification = name => {
|
||||
props.addNotification({
|
||||
type: 'error',
|
||||
message: `Category ‘${name}’ already exists in group (May be Hidden)`,
|
||||
});
|
||||
};
|
||||
|
||||
const onSaveCategory = async category => {
|
||||
let exists =
|
||||
(await props.getCategories()).grouped
|
||||
.filter(g => g.id === category.cat_group)[0]
|
||||
.categories.filter(
|
||||
c => c.name.toUpperCase() === category.name.toUpperCase(),
|
||||
)
|
||||
.filter(c => (category.id === 'new' ? true : c.id !== category.id))
|
||||
.length > 0;
|
||||
|
||||
if (exists) {
|
||||
categoryNameAlreadyExistsNotification(category.name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (category.id === 'new') {
|
||||
let id = await props.createCategory(
|
||||
category.name,
|
||||
@@ -350,6 +372,21 @@ function Budget(props: BudgetProps) {
|
||||
};
|
||||
|
||||
const onReorderCategory = async sortInfo => {
|
||||
let cats = await props.getCategories();
|
||||
let moveCandidate = cats.list.filter(c => c.id === sortInfo.id)[0];
|
||||
let exists =
|
||||
cats.grouped
|
||||
.filter(g => g.id === sortInfo.groupId)[0]
|
||||
.categories.filter(
|
||||
c => c.name.toUpperCase() === moveCandidate.name.toUpperCase(),
|
||||
)
|
||||
.filter(c => c.id !== moveCandidate.id).length > 0;
|
||||
|
||||
if (exists) {
|
||||
categoryNameAlreadyExistsNotification(moveCandidate.name);
|
||||
return;
|
||||
}
|
||||
|
||||
props.moveCategory(sortInfo.id, sortInfo.groupId, sortInfo.targetId);
|
||||
setCategoryGroups(state =>
|
||||
moveCategory(state, sortInfo.id, sortInfo.groupId, sortInfo.targetId),
|
||||
|
||||
@@ -346,6 +346,17 @@ export async function insertCategory(
|
||||
|
||||
let id_;
|
||||
await batchMessages(async () => {
|
||||
// Dont allow duplicated names in groups
|
||||
const existingCatInGroup = await first(
|
||||
`SELECT id FROM categories WHERE cat_group = ? and UPPER(name) = ? LIMIT 1`,
|
||||
[category.cat_group, category.name.toUpperCase()],
|
||||
);
|
||||
if (existingCatInGroup) {
|
||||
throw new Error(
|
||||
`Category ‘${category.name}’ already exists in group ‘${category.cat_group}’`,
|
||||
);
|
||||
}
|
||||
|
||||
if (atEnd) {
|
||||
const lastCat = await first(`
|
||||
SELECT sort_order FROM categories WHERE tombstone = 0 ORDER BY sort_order DESC, id DESC LIMIT 1
|
||||
|
||||
6
upcoming-release-notes/1833.md
Normal file
6
upcoming-release-notes/1833.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Enhancements
|
||||
authors: [Shazib]
|
||||
---
|
||||
|
||||
Not allowed duplicated Category names in Category Groups
|
||||
Reference in New Issue
Block a user