From fdf4b006c0cf469bf31fa9e30f92da41be98f710 Mon Sep 17 00:00:00 2001
From: Chen Asraf
Date: Mon, 6 Apr 2026 01:40:22 +0300
Subject: [PATCH] feat: edit/delete lists, label updates, workflow fix
---
.github/workflows/release.yml | 2 +-
lib/Db/ShoppingListItem.php | 6 ++
src/components/CategoryPicker.vue | 6 +-
src/components/RecurrenceEditor.vue | 14 +--
src/composables/useShoppingList.ts | 9 +-
src/views/HouseSettingsView.vue | 4 +-
src/views/MembersView.vue | 4 +-
src/views/ShoppingListsView.vue | 133 ++++++++++++++++++++++++++--
src/views/SideNavigation.vue | 13 ++-
9 files changed, 163 insertions(+), 28 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index bb6bf8b..44213fc 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -101,6 +101,7 @@ jobs:
name: Release to Nextcloud Apps
runs-on: ubuntu-latest
needs: [build, release, upload]
+ if: ${{ needs.release.outputs.release_created }}
steps:
- name: Checkout
@@ -116,7 +117,6 @@ jobs:
echo -n "${{ secrets.NEXTCLOUD_APP_PRIVATE_KEY }}" > ~/.nextcloud/certificates/pantry.key
- name: Release to Nextcloud Apps
- if: ${{ needs.release.outputs.release_created }}
env:
NEXTCLOUD_API_TOKEN: ${{ secrets.NEXTCLOUD_API_TOKEN }}
run: |
diff --git a/lib/Db/ShoppingListItem.php b/lib/Db/ShoppingListItem.php
index 4a7b1e6..82e1da0 100644
--- a/lib/Db/ShoppingListItem.php
+++ b/lib/Db/ShoppingListItem.php
@@ -62,6 +62,12 @@ class ShoppingListItem extends Entity implements \JsonSerializable {
$this->addType('sortOrder', 'integer');
$this->addType('createdAt', 'integer');
$this->addType('updatedAt', 'integer');
+ // Force these bool fields to be included in INSERTs. Their PHP defaults
+ // match the initial value, so the magic setter would otherwise never
+ // mark them dirty and the column would be omitted from the INSERT.
+ // fromRow() resets updated fields after hydration, so reads are unaffected.
+ $this->markFieldUpdated('bought');
+ $this->markFieldUpdated('repeatFromCompletion');
}
public function jsonSerialize(): array {
diff --git a/src/components/CategoryPicker.vue b/src/components/CategoryPicker.vue
index 83ded79..3506ad8 100644
--- a/src/components/CategoryPicker.vue
+++ b/src/components/CategoryPicker.vue
@@ -231,10 +231,10 @@ function iconFor(key: string) {
const strings = {
placeholder: t('pantry', 'Pick a category'),
createTitle: t('pantry', 'New category'),
- nameLabel: t('pantry', 'Name:'),
+ nameLabel: t('pantry', 'Name'),
namePlaceholder: t('pantry', 'e.g. Produce, Dairy'),
- iconLabel: t('pantry', 'Icon:'),
- colorLabel: t('pantry', 'Color:'),
+ iconLabel: t('pantry', 'Icon'),
+ colorLabel: t('pantry', 'Color'),
create: t('pantry', 'Create'),
saving: t('pantry', 'Saving …'),
cancel: t('pantry', 'Cancel'),
diff --git a/src/components/RecurrenceEditor.vue b/src/components/RecurrenceEditor.vue
index 7a45730..82e380d 100644
--- a/src/components/RecurrenceEditor.vue
+++ b/src/components/RecurrenceEditor.vue
@@ -458,19 +458,19 @@ function clear(): void {
const strings = {
title: t('pantry', 'Recurrence'),
- presetsLabel: t('pantry', 'Presets:'),
- frequencyLabel: t('pantry', 'Unit:'),
- everyLabel: t('pantry', 'Every:'),
- weekdaysLabel: t('pantry', 'Repeat on:'),
- monthDaysLabel: t('pantry', 'Days of the month:'),
+ presetsLabel: t('pantry', 'Presets'),
+ frequencyLabel: t('pantry', 'Unit'),
+ everyLabel: t('pantry', 'Every'),
+ weekdaysLabel: t('pantry', 'Repeat on'),
+ monthDaysLabel: t('pantry', 'Days of the month'),
monthDaysHint: t('pantry', 'Leave empty to repeat on the same day each month.'),
- endsLabel: t('pantry', 'Ends:'),
+ endsLabel: t('pantry', 'Ends'),
endNever: t('pantry', 'Never'),
endAfter: t('pantry', 'After'),
endAfterSuffix: t('pantry', 'occurrences'),
endOn: t('pantry', 'On date'),
fromCompletionLabel: t('pantry', 'Count interval from when the item is ticked off'),
- summaryLabel: t('pantry', 'Summary:'),
+ summaryLabel: t('pantry', 'Summary'),
cancel: t('pantry', 'Cancel'),
save: t('pantry', 'Save'),
clearButton: t('pantry', 'Remove recurrence'),
diff --git a/src/composables/useShoppingList.ts b/src/composables/useShoppingList.ts
index af3aaff..c016763 100644
--- a/src/composables/useShoppingList.ts
+++ b/src/composables/useShoppingList.ts
@@ -25,8 +25,11 @@ export function useShoppingLists(houseId: number) {
return created
}
- async function rename(listId: number, name: string): Promise {
- const updated = await api.updateList(houseId, listId, { name })
+ async function update(
+ listId: number,
+ patch: { name?: string; description?: string | null },
+ ): Promise {
+ const updated = await api.updateList(houseId, listId, patch)
lists.value = lists.value.map((l) => (l.id === listId ? updated : l))
}
@@ -35,7 +38,7 @@ export function useShoppingLists(houseId: number) {
lists.value = lists.value.filter((l) => l.id !== listId)
}
- return { lists, loading, error, load, create, rename, remove }
+ return { lists, loading, error, load, create, update, remove }
}
export function useShoppingListItems(houseId: number, listId: number) {
diff --git a/src/views/HouseSettingsView.vue b/src/views/HouseSettingsView.vue
index 3369020..c56bee8 100644
--- a/src/views/HouseSettingsView.vue
+++ b/src/views/HouseSettingsView.vue
@@ -98,9 +98,9 @@ async function deleteHouse() {
const strings = {
title: t('pantry', 'House settings'),
- nameLabel: t('pantry', 'Name:'),
+ nameLabel: t('pantry', 'Name'),
namePlaceholder: t('pantry', 'House name'),
- descriptionLabel: t('pantry', 'Description:'),
+ descriptionLabel: t('pantry', 'Description'),
descriptionPlaceholder: t('pantry', 'A short description'),
save: t('pantry', 'Save changes'),
saving: t('pantry', 'Saving …'),
diff --git a/src/views/MembersView.vue b/src/views/MembersView.vue
index 1b6b276..7f09b8f 100644
--- a/src/views/MembersView.vue
+++ b/src/views/MembersView.vue
@@ -186,9 +186,9 @@ const strings = {
colRole: t('pantry', 'Role'),
colJoined: t('pantry', 'Joined'),
addDialogTitle: t('pantry', 'Add a member'),
- userIdLabel: t('pantry', 'Account ID:'),
+ userIdLabel: t('pantry', 'Account ID'),
userIdPlaceholder: t('pantry', 'The Nextcloud username'),
- roleLabel: t('pantry', 'Role:'),
+ roleLabel: t('pantry', 'Role'),
cancel: t('pantry', 'Cancel'),
}
diff --git a/src/views/ShoppingListsView.vue b/src/views/ShoppingListsView.vue
index 8185f27..75cc899 100644
--- a/src/views/ShoppingListsView.vue
+++ b/src/views/ShoppingListsView.vue
@@ -30,7 +30,7 @@
- -
+
-
{{ list.description }}
+
+
+
+ {{ strings.edit }}
+
+
+
+ {{ strings.delete }}
+
+
@@ -53,7 +63,7 @@
:open="showCreate"
@update:open="showCreate = $event"
>
-