more bug fix in support tickets
This commit is contained in:
parent
aa75b9c743
commit
6a07d3ede5
|
|
@ -60,6 +60,34 @@ class TicketRepository(BaseRepository[Ticket]):
|
|||
)\
|
||||
.filter(Ticket.user_id == user_id)
|
||||
|
||||
# اعمال فیلترها
|
||||
if query_info.filters:
|
||||
for filter_item in query_info.filters:
|
||||
if filter_item.property == "title" and hasattr(Ticket, "title"):
|
||||
if filter_item.operator == "*":
|
||||
query = query.filter(Ticket.title.ilike(f"%{filter_item.value}%"))
|
||||
elif filter_item.operator == "*?":
|
||||
query = query.filter(Ticket.title.ilike(f"{filter_item.value}%"))
|
||||
elif filter_item.operator == "?*":
|
||||
query = query.filter(Ticket.title.ilike(f"%{filter_item.value}"))
|
||||
elif filter_item.operator == "=":
|
||||
query = query.filter(Ticket.title == filter_item.value)
|
||||
elif filter_item.property == "category.name":
|
||||
query = query.join(Ticket.category).filter(Ticket.category.has(name=filter_item.value))
|
||||
elif filter_item.property == "priority.name":
|
||||
query = query.join(Ticket.priority).filter(Ticket.priority.has(name=filter_item.value))
|
||||
elif filter_item.property == "status.name":
|
||||
query = query.join(Ticket.status).filter(Ticket.status.has(name=filter_item.value))
|
||||
elif filter_item.property == "description" and hasattr(Ticket, "description"):
|
||||
if filter_item.operator == "*":
|
||||
query = query.filter(Ticket.description.ilike(f"%{filter_item.value}%"))
|
||||
elif filter_item.operator == "*?":
|
||||
query = query.filter(Ticket.description.ilike(f"{filter_item.value}%"))
|
||||
elif filter_item.operator == "?*":
|
||||
query = query.filter(Ticket.description.ilike(f"%{filter_item.value}"))
|
||||
elif filter_item.operator == "=":
|
||||
query = query.filter(Ticket.description == filter_item.value)
|
||||
|
||||
# اعمال جستجو
|
||||
if query_info.search and query_info.search_fields:
|
||||
search_conditions = []
|
||||
|
|
@ -98,6 +126,43 @@ class TicketRepository(BaseRepository[Ticket]):
|
|||
joinedload(Ticket.status)
|
||||
)
|
||||
|
||||
# اعمال فیلترها
|
||||
if query_info.filters:
|
||||
for filter_item in query_info.filters:
|
||||
if filter_item.property == "title" and hasattr(Ticket, "title"):
|
||||
if filter_item.operator == "*":
|
||||
query = query.filter(Ticket.title.ilike(f"%{filter_item.value}%"))
|
||||
elif filter_item.operator == "*?":
|
||||
query = query.filter(Ticket.title.ilike(f"{filter_item.value}%"))
|
||||
elif filter_item.operator == "?*":
|
||||
query = query.filter(Ticket.title.ilike(f"%{filter_item.value}"))
|
||||
elif filter_item.operator == "=":
|
||||
query = query.filter(Ticket.title == filter_item.value)
|
||||
elif filter_item.property == "category.name":
|
||||
query = query.join(Ticket.category).filter(Ticket.category.has(name=filter_item.value))
|
||||
elif filter_item.property == "priority.name":
|
||||
query = query.join(Ticket.priority).filter(Ticket.priority.has(name=filter_item.value))
|
||||
elif filter_item.property == "status.name":
|
||||
query = query.join(Ticket.status).filter(Ticket.status.has(name=filter_item.value))
|
||||
elif filter_item.property == "description" and hasattr(Ticket, "description"):
|
||||
if filter_item.operator == "*":
|
||||
query = query.filter(Ticket.description.ilike(f"%{filter_item.value}%"))
|
||||
elif filter_item.operator == "*?":
|
||||
query = query.filter(Ticket.description.ilike(f"{filter_item.value}%"))
|
||||
elif filter_item.operator == "?*":
|
||||
query = query.filter(Ticket.description.ilike(f"%{filter_item.value}"))
|
||||
elif filter_item.operator == "=":
|
||||
query = query.filter(Ticket.description == filter_item.value)
|
||||
elif filter_item.property == "user_email":
|
||||
query = query.join(Ticket.user).filter(Ticket.user.has(email=filter_item.value))
|
||||
elif filter_item.property == "user_name":
|
||||
query = query.join(Ticket.user).filter(
|
||||
or_(
|
||||
Ticket.user.has(first_name=filter_item.value),
|
||||
Ticket.user.has(last_name=filter_item.value)
|
||||
)
|
||||
)
|
||||
|
||||
# اعمال جستجو
|
||||
if query_info.search and query_info.search_fields:
|
||||
search_conditions = []
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class _SupportPageState extends State<SupportPage> {
|
|||
},
|
||||
defaultPageSize: 20,
|
||||
pageSizeOptions: const [10, 20, 50, 100],
|
||||
showRefreshButton: true,
|
||||
showFiltersButton: false,
|
||||
showClearFiltersButton: true,
|
||||
emptyStateMessage: t.noTickets,
|
||||
loadingMessage: t.loadingTickets,
|
||||
|
|
|
|||
|
|
@ -215,6 +215,9 @@ class DataTableConfig<T> {
|
|||
// Custom header actions
|
||||
final List<Widget>? customHeaderActions;
|
||||
|
||||
// Show individual action buttons
|
||||
final bool showFiltersButton;
|
||||
|
||||
const DataTableConfig({
|
||||
required this.endpoint,
|
||||
required this.columns,
|
||||
|
|
@ -276,6 +279,7 @@ class DataTableConfig<T> {
|
|||
this.initialColumnSettings,
|
||||
this.onColumnSettingsChanged,
|
||||
this.customHeaderActions,
|
||||
this.showFiltersButton = true,
|
||||
});
|
||||
|
||||
/// Get column width as double
|
||||
|
|
|
|||
|
|
@ -772,7 +772,7 @@ class _DataTableWidgetState<T> extends State<DataTableWidget<T>> {
|
|||
const Spacer(),
|
||||
|
||||
// Filter buttons
|
||||
if (widget.config.showFilters) ...[
|
||||
if (widget.config.showFilters && widget.config.showFiltersButton) ...[
|
||||
Tooltip(
|
||||
message: _showFilters ? t.hideFilters : t.showFilters,
|
||||
child: IconButton(
|
||||
|
|
@ -807,37 +807,74 @@ class _DataTableWidgetState<T> extends State<DataTableWidget<T>> {
|
|||
const SizedBox(width: 8),
|
||||
],
|
||||
|
||||
if (widget.config.showRefreshButton)
|
||||
IconButton(
|
||||
onPressed: _fetchData,
|
||||
icon: const Icon(Icons.refresh),
|
||||
tooltip: t.refresh,
|
||||
),
|
||||
|
||||
// Custom header actions
|
||||
if (widget.config.customHeaderActions != null) ...[
|
||||
const SizedBox(width: 8),
|
||||
...widget.config.customHeaderActions!,
|
||||
],
|
||||
|
||||
// Column settings button (moved after refresh button)
|
||||
if (widget.config.showColumnSettingsButton && widget.config.enableColumnSettings) ...[
|
||||
const SizedBox(width: 4),
|
||||
Tooltip(
|
||||
message: t.columnSettings,
|
||||
child: IconButton(
|
||||
onPressed: _isLoadingColumnSettings ? null : _openColumnSettingsDialog,
|
||||
icon: _isLoadingColumnSettings
|
||||
// Actions menu
|
||||
PopupMenuButton<String>(
|
||||
icon: const Icon(Icons.more_vert),
|
||||
tooltip: 'عملیات',
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'refresh':
|
||||
_fetchData();
|
||||
break;
|
||||
case 'filters':
|
||||
setState(() {
|
||||
_showFilters = !_showFilters;
|
||||
});
|
||||
break;
|
||||
case 'columnSettings':
|
||||
_openColumnSettingsDialog();
|
||||
break;
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
if (widget.config.showRefreshButton)
|
||||
PopupMenuItem(
|
||||
value: 'refresh',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.refresh, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
Text(t.refresh),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (widget.config.showFilters && widget.config.showFiltersButton)
|
||||
PopupMenuItem(
|
||||
value: 'filters',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(_showFilters ? Icons.filter_list_off : Icons.filter_list, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
Text(_showFilters ? t.hideFilters : t.showFilters),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (widget.config.showColumnSettingsButton && widget.config.enableColumnSettings)
|
||||
PopupMenuItem(
|
||||
value: 'columnSettings',
|
||||
enabled: !_isLoadingColumnSettings,
|
||||
child: Row(
|
||||
children: [
|
||||
_isLoadingColumnSettings
|
||||
? const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.view_column),
|
||||
tooltip: t.columnSettings,
|
||||
: const Icon(Icons.view_column, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
Text(t.columnSettings),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue