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" > -
+ + + + + + +