From 3887f751d8fe19c278326293c6ced1b7bb88a6ec Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Tue, 7 Apr 2026 00:28:17 +0300 Subject: [PATCH] refactor: shopping lists -> checklists --- README.md | 8 +- appinfo/info.xml | 4 +- lib/BackgroundJob/ReopenRecurringItemsJob.php | 6 +- ...Controller.php => ChecklistController.php} | 18 +- lib/Db/{ShoppingList.php => Checklist.php} | 2 +- ...ShoppingListItem.php => ChecklistItem.php} | 2 +- ...ItemMapper.php => ChecklistItemMapper.php} | 12 +- ...pingListMapper.php => ChecklistMapper.php} | 10 +- lib/Migration/Version1Date20260405000000.php | 2 +- ...ngListService.php => ChecklistService.php} | 42 +- lib/Service/HouseService.php | 8 +- lib/Service/ImageService.php | 8 +- openapi.json | 3088 ++++++++--------- src/Settings.vue | 2 +- src/api/lists.ts | 42 +- src/api/types.ts | 4 +- .../AccountSettingsDialog.vue | 2 +- .../HouseSettingsDialog.vue | 2 +- .../PageToolbar/PageToolbar.test.ts | 4 +- .../{useShoppingList.ts => useChecklist.ts} | 14 +- src/router.ts | 4 +- ...pingListDetail.vue => ChecklistDetail.vue} | 20 +- ...oppingListsView.vue => ChecklistsView.vue} | 30 +- src/views/SideNavigation.vue | 6 +- src/views/WelcomeView.vue | 2 +- ...rviceTest.php => ChecklistServiceTest.php} | 38 +- 26 files changed, 1690 insertions(+), 1690 deletions(-) rename lib/Controller/{ShoppingListController.php => ChecklistController.php} (97%) rename lib/Db/{ShoppingList.php => Checklist.php} (95%) rename lib/Db/{ShoppingListItem.php => ChecklistItem.php} (97%) rename lib/Db/{ShoppingListItemMapper.php => ChecklistItemMapper.php} (88%) rename lib/Db/{ShoppingListMapper.php => ChecklistMapper.php} (83%) rename lib/Service/{ShoppingListService.php => ChecklistService.php} (89%) rename src/composables/{useShoppingList.ts => useChecklist.ts} (89%) rename src/views/{ShoppingListDetail.vue => ChecklistDetail.vue} (97%) rename src/views/{ShoppingListsView.vue => ChecklistsView.vue} (91%) rename tests/unit/Service/{ShoppingListServiceTest.php => ChecklistServiceTest.php} (84%) diff --git a/README.md b/README.md index c79b0a8..e64f1f8 100755 --- a/README.md +++ b/README.md @@ -12,15 +12,15 @@ SPDX-License-Identifier: CC0-1.0 [![PHPUnit MySQL](https://github.com/chenasraf/nextcloud-pantry/actions/workflows/phpunit-mysql.yml/badge.svg)](https://github.com/chenasraf/nextcloud-pantry/actions/workflows/phpunit-mysql.yml) [![PHPUnit PostgreSQL](https://github.com/chenasraf/nextcloud-pantry/actions/workflows/phpunit-pgsql.yml/badge.svg)](https://github.com/chenasraf/nextcloud-pantry/actions/workflows/phpunit-pgsql.yml) -A household management app for Nextcloud — shared shopping lists, photo boards, and notes, all in -one place. +A household management app for Nextcloud — shared checklists, photo boards, and notes, all in one +place. ## Features - **Houses**: Group household members and their shared data. A person can belong to multiple houses and switch between them freely. -- **Shopping Lists**: Create and manage shared shopping lists with support for recurring items (e.g. - milk every week) that automatically reappear when due. +- **Checklists**: Create and manage shared checklists with support for recurring items (e.g. milk + every week) that automatically reappear when due. - **Photo Boards**: Keep shared reference photos organized in folders — the right brand of dog food, a favorite recipe card, a product label, and so on. - **Notes Wall**: A lightweight shared space for household reminders, pinned messages, and quick diff --git a/appinfo/info.xml b/appinfo/info.xml index 8b02585..b9f62a8 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -6,12 +6,12 @@ --> pantry Pantry - Manage your household: shared shopping lists, photo boards, and notes. + Manage your household: shared checklists, photo boards, and notes. $limit Maximum number of lists to return. @@ -66,7 +66,7 @@ final class ShoppingListController extends OCSController { } /** - * Create a shopping list in a house + * Create a checklist in a house * * @param int $houseId House id. * @param string $name List name. @@ -87,7 +87,7 @@ final class ShoppingListController extends OCSController { } /** - * Get a shopping list + * Get a checklist * * @param int $houseId House id. * @param int $listId List id. @@ -108,7 +108,7 @@ final class ShoppingListController extends OCSController { } /** - * Update a shopping list + * Update a checklist * * @param int $houseId House id. * @param int $listId List id. @@ -143,7 +143,7 @@ final class ShoppingListController extends OCSController { } /** - * Delete a shopping list + * Delete a checklist * * @param int $houseId House id. * @param int $listId List id. @@ -165,7 +165,7 @@ final class ShoppingListController extends OCSController { } /** - * List items in a shopping list + * List items in a checklist * * Auto-reopens recurring items whose next occurrence has arrived. * diff --git a/lib/Db/ShoppingList.php b/lib/Db/Checklist.php similarity index 95% rename from lib/Db/ShoppingList.php rename to lib/Db/Checklist.php index cc1b787..0870933 100644 --- a/lib/Db/ShoppingList.php +++ b/lib/Db/Checklist.php @@ -23,7 +23,7 @@ use OCP\AppFramework\Db\Entity; * @method int getUpdatedAt() * @method void setUpdatedAt(int $updatedAt) */ -class ShoppingList extends Entity implements \JsonSerializable { +class Checklist extends Entity implements \JsonSerializable { protected int $houseId = 0; protected string $name = ''; protected ?string $description = null; diff --git a/lib/Db/ShoppingListItem.php b/lib/Db/ChecklistItem.php similarity index 97% rename from lib/Db/ShoppingListItem.php rename to lib/Db/ChecklistItem.php index 4185e9f..e46f94c 100644 --- a/lib/Db/ShoppingListItem.php +++ b/lib/Db/ChecklistItem.php @@ -39,7 +39,7 @@ use OCP\AppFramework\Db\Entity; * @method int getUpdatedAt() * @method void setUpdatedAt(int $updatedAt) */ -class ShoppingListItem extends Entity implements \JsonSerializable { +class ChecklistItem extends Entity implements \JsonSerializable { protected int $listId = 0; protected string $name = ''; protected ?int $categoryId = null; diff --git a/lib/Db/ShoppingListItemMapper.php b/lib/Db/ChecklistItemMapper.php similarity index 88% rename from lib/Db/ShoppingListItemMapper.php rename to lib/Db/ChecklistItemMapper.php index c2eed25..5866761 100644 --- a/lib/Db/ShoppingListItemMapper.php +++ b/lib/Db/ChecklistItemMapper.php @@ -14,15 +14,15 @@ use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; /** - * @template-extends QBMapper + * @template-extends QBMapper */ -class ShoppingListItemMapper extends QBMapper { +class ChecklistItemMapper extends QBMapper { public function __construct(IDBConnection $db) { - parent::__construct($db, Application::tableName('list_items'), ShoppingListItem::class); + parent::__construct($db, Application::tableName('list_items'), ChecklistItem::class); } /** - * @return ShoppingListItem[] + * @return ChecklistItem[] */ public function findByList(int $listId): array { $qb = $this->db->getQueryBuilder(); @@ -38,7 +38,7 @@ class ShoppingListItemMapper extends QBMapper { /** * @throws DoesNotExistException */ - public function findById(int $id): ShoppingListItem { + public function findById(int $id): ChecklistItem { $qb = $this->db->getQueryBuilder(); $qb->select('*') ->from($this->getTableName()) @@ -50,7 +50,7 @@ class ShoppingListItemMapper extends QBMapper { /** * Find all bought items whose next_due_at has passed. * - * @return ShoppingListItem[] + * @return ChecklistItem[] */ public function findDueRecurring(int $now): array { $qb = $this->db->getQueryBuilder(); diff --git a/lib/Db/ShoppingListMapper.php b/lib/Db/ChecklistMapper.php similarity index 83% rename from lib/Db/ShoppingListMapper.php rename to lib/Db/ChecklistMapper.php index 5d76d5f..9e62c68 100644 --- a/lib/Db/ShoppingListMapper.php +++ b/lib/Db/ChecklistMapper.php @@ -14,15 +14,15 @@ use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; /** - * @template-extends QBMapper + * @template-extends QBMapper */ -class ShoppingListMapper extends QBMapper { +class ChecklistMapper extends QBMapper { public function __construct(IDBConnection $db) { - parent::__construct($db, Application::tableName('lists'), ShoppingList::class); + parent::__construct($db, Application::tableName('lists'), Checklist::class); } /** - * @return ShoppingList[] + * @return Checklist[] */ public function findByHouse(int $houseId): array { $qb = $this->db->getQueryBuilder(); @@ -38,7 +38,7 @@ class ShoppingListMapper extends QBMapper { /** * @throws DoesNotExistException */ - public function findById(int $id): ShoppingList { + public function findById(int $id): Checklist { $qb = $this->db->getQueryBuilder(); $qb->select('*') ->from($this->getTableName()) diff --git a/lib/Migration/Version1Date20260405000000.php b/lib/Migration/Version1Date20260405000000.php index 7bd66ac..8f6c2c3 100644 --- a/lib/Migration/Version1Date20260405000000.php +++ b/lib/Migration/Version1Date20260405000000.php @@ -15,7 +15,7 @@ use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; /** - * Initial schema for Pantry: houses, members, shopping lists, list items. + * Initial schema for Pantry: houses, members, checklists, list items. */ class Version1Date20260405000000 extends SimpleMigrationStep { /** diff --git a/lib/Service/ShoppingListService.php b/lib/Service/ChecklistService.php similarity index 89% rename from lib/Service/ShoppingListService.php rename to lib/Service/ChecklistService.php index 0dae314..b1f0d44 100644 --- a/lib/Service/ShoppingListService.php +++ b/lib/Service/ChecklistService.php @@ -7,17 +7,17 @@ declare(strict_types=1); namespace OCA\Pantry\Service; -use OCA\Pantry\Db\ShoppingList; -use OCA\Pantry\Db\ShoppingListItem; -use OCA\Pantry\Db\ShoppingListItemMapper; -use OCA\Pantry\Db\ShoppingListMapper; +use OCA\Pantry\Db\Checklist; +use OCA\Pantry\Db\ChecklistItem; +use OCA\Pantry\Db\ChecklistItemMapper; +use OCA\Pantry\Db\ChecklistMapper; use OCA\Pantry\Exception\NotFoundException; use OCP\AppFramework\Db\DoesNotExistException; -class ShoppingListService { +class ChecklistService { public function __construct( - private ShoppingListMapper $listMapper, - private ShoppingListItemMapper $itemMapper, + private ChecklistMapper $listMapper, + private ChecklistItemMapper $itemMapper, private RecurrenceService $recurrence, ) { } @@ -25,13 +25,13 @@ class ShoppingListService { // ----- Lists ----- /** - * @return ShoppingList[] + * @return Checklist[] */ public function listForHouse(int $houseId): array { return $this->listMapper->findByHouse($houseId); } - public function getList(int $listId): ShoppingList { + public function getList(int $listId): Checklist { try { return $this->listMapper->findById($listId); } catch (DoesNotExistException) { @@ -39,25 +39,25 @@ class ShoppingListService { } } - public function createList(int $houseId, string $name, ?string $description): ShoppingList { + public function createList(int $houseId, string $name, ?string $description): Checklist { $name = trim($name); if ($name === '') { throw new \InvalidArgumentException('List name cannot be empty'); } $now = time(); - $list = new ShoppingList(); + $list = new Checklist(); $list->setHouseId($houseId); $list->setName($name); $list->setDescription($description !== null && $description !== '' ? $description : null); $list->setSortOrder(0); $list->setCreatedAt($now); $list->setUpdatedAt($now); - /** @var ShoppingList $saved */ + /** @var Checklist $saved */ $saved = $this->listMapper->insert($list); return $saved; } - public function updateList(int $listId, array $patch): ShoppingList { + public function updateList(int $listId, array $patch): Checklist { $list = $this->getList($listId); if (isset($patch['name'])) { $name = trim((string)$patch['name']); @@ -89,7 +89,7 @@ class ShoppingListService { /** * List items for a list, auto-unchecking any recurring items whose next_due_at has passed. * - * @return ShoppingListItem[] + * @return ChecklistItem[] */ public function listItems(int $listId, ?int $now = null): array { // Eagerly reopen any due recurring items in this list before returning. @@ -97,7 +97,7 @@ class ShoppingListService { return $this->itemMapper->findByList($listId); } - public function getItem(int $itemId): ShoppingListItem { + public function getItem(int $itemId): ChecklistItem { try { return $this->itemMapper->findById($itemId); } catch (DoesNotExistException) { @@ -105,7 +105,7 @@ class ShoppingListService { } } - public function addItem(int $listId, array $data): ShoppingListItem { + public function addItem(int $listId, array $data): ChecklistItem { // Ensure the list exists. $this->getList($listId); @@ -122,7 +122,7 @@ class ShoppingListService { } $now = time(); - $item = new ShoppingListItem(); + $item = new ChecklistItem(); $item->setListId($listId); $item->setName($name); $item->setCategoryId($this->intOrNull($data['categoryId'] ?? null)); @@ -137,12 +137,12 @@ class ShoppingListService { $item->setSortOrder(isset($data['sortOrder']) ? (int)$data['sortOrder'] : 0); $item->setCreatedAt($now); $item->setUpdatedAt($now); - /** @var ShoppingListItem $saved */ + /** @var ChecklistItem $saved */ $saved = $this->itemMapper->insert($item); return $saved; } - public function updateItem(int $itemId, array $patch): ShoppingListItem { + public function updateItem(int $itemId, array $patch): ChecklistItem { $item = $this->getItem($itemId); if (isset($patch['name'])) { @@ -192,7 +192,7 @@ class ShoppingListService { return $item; } - public function toggleItem(int $itemId, string $uid, ?int $now = null): ShoppingListItem { + public function toggleItem(int $itemId, string $uid, ?int $now = null): ChecklistItem { $item = $this->getItem($itemId); $now ??= time(); @@ -221,7 +221,7 @@ class ShoppingListService { * - "fixed schedule" mode: the schedule is anchored at the item's creation time; next * occurrence is the first one strictly after now on that anchored series. */ - private function computeNextDueAt(ShoppingListItem $item, int $now): ?\DateTimeImmutable { + private function computeNextDueAt(ChecklistItem $item, int $now): ?\DateTimeImmutable { $rrule = $item->getRrule(); if ($rrule === null) { return null; diff --git a/lib/Service/HouseService.php b/lib/Service/HouseService.php index e3474f0..5716fcc 100644 --- a/lib/Service/HouseService.php +++ b/lib/Service/HouseService.php @@ -8,6 +8,8 @@ declare(strict_types=1); namespace OCA\Pantry\Service; use OCA\Pantry\Db\CategoryMapper; +use OCA\Pantry\Db\ChecklistItemMapper; +use OCA\Pantry\Db\ChecklistMapper; use OCA\Pantry\Db\House; use OCA\Pantry\Db\HouseMapper; use OCA\Pantry\Db\HouseMember; @@ -15,8 +17,6 @@ use OCA\Pantry\Db\HouseMemberMapper; use OCA\Pantry\Db\NoteMapper; use OCA\Pantry\Db\PhotoFolderMapper; use OCA\Pantry\Db\PhotoMapper; -use OCA\Pantry\Db\ShoppingListItemMapper; -use OCA\Pantry\Db\ShoppingListMapper; use OCA\Pantry\Exception\ForbiddenException; use OCA\Pantry\Exception\NotFoundException; use OCP\AppFramework\Db\DoesNotExistException; @@ -27,8 +27,8 @@ class HouseService { public function __construct( private HouseMapper $houseMapper, private HouseMemberMapper $memberMapper, - private ShoppingListMapper $listMapper, - private ShoppingListItemMapper $itemMapper, + private ChecklistMapper $listMapper, + private ChecklistItemMapper $itemMapper, private CategoryMapper $categoryMapper, private PhotoMapper $photoMapper, private PhotoFolderMapper $photoFolderMapper, diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php index e284008..7610ed0 100644 --- a/lib/Service/ImageService.php +++ b/lib/Service/ImageService.php @@ -12,7 +12,7 @@ use OCP\Files\IRootFolder; use OCP\Files\NotPermittedException; class ImageService { - public const SHOPPING_ITEMS_SUBDIR = 'Shopping list items'; + public const CHECKLIST_ITEMS_SUBDIR = 'Checklist items'; public const PHOTO_WALL_SUBDIR = 'Photo wall'; public function __construct( @@ -29,7 +29,7 @@ class ImageService { if ($data === '') { throw new \InvalidArgumentException('Empty file'); } - $folder = $this->resolveShoppingItemsFolder($uid, $houseId); + $folder = $this->resolveChecklistItemsFolder($uid, $houseId); $filename = $this->uniqueName($folder, $originalName); try { $file = $folder->newFile($filename, $data); @@ -62,9 +62,9 @@ class ImageService { return $this->getOrCreateSubFolder($base, self::PHOTO_WALL_SUBDIR); } - private function resolveShoppingItemsFolder(string $uid, int $houseId): Folder { + private function resolveChecklistItemsFolder(string $uid, int $houseId): Folder { $base = $this->resolveBaseFolder($uid, $houseId); - return $this->getOrCreateSubFolder($base, self::SHOPPING_ITEMS_SUBDIR); + return $this->getOrCreateSubFolder($base, self::CHECKLIST_ITEMS_SUBDIR); } private function resolveBaseFolder(string $uid, int $houseId): Folder { diff --git a/openapi.json b/openapi.json index 0f23d4c..c23e4e2 100644 --- a/openapi.json +++ b/openapi.json @@ -3,7 +3,7 @@ "info": { "title": "pantry", "version": "0.0.1", - "description": "Manage your household: shared shopping lists, photos and notes.", + "description": "Manage your household: shared checklists, photo boards, and notes.", "license": { "name": "agpl" } @@ -988,6 +988,1549 @@ } } }, + "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists": { + "get": { + "operationId": "checklist-index-lists", + "summary": "List all checklists in a house", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of lists to return.", + "schema": { + "type": "integer", + "format": "int64", + "default": 100, + "minimum": 1, + "maximum": 500 + } + }, + { + "name": "offset", + "in": "query", + "description": "Number of lists to skip.", + "schema": { + "type": "integer", + "format": "int64", + "default": 0, + "minimum": 0 + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Lists returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/List" + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "post": { + "operationId": "checklist-create-list", + "summary": "Create a checklist in a house", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "List name." + }, + "description": { + "type": "string", + "nullable": true, + "default": null, + "description": "Optional description." + } + } + } + } + } + }, + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "List created", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/List" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}": { + "get": { + "operationId": "checklist-show-list", + "summary": "Get a checklist", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "List returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/List" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "patch": { + "operationId": "checklist-update-list", + "summary": "Update a checklist", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "default": null, + "description": "New name." + }, + "description": { + "type": "string", + "nullable": true, + "default": null, + "description": "New description." + }, + "sortOrder": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "New sort order." + } + } + } + } + } + }, + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "List updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/List" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "checklist-delete-list", + "summary": "Delete a checklist", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "List deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Success" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items": { + "get": { + "operationId": "checklist-index-items", + "summary": "List items in a checklist", + "description": "Auto-reopens recurring items whose next occurrence has arrived.", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of items to return.", + "schema": { + "type": "integer", + "format": "int64", + "default": 200, + "minimum": 1, + "maximum": 1000 + } + }, + { + "name": "offset", + "in": "query", + "description": "Number of items to skip.", + "schema": { + "type": "integer", + "format": "int64", + "default": 0, + "minimum": 0 + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Items returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ListItem" + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "post": { + "operationId": "checklist-add-item", + "summary": "Add an item to a list", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Item name." + }, + "categoryId": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "Optional category id (must belong to the same house)." + }, + "quantity": { + "type": "string", + "nullable": true, + "default": null, + "description": "Optional quantity string." + }, + "rrule": { + "type": "string", + "nullable": true, + "default": null, + "description": "Optional RFC 5545 RRULE for recurrence." + }, + "repeatFromCompletion": { + "type": "boolean", + "default": false, + "description": "If true, the next occurrence is measured from when the item is marked bought; if false, the schedule is anchored at item creation." + }, + "sortOrder": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "Optional sort order." + } + } + } + } + } + }, + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Item added", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ListItem" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items/{itemId}": { + "patch": { + "operationId": "checklist-update-item", + "summary": "Update an item", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "default": null, + "description": "New name." + }, + "categoryId": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "New category id (0 or negative clears)." + }, + "quantity": { + "type": "string", + "nullable": true, + "default": null, + "description": "New quantity (empty string clears)." + }, + "rrule": { + "type": "string", + "nullable": true, + "default": null, + "description": "New RRULE (empty string clears)." + }, + "repeatFromCompletion": { + "type": "boolean", + "nullable": true, + "default": null, + "description": "New recurrence anchor mode." + }, + "imageFileId": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "File id of attached image (0 or negative clears)." + }, + "sortOrder": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "New sort order." + } + } + } + } + } + }, + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "itemId", + "in": "path", + "description": "Item id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Item updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ListItem" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "checklist-delete-item", + "summary": "Delete an item", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "itemId", + "in": "path", + "description": "Item id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Item deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Success" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items/{itemId}/toggle": { + "post": { + "operationId": "checklist-toggle-item", + "summary": "Toggle an item's bought status", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "itemId", + "in": "path", + "description": "Item id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Item toggled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ListItem" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items/{itemId}/image": { + "post": { + "operationId": "checklist-upload-item-image", + "summary": "Upload an image for an item", + "description": "Uploads the request body as an image into the user's configured pantry image folder and attaches it to the item.", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "itemId", + "in": "path", + "description": "Item id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Image uploaded and attached", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ListItem" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "checklist-clear-item-image", + "summary": "Clear the image attached to an item", + "tags": [ + "checklist" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "houseId", + "in": "path", + "description": "House id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "listId", + "in": "path", + "description": "List id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "itemId", + "in": "path", + "description": "Item id.", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Image cleared", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ListItem" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/apps/pantry/api/houses": { "get": { "operationId": "house-index", @@ -4637,1549 +6180,6 @@ } } } - }, - "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists": { - "get": { - "operationId": "shopping_list-index-lists", - "summary": "List all shopping lists in a house", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum number of lists to return.", - "schema": { - "type": "integer", - "format": "int64", - "default": 100, - "minimum": 1, - "maximum": 500 - } - }, - { - "name": "offset", - "in": "query", - "description": "Number of lists to skip.", - "schema": { - "type": "integer", - "format": "int64", - "default": 0, - "minimum": 0 - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Lists returned", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/List" - } - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - }, - "post": { - "operationId": "shopping_list-create-list", - "summary": "Create a shopping list in a house", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "description": "List name." - }, - "description": { - "type": "string", - "nullable": true, - "default": null, - "description": "Optional description." - } - } - } - } - } - }, - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "List created", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/List" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - } - }, - "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}": { - "get": { - "operationId": "shopping_list-show-list", - "summary": "Get a shopping list", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "List returned", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/List" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - }, - "patch": { - "operationId": "shopping_list-update-list", - "summary": "Update a shopping list", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "requestBody": { - "required": false, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "default": null, - "description": "New name." - }, - "description": { - "type": "string", - "nullable": true, - "default": null, - "description": "New description." - }, - "sortOrder": { - "type": "integer", - "format": "int64", - "nullable": true, - "default": null, - "description": "New sort order." - } - } - } - } - } - }, - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "List updated", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/List" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - }, - "delete": { - "operationId": "shopping_list-delete-list", - "summary": "Delete a shopping list", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "List deleted", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/Success" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - } - }, - "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items": { - "get": { - "operationId": "shopping_list-index-items", - "summary": "List items in a shopping list", - "description": "Auto-reopens recurring items whose next occurrence has arrived.", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum number of items to return.", - "schema": { - "type": "integer", - "format": "int64", - "default": 200, - "minimum": 1, - "maximum": 1000 - } - }, - { - "name": "offset", - "in": "query", - "description": "Number of items to skip.", - "schema": { - "type": "integer", - "format": "int64", - "default": 0, - "minimum": 0 - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Items returned", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ListItem" - } - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - }, - "post": { - "operationId": "shopping_list-add-item", - "summary": "Add an item to a list", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "description": "Item name." - }, - "categoryId": { - "type": "integer", - "format": "int64", - "nullable": true, - "default": null, - "description": "Optional category id (must belong to the same house)." - }, - "quantity": { - "type": "string", - "nullable": true, - "default": null, - "description": "Optional quantity string." - }, - "rrule": { - "type": "string", - "nullable": true, - "default": null, - "description": "Optional RFC 5545 RRULE for recurrence." - }, - "repeatFromCompletion": { - "type": "boolean", - "default": false, - "description": "If true, the next occurrence is measured from when the item is marked bought; if false, the schedule is anchored at item creation." - }, - "sortOrder": { - "type": "integer", - "format": "int64", - "nullable": true, - "default": null, - "description": "Optional sort order." - } - } - } - } - } - }, - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Item added", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/ListItem" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - } - }, - "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items/{itemId}": { - "patch": { - "operationId": "shopping_list-update-item", - "summary": "Update an item", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "requestBody": { - "required": false, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "default": null, - "description": "New name." - }, - "categoryId": { - "type": "integer", - "format": "int64", - "nullable": true, - "default": null, - "description": "New category id (0 or negative clears)." - }, - "quantity": { - "type": "string", - "nullable": true, - "default": null, - "description": "New quantity (empty string clears)." - }, - "rrule": { - "type": "string", - "nullable": true, - "default": null, - "description": "New RRULE (empty string clears)." - }, - "repeatFromCompletion": { - "type": "boolean", - "nullable": true, - "default": null, - "description": "New recurrence anchor mode." - }, - "imageFileId": { - "type": "integer", - "format": "int64", - "nullable": true, - "default": null, - "description": "File id of attached image (0 or negative clears)." - }, - "sortOrder": { - "type": "integer", - "format": "int64", - "nullable": true, - "default": null, - "description": "New sort order." - } - } - } - } - } - }, - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "itemId", - "in": "path", - "description": "Item id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Item updated", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/ListItem" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - }, - "delete": { - "operationId": "shopping_list-delete-item", - "summary": "Delete an item", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "itemId", - "in": "path", - "description": "Item id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Item deleted", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/Success" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - } - }, - "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items/{itemId}/toggle": { - "post": { - "operationId": "shopping_list-toggle-item", - "summary": "Toggle an item's bought status", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "itemId", - "in": "path", - "description": "Item id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Item toggled", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/ListItem" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - } - }, - "/ocs/v2.php/apps/pantry/api/houses/{houseId}/lists/{listId}/items/{itemId}/image": { - "post": { - "operationId": "shopping_list-upload-item-image", - "summary": "Upload an image for an item", - "description": "Uploads the request body as an image into the user's configured pantry image folder and attaches it to the item.", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "itemId", - "in": "path", - "description": "Item id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Image uploaded and attached", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/ListItem" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - }, - "delete": { - "operationId": "shopping_list-clear-item-image", - "summary": "Clear the image attached to an item", - "tags": [ - "shopping_list" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "houseId", - "in": "path", - "description": "House id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "listId", - "in": "path", - "description": "List id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "itemId", - "in": "path", - "description": "Item id.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Image cleared", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "$ref": "#/components/schemas/ListItem" - } - } - } - } - } - } - } - }, - "401": { - "description": "Current user is not logged in", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": {} - } - } - } - } - } - } - } - } - } } }, "tags": [] diff --git a/src/Settings.vue b/src/Settings.vue index b6014dc..d310b5a 100644 --- a/src/Settings.vue +++ b/src/Settings.vue @@ -23,7 +23,7 @@ export default { aboutHeader: t('pantry', 'About:'), aboutBody: t( 'pantry', - 'Pantry is a household organizer. Open the Pantry app from the top navigation to manage your houses, shopping lists, photos and notes.', + 'Pantry is a household organizer. Open the Pantry app from the top navigation to manage your houses, checklists, photos and notes.', ), }, } diff --git a/src/api/lists.ts b/src/api/lists.ts index 4e88e93..1a54456 100644 --- a/src/api/lists.ts +++ b/src/api/lists.ts @@ -1,8 +1,8 @@ import { ocs } from '@/axios' -import type { ShoppingList, ShoppingListItem } from './types' +import type { Checklist, ChecklistItem } from './types' -export async function listLists(houseId: number): Promise { - const resp = await ocs.get(`/houses/${houseId}/lists`) +export async function listLists(houseId: number): Promise { + const resp = await ocs.get(`/houses/${houseId}/lists`) return resp.data ?? [] } @@ -10,16 +10,16 @@ export async function createList( houseId: number, name: string, description?: string | null, -): Promise { - const resp = await ocs.post(`/houses/${houseId}/lists`, { +): Promise { + const resp = await ocs.post(`/houses/${houseId}/lists`, { name, description: description ?? null, }) return resp.data } -export async function getList(houseId: number, listId: number): Promise { - const resp = await ocs.get(`/houses/${houseId}/lists/${listId}`) +export async function getList(houseId: number, listId: number): Promise { + const resp = await ocs.get(`/houses/${houseId}/lists/${listId}`) return resp.data } @@ -27,8 +27,8 @@ export async function updateList( houseId: number, listId: number, patch: { name?: string; description?: string | null; sortOrder?: number }, -): Promise { - const resp = await ocs.patch(`/houses/${houseId}/lists/${listId}`, patch) +): Promise { + const resp = await ocs.patch(`/houses/${houseId}/lists/${listId}`, patch) return resp.data } @@ -36,8 +36,8 @@ export async function deleteList(houseId: number, listId: number): Promise await ocs.delete(`/houses/${houseId}/lists/${listId}`) } -export async function listItems(houseId: number, listId: number): Promise { - const resp = await ocs.get(`/houses/${houseId}/lists/${listId}/items`) +export async function listItems(houseId: number, listId: number): Promise { + const resp = await ocs.get(`/houses/${houseId}/lists/${listId}/items`) return resp.data ?? [] } @@ -54,8 +54,8 @@ export async function addItem( houseId: number, listId: number, input: ItemInput, -): Promise { - const resp = await ocs.post(`/houses/${houseId}/lists/${listId}/items`, input) +): Promise { + const resp = await ocs.post(`/houses/${houseId}/lists/${listId}/items`, input) return resp.data } @@ -64,8 +64,8 @@ export async function updateItem( listId: number, itemId: number, patch: Partial, -): Promise { - const resp = await ocs.patch( +): Promise { + const resp = await ocs.patch( `/houses/${houseId}/lists/${listId}/items/${itemId}`, patch, ) @@ -76,8 +76,8 @@ export async function toggleItem( houseId: number, listId: number, itemId: number, -): Promise { - const resp = await ocs.post( +): Promise { + const resp = await ocs.post( `/houses/${houseId}/lists/${listId}/items/${itemId}/toggle`, ) return resp.data @@ -92,10 +92,10 @@ export async function uploadItemImage( listId: number, itemId: number, file: File, -): Promise { +): Promise { const form = new FormData() form.append('image', file, file.name) - const resp = await ocs.post( + const resp = await ocs.post( `/houses/${houseId}/lists/${listId}/items/${itemId}/image`, form, ) @@ -106,8 +106,8 @@ export async function clearItemImage( houseId: number, listId: number, itemId: number, -): Promise { - const resp = await ocs.delete( +): Promise { + const resp = await ocs.delete( `/houses/${houseId}/lists/${listId}/items/${itemId}/image`, ) return resp.data diff --git a/src/api/types.ts b/src/api/types.ts index 1ac7aa8..eb869c9 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -19,7 +19,7 @@ export interface HouseMember { joinedAt: number } -export interface ShoppingList { +export interface Checklist { id: number houseId: number name: string @@ -40,7 +40,7 @@ export interface Category { updatedAt: number } -export interface ShoppingListItem { +export interface ChecklistItem { id: number listId: number name: string diff --git a/src/components/AccountSettingsDialog/AccountSettingsDialog.vue b/src/components/AccountSettingsDialog/AccountSettingsDialog.vue index 8d62a18..95b07ee 100644 --- a/src/components/AccountSettingsDialog/AccountSettingsDialog.vue +++ b/src/components/AccountSettingsDialog/AccountSettingsDialog.vue @@ -166,7 +166,7 @@ const strings = { imagesSection: t('pantry', 'Images'), imagesHint: t( 'pantry', - 'Pick the base folder where Pantry will store uploaded images. Shopping list item images go into a "Shopping list items" subfolder inside it, created automatically.', + 'Pick the base folder where Pantry will store uploaded images. Checklist item images go into a "Checklist items" subfolder inside it, created automatically.', ), folderLabel: t('pantry', 'Upload folder'), browse: t('pantry', 'Browse …'), diff --git a/src/components/HouseSettingsDialog/HouseSettingsDialog.vue b/src/components/HouseSettingsDialog/HouseSettingsDialog.vue index e69ef6b..8de7030 100644 --- a/src/components/HouseSettingsDialog/HouseSettingsDialog.vue +++ b/src/components/HouseSettingsDialog/HouseSettingsDialog.vue @@ -306,7 +306,7 @@ const strings = { imagesSection: t('pantry', 'Images'), imagesHint: t( 'pantry', - 'Pick the base folder where Pantry will store uploaded images for this house. Shopping list item images go into a "Shopping list items" subfolder inside it, created automatically.', + 'Pick the base folder where Pantry will store uploaded images for this house. Checklist item images go into a "Checklist items" subfolder inside it, created automatically.', ), folderLabel: t('pantry', 'Upload folder'), browse: t('pantry', 'Browse …'), diff --git a/src/components/PageToolbar/PageToolbar.test.ts b/src/components/PageToolbar/PageToolbar.test.ts index 6ce3aec..2ea33ae 100644 --- a/src/components/PageToolbar/PageToolbar.test.ts +++ b/src/components/PageToolbar/PageToolbar.test.ts @@ -13,12 +13,12 @@ describe('PageToolbar', () => { it('renders the title when provided', () => { const wrapper = mount(PageToolbar, { - props: { title: 'Shopping lists' }, + props: { title: 'Checklists' }, }) const h2 = wrapper.find('.pantry-toolbar__title') expect(h2.exists()).toBe(true) - expect(h2.text()).toBe('Shopping lists') + expect(h2.text()).toBe('Checklists') }) it('does not render the title element when omitted', () => { diff --git a/src/composables/useShoppingList.ts b/src/composables/useChecklist.ts similarity index 89% rename from src/composables/useShoppingList.ts rename to src/composables/useChecklist.ts index 9adb77c..c14be6d 100644 --- a/src/composables/useShoppingList.ts +++ b/src/composables/useChecklist.ts @@ -1,9 +1,9 @@ import { ref } from 'vue' import * as api from '@/api/lists' -import type { ShoppingList, ShoppingListItem } from '@/api/types' +import type { Checklist, ChecklistItem } from '@/api/types' -export function useShoppingLists(houseId: number) { - const lists = ref([]) +export function useChecklists(houseId: number) { + const lists = ref([]) const loading = ref(false) const error = ref(null) @@ -19,7 +19,7 @@ export function useShoppingLists(houseId: number) { } } - async function create(name: string, description?: string | null): Promise { + async function create(name: string, description?: string | null): Promise { const created = await api.createList(houseId, name, description) lists.value = [...lists.value, created] return created @@ -41,8 +41,8 @@ export function useShoppingLists(houseId: number) { return { lists, loading, error, load, create, update, remove } } -export function useShoppingListItems(houseId: number, listId: number) { - const items = ref([]) +export function useChecklistItems(houseId: number, listId: number) { + const items = ref([]) const loading = ref(false) const error = ref(null) @@ -58,7 +58,7 @@ export function useShoppingListItems(houseId: number, listId: number) { } } - async function add(input: api.ItemInput): Promise { + async function add(input: api.ItemInput): Promise { const created = await api.addItem(houseId, listId, input) items.value = [...items.value, created] return created diff --git a/src/router.ts b/src/router.ts index 7447e4a..ec8d21e 100644 --- a/src/router.ts +++ b/src/router.ts @@ -33,13 +33,13 @@ const routes: RouteRecordRaw[] = [ { path: 'lists', name: 'lists', - component: () => import('@/views/ShoppingListsView.vue'), + component: () => import('@/views/ChecklistsView.vue'), props: true, }, { path: 'lists/:listId', name: 'list-detail', - component: () => import('@/views/ShoppingListDetail.vue'), + component: () => import('@/views/ChecklistDetail.vue'), props: true, }, { diff --git a/src/views/ShoppingListDetail.vue b/src/views/ChecklistDetail.vue similarity index 97% rename from src/views/ShoppingListDetail.vue rename to src/views/ChecklistDetail.vue index 906c3f2..3342884 100644 --- a/src/views/ShoppingListDetail.vue +++ b/src/views/ChecklistDetail.vue @@ -55,7 +55,7 @@ :description="strings.emptyBody" > @@ -254,15 +254,15 @@ import ArrowLeftIcon from '@icons/ArrowLeft.vue' import DeleteIcon from '@icons/Delete.vue' import PencilIcon from '@icons/Pencil.vue' import RepeatIcon from '@icons/Repeat.vue' -import CartIcon from '@icons/Cart.vue' +import ClipboardCheckIcon from '@icons/ClipboardCheck.vue' import UploadIcon from '@icons/Upload.vue' import RecurrenceEditor from '@/components/RecurrenceEditor' import CategoryPicker from '@/components/CategoryPicker' import { categoryIconComponent } from '@/components/CategoryPicker' -import { useShoppingListItems } from '@/composables/useShoppingList' +import { useChecklistItems } from '@/composables/useChecklist' import { useCategories } from '@/composables/useCategories' import { getList } from '@/api/lists' -import type { ShoppingList, ShoppingListItem } from '@/api/types' +import type { Checklist, ChecklistItem } from '@/api/types' import { RRule } from 'rrule' const props = defineProps<{ houseId: string; listId: string }>() @@ -270,9 +270,9 @@ const props = defineProps<{ houseId: string; listId: string }>() const houseIdNum = computed(() => Number(props.houseId)) const listIdNum = computed(() => Number(props.listId)) -const list = ref(null) +const list = ref(null) const { items, loading, load, add, update, toggle, remove, uploadImage, clearImage } = - useShoppingListItems(houseIdNum.value, listIdNum.value) + useChecklistItems(houseIdNum.value, listIdNum.value) const categories = useCategories(houseIdNum.value) function categoryFor(id: number | null) { @@ -340,7 +340,7 @@ async function handleRemove(itemId: number) { await remove(itemId) } -const editing = ref(null) +const editing = ref(null) const editName = ref('') const editQuantity = ref('') const editCategoryId = ref(null) @@ -349,7 +349,7 @@ const editRepeatFromCompletion = ref(false) const showEditRecurrenceEditor = ref(false) const savingEdit = ref(false) -function startEdit(item: ShoppingListItem) { +function startEdit(item: ChecklistItem) { editing.value = item editName.value = item.name editQuantity.value = item.quantity ?? '' @@ -378,8 +378,8 @@ async function submitEdit() { } } -const previewing = ref(null) -function openPreview(item: ShoppingListItem) { +const previewing = ref(null) +function openPreview(item: ChecklistItem) { previewing.value = item } diff --git a/src/views/ShoppingListsView.vue b/src/views/ChecklistsView.vue similarity index 91% rename from src/views/ShoppingListsView.vue rename to src/views/ChecklistsView.vue index b3abf88..f9ea63d 100644 --- a/src/views/ShoppingListsView.vue +++ b/src/views/ChecklistsView.vue @@ -22,7 +22,7 @@ :description="strings.emptyBody" >