progress in base menu
This commit is contained in:
parent
a8ae3a0efb
commit
dd1672852a
|
|
@ -522,6 +522,7 @@
|
||||||
"storageSpace": "Storage Space",
|
"storageSpace": "Storage Space",
|
||||||
"taxpayers": "Taxpayers",
|
"taxpayers": "Taxpayers",
|
||||||
"others": "Others",
|
"others": "Others",
|
||||||
|
"pluginMarketplace": "Plugin Marketplace",
|
||||||
"practicalTools": "Practical Tools",
|
"practicalTools": "Practical Tools",
|
||||||
"usersAndPermissions": "Users and Permissions",
|
"usersAndPermissions": "Users and Permissions",
|
||||||
"businessUsers": "Business Users",
|
"businessUsers": "Business Users",
|
||||||
|
|
|
||||||
|
|
@ -521,6 +521,7 @@
|
||||||
"storageSpace": "فضای ذخیرهسازی",
|
"storageSpace": "فضای ذخیرهسازی",
|
||||||
"taxpayers": "مودیان مالیاتی",
|
"taxpayers": "مودیان مالیاتی",
|
||||||
"others": "سایر",
|
"others": "سایر",
|
||||||
|
"pluginMarketplace": "بازار افزونهها",
|
||||||
"practicalTools": "ابزارهای کاربردی",
|
"practicalTools": "ابزارهای کاربردی",
|
||||||
"usersAndPermissions": "کاربران و دسترسیها",
|
"usersAndPermissions": "کاربران و دسترسیها",
|
||||||
"businessUsers": "کاربران کسب و کار",
|
"businessUsers": "کاربران کسب و کار",
|
||||||
|
|
|
||||||
|
|
@ -2930,6 +2930,12 @@ abstract class AppLocalizations {
|
||||||
/// **'Others'**
|
/// **'Others'**
|
||||||
String get others;
|
String get others;
|
||||||
|
|
||||||
|
/// No description provided for @pluginMarketplace.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Plugin Marketplace'**
|
||||||
|
String get pluginMarketplace;
|
||||||
|
|
||||||
/// No description provided for @practicalTools.
|
/// No description provided for @practicalTools.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|
|
||||||
|
|
@ -1465,6 +1465,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get others => 'Others';
|
String get others => 'Others';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pluginMarketplace => 'Plugin Marketplace';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get practicalTools => 'Practical Tools';
|
String get practicalTools => 'Practical Tools';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1455,6 +1455,9 @@ class AppLocalizationsFa extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get others => 'سایر';
|
String get others => 'سایر';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pluginMarketplace => 'بازار افزونهها';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get practicalTools => 'ابزارهای کاربردی';
|
String get practicalTools => 'ابزارهای کاربردی';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -388,6 +388,14 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
_MenuItem(
|
||||||
|
label: t.pluginMarketplace,
|
||||||
|
icon: Icons.store,
|
||||||
|
selectedIcon: Icons.store,
|
||||||
|
path: '/business/${widget.businessId}/plugin-marketplace',
|
||||||
|
type: _MenuItemType.simple,
|
||||||
|
hasAddButton: false,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
int selectedIndex = 0;
|
int selectedIndex = 0;
|
||||||
|
|
@ -493,23 +501,6 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMenuIndexFromTotalIndex(int totalIndex) {
|
|
||||||
int currentIndex = 0;
|
|
||||||
for (int i = 0; i < menuItems.length; i++) {
|
|
||||||
if (currentIndex == totalIndex) return i;
|
|
||||||
currentIndex++;
|
|
||||||
|
|
||||||
final item = menuItems[i];
|
|
||||||
if (item.type == _MenuItemType.expandable && isExpanded(item) && railExtended) {
|
|
||||||
final childrenCount = item.children?.length ?? 0;
|
|
||||||
if (totalIndex >= currentIndex && totalIndex < currentIndex + childrenCount) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
currentIndex += childrenCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Brand top bar with contrast color
|
// Brand top bar with contrast color
|
||||||
final Color appBarBg = Theme.of(context).brightness == Brightness.dark
|
final Color appBarBg = Theme.of(context).brightness == Brightness.dark
|
||||||
|
|
@ -581,7 +572,33 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
itemCount: getTotalMenuItemsCount(),
|
itemCount: getTotalMenuItemsCount(),
|
||||||
itemBuilder: (ctx, index) {
|
itemBuilder: (ctx, index) {
|
||||||
final menuIndex = getMenuIndexFromTotalIndex(index);
|
// محاسبه ایندکس منو و تشخیص نوع آیتم
|
||||||
|
int menuIndex = 0;
|
||||||
|
int childIndex = -1;
|
||||||
|
bool isChildItem = false;
|
||||||
|
|
||||||
|
int currentIndex = 0;
|
||||||
|
for (int i = 0; i < menuItems.length; i++) {
|
||||||
|
final item = menuItems[i];
|
||||||
|
|
||||||
|
if (currentIndex == index) {
|
||||||
|
menuIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentIndex++;
|
||||||
|
|
||||||
|
if (item.type == _MenuItemType.expandable && isExpanded(item) && railExtended) {
|
||||||
|
final childrenCount = item.children?.length ?? 0;
|
||||||
|
if (index >= currentIndex && index < currentIndex + childrenCount) {
|
||||||
|
menuIndex = i;
|
||||||
|
childIndex = index - currentIndex;
|
||||||
|
isChildItem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentIndex += childrenCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final item = menuItems[menuIndex];
|
final item = menuItems[menuIndex];
|
||||||
final bool isHovered = index == _hoverIndex;
|
final bool isHovered = index == _hoverIndex;
|
||||||
final bool isSelected = menuIndex == selectedIndex;
|
final bool isSelected = menuIndex == selectedIndex;
|
||||||
|
|
@ -593,155 +610,105 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
? (isHovered && !isSelected ? activeBg.withValues(alpha: 0.85) : activeBg)
|
? (isHovered && !isSelected ? activeBg.withValues(alpha: 0.85) : activeBg)
|
||||||
: Colors.transparent;
|
: Colors.transparent;
|
||||||
|
|
||||||
// اگر آیتم بازشونده است و در حالت باز است، زیرآیتمها را نمایش بده
|
if (isChildItem && item.children != null && childIndex >= 0 && childIndex < item.children!.length) {
|
||||||
if (item.type == _MenuItemType.expandable && isExpanded(item) && railExtended) {
|
// زیرآیتم
|
||||||
if (index == getMenuIndexFromTotalIndex(index)) {
|
final child = item.children![childIndex];
|
||||||
// آیتم اصلی
|
return MouseRegion(
|
||||||
return MouseRegion(
|
onEnter: (_) => setState(() => _hoverIndex = index),
|
||||||
onEnter: (_) => setState(() => _hoverIndex = index),
|
onExit: (_) => setState(() => _hoverIndex = -1),
|
||||||
onExit: (_) => setState(() => _hoverIndex = -1),
|
child: InkWell(
|
||||||
child: InkWell(
|
borderRadius: br,
|
||||||
borderRadius: br,
|
onTap: () => onSelectChild(menuIndex, childIndex),
|
||||||
onTap: () {
|
child: Container(
|
||||||
setState(() {
|
margin: EdgeInsets.zero,
|
||||||
if (item.label == t.people) _isPeopleExpanded = !_isPeopleExpanded;
|
padding: EdgeInsets.symmetric(
|
||||||
if (item.label == t.productsAndServices) _isProductsAndServicesExpanded = !_isProductsAndServicesExpanded;
|
horizontal: railExtended ? 24 : 16, // بیشتر indent برای زیرآیتم
|
||||||
if (item.label == t.banking) _isBankingExpanded = !_isBankingExpanded;
|
vertical: 8,
|
||||||
if (item.label == t.accountingMenu) _isAccountingMenuExpanded = !_isAccountingMenuExpanded;
|
),
|
||||||
if (item.label == t.warehouseManagement) _isWarehouseManagementExpanded = !_isWarehouseManagementExpanded;
|
decoration: BoxDecoration(
|
||||||
if (item.label == t.settings) _isBasicToolsExpanded = !_isBasicToolsExpanded;
|
color: bgColor,
|
||||||
});
|
borderRadius: br,
|
||||||
},
|
),
|
||||||
child: Container(
|
child: Row(
|
||||||
margin: EdgeInsets.zero,
|
children: [
|
||||||
padding: EdgeInsets.symmetric(
|
Icon(
|
||||||
horizontal: railExtended ? 16 : 8,
|
child.icon,
|
||||||
vertical: 8,
|
color: sideFg,
|
||||||
),
|
size: 20,
|
||||||
decoration: BoxDecoration(
|
),
|
||||||
color: bgColor,
|
if (railExtended) ...[
|
||||||
borderRadius: br,
|
const SizedBox(width: 12),
|
||||||
),
|
Expanded(
|
||||||
child: Row(
|
child: Text(
|
||||||
children: [
|
child.label,
|
||||||
Icon(
|
style: TextStyle(
|
||||||
active ? item.selectedIcon : item.icon,
|
color: sideFg,
|
||||||
color: active ? activeFg : sideFg,
|
fontWeight: FontWeight.w400,
|
||||||
size: 24,
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
if (railExtended) ...[
|
if (child.hasAddButton)
|
||||||
const SizedBox(width: 12),
|
GestureDetector(
|
||||||
Expanded(
|
onTap: () {
|
||||||
child: Text(
|
// Navigate to add new item
|
||||||
item.label,
|
if (child.label == t.receipts) {
|
||||||
style: TextStyle(
|
// Navigate to add receipt
|
||||||
color: active ? activeFg : sideFg,
|
} else if (child.label == t.payments) {
|
||||||
fontWeight: active ? FontWeight.w600 : FontWeight.w400,
|
// Navigate to add payment
|
||||||
|
} else if (child.label == t.products) {
|
||||||
|
// Navigate to add product
|
||||||
|
} else if (child.label == t.priceLists) {
|
||||||
|
// Navigate to add price list
|
||||||
|
} else if (child.label == t.categories) {
|
||||||
|
// Navigate to add category
|
||||||
|
} else if (child.label == t.productAttributes) {
|
||||||
|
// Navigate to add product attribute
|
||||||
|
} else if (child.label == t.accounts) {
|
||||||
|
// Navigate to add account
|
||||||
|
} else if (child.label == t.pettyCash) {
|
||||||
|
// Navigate to add petty cash
|
||||||
|
} else if (child.label == t.cashBox) {
|
||||||
|
// Navigate to add cash box
|
||||||
|
} else if (child.label == t.wallet) {
|
||||||
|
// Navigate to add wallet
|
||||||
|
} else if (child.label == t.checks) {
|
||||||
|
// Navigate to add check
|
||||||
|
} else if (child.label == t.transfers) {
|
||||||
|
// Navigate to add transfer
|
||||||
|
} else if (child.label == t.invoice) {
|
||||||
|
// Navigate to add invoice
|
||||||
|
} else if (child.label == t.expenseAndIncome) {
|
||||||
|
// Navigate to add expense/income
|
||||||
|
} else if (child.label == t.documents) {
|
||||||
|
// Navigate to add document
|
||||||
|
} else if (child.label == t.warehouses) {
|
||||||
|
// Navigate to add warehouse
|
||||||
|
} else if (child.label == t.shipments) {
|
||||||
|
// Navigate to add shipment
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: sideFg.withValues(alpha: 0.1),
|
||||||
|
borderRadius: BorderRadius.circular(3),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 14,
|
||||||
|
color: sideFg,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Icon(
|
|
||||||
isExpanded(item) ? Icons.expand_less : Icons.expand_more,
|
|
||||||
color: sideFg,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
} else {
|
);
|
||||||
// زیرآیتمها
|
|
||||||
final childIndex = index - getMenuIndexFromTotalIndex(index) - 1;
|
|
||||||
if (childIndex < (item.children?.length ?? 0)) {
|
|
||||||
final child = item.children![childIndex];
|
|
||||||
return MouseRegion(
|
|
||||||
onEnter: (_) => setState(() => _hoverIndex = index),
|
|
||||||
onExit: (_) => setState(() => _hoverIndex = -1),
|
|
||||||
child: InkWell(
|
|
||||||
borderRadius: br,
|
|
||||||
onTap: () => onSelectChild(menuIndex, childIndex),
|
|
||||||
child: Container(
|
|
||||||
margin: EdgeInsets.zero,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: railExtended ? 24 : 16, // بیشتر indent برای زیرآیتم
|
|
||||||
vertical: 8,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: bgColor,
|
|
||||||
borderRadius: br,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
child.icon,
|
|
||||||
color: sideFg,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
if (railExtended) ...[
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
child.label,
|
|
||||||
style: TextStyle(
|
|
||||||
color: sideFg,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (child.hasAddButton)
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.add, size: 16),
|
|
||||||
onPressed: () {
|
|
||||||
// Navigate to add new item
|
|
||||||
if (child.label == t.receipts) {
|
|
||||||
// Navigate to add receipt
|
|
||||||
} else if (child.label == t.payments) {
|
|
||||||
// Navigate to add payment
|
|
||||||
} else if (child.label == t.products) {
|
|
||||||
// Navigate to add product
|
|
||||||
} else if (child.label == t.priceLists) {
|
|
||||||
// Navigate to add price list
|
|
||||||
} else if (child.label == t.categories) {
|
|
||||||
// Navigate to add category
|
|
||||||
} else if (child.label == t.productAttributes) {
|
|
||||||
// Navigate to add product attribute
|
|
||||||
} else if (child.label == t.accounts) {
|
|
||||||
// Navigate to add account
|
|
||||||
} else if (child.label == t.pettyCash) {
|
|
||||||
// Navigate to add petty cash
|
|
||||||
} else if (child.label == t.cashBox) {
|
|
||||||
// Navigate to add cash box
|
|
||||||
} else if (child.label == t.wallet) {
|
|
||||||
// Navigate to add wallet
|
|
||||||
} else if (child.label == t.checks) {
|
|
||||||
// Navigate to add check
|
|
||||||
} else if (child.label == t.transfers) {
|
|
||||||
// Navigate to add transfer
|
|
||||||
} else if (child.label == t.invoice) {
|
|
||||||
// Navigate to add invoice
|
|
||||||
} else if (child.label == t.expenseAndIncome) {
|
|
||||||
// Navigate to add expense/income
|
|
||||||
} else if (child.label == t.documents) {
|
|
||||||
// Navigate to add document
|
|
||||||
} else if (child.label == t.warehouses) {
|
|
||||||
// Navigate to add warehouse
|
|
||||||
} else if (child.label == t.shipments) {
|
|
||||||
// Navigate to add shipment
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// آیتم ساده، آیتم بازشونده در حالت بسته، یا آیتم جداکننده
|
// آیتم اصلی (ساده، بازشونده، یا جداکننده)
|
||||||
if (item.type == _MenuItemType.separator) {
|
if (item.type == _MenuItemType.separator) {
|
||||||
// آیتم جداکننده
|
// آیتم جداکننده
|
||||||
return Container(
|
return Container(
|
||||||
|
|
@ -786,7 +753,7 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// آیتم ساده یا آیتم بازشونده در حالت بسته
|
// آیتم ساده یا آیتم بازشونده
|
||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
onEnter: (_) => setState(() => _hoverIndex = index),
|
onEnter: (_) => setState(() => _hoverIndex = index),
|
||||||
onExit: (_) => setState(() => _hoverIndex = -1),
|
onExit: (_) => setState(() => _hoverIndex = -1),
|
||||||
|
|
@ -839,6 +806,40 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
isExpanded(item) ? Icons.expand_less : Icons.expand_more,
|
isExpanded(item) ? Icons.expand_less : Icons.expand_more,
|
||||||
color: sideFg,
|
color: sideFg,
|
||||||
size: 20,
|
size: 20,
|
||||||
|
)
|
||||||
|
else if (item.hasAddButton)
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// Navigate to add new item
|
||||||
|
if (item.label == t.invoice) {
|
||||||
|
// Navigate to add invoice
|
||||||
|
} else if (item.label == t.expenseAndIncome) {
|
||||||
|
// Navigate to add expense/income
|
||||||
|
} else if (item.label == t.reports) {
|
||||||
|
// Navigate to add report
|
||||||
|
} else if (item.label == t.inquiries) {
|
||||||
|
// Navigate to add inquiry
|
||||||
|
} else if (item.label == t.storageSpace) {
|
||||||
|
// Navigate to add storage space
|
||||||
|
} else if (item.label == t.taxpayers) {
|
||||||
|
// Navigate to add taxpayer
|
||||||
|
} else if (item.label == t.pluginMarketplace) {
|
||||||
|
// Navigate to add plugin
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: sideFg.withValues(alpha: 0.1),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 16,
|
||||||
|
color: sideFg,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
@ -848,7 +849,6 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return const SizedBox.shrink();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -933,9 +933,8 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
children: item.children?.map((child) => ListTile(
|
children: item.children?.map((child) => ListTile(
|
||||||
leading: const SizedBox(width: 24),
|
leading: const SizedBox(width: 24),
|
||||||
title: Text(child.label),
|
title: Text(child.label),
|
||||||
trailing: child.hasAddButton ? IconButton(
|
trailing: child.hasAddButton ? GestureDetector(
|
||||||
icon: const Icon(Icons.add, size: 20),
|
onTap: () {
|
||||||
onPressed: () {
|
|
||||||
context.pop();
|
context.pop();
|
||||||
// Navigate to add new item
|
// Navigate to add new item
|
||||||
if (child.label == t.receipts) {
|
if (child.label == t.receipts) {
|
||||||
|
|
@ -974,6 +973,19 @@ class _BusinessShellState extends State<BusinessShell> {
|
||||||
// Navigate to add shipment
|
// Navigate to add shipment
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: sideFg.withValues(alpha: 0.1),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 16,
|
||||||
|
color: sideFg,
|
||||||
|
),
|
||||||
|
),
|
||||||
) : null,
|
) : null,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pop();
|
context.pop();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue