Skip to content

Commit 88b8d00

Browse files
authored
feat: change shopping list category order (#1932)
2 parents 3b91bb6 + 43189e0 commit 88b8d00

File tree

20 files changed

+250
-98
lines changed

20 files changed

+250
-98
lines changed

package-lock.json

Lines changed: 35 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
},
99
"private": true,
1010
"dependencies": {
11-
"@ai-sdk/anthropic": "^3.0.0-beta.54",
12-
"@ai-sdk/openai": "^3.0.0-beta.63",
11+
"@ai-sdk/anthropic": "^3.0.0-beta.71",
12+
"@ai-sdk/openai": "^3.0.0-beta.81",
1313
"@angular/common": "20.3.10",
1414
"@angular/core": "20.3.10",
1515
"@angular/forms": "20.3.10",
@@ -44,7 +44,7 @@
4444
"@types/jsdom": "^21.1.7",
4545
"accept-language": "^3.0.20",
4646
"ahocorasick": "^1.0.2",
47-
"ai": "^6.0.0-beta.99",
47+
"ai": "^6.0.0-beta.130",
4848
"axios": "^1.8.4",
4949
"body-parser": "~2.2.1",
5050
"commander": "14.0.1",

packages/express/src/routes/print/printShoppingList.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ export const printShoppingListHandler = defineHandler(
134134
itemSummariesTranslated,
135135
req.query.sortBy || ShoppingListSortOptions.TitleDesc,
136136
categoryTitlesToi18n.uncategorized,
137+
shoppingList.categoryOrder,
137138
);
138139

139140
res.render("shoppinglist-default", {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<ion-header>
2+
<ion-toolbar>
3+
<ion-title
4+
>{{ 'pages.shoppingListCategoryOrderModal.title' | translate }}</ion-title
5+
>
6+
7+
<ion-buttons slot="end">
8+
<ion-button (click)="close()">
9+
<ion-icon name="close" slot="icon-only"></ion-icon>
10+
</ion-button>
11+
</ion-buttons>
12+
</ion-toolbar>
13+
</ion-header>
14+
15+
<ion-content class="ion-padding">
16+
<ion-item class="ion-no-padding">
17+
<ion-label class="ion-text-wrap">
18+
{{ 'pages.shoppingListCategoryOrderModal.description' | translate }}
19+
20+
<p>
21+
{{ 'pages.shoppingListCategoryOrderModal.instructions' | translate }}
22+
</p>
23+
</ion-label>
24+
</ion-item>
25+
26+
<ion-textarea
27+
label="{{ 'pages.shoppingListCategoryOrderModal.label' | translate }}"
28+
labelPlacement="stacked"
29+
placeholder="{{ 'pages.shoppingListCategoryOrderModal.placeholder' | translate }}"
30+
[(ngModel)]="categoryOrder"
31+
rows="8"
32+
auto-grow="true"
33+
></ion-textarea>
34+
</ion-content>
35+
36+
<ion-footer class="ion-padding">
37+
<ion-button expand="block" (click)="save()">
38+
<ion-icon name="save" slot="start"></ion-icon>
39+
<ion-label> {{ 'generic.save' | translate }} </ion-label>
40+
</ion-button>
41+
</ion-footer>

packages/frontend/src/app/pages/shopping-list-components/shopping-list-category-order-modal/shopping-list-category-order-modal.page.scss

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Component, inject, Input } from "@angular/core";
2+
import { ModalController } from "@ionic/angular";
3+
4+
import { SHARED_UI_IMPORTS } from "../../../providers/shared-ui.provider";
5+
import { TRPCService } from "../../../services/trpc.service";
6+
7+
@Component({
8+
selector: "page-shopping-list-category-order-modal",
9+
templateUrl: "shopping-list-category-order-modal.page.html",
10+
styleUrls: ["shopping-list-category-order-modal.page.scss"],
11+
imports: [...SHARED_UI_IMPORTS],
12+
})
13+
export class ShoppingListCategoryOrderModalPage {
14+
private modalCtrl = inject(ModalController);
15+
private trpcService = inject(TRPCService);
16+
17+
@Input({
18+
required: true,
19+
})
20+
shoppingListId!: string;
21+
22+
@Input({
23+
required: true,
24+
})
25+
categoryOrder: string | undefined;
26+
27+
async save() {
28+
await this.trpcService.handle(
29+
this.trpcService.trpc.shoppingLists.updateShoppingList.mutate({
30+
id: this.shoppingListId,
31+
categoryOrder: this.categoryOrder,
32+
}),
33+
);
34+
this.close();
35+
}
36+
37+
close() {
38+
this.modalCtrl.dismiss();
39+
}
40+
}

packages/frontend/src/app/pages/shopping-list-components/shopping-list-ignore-modal/shopping-list-ignore-modal.page.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@
1616
<ion-item class="ion-no-padding">
1717
<ion-label class="ion-text-wrap">
1818
{{ 'pages.shoppingListIgnoreModal.description' | translate }}
19-
</ion-label>
20-
</ion-item>
21-
<ion-item class="ion-no-padding">
22-
<ion-label class="ion-text-wrap">
23-
{{ 'pages.shoppingListIgnoreModal.instructions' | translate }}
19+
<p>{{ 'pages.shoppingListIgnoreModal.instructions' | translate }}</p>
2420
</ion-label>
2521
</ion-item>
2622

packages/frontend/src/app/pages/shopping-list-components/shopping-list-popover/shopping-list-popover.page.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@
108108
{{ 'pages.shoppingListPopover.update' | translate }}
109109
</ion-button>
110110

111+
<ion-button
112+
(click)="showCategoryOrderModal()"
113+
expand="block"
114+
size="small"
115+
class="ion-margin"
116+
>
117+
<ion-icon name="reorder-three" slot="start"></ion-icon>
118+
{{ 'pages.shoppingListPopover.categoryOrder' | translate }}
119+
</ion-button>
120+
111121
<ion-list-header>
112122
{{ 'pages.shoppingListPopover.dangerZone.title' | translate }}
113123
</ion-list-header>

packages/frontend/src/app/pages/shopping-list-components/shopping-list-popover/shopping-list-popover.page.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
ShoppingListSummary,
2323
} from "@recipesage/prisma";
2424
import { TRPCService } from "../../../services/trpc.service";
25+
import { ShoppingListCategoryOrderModalPage } from "../shopping-list-category-order-modal/shopping-list-category-order-modal.page";
2526

2627
@Component({
2728
selector: "page-shopping-list-popover",
@@ -192,4 +193,18 @@ export class ShoppingListPopoverPage {
192193

193194
this.dismiss();
194195
}
196+
197+
async showCategoryOrderModal() {
198+
const modal = await this.modalCtrl.create({
199+
component: ShoppingListCategoryOrderModalPage,
200+
componentProps: {
201+
shoppingListId: this.shoppingListId,
202+
categoryOrder: this.shoppingList.categoryOrder,
203+
},
204+
});
205+
await modal.present();
206+
await modal.onDidDismiss();
207+
208+
this.dismiss();
209+
}
195210
}

packages/frontend/src/app/pages/shopping-list-components/shopping-list/shopping-list.page.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,10 @@ export class ShoppingListPage {
145145
this.me = me;
146146
}
147147

148-
async processList(_items: ShoppingListItemSummary[]) {
148+
async processList(
149+
_items: ShoppingListItemSummary[],
150+
categoryOrder: string | null,
151+
) {
149152
const items = _items
150153
.filter((item) => !item.completed)
151154
.map((el) => {
@@ -190,6 +193,7 @@ export class ShoppingListPage {
190193
items,
191194
this.preferences[ShoppingListPreferenceKey.SortBy],
192195
this.parseCategoryTitle("::uncategorized"),
196+
categoryOrder,
193197
);
194198

195199
this.items = sortedItems;
@@ -203,6 +207,7 @@ export class ShoppingListPage {
203207
completedItems,
204208
this.preferences[ShoppingListPreferenceKey.SortBy],
205209
this.parseCategoryTitle("::uncategorized"),
210+
categoryOrder,
206211
);
207212

208213
this.completedItems = sortedCompletedItems;
@@ -232,7 +237,7 @@ export class ShoppingListPage {
232237
.toPromise();
233238
this.titleService.setTitle(title);
234239

235-
this.processList(shoppingListItems);
240+
this.processList(shoppingListItems, shoppingList.categoryOrder);
236241
}
237242

238243
async completeItems(items: ShoppingListItemSummary[], completed: boolean) {

0 commit comments

Comments
 (0)