Skip to content

Commit 2853886

Browse files
committed
fix(content_management): improve headline pagination and UI
- Remove loading indicator row from _HeadlinesDataSource - Add LinearProgressIndicator for loading state - Adjust row count logic in _HeadlinesDataSource - Update tooltip text for archive button (TODO: to be fixed in l10n phase) - Refactor PaginatedDataTable2 widget for better layout
1 parent 08af2ed commit 2853886

File tree

1 file changed

+65
-70
lines changed

1 file changed

+65
-70
lines changed

lib/content_management/view/headlines_page.dart

Lines changed: 65 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class _HeadlinesPageState extends State<HeadlinesPage> {
2727
void initState() {
2828
super.initState();
2929
context.read<ContentManagementBloc>().add(
30-
const LoadHeadlinesRequested(limit: kDefaultRowsPerPage),
31-
);
30+
const LoadHeadlinesRequested(limit: kDefaultRowsPerPage),
31+
);
3232
}
3333

3434
@override
@@ -51,58 +51,75 @@ class _HeadlinesPageState extends State<HeadlinesPage> {
5151
return FailureStateWidget(
5252
exception: state.exception!,
5353
onRetry: () => context.read<ContentManagementBloc>().add(
54-
const LoadHeadlinesRequested(limit: kDefaultRowsPerPage),
55-
),
54+
const LoadHeadlinesRequested(limit: kDefaultRowsPerPage),
55+
),
5656
);
5757
}
5858

5959
if (state.headlines.isEmpty) {
6060
return Center(child: Text(l10n.noHeadlinesFound));
6161
}
6262

63-
return PaginatedDataTable2(
64-
columns: [
65-
DataColumn2(label: Text(l10n.headlineTitle), size: ColumnSize.L),
66-
DataColumn2(label: Text(l10n.sourceName), size: ColumnSize.M),
67-
DataColumn2(label: Text(l10n.status), size: ColumnSize.S),
68-
DataColumn2(label: Text(l10n.lastUpdated), size: ColumnSize.M),
69-
DataColumn2(
70-
label: Text(l10n.actions),
71-
size: ColumnSize.S,
72-
fixedWidth: 120,
63+
return Column(
64+
children: [
65+
if (state.headlinesStatus == ContentManagementStatus.loading &&
66+
state.headlines.isNotEmpty)
67+
const LinearProgressIndicator(),
68+
Expanded(
69+
child: PaginatedDataTable2(
70+
columns: [
71+
DataColumn2(
72+
label: Text(l10n.headlineTitle),
73+
size: ColumnSize.L,
74+
),
75+
DataColumn2(
76+
label: Text(l10n.sourceName),
77+
size: ColumnSize.M,
78+
),
79+
DataColumn2(label: Text(l10n.status), size: ColumnSize.S),
80+
DataColumn2(
81+
label: Text(l10n.lastUpdated),
82+
size: ColumnSize.M,
83+
),
84+
DataColumn2(
85+
label: Text(l10n.actions),
86+
size: ColumnSize.S,
87+
fixedWidth: 120,
88+
),
89+
],
90+
source: _HeadlinesDataSource(
91+
context: context,
92+
headlines: state.headlines,
93+
hasMore: state.headlinesHasMore,
94+
l10n: l10n,
95+
),
96+
rowsPerPage: kDefaultRowsPerPage,
97+
availableRowsPerPage: const [kDefaultRowsPerPage],
98+
onPageChanged: (pageIndex) {
99+
final newOffset = pageIndex * kDefaultRowsPerPage;
100+
if (newOffset >= state.headlines.length &&
101+
state.headlinesHasMore &&
102+
state.headlinesStatus !=
103+
ContentManagementStatus.loading) {
104+
context.read<ContentManagementBloc>().add(
105+
LoadHeadlinesRequested(
106+
startAfterId: state.headlinesCursor,
107+
limit: kDefaultRowsPerPage,
108+
),
109+
);
110+
}
111+
},
112+
empty: Center(child: Text(l10n.noHeadlinesFound)),
113+
showCheckboxColumn: false,
114+
showFirstLastButtons: true,
115+
fit: FlexFit.tight,
116+
headingRowHeight: 56,
117+
dataRowHeight: 56,
118+
columnSpacing: AppSpacing.md,
119+
horizontalMargin: AppSpacing.md,
120+
),
73121
),
74122
],
75-
source: _HeadlinesDataSource(
76-
context: context,
77-
headlines: state.headlines,
78-
isLoading:
79-
state.headlinesStatus == ContentManagementStatus.loading,
80-
hasMore: state.headlinesHasMore,
81-
l10n: l10n,
82-
),
83-
rowsPerPage: kDefaultRowsPerPage,
84-
availableRowsPerPage: const [kDefaultRowsPerPage],
85-
onPageChanged: (pageIndex) {
86-
final newOffset = pageIndex * kDefaultRowsPerPage;
87-
if (newOffset >= state.headlines.length &&
88-
state.headlinesHasMore &&
89-
state.headlinesStatus != ContentManagementStatus.loading) {
90-
context.read<ContentManagementBloc>().add(
91-
LoadHeadlinesRequested(
92-
startAfterId: state.headlinesCursor,
93-
limit: kDefaultRowsPerPage,
94-
),
95-
);
96-
}
97-
},
98-
empty: Center(child: Text(l10n.noHeadlinesFound)),
99-
showCheckboxColumn: false,
100-
showFirstLastButtons: true,
101-
fit: FlexFit.tight,
102-
headingRowHeight: 56,
103-
dataRowHeight: 56,
104-
columnSpacing: AppSpacing.md,
105-
horizontalMargin: AppSpacing.md,
106123
);
107124
},
108125
),
@@ -114,30 +131,18 @@ class _HeadlinesDataSource extends DataTableSource {
114131
_HeadlinesDataSource({
115132
required this.context,
116133
required this.headlines,
117-
required this.isLoading,
118134
required this.hasMore,
119135
required this.l10n,
120136
});
121137

122138
final BuildContext context;
123139
final List<Headline> headlines;
124-
final bool isLoading;
125140
final bool hasMore;
126141
final AppLocalizations l10n;
127142

128143
@override
129144
DataRow? getRow(int index) {
130145
if (index >= headlines.length) {
131-
// This can happen if hasMore is true and the user is on the last page.
132-
// If we are loading, show a spinner. Otherwise, we've reached the end.
133-
if (isLoading) {
134-
return DataRow2(
135-
cells: List.generate(
136-
5,
137-
(_) => const DataCell(Center(child: CircularProgressIndicator())),
138-
),
139-
);
140-
}
141146
return null;
142147
}
143148
final headline = headlines[index];
@@ -181,11 +186,11 @@ class _HeadlinesDataSource extends DataTableSource {
181186
),
182187
IconButton(
183188
icon: const Icon(Icons.archive),
184-
tooltip: l10n.archive,
189+
tooltip: 'Archive', // TODO(you): Will be fixed in l10n phase.
185190
onPressed: () {
186191
context.read<ContentManagementBloc>().add(
187-
ArchiveHeadlineRequested(headline.id),
188-
);
192+
ArchiveHeadlineRequested(headline.id),
193+
);
189194
},
190195
),
191196
],
@@ -200,16 +205,6 @@ class _HeadlinesDataSource extends DataTableSource {
200205

201206
@override
202207
int get rowCount {
203-
// If we have more items to fetch, we add 1 to the current length.
204-
// This signals to PaginatedDataTable2 that there is at least one more page,
205-
// which enables the 'next page' button.
206-
if (hasMore) {
207-
// When loading, we show an extra row for the spinner.
208-
// Otherwise, we just indicate that there are more rows.
209-
return isLoading
210-
? headlines.length + 1
211-
: headlines.length + kDefaultRowsPerPage;
212-
}
213208
return headlines.length;
214209
}
215210

0 commit comments

Comments
 (0)