initial commit
This commit is contained in:
@@ -17,12 +17,13 @@ class MonthlyView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MonthlyViewState extends State<MonthlyView> {
|
class _MonthlyViewState extends State<MonthlyView> {
|
||||||
// Spaltenbreiten (Header & Body identisch -> exakte Ausrichtung)
|
// Kompaktere Layout-Parameter
|
||||||
static const double _wDate = 120;
|
static const double _wDate = 96;
|
||||||
static const double _wHoliday = 160;
|
static const double _wHoliday = 120;
|
||||||
static const double _wTime = 84;
|
static const double _wTime = 60;
|
||||||
static const double _wCode = 110;
|
static const double _wCode = 70;
|
||||||
static const double _wNumber = 92;
|
static const double _wNumber = 76;
|
||||||
|
static const double _fontSize = 12;
|
||||||
|
|
||||||
// Edit/Fokus/Controller je Feld
|
// Edit/Fokus/Controller je Feld
|
||||||
final Set<String> _invalidCells = <String>{};
|
final Set<String> _invalidCells = <String>{};
|
||||||
@@ -127,24 +128,28 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
double get _tableMinWidth =>
|
double get _tableMinWidth =>
|
||||||
_wDate + _wHoliday + (10 * _wTime) + _wCode + (4 * _wNumber) + _wDate;
|
_wDate + _wHoliday + (10 * _wTime) + _wCode + (4 * _wNumber) + _wDate;
|
||||||
|
|
||||||
// Override für Ist-Minuten nach Code
|
// Ist-Override für U/SU/K/T
|
||||||
int _workedFor(WorkDay d) {
|
int _workedFor(WorkDay d) {
|
||||||
final c = d.code;
|
final c = d.code;
|
||||||
if (c == 'U' || c == 'SU' || c == 'K' || c == 'T') {
|
if (c == 'U' || c == 'SU' || c == 'K' || c == 'T') {
|
||||||
return d.targetMinutes; // Urlaub/Sonderurlaub/Krankenstand/Training -> Ist = Soll
|
return d.targetMinutes;
|
||||||
}
|
}
|
||||||
return d.workedMinutes; // normal aus Intervallen
|
return d.workedMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color? _rowColorFor(WorkDay d, {required Color? holidayBg, required Color? weekendBg}) {
|
Color? _rowColorFor(WorkDay d, {required Color? holidayBg, required Color? weekendBg}) {
|
||||||
switch (d.code) {
|
switch (d.code) {
|
||||||
case 'GZ': return const Color(0xFFBFBFFF);
|
case 'GZ':
|
||||||
case 'U': return const Color(0xFF7F7FFF);
|
return const Color(0xFFBFBFFF); // 0xBFBFFF mit vollem Alpha
|
||||||
case 'SU': return const Color(0xFF7F7FFF);
|
case 'U':
|
||||||
case 'K': return Colors.yellow;
|
return const Color(0xFF7F7FFF); // 0x7F7FFF mit vollem Alpha
|
||||||
case 'T': return Colors.red;
|
case 'SU':
|
||||||
|
return const Color(0xFF7F7FFF);
|
||||||
|
case 'K':
|
||||||
|
return Colors.yellow;
|
||||||
|
case 'T':
|
||||||
|
return Colors.red;
|
||||||
}
|
}
|
||||||
// kein Code -> ggf. Feiertag/Wochenende
|
|
||||||
final isHoliday = _holidays.containsKey(ymd(d.date));
|
final isHoliday = _holidays.containsKey(ymd(d.date));
|
||||||
final isWeekend = d.date.weekday == DateTime.saturday || d.date.weekday == DateTime.sunday;
|
final isWeekend = d.date.weekday == DateTime.saturday || d.date.weekday == DateTime.sunday;
|
||||||
if (isHoliday) return holidayBg;
|
if (isHoliday) return holidayBg;
|
||||||
@@ -155,16 +160,15 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final headerColumns = _buildColumns();
|
final headerColumns = _buildColumns();
|
||||||
final bodyColumns = _buildColumns(); // gleiche Struktur (Body blendet Header aus)
|
final bodyColumns = _buildColumns();
|
||||||
|
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final holidayBg = theme.colorScheme.secondaryContainer.withOpacity(0.45);
|
final holidayBg = theme.colorScheme.secondaryContainer.withOpacity(0.45);
|
||||||
final weekendBg = Colors.grey.withOpacity(0.30);
|
final weekendBg = Colors.grey.withOpacity(0.30);
|
||||||
|
|
||||||
// Effektive Tage (inkl. Live-Edits)
|
|
||||||
final effectiveDays = List<WorkDay>.generate(_days.length, (i) => _effectiveDay(i, _days[i]));
|
final effectiveDays = List<WorkDay>.generate(_days.length, (i) => _effectiveDay(i, _days[i]));
|
||||||
|
|
||||||
// kumulative Differenz basierend auf Override- oder Intervall-Arbeitszeit
|
// diffs & kumuliert (mit Override)
|
||||||
final diffs = <int>[];
|
final diffs = <int>[];
|
||||||
for (final d in effectiveDays) {
|
for (final d in effectiveDays) {
|
||||||
final worked = _workedFor(d);
|
final worked = _workedFor(d);
|
||||||
@@ -218,20 +222,20 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const Text('Fehler beim Laden:'),
|
Text('Fehler beim Laden:', style: TextStyle(fontSize: _fontSize)),
|
||||||
SelectableText(_error ?? ''),
|
SelectableText(_error ?? '', style: const TextStyle(fontSize: _fontSize)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => _loadMonth(_monthStart),
|
onPressed: () => _loadMonth(_monthStart),
|
||||||
child: const Text('Erneut versuchen'),
|
child: Text('Erneut versuchen', style: const TextStyle(fontSize: _fontSize)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// FIXIERTE KOPFZEILE (nur horizontal scrollend)
|
// FIXIERTE KOPFZEILE
|
||||||
Scrollbar(
|
Scrollbar(
|
||||||
controller: _hCtrl,
|
controller: _hCtrl,
|
||||||
notificationPredicate: (n) => n.metrics.axis == Axis.horizontal,
|
notificationPredicate: (n) => n.metrics.axis == Axis.horizontal,
|
||||||
@@ -242,22 +246,24 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(minWidth: _tableMinWidth),
|
constraints: BoxConstraints(minWidth: _tableMinWidth),
|
||||||
child: DataTableTheme(
|
child: DataTableTheme(
|
||||||
data: const DataTableThemeData(
|
data: DataTableThemeData(
|
||||||
headingRowHeight: 42,
|
headingRowHeight: 30,
|
||||||
columnSpacing: 20,
|
columnSpacing: 10,
|
||||||
headingTextStyle: TextStyle(fontWeight: FontWeight.w700),
|
headingTextStyle: const TextStyle(fontWeight: FontWeight.w700).copyWith(
|
||||||
|
fontSize: _fontSize,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
showCheckboxColumn: false,
|
showCheckboxColumn: false,
|
||||||
columns: headerColumns,
|
columns: headerColumns,
|
||||||
rows: const <DataRow>[], // nur Header anzeigen
|
rows: const <DataRow>[],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// BODY (horiz. & vert. Scroll, aber Header im Body ausgeblendet)
|
// BODY
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Scrollbar(
|
child: Scrollbar(
|
||||||
controller: _hCtrl,
|
controller: _hCtrl,
|
||||||
@@ -265,7 +271,7 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
thumbVisibility: true,
|
thumbVisibility: true,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
controller: _hCtrl,
|
controller: _hCtrl,
|
||||||
padding: const EdgeInsets.only(bottom: 24),
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(minWidth: _tableMinWidth),
|
constraints: BoxConstraints(minWidth: _tableMinWidth),
|
||||||
@@ -277,10 +283,10 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
controller: _vCtrl,
|
controller: _vCtrl,
|
||||||
child: DataTableTheme(
|
child: DataTableTheme(
|
||||||
data: const DataTableThemeData(
|
data: const DataTableThemeData(
|
||||||
headingRowHeight: 0, // Header hier ausblenden
|
headingRowHeight: 0,
|
||||||
dataRowMinHeight: 44,
|
dataRowMinHeight: 30,
|
||||||
dataRowMaxHeight: 54,
|
dataRowMaxHeight: 34,
|
||||||
columnSpacing: 20,
|
columnSpacing: 10,
|
||||||
),
|
),
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
showCheckboxColumn: false,
|
showCheckboxColumn: false,
|
||||||
@@ -303,19 +309,18 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
width: width,
|
width: width,
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: align,
|
alignment: align,
|
||||||
child: Text(label, textAlign: _toTextAlign(align)),
|
child: Text(
|
||||||
|
label,
|
||||||
|
textAlign: _toTextAlign(align),
|
||||||
|
style: const TextStyle(fontSize: _fontSize),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// 0 Datum (rechtsbündig)
|
|
||||||
c('Datum', align: Alignment.centerRight, width: _wDate),
|
c('Datum', align: Alignment.centerRight, width: _wDate),
|
||||||
|
|
||||||
// 1 Feiertag (links)
|
|
||||||
c('Feiertag', align: Alignment.centerLeft, width: _wHoliday),
|
c('Feiertag', align: Alignment.centerLeft, width: _wHoliday),
|
||||||
|
|
||||||
// 2..11 Zeitspalten (zentriert)
|
|
||||||
c('Start 1', align: Alignment.center, width: _wTime),
|
c('Start 1', align: Alignment.center, width: _wTime),
|
||||||
c('Ende 1', align: Alignment.center, width: _wTime),
|
c('Ende 1', align: Alignment.center, width: _wTime),
|
||||||
c('Start 2', align: Alignment.center, width: _wTime),
|
c('Start 2', align: Alignment.center, width: _wTime),
|
||||||
@@ -326,24 +331,19 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
c('Ende 4', align: Alignment.center, width: _wTime),
|
c('Ende 4', align: Alignment.center, width: _wTime),
|
||||||
c('Start 5', align: Alignment.center, width: _wTime),
|
c('Start 5', align: Alignment.center, width: _wTime),
|
||||||
c('Ende 5', align: Alignment.center, width: _wTime),
|
c('Ende 5', align: Alignment.center, width: _wTime),
|
||||||
|
|
||||||
// 12 Code (zentriert)
|
|
||||||
c('Code', align: Alignment.center, width: _wCode),
|
c('Code', align: Alignment.center, width: _wCode),
|
||||||
|
|
||||||
// 13..16 Kennzahlen (rechtsbündig)
|
|
||||||
c('Soll', align: Alignment.centerRight, width: _wNumber),
|
c('Soll', align: Alignment.centerRight, width: _wNumber),
|
||||||
c('Ist', align: Alignment.centerRight, width: _wNumber),
|
c('Ist', align: Alignment.centerRight, width: _wNumber),
|
||||||
c('Differenz', align: Alignment.centerRight, width: _wNumber),
|
c('Differenz', align: Alignment.centerRight, width: _wNumber),
|
||||||
c('Differenz gesamt', align: Alignment.centerRight, width: _wNumber),
|
c('Differenz gesamt', align: Alignment.centerRight, width: _wNumber),
|
||||||
|
|
||||||
// 17 Datum (linksbündig)
|
|
||||||
c('Datum', align: Alignment.centerLeft, width: _wDate),
|
c('Datum', align: Alignment.centerLeft, width: _wDate),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DataCell> _buildEditableCells(int dayIndex, WorkDay day, int runningDiff) {
|
List<DataCell> _buildEditableCells(int dayIndex, WorkDay day, int runningDiff) {
|
||||||
final leftLabel = leftDayLabel(day.date);
|
// Gewünscht: links Wochentag zuerst, rechts Datum zuerst.
|
||||||
final rightLabel = rightDayLabel(day.date);
|
final leftLabel = rightDayLabel(day.date); // Wochentag Datum
|
||||||
|
final rightLabel = leftDayLabel(day.date); // Datum Wochentag
|
||||||
final hName = _holidays[ymd(day.date)] ?? '';
|
final hName = _holidays[ymd(day.date)] ?? '';
|
||||||
|
|
||||||
String slotText(int slot, bool isStart) {
|
String slotText(int slot, bool isStart) {
|
||||||
@@ -362,15 +362,21 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
// 0: Datum (rechts)
|
// 0: Datum (rechts)
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wDate,
|
width: _wDate,
|
||||||
child: Align(alignment: Alignment.centerRight, child: Text(leftLabel)),
|
child: Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: Text(leftLabel, style: const TextStyle(fontSize: _fontSize)),
|
||||||
|
),
|
||||||
)));
|
)));
|
||||||
// 1: Feiertag-Name
|
// 1: Feiertag
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wHoliday,
|
width: _wHoliday,
|
||||||
child: Align(alignment: Alignment.centerLeft, child: Text(hName)),
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(hName, style: const TextStyle(fontSize: _fontSize)),
|
||||||
|
),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// 2..11: editierbare Zeiten (zentriert)
|
// 2..11: Zeiten
|
||||||
for (int slot = 0; slot < 5; slot++) {
|
for (int slot = 0; slot < 5; slot++) {
|
||||||
// Start
|
// Start
|
||||||
final keyS = 't_${dayIndex}_${slot}_s';
|
final keyS = 't_${dayIndex}_${slot}_s';
|
||||||
@@ -398,7 +404,7 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
if (valid && (text.isEmpty || text.length == 5)) {
|
if (valid && (text.isEmpty || text.length == 5)) {
|
||||||
_commitTime(dayIndex, slot, true, text);
|
_commitTime(dayIndex, slot, true, text);
|
||||||
} else {
|
} else {
|
||||||
setState(() {}); // live neu berechnen
|
setState(() {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSubmitted: (text) {
|
onSubmitted: (text) {
|
||||||
@@ -436,7 +442,7 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
if (valid && (text.isEmpty || text.length == 5)) {
|
if (valid && (text.isEmpty || text.length == 5)) {
|
||||||
_commitTime(dayIndex, slot, false, text);
|
_commitTime(dayIndex, slot, false, text);
|
||||||
} else {
|
} else {
|
||||||
setState(() {}); // live neu berechnen
|
setState(() {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSubmitted: (text) {
|
onSubmitted: (text) {
|
||||||
@@ -449,13 +455,13 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12: Code (Dropdown) — zentriert (Kurzname geschlossen, Langname in Liste)
|
// 12: Code
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wCode,
|
width: _wCode,
|
||||||
child: Align(alignment: Alignment.center, child: _codeDropdown(dayIndex, day)),
|
child: Align(alignment: Alignment.center, child: _codeDropdown(dayIndex, day)),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// 13..16: Kennzahlen (rechts) – mit Override
|
// 13..16: Kennzahlen (mit Override)
|
||||||
final worked = _workedFor(day);
|
final worked = _workedFor(day);
|
||||||
final soll = minutesToHHMM(day.targetMinutes);
|
final soll = minutesToHHMM(day.targetMinutes);
|
||||||
final ist = minutesToHHMM(worked);
|
final ist = minutesToHHMM(worked);
|
||||||
@@ -464,25 +470,28 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
|
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wNumber,
|
width: _wNumber,
|
||||||
child: Align(alignment: Alignment.centerRight, child: mono(soll)),
|
child: Align(alignment: Alignment.centerRight, child: _monoSmall(soll)),
|
||||||
)));
|
)));
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wNumber,
|
width: _wNumber,
|
||||||
child: Align(alignment: Alignment.centerRight, child: mono(ist)),
|
child: Align(alignment: Alignment.centerRight, child: _monoSmall(ist)),
|
||||||
)));
|
)));
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wNumber,
|
width: _wNumber,
|
||||||
child: Align(alignment: Alignment.centerRight, child: mono(diff)),
|
child: Align(alignment: Alignment.centerRight, child: _monoSmall(diff)),
|
||||||
)));
|
)));
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wNumber,
|
width: _wNumber,
|
||||||
child: Align(alignment: Alignment.centerRight, child: mono(diffSum)),
|
child: Align(alignment: Alignment.centerRight, child: _monoSmall(diffSum)),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// 17: Datum (links)
|
// 17: Datum (links)
|
||||||
cells.add(DataCell(SizedBox(
|
cells.add(DataCell(SizedBox(
|
||||||
width: _wDate,
|
width: _wDate,
|
||||||
child: Align(alignment: Alignment.centerLeft, child: Text(rightLabel)),
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(rightLabel, style: const TextStyle(fontSize: _fontSize)),
|
||||||
|
),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
assert(cells.length == 18, 'Row has ${cells.length} cells but expected 18.');
|
assert(cells.length == 18, 'Row has ${cells.length} cells but expected 18.');
|
||||||
@@ -490,25 +499,23 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _codeDropdown(int dayIndex, WorkDay day) {
|
Widget _codeDropdown(int dayIndex, WorkDay day) {
|
||||||
final value = day.code; // null => kein Code (—)
|
final value = day.code;
|
||||||
final values = <String?>[null, ...kAbsenceCodes];
|
final values = <String?>[null, ...kAbsenceCodes];
|
||||||
|
|
||||||
return DropdownButton<String?>(
|
return DropdownButton<String?>(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: value,
|
value: value,
|
||||||
// Langnamen in der aufgeklappten Liste:
|
|
||||||
items: values.map((v) {
|
items: values.map((v) {
|
||||||
final label = v == null ? '—' : codeLabel(v);
|
final label = v == null ? '—' : codeLabel(v);
|
||||||
return DropdownMenuItem<String?>(
|
return DropdownMenuItem<String?>(
|
||||||
value: v,
|
value: v,
|
||||||
child: Text(label, textAlign: TextAlign.center),
|
child: Text(label, textAlign: TextAlign.center, style: const TextStyle(fontSize: _fontSize)),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
// Kurznamen (zentriert) in der geschlossenen Anzeige:
|
|
||||||
selectedItemBuilder: (context) {
|
selectedItemBuilder: (context) {
|
||||||
return values.map((v) {
|
return values.map((v) {
|
||||||
final shortText = v ?? '—';
|
final shortText = v ?? '—';
|
||||||
return Center(child: Text(shortText));
|
return Center(child: Text(shortText, style: const TextStyle(fontSize: _fontSize)));
|
||||||
}).toList();
|
}).toList();
|
||||||
},
|
},
|
||||||
onChanged: (newCode) {
|
onChanged: (newCode) {
|
||||||
@@ -624,7 +631,7 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rahmenlose Eingabefelder, nur dezente Füllung bei invalid
|
// kompakte, rahmenlose Eingabefelder
|
||||||
Widget _timeField({
|
Widget _timeField({
|
||||||
required Key key,
|
required Key key,
|
||||||
required TextEditingController controller,
|
required TextEditingController controller,
|
||||||
@@ -643,12 +650,15 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
controller: controller,
|
controller: controller,
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(fontFeatures: [FontFeature.tabularFigures()]),
|
style: const TextStyle(
|
||||||
|
fontFeatures: [FontFeature.tabularFigures()],
|
||||||
|
fontSize: _fontSize,
|
||||||
|
),
|
||||||
keyboardType: TextInputType.datetime,
|
keyboardType: TextInputType.datetime,
|
||||||
inputFormatters: const [HHmmInputFormatter()],
|
inputFormatters: const [HHmmInputFormatter()],
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
isDense: true,
|
isDense: true,
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 6, vertical: 6),
|
contentPadding: EdgeInsets.symmetric(horizontal: 4, vertical: 2),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
enabledBorder: InputBorder.none,
|
enabledBorder: InputBorder.none,
|
||||||
focusedBorder: InputBorder.none,
|
focusedBorder: InputBorder.none,
|
||||||
@@ -662,6 +672,14 @@ class _MonthlyViewState extends State<MonthlyView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _monoSmall(String s) => Text(
|
||||||
|
s,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: _fontSize,
|
||||||
|
fontFeatures: [FontFeature.tabularFigures()],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
TextAlign _toTextAlign(Alignment a) {
|
TextAlign _toTextAlign(Alignment a) {
|
||||||
if (a == Alignment.centerRight) return TextAlign.right;
|
if (a == Alignment.centerRight) return TextAlign.right;
|
||||||
if (a == Alignment.centerLeft) return TextAlign.left;
|
if (a == Alignment.centerLeft) return TextAlign.left;
|
||||||
@@ -696,7 +714,7 @@ class _MonthHeader extends StatelessWidget {
|
|||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
onPressed: loading ? null : onPickMonth,
|
onPressed: loading ? null : onPickMonth,
|
||||||
icon: const Icon(Icons.calendar_month),
|
icon: const Icon(Icons.calendar_month),
|
||||||
label: Text(title, style: Theme.of(context).textTheme.titleLarge),
|
label: Text(title, style: Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 16)),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
foregroundColor: Theme.of(context).colorScheme.onSurface,
|
foregroundColor: Theme.of(context).colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user