diff --git a/assets/l10n/en/order.yaml b/assets/l10n/en/order.yaml index 65612e98..eb743e64 100644 --- a/assets/l10n/en/order.yaml +++ b/assets/l10n/en/order.yaml @@ -143,8 +143,8 @@ checkout: name: order attribute: tab: Customer - cashier: - tab: Checkout + details: + tab: Details calculator: label: paid: Paid diff --git a/assets/l10n/en/transit.yaml b/assets/l10n/en/transit.yaml index 5feb5c9c..3bf9f293 100644 --- a/assets/l10n/en/transit.yaml +++ b/assets/l10n/en/transit.yaml @@ -116,7 +116,7 @@ GS: - name: exist: label: - - Specify & Export + - Export - Inform the user that data will be exported to the specified spreadsheet. hint: - Export to spreadsheet "{name}" @@ -136,6 +136,7 @@ GS: empty: label: Select Spreadsheet hint: Once you choose the spreadsheet to import, you can start importing data. + dropdownHint: Sheet to Import confirm: - This action will {hint} - hint: diff --git a/assets/l10n/zh/order.yaml b/assets/l10n/zh/order.yaml index 10c90297..4118320f 100644 --- a/assets/l10n/zh/order.yaml +++ b/assets/l10n/zh/order.yaml @@ -107,8 +107,8 @@ checkout: name: 訂單 attribute: tab: 顧客設定 - cashier: - tab: 收銀機 + details: + tab: 訂單細項 calculator: label: paid: 付額 diff --git a/assets/l10n/zh/transit.yaml b/assets/l10n/zh/transit.yaml index b6ab5443..cb6e6f24 100644 --- a/assets/l10n/zh/transit.yaml +++ b/assets/l10n/zh/transit.yaml @@ -103,6 +103,7 @@ GS: empty: label: 選擇試算表 hint: 選擇要匯入的試算表後,就能開始匯入資料 + dropdownHint: 匯入的表單 confirm: 此動作將會{hint} selectionHint: - _: 輸入試算表網址或試算表 ID diff --git a/lib/components/item_loader.dart b/lib/components/item_loader.dart index 06cb5401..3951332a 100644 --- a/lib/components/item_loader.dart +++ b/lib/components/item_loader.dart @@ -59,6 +59,14 @@ class ItemLoaderState extends State> { key: const Key('item_loader'), prototypeItem: widget.leading == null ? widget.prototypeItem : null, itemBuilder: (context, index) { + // leading is always the first item + if (widget.leading != null) { + if (index == 0) { + return widget.leading!; + } + index--; + } + if (index == 0) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), @@ -66,11 +74,7 @@ class ItemLoaderState extends State> { ); } - if (widget.leading != null && index == 1) { - return widget.leading!; - } - - index = widget.leading == null ? index - 1 : index - 2; + index--; // loading over the size if (items.length == index) { if (isFinish) { diff --git a/lib/components/slidable_item_list.dart b/lib/components/slidable_item_list.dart index fdeb2a78..c0bb6726 100644 --- a/lib/components/slidable_item_list.dart +++ b/lib/components/slidable_item_list.dart @@ -10,7 +10,6 @@ class SlidableItemList extends StatelessWidget { final SlidableItemDelegate delegate; final String? hintText; final Widget? leading; - final Widget? tailing; final Widget? action; const SlidableItemList({ @@ -18,31 +17,35 @@ class SlidableItemList extends StatelessWidget { required this.delegate, this.hintText, this.leading, - this.tailing, this.action, }); @override Widget build(BuildContext context) { - return SingleChildScrollView( - padding: const EdgeInsets.only(top: kTopSpacing, bottom: kFABSpacing), - child: Column(children: [ - if (leading != null) leading!, - Row(children: [ - Expanded(child: Center(child: HintText(hintText ?? S.totalCount(delegate.items.length)))), - if (action != null) + return Material( + child: SingleChildScrollView( + padding: const EdgeInsets.only(top: kTopSpacing, bottom: kFABSpacing), + child: Column(children: [ + if (leading != null) Padding( - padding: const EdgeInsets.only(right: kHorizontalSpacing), - child: action, + padding: const EdgeInsets.symmetric(horizontal: kHorizontalSpacing), + child: leading!, ), + Row(children: [ + Expanded(child: Center(child: HintText(hintText ?? S.totalCount(delegate.items.length)))), + if (action != null) + Padding( + padding: const EdgeInsets.only(right: kHorizontalSpacing), + child: action, + ), + ]), + const SizedBox(height: kInternalSpacing), + for (final widget in delegate.items.mapIndexed( + (index, item) => delegate.build(item, index), + )) + widget, ]), - const SizedBox(height: kInternalSpacing), - for (final widget in delegate.items.mapIndexed( - (index, item) => delegate.build(item, index), - )) - widget, - if (tailing != null) tailing!, - ]), + ), ); } } diff --git a/lib/components/style/footer.dart b/lib/components/style/footer.dart index e0336c72..4232b6a0 100644 --- a/lib/components/style/footer.dart +++ b/lib/components/style/footer.dart @@ -7,7 +7,7 @@ class Footer extends StatelessWidget { @override Widget build(BuildContext context) { - return Wrap(alignment: WrapAlignment.center, children: [ + return Wrap(alignment: WrapAlignment.center, crossAxisAlignment: WrapCrossAlignment.center, children: [ TextButton( onPressed: _links[0].launch, child: Text(_links[0].text), diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8ce2c655..eea00cd8 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,6 +1,6 @@ { "@@locale": "en", - "@@last_modified": "2024-09-11T08:15:55.169432Z", + "@@last_modified": "2024-09-14T13:02:19.109593Z", "@@author": "Lu Shueh Chou", "settingTab": "Settings", "settingVersion": "Version: {version}", @@ -367,7 +367,7 @@ } } }, - "transitGSSpreadsheetExportExistLabel": "Specify & Export", + "transitGSSpreadsheetExportExistLabel": "Export", "@transitGSSpreadsheetExportExistLabel": { "description": "Inform the user that data will be exported to the specified spreadsheet." }, @@ -387,6 +387,7 @@ "transitGSSpreadsheetImportExistHint": "Get all sheet names from the spreadsheet and ready to import.", "transitGSSpreadsheetImportEmptyLabel": "Select Spreadsheet", "transitGSSpreadsheetImportEmptyHint": "Once you choose the spreadsheet to import, you can start importing data.", + "transitGSSpreadsheetImportDropdownHint": "Sheet to Import", "transitGSSpreadsheetConfirm": "This action will {hint}", "@transitGSSpreadsheetConfirm": { "placeholders": { diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 9365fda3..39b0d034 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1,6 +1,6 @@ { "@@locale": "zh", - "@@last_modified": "2024-09-11T08:15:55.195501Z", + "@@last_modified": "2024-09-14T13:02:19.146195Z", "@@author": "Lu Shueh Chou", "settingTab": "設定", "settingVersion": "版本:{version}", @@ -387,6 +387,7 @@ "transitGSSpreadsheetImportExistHint": "從試算表中取得所有表單的名稱,並進行匯入", "transitGSSpreadsheetImportEmptyLabel": "選擇試算表", "transitGSSpreadsheetImportEmptyHint": "選擇要匯入的試算表後,就能開始匯入資料", + "transitGSSpreadsheetImportDropdownHint": "匯入的表單", "transitGSSpreadsheetConfirm": "此動作將會{hint}", "@transitGSSpreadsheetConfirm": { "placeholders": { diff --git a/lib/ui/analysis/analysis_view.dart b/lib/ui/analysis/analysis_view.dart index 8c0b7319..c54204a1 100644 --- a/lib/ui/analysis/analysis_view.dart +++ b/lib/ui/analysis/analysis_view.dart @@ -36,9 +36,11 @@ class _AnalysisViewState extends State with AutomaticKeepAliveClie final bp = Breakpoint.find(box: constraints); return CustomScrollView(slivers: [ child!, - SliverAppBar(primary: false, title: Text(S.analysisChartTitle), actions: const [ - _MoreButton(), - ]), + SliverAppBar( + primary: false, + automaticallyImplyLeading: false, // avoid giving drawer's menu icon + title: Text(S.analysisChartTitle), actions: const [_MoreButton()], + ), _buildChartHeader(), _buildCharts(Analysis.instance.itemList, bp), ]); @@ -87,17 +89,16 @@ class _AnalysisViewState extends State with AutomaticKeepAliveClie } Widget _buildCharts(List items, Breakpoint bp) { + final col = bp.lookup(compact: 1, medium: 2, expanded: 3, large: 4); return SliverPadding( padding: const EdgeInsets.only(bottom: kFABSpacing), sliver: SliverGrid.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: bp.lookup(expanded: 2, large: 3, compact: 1), - ), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: col), itemCount: items.length + 1, itemBuilder: (context, index) { if (index == items.length) { return Align( - alignment: Alignment.topCenter, + alignment: col == 1 ? Alignment.topCenter : Alignment.center, child: SizedBox( width: 200, height: 200, diff --git a/lib/ui/analysis/history_page.dart b/lib/ui/analysis/history_page.dart index 841bdf81..98c328e6 100644 --- a/lib/ui/analysis/history_page.dart +++ b/lib/ui/analysis/history_page.dart @@ -24,6 +24,7 @@ class _HistoryPageState extends State { @override Widget build(BuildContext context) { + final singleView = MediaQuery.sizeOf(context).width <= Breakpoint.medium.max; return TutorialWrapper( child: Scaffold( appBar: AppBar( @@ -57,7 +58,7 @@ class _HistoryPageState extends State { ), ], ), - body: MediaQuery.sizeOf(context).width <= Breakpoint.medium.max ? _buildSingleColumn() : _buildTwoColumns(), + body: singleView ? _buildSingleColumn() : _buildTwoColumns(), ), ); } diff --git a/lib/ui/analysis/widgets/goals_card_view.dart b/lib/ui/analysis/widgets/goals_card_view.dart index 197ac2eb..cdf6a4cf 100644 --- a/lib/ui/analysis/widgets/goals_card_view.dart +++ b/lib/ui/analysis/widgets/goals_card_view.dart @@ -145,7 +145,9 @@ class _GoalsCardViewState extends State { ); // Remove the first data, which is the latest data. - final todayData = result.firstOrNull?.at == range.end ? result.removeAt(0) : OrderSummary(at: range.start); + final todayData = result.firstOrNull?.at == range.end.subtract(const Duration(days: 1)) + ? result.removeAt(0) + : OrderSummary(at: range.start); if (goal == null) { final reversed = result.take(20).toList().reversed; diff --git a/lib/ui/analysis/widgets/history_calendar_view.dart b/lib/ui/analysis/widgets/history_calendar_view.dart index 7765a50a..9ee717a1 100644 --- a/lib/ui/analysis/widgets/history_calendar_view.dart +++ b/lib/ui/analysis/widgets/history_calendar_view.dart @@ -3,6 +3,7 @@ import 'dart:collection'; import 'package:flutter/material.dart'; import 'package:possystem/helpers/util.dart'; import 'package:possystem/models/repository/seller.dart'; +import 'package:possystem/services/cache.dart'; import 'package:possystem/settings/language_setting.dart'; import 'package:possystem/translator.dart'; import 'package:provider/provider.dart'; @@ -34,7 +35,7 @@ class _HistoryCalendarViewState extends State { hashCode: _hashDate, ); - CalendarFormat _calendarFormat = CalendarFormat.week; + late CalendarFormat _calendarFormat; late DateTime _selectedDay; @@ -74,7 +75,10 @@ class _HistoryCalendarViewState extends State { defaultBuilder: _defaultBuilder, ), onPageChanged: _searchPageData, - onFormatChanged: (format) => setState(() => _calendarFormat = format), + onFormatChanged: (format) async { + setState(() => _calendarFormat = format); + await Cache.instance.set('history.calendar_format', format.index); + }, onDaySelected: (DateTime selectedDay, DateTime focusedDay) => _onDaySelected(selectedDay), ), ); @@ -82,9 +86,14 @@ class _HistoryCalendarViewState extends State { @override void initState() { - super.initState(); - _focusedDay = _selectedDay = widget.notifier.value.start; + + // cache from last time, or default to month if in wide screen else week + final cached = Cache.instance.get('history.calendar_format') ?? CalendarFormat.values.length; + _calendarFormat = CalendarFormat.values.elementAtOrNull(cached) ?? + (widget.shouldFillViewport ? CalendarFormat.month : CalendarFormat.week); + + super.initState(); } @override diff --git a/lib/ui/image_gallery_page.dart b/lib/ui/image_gallery_page.dart index 882ffa1e..2bc3671c 100644 --- a/lib/ui/image_gallery_page.dart +++ b/lib/ui/image_gallery_page.dart @@ -108,33 +108,37 @@ class ImageGalleryPageState extends State { } final spacing = bp.lookup(compact: 4.0, expanded: 12.0); + // maximum width is 800 + final crossAxisCount = bp.lookup(compact: 3, medium: 4); return GridView.builder( primary: false, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: bp.lookup(compact: 3, expanded: 4), + crossAxisCount: crossAxisCount, crossAxisSpacing: spacing, mainAxisSpacing: spacing, ), - // add 1 for add button, add crossAxisCount for spacing - itemCount: images!.length + (selecting ? 0 : 1) + 3, + // add 1 for add button, and add crossAxisCount for bottom spacing + itemCount: images!.length + (selecting ? 0 : 1) + crossAxisCount, semanticChildCount: images!.length, itemBuilder: (context, index) { - if (!selecting && index == images!.length) { - return Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - key: const Key('image_gallery.add'), - onPressed: createImage, - child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(KIcons.add), - Text(S.imageGalleryActionCreate, textAlign: TextAlign.center), - ]), - ), - ); + if (!selecting) { + if (index == 0) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + key: const Key('image_gallery.add'), + onPressed: createImage, + child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + const Icon(KIcons.add), + Text(S.imageGalleryActionCreate, textAlign: TextAlign.center), + ]), + ), + ); + } + index--; // remove 0-index of add button } if (index >= images!.length) { - // Floating action button offset return const SizedBox(height: kFABSpacing); } diff --git a/lib/ui/menu/menu_page.dart b/lib/ui/menu/menu_page.dart index 64124b48..8f2bd674 100644 --- a/lib/ui/menu/menu_page.dart +++ b/lib/ui/menu/menu_page.dart @@ -109,21 +109,28 @@ class _MenuPageState extends State { return const MenuProductList(catalog: null); } + final addButton = Row(children: [ + Expanded( + child: ElevatedButton.icon( + key: const Key('menu.add_catalog'), + onPressed: _handleCatalogCreate, + label: Text(S.menuCatalogTitleCreate), + icon: const Icon(KIcons.add), + ), + ), + ]); + return MenuCatalogList( Menu.instance.itemList, // put it here to handle reload - leading: singleView - ? null - : const Padding( - padding: EdgeInsets.only(left: kHorizontalSpacing), - child: _SearchAction(withTextFiled: true), - ), + leading: Column(children: [ + if (!singleView) + const Padding( + padding: EdgeInsets.only(bottom: kInternalSpacing), + child: _SearchAction(withTextFiled: true), + ), + addButton, + ]), onSelected: _handleSelected, - tailing: ElevatedButton.icon( - key: const Key('menu.add_catalog'), - onPressed: _handleCatalogCreate, - label: Text(S.menuCatalogTitleCreate), - icon: const Icon(KIcons.add), - ), ); } @@ -145,12 +152,16 @@ class _MenuPageState extends State { return MenuProductList( catalog: selected, - tailing: ElevatedButton.icon( - key: const Key('menu.add_product'), - onPressed: _handleProductCreate, - label: Text(S.menuProductTitleCreate), - icon: const Icon(KIcons.add), - ), + leading: Row(children: [ + Expanded( + child: ElevatedButton.icon( + key: const Key('menu.add_product'), + onPressed: _handleProductCreate, + label: Text(S.menuProductTitleCreate), + icon: const Icon(KIcons.add), + ), + ), + ]), ); } diff --git a/lib/ui/menu/product_page.dart b/lib/ui/menu/product_page.dart index e9bf3b17..7e8baf12 100644 --- a/lib/ui/menu/product_page.dart +++ b/lib/ui/menu/product_page.dart @@ -64,15 +64,10 @@ class _ProductPageState extends State { sliver: SliverList( delegate: SliverChildBuilderDelegate( (_, int index) { - if (index == items.length) { - return ElevatedButton.icon( - key: const Key('product.add'), - icon: const Icon(KIcons.add), - label: Text(S.menuProductTitleCreate), - onPressed: _handleCreateIng, - ); + if (index == 0) { + return _buildAddButton(); } - return ProductIngredientView(items[index]); + return ProductIngredientView(items[index - 1]); }, childCount: items.length + 1, ), @@ -109,15 +104,9 @@ class _ProductPageState extends State { child: Column(children: [ metadataTile, _buildIngredientTitle(), + if (widget.product.isNotEmpty) _buildAddButton(), if (widget.product.isNotEmpty) for (final item in widget.product.itemList) ProductIngredientView(item), - if (widget.product.isNotEmpty) - ElevatedButton.icon( - key: const Key('product.add'), - icon: const Icon(KIcons.add), - label: Text(S.menuProductTitleCreate), - onPressed: _handleCreateIng, - ), const SizedBox(height: kFABSpacing), ]), ), @@ -164,6 +153,19 @@ class _ProductPageState extends State { ]); } + Widget _buildAddButton() { + return Row(children: [ + Expanded( + child: ElevatedButton.icon( + key: const Key('product.add'), + icon: const Icon(KIcons.add), + label: Text(S.menuIngredientTitleCreate), + onPressed: _handleCreateIng, + ), + ), + ]); + } + Widget _buildActionButton() { return MoreButton( key: const Key('product.more'), diff --git a/lib/ui/menu/widgets/menu_catalog_list.dart b/lib/ui/menu/widgets/menu_catalog_list.dart index 60a003f7..8db8c92a 100644 --- a/lib/ui/menu/widgets/menu_catalog_list.dart +++ b/lib/ui/menu/widgets/menu_catalog_list.dart @@ -12,24 +12,20 @@ import 'package:possystem/translator.dart'; class MenuCatalogList extends StatelessWidget { final List catalogs; - /// Search bar in wide screen - final Widget? leading; - final Widget tailing; + final Widget leading; final void Function(Catalog) onSelected; const MenuCatalogList( this.catalogs, { super.key, required this.onSelected, - this.leading, - required this.tailing, + required this.leading, }); @override Widget build(BuildContext context) { return SlidableItemList( leading: leading, - tailing: tailing, action: RouteIconButton( label: S.menuCatalogTitleReorder, icon: const Icon(KIcons.reorder), diff --git a/lib/ui/menu/widgets/menu_product_list.dart b/lib/ui/menu/widgets/menu_product_list.dart index 3f35b3b5..3bf845a1 100644 --- a/lib/ui/menu/widgets/menu_product_list.dart +++ b/lib/ui/menu/widgets/menu_product_list.dart @@ -15,18 +15,18 @@ import 'package:possystem/translator.dart'; class MenuProductList extends StatelessWidget { final Catalog? catalog; - final Widget? tailing; + final Widget? leading; const MenuProductList({ super.key, required this.catalog, - this.tailing, + this.leading, }); @override Widget build(BuildContext context) { return SlidableItemList( - tailing: tailing, + leading: leading, action: RouteIconButton( label: S.menuProductTitleReorder, icon: const Icon(KIcons.reorder), diff --git a/lib/ui/order_attr/order_attribute_page.dart b/lib/ui/order_attr/order_attribute_page.dart index a3bb2bd0..a2a48685 100644 --- a/lib/ui/order_attr/order_attribute_page.dart +++ b/lib/ui/order_attr/order_attribute_page.dart @@ -46,6 +46,19 @@ class OrderAttributePage extends StatelessWidget { return ConstrainedBox( constraints: BoxConstraints(maxWidth: Breakpoint.medium.max), child: ListView(padding: const EdgeInsets.only(bottom: kFABSpacing, top: kTopSpacing), children: [ + Row(children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: kHorizontalSpacing), + child: RouteElevatedIconButton( + key: const Key('order_attributes.add'), + icon: const Icon(KIcons.add), + label: S.orderAttributeTitleCreate, + route: Routes.orderAttrCreate, + ), + ), + ), + ]), Row(children: [ Expanded( child: Center(child: HintText(S.totalCount(OrderAttributes.instance.length))), @@ -61,12 +74,6 @@ class OrderAttributePage extends StatelessWidget { ]), const SizedBox(height: kInternalSpacing), for (final attribute in OrderAttributes.instance.itemList) OrderAttributeTile(attr: attribute), - RouteElevatedIconButton( - key: const Key('order_attributes.add'), - icon: const Icon(KIcons.add), - label: S.orderAttributeTitleCreate, - route: Routes.orderAttrCreate, - ), ]), ); } diff --git a/lib/ui/order_attr/widgets/order_attribute_tile.dart b/lib/ui/order_attr/widgets/order_attribute_tile.dart index 7fa40d88..902243d9 100644 --- a/lib/ui/order_attr/widgets/order_attribute_tile.dart +++ b/lib/ui/order_attr/widgets/order_attribute_tile.dart @@ -64,6 +64,7 @@ class OrderAttributeTile extends StatelessWidget { Widget _buildActions(BuildContext context) { return Row(children: [ + const SizedBox(width: kHorizontalSpacing), Expanded( child: ElevatedButton.icon( key: Key('order_attributes.${attr.id}.add'), @@ -75,11 +76,11 @@ class OrderAttributeTile extends StatelessWidget { icon: const Icon(KIcons.add), ), ), - const SizedBox(width: kInternalSpacing), EntryMoreButton( key: Key('order_attributes.${attr.id}.more'), onPressed: _showActions, ), + const SizedBox(width: kHorizontalSpacing), ]); } diff --git a/lib/ui/stock/quantities_page.dart b/lib/ui/stock/quantities_page.dart index b3eb978c..a4cd8bb9 100644 --- a/lib/ui/stock/quantities_page.dart +++ b/lib/ui/stock/quantities_page.dart @@ -3,6 +3,7 @@ import 'package:possystem/components/style/empty_body.dart'; import 'package:possystem/components/style/pop_button.dart'; import 'package:possystem/components/style/route_buttons.dart'; import 'package:possystem/constants/icons.dart'; +import 'package:possystem/helpers/breakpoint.dart'; import 'package:possystem/models/repository/quantities.dart'; import 'package:possystem/routes.dart'; import 'package:possystem/translator.dart'; @@ -20,7 +21,9 @@ class QuantitiesPage extends StatelessWidget { builder: (context, child) => _buildBody(context), ); - return Routes.homeMode.value == HomeMode.bottomNavigationBar + final withScaffold = MediaQuery.sizeOf(context).width <= Breakpoint.medium.max; + + return withScaffold ? Scaffold( appBar: AppBar( title: Text(S.stockQuantityTitle), @@ -28,7 +31,10 @@ class QuantitiesPage extends StatelessWidget { ), body: body, ) - : body; + : ConstrainedBox( + constraints: BoxConstraints(maxWidth: Breakpoint.medium.max), + child: body, + ); } Widget _buildBody(BuildContext context) { @@ -41,12 +47,16 @@ class QuantitiesPage extends StatelessWidget { return StockQuantityList( quantities: Quantities.instance.itemList, - tailing: RouteElevatedIconButton( - key: const Key('quantity.add'), - route: Routes.quantityCreate, - label: S.stockQuantityTitleCreate, - icon: const Icon(KIcons.add), - ), + leading: Row(children: [ + Expanded( + child: RouteElevatedIconButton( + key: const Key('quantity.add'), + route: Routes.quantityCreate, + label: S.stockQuantityTitleCreate, + icon: const Icon(KIcons.add), + ), + ), + ]), ); } } diff --git a/lib/ui/stock/replenishment_page.dart b/lib/ui/stock/replenishment_page.dart index 9519efdf..f4c01b8c 100644 --- a/lib/ui/stock/replenishment_page.dart +++ b/lib/ui/stock/replenishment_page.dart @@ -35,12 +35,16 @@ class ReplenishmentPage extends StatelessWidget { return buildList( (Replenishment a, ReplenishActions b) => handleActions(context, a, b), - ElevatedButton.icon( - key: const Key('replenisher.add'), - onPressed: handleCreate, - label: Text(S.stockReplenishmentTitleCreate), - icon: const Icon(KIcons.add), - ), + Row(children: [ + Expanded( + child: ElevatedButton.icon( + key: const Key('replenisher.add'), + onPressed: handleCreate, + label: Text(S.stockReplenishmentTitleCreate), + icon: const Icon(KIcons.add), + ), + ), + ]), ); }, ), @@ -49,10 +53,10 @@ class ReplenishmentPage extends StatelessWidget { Widget buildList( void Function(Replenishment a, ReplenishActions b) actionHandler, - Widget trailing, + Widget leading, ) { return SlidableItemList( - tailing: trailing, + leading: leading, delegate: SlidableItemDelegate( handleDelete: (item) => item.remove(), deleteValue: ReplenishActions.delete, diff --git a/lib/ui/stock/stock_view.dart b/lib/ui/stock/stock_view.dart index 6af1631d..8c05eee7 100644 --- a/lib/ui/stock/stock_view.dart +++ b/lib/ui/stock/stock_view.dart @@ -48,14 +48,25 @@ class _StockViewState extends State with AutomaticKeepAliveClientMixi _buildActions(), const SizedBox(width: kHorizontalSpacing), ]), - const SizedBox(height: kInternalSpacing), - for (final item in Stock.instance.itemList) StockIngredientListTile(item: item), - RouteElevatedIconButton( - key: const Key('stock.add'), - icon: const Icon(KIcons.add), - label: S.stockIngredientTitleCreate, - route: Routes.stockIngrCreate, + Padding( + padding: const EdgeInsets.fromLTRB( + kHorizontalSpacing, + kInternalSpacing, + kHorizontalSpacing, + kInternalSpacing, + ), + child: Row(children: [ + Expanded( + child: RouteElevatedIconButton( + key: const Key('stock.add'), + icon: const Icon(KIcons.add), + label: S.stockIngredientTitleCreate, + route: Routes.stockIngrCreate, + ), + ), + ]), ), + for (final item in Stock.instance.itemList) StockIngredientListTile(item: item), ]); }, ), diff --git a/lib/ui/stock/widgets/stock_quantity_list.dart b/lib/ui/stock/widgets/stock_quantity_list.dart index f1802fc5..ca4cf0a4 100644 --- a/lib/ui/stock/widgets/stock_quantity_list.dart +++ b/lib/ui/stock/widgets/stock_quantity_list.dart @@ -12,18 +12,18 @@ import 'package:possystem/translator.dart'; class StockQuantityList extends StatelessWidget { final List quantities; - final Widget tailing; + final Widget leading; const StockQuantityList({ super.key, required this.quantities, - required this.tailing, + required this.leading, }); @override Widget build(BuildContext context) { return SlidableItemList( - tailing: tailing, + leading: leading, delegate: SlidableItemDelegate( items: quantities, deleteValue: 0, diff --git a/lib/ui/transit/google_sheet/sheet_selector.dart b/lib/ui/transit/google_sheet/sheet_selector.dart index 4db765c2..dabfe262 100644 --- a/lib/ui/transit/google_sheet/sheet_selector.dart +++ b/lib/ui/transit/google_sheet/sheet_selector.dart @@ -29,9 +29,7 @@ class SheetSelectorState extends State { value: selected, style: Theme.of(context).textTheme.bodyMedium, decoration: InputDecoration( - label: Text(S.transitGSSheetNameLabel( - S.transitModelName(widget.label), - )), + label: Text(S.transitGSSheetNameLabel(S.transitModelName(widget.label))), floatingLabelBehavior: FloatingLabelBehavior.always, ), onChanged: (newSelected) => setState(() => selected = newSelected), @@ -39,7 +37,7 @@ class SheetSelectorState extends State { DropdownMenuItem( value: null, child: Text( - S.stockReplenishmentNameHint, + S.transitGSSpreadsheetImportDropdownHint, style: TextStyle(color: Theme.of(context).hintColor), ), ), diff --git a/test/ui/analysis/analysis_view_test.dart b/test/ui/analysis/analysis_view_test.dart index 0f7efb37..7e1ba3db 100644 --- a/test/ui/analysis/analysis_view_test.dart +++ b/test/ui/analysis/analysis_view_test.dart @@ -8,8 +8,10 @@ import 'package:possystem/models/analysis/analysis.dart'; import 'package:possystem/models/analysis/chart.dart'; import 'package:possystem/models/repository/seller.dart'; import 'package:possystem/routes.dart'; +import 'package:possystem/translator.dart'; import 'package:possystem/ui/analysis/analysis_view.dart'; import 'package:provider/provider.dart'; +import 'package:table_calendar/table_calendar.dart' show CalendarFormat; import 'package:visibility_detector/visibility_detector.dart'; import '../../mocks/mock_cache.dart'; @@ -86,8 +88,11 @@ void main() { await tester.pumpWidget(buildApp()); await tester.pumpAndSettle(); + when(cache.get('history.calendar_format')).thenReturn(CalendarFormat.twoWeeks.index); await tester.tap(find.byKey(const Key('anal.history'))); await tester.pumpAndSettle(); + + expect(find.text(S.singleWeek), findsOneWidget); }); testWidgets('interact with chart', (tester) async { diff --git a/test/ui/analysis/history_page_test.dart b/test/ui/analysis/history_page_test.dart index 4b508351..50d85c96 100644 --- a/test/ui/analysis/history_page_test.dart +++ b/test/ui/analysis/history_page_test.dart @@ -7,6 +7,7 @@ import 'package:possystem/routes.dart'; import 'package:possystem/translator.dart'; import 'package:possystem/ui/analysis/history_page.dart'; import 'package:provider/provider.dart'; +import 'package:table_calendar/table_calendar.dart' show CalendarFormat; import '../../mocks/mock_cache.dart'; import '../../mocks/mock_database.dart'; @@ -119,10 +120,6 @@ void main() { await tester.pumpWidget(buildApp(themeMode: ThemeMode.dark)); await tester.pumpAndSettle(); - // change format - await tester.tap(find.text(S.singleMonth)); - await tester.pumpAndSettle(); - expect(find.text('50'), findsOneWidget); expect(find.text('60'), findsNothing); @@ -133,6 +130,14 @@ void main() { expect(find.text('50'), now.day < now.weekday ? findsOneWidget : findsNothing); expect(find.text('60'), findsOneWidget); + + // change format + when(cache.set(any, any)).thenAnswer((_) => Future.value(true)); + + await tester.tap(find.text(S.twoWeeks)); + await tester.pumpAndSettle(); + + verify(cache.set('history.calendar_format', CalendarFormat.twoWeeks.index)); }); testWidgets('should navigate to exporter', (tester) async { @@ -151,6 +156,10 @@ void main() { expect(find.text(S.transitMethodName('plainText')), findsOneWidget); }); + setUp(() { + reset(cache); + }); + setUpAll(() { initializeCache(); initializeDatabase(); diff --git a/test/ui/analysis/widgets/goals_card_view_test.dart b/test/ui/analysis/widgets/goals_card_view_test.dart index 97b5a1ce..8244c167 100644 --- a/test/ui/analysis/widgets/goals_card_view_test.dart +++ b/test/ui/analysis/widgets/goals_card_view_test.dart @@ -33,7 +33,7 @@ void main() { when(mockQuery(fortyDaysAgo, tomorrow)).thenAnswer((_) async => [ for (var i = 20; i >= 0; i--) { - 'day': 21 + i, + 'day': 20 + i, 'count': i, 'revenue': i * 1.1, 'profit': i * 1.2, @@ -64,7 +64,7 @@ void main() { // notify the seller to update the view when(mockQuery(today, tomorrow)).thenAnswer((_) => Future.value([ { - 'day': 1, + 'day': 0, 'count': 2, 'profit': 2.1, 'revenue': 2.2, diff --git a/test/ui/transit/google_sheet/export_basic_test.dart b/test/ui/transit/google_sheet/export_basic_test.dart index f71ba65e..bcf46aeb 100644 --- a/test/ui/transit/google_sheet/export_basic_test.dart +++ b/test/ui/transit/google_sheet/export_basic_test.dart @@ -130,9 +130,9 @@ void main() { bool selected = true, }) async { await tester.pumpAndSettle(); - await tester.tap(find.text( - selected ? S.transitGSSpreadsheetExportExistLabel : S.transitGSSpreadsheetExportEmptyLabel, - )); + await tester.tap( + find.text(selected ? S.transitGSSpreadsheetExportExistLabel : S.transitGSSpreadsheetExportEmptyLabel).first, + ); await tester.pumpAndSettle(); await tester.tap(find.byKey(const Key('confirm_dialog.confirm'))); await tester.pumpAndSettle();