This commit is contained in:
Dwi Swandhana
2026-07-22 14:06:01 +07:00
parent 848f0e4100
commit e04d43dfdf
9 changed files with 778 additions and 203 deletions
@@ -124,35 +124,10 @@ class _CciExpertiseWizardState extends State<CciExpertiseWizard> {
Step( Step(
title: const Text('Data Alat'), title: const Text('Data Alat'),
isActive: _step == 2, isActive: _step == 2,
content: Column( content: ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
), ),
), ),
Step( Step(
@@ -229,6 +204,7 @@ class _CciExpertiseWizardState extends State<CciExpertiseWizard> {
return values.isEmpty ? fallback : values; return values.isEmpty ? fallback : values;
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,
@@ -141,35 +141,10 @@ class _CovidExpertiseWizardState extends State<CovidExpertiseWizard> {
} }
Widget _toolData() { Widget _toolData() {
return Column( return ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
); );
} }
@@ -245,6 +220,7 @@ class _CovidExpertiseWizardState extends State<CovidExpertiseWizard> {
); );
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,
@@ -1055,6 +1055,656 @@ class _AntibioticSensitivityPanelState
} }
} }
class ToolDataPanel extends StatefulWidget {
const ToolDataPanel({
super.key,
required this.textControllers,
required this.selectValues,
required this.onChanged,
});
final Map<String, TextEditingController> textControllers;
final Map<String, String> selectValues;
final VoidCallback onChanged;
@override
State<ToolDataPanel> createState() => _ToolDataPanelState();
}
class _ToolDataPanelState extends State<ToolDataPanel> {
int _selectedTab = 0;
static const List<_ToolTabConfig> _tabs = [
_ToolTabConfig(
label: 'Vitek',
tableId: 'tblvitek',
rowField: 'vitek_antibiotic_rows',
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
automatic: true,
),
_ToolTabConfig(
label: 'Malditof',
tableId: 'tblkumanmanual1',
rowField: 'malditof_antibiotic_rows',
bacteriaField: 'id_bakteri01',
antibioticSetField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_ToolTabConfig(
label: 'Manual',
tableId: 'tblkumanmanual2',
rowField: 'manual_antibiotic_rows',
bacteriaField: 'id_bakteri02',
antibioticSetField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
];
@override
Widget build(BuildContext context) {
final tab = _tabs[_selectedTab];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Data Alat',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w800,
color: const Color(0xFF0F766E),
),
),
const SizedBox(height: 10),
_tabBar(),
const SizedBox(height: 12),
_toolForm(tab),
const SizedBox(height: 12),
_toolButtons(tab),
const SizedBox(height: 12),
_antibioticTable(tab),
],
);
}
Widget _tabBar() {
return SizedBox(
height: 54,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: _tabs.length,
separatorBuilder: (_, _) => const SizedBox(width: 8),
itemBuilder: (context, index) {
final tab = _tabs[index];
final selected = index == _selectedTab;
return ChoiceChip(
selected: selected,
showCheckmark: false,
avatar: Icon(
index == 0
? Icons.memory_outlined
: index == 1
? Icons.biotech_outlined
: Icons.edit_note_outlined,
size: 18,
color: selected ? const Color(0xFF0F766E) : Colors.black54,
),
label: Text(tab.label),
onSelected: (_) => setState(() => _selectedTab = index),
);
},
),
);
}
Widget _toolForm(_ToolTabConfig tab) {
final rows = _rows(tab);
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: [
Expanded(
child: Text(
tab.label,
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w800,
),
),
),
BadgeLabel(
text: '${rows.length} antibiotik',
color: const Color(0xFF0F766E),
),
],
),
const SizedBox(height: 12),
if (tab.automatic)
_readonlyBacteria(tab)
else
_bacteriaAutocomplete(tab),
if (tab.antibioticSetField != null)
_selectText(
tab.antibioticSetField!,
'Set Antibiotik',
_antibioticSetOptions,
onChanged: () => _autoGenerate(tab),
),
_selectText(
tab.sirField,
'Resistensi',
_sirOptions,
onChanged: () => _autoGenerate(tab),
),
_selectText(tab.colonyField, 'Hitung Koloni', _colonyOptions),
_text(tab.colonyTextField, 'Hitung Koloni Lainnya'),
_selectText(tab.printField, 'Cetak', const ['YA', 'TIDAK']),
],
),
),
);
}
Widget _readonlyBacteria(_ToolTabConfig tab) {
final controller = widget.textControllers[tab.bacteriaField] ??=
TextEditingController();
final text = controller.text.trim();
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: TextField(
controller: controller,
readOnly: true,
decoration: InputDecoration(
labelText: 'Kuman',
helperText: text.isEmpty
? 'Readonly dari hasil alat Vitek'
: 'Readonly dari hasil alat Vitek',
border: const OutlineInputBorder(),
prefixIcon: const Icon(Icons.lock_outline),
),
),
);
}
Widget _bacteriaAutocomplete(_ToolTabConfig tab) {
final controller = widget.textControllers[tab.bacteriaField] ??=
TextEditingController();
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Autocomplete<String>(
initialValue: TextEditingValue(text: controller.text),
optionsBuilder: (value) {
final query = value.text.trim().toLowerCase();
if (query.isEmpty) {
return _bacteriaOptions;
}
return _bacteriaOptions.where(
(option) => option.toLowerCase().contains(query),
);
},
onSelected: (value) {
controller.text = value;
_autoGenerate(tab);
},
fieldViewBuilder:
(context, fieldController, focusNode, onFieldSubmitted) {
if (fieldController.text != controller.text) {
fieldController.text = controller.text;
}
return TextField(
controller: fieldController,
focusNode: focusNode,
decoration: const InputDecoration(
labelText: 'Kuman',
border: OutlineInputBorder(),
),
onChanged: (value) {
controller.text = value;
widget.onChanged();
},
onSubmitted: (_) => _autoGenerate(tab),
);
},
),
);
}
Widget _toolButtons(_ToolTabConfig tab) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFFF1F5F9),
borderRadius: BorderRadius.circular(8),
),
child: Wrap(
spacing: 8,
runSpacing: 8,
children: [
FilledButton.icon(
onPressed: () => _generateRows(tab, replace: true),
icon: const Icon(Icons.table_rows_outlined),
label: Text(
tab.automatic ? 'Muat Tabel Otomatis' : 'Generate Tabel',
),
),
OutlinedButton.icon(
onPressed: () => _setAllPrint(tab, printRow: true, printMic: true),
icon: const Icon(Icons.check_circle_outline),
label: const Text('Print Semua'),
),
OutlinedButton.icon(
onPressed: () =>
_setAllPrint(tab, printRow: false, printMic: false),
icon: const Icon(Icons.block_outlined),
label: const Text('Unprint Semua'),
),
OutlinedButton.icon(
onPressed: () => _clearRows(tab),
icon: const Icon(Icons.delete_sweep_outlined),
label: const Text('Reset Tabel'),
),
],
),
);
}
Widget _antibioticTable(_ToolTabConfig tab) {
final rows = _rows(tab);
if (rows.isEmpty) {
return EmptyPanel(
text: tab.automatic
? 'Belum ada tabel antibiotik otomatis dari Vitek.'
: 'Pilih kuman dan resistensi untuk membuat tabel antibiotik.',
);
}
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(12, 12, 12, 4),
child: Text(
tab.tableId,
style: Theme.of(
context,
).textTheme.labelMedium?.copyWith(color: Colors.black54),
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
headingRowHeight: 40,
dataRowMinHeight: 60,
dataRowMaxHeight: 76,
columns: [
const DataColumn(label: Text('#')),
const DataColumn(label: Text('Print')),
const DataColumn(label: Text('Antibiotik')),
const DataColumn(label: Text('Value')),
const DataColumn(label: Text('Interpretation')),
if (!tab.automatic) ...[
const DataColumn(label: Text('S')),
const DataColumn(label: Text('I')),
const DataColumn(label: Text('R')),
],
const DataColumn(label: Text('Print Value')),
const DataColumn(label: Text('Delete')),
],
rows: [
for (var i = 0; i < rows.length; i += 1)
DataRow(
cells: [
DataCell(Text('${i + 1}')),
DataCell(
IconButton(
tooltip: rows[i]['printrow'] == true
? 'Unprint row'
: 'Print row',
onPressed: () => _toggleBool(tab, i, 'printrow'),
icon: Icon(
rows[i]['printrow'] == true
? Icons.check_circle
: Icons.block,
color: rows[i]['printrow'] == true
? const Color(0xFF15803D)
: const Color(0xFFDC2626),
),
),
),
DataCell(
SizedBox(
width: 150,
child: Text(
_cell(rows[i], 'antibiotic'),
overflow: TextOverflow.ellipsis,
),
),
),
DataCell(
SizedBox(
width: 104,
child: TextFormField(
initialValue: _cell(rows[i], 'value'),
decoration: const InputDecoration(
isDense: true,
border: OutlineInputBorder(),
),
onChanged: (value) =>
_updateRow(tab, i, 'value', value),
),
),
),
DataCell(
SizedBox(
width: 118,
child: DropdownButtonFormField<String>(
initialValue:
_interpretationOptions.contains(
rows[i]['interpretation'],
)
? rows[i]['interpretation'].toString()
: '',
isExpanded: true,
decoration: const InputDecoration(
isDense: true,
border: OutlineInputBorder(),
),
items: _interpretationOptions
.map(
(option) => DropdownMenuItem(
value: option,
child: Text(
option.isEmpty ? 'null' : option,
),
),
)
.toList(),
onChanged: (value) => _updateRow(
tab,
i,
'interpretation',
value ?? '',
),
),
),
),
if (!tab.automatic) ...[
DataCell(Text(_cell(rows[i], 'batasatas'))),
DataCell(Text(_cell(rows[i], 'midrange'))),
DataCell(Text(_cell(rows[i], 'batasbawah'))),
],
DataCell(
IconButton(
tooltip: rows[i]['printcol'] == true
? 'Unprint value'
: 'Print value',
onPressed: () => _toggleBool(tab, i, 'printcol'),
icon: Icon(
rows[i]['printcol'] == true
? Icons.check_circle
: Icons.block,
color: rows[i]['printcol'] == true
? const Color(0xFF15803D)
: const Color(0xFFDC2626),
),
),
),
DataCell(
IconButton(
tooltip: 'Delete MIC',
color: const Color(0xFFDC2626),
onPressed: () => _deleteRow(tab, i),
icon: const Icon(Icons.delete_outline),
),
),
],
),
],
),
),
],
),
);
}
Widget _selectText(
String name,
String label,
List<String> options, {
VoidCallback? onChanged,
}) {
final current = widget.selectValues[name] ?? '';
final effectiveOptions = [
if (current.isNotEmpty && !options.contains(current)) current,
...options,
];
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: DropdownButtonFormField<String>(
initialValue: current.isNotEmpty && effectiveOptions.contains(current)
? current
: null,
isExpanded: true,
decoration: InputDecoration(
labelText: label,
border: const OutlineInputBorder(),
),
items: effectiveOptions
.map(
(option) => DropdownMenuItem(
value: option,
child: Text(decodeHtmlEntities(option)),
),
)
.toList(),
onChanged: (value) {
widget.selectValues[name] = value ?? '';
widget.onChanged();
onChanged?.call();
},
),
);
}
Widget _text(String name, String label) {
final controller = widget.textControllers[name] ??= TextEditingController();
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: TextField(
controller: controller,
decoration: InputDecoration(
labelText: label,
border: const OutlineInputBorder(),
),
onChanged: (_) => widget.onChanged(),
),
);
}
List<Map<String, dynamic>> _rows(_ToolTabConfig tab) {
final raw = widget.textControllers[tab.rowField]?.text ?? '';
if (raw.trim().isEmpty) {
return <Map<String, dynamic>>[];
}
try {
final decoded = jsonDecode(raw);
if (decoded is List) {
return decoded.map((item) => asMap(item)).toList();
}
} catch (_) {
return <Map<String, dynamic>>[];
}
return <Map<String, dynamic>>[];
}
void _saveRows(_ToolTabConfig tab, List<Map<String, dynamic>> rows) {
widget.textControllers[tab.rowField] ??= TextEditingController();
widget.textControllers[tab.rowField]!.text = jsonEncode(rows);
widget.onChanged();
}
void _autoGenerate(_ToolTabConfig tab) {
if (tab.automatic) {
return;
}
final bacteria =
widget.textControllers[tab.bacteriaField]?.text.trim() ?? '';
final sir = widget.selectValues[tab.sirField]?.trim() ?? '';
if (bacteria.isEmpty || sir.isEmpty) {
return;
}
_generateRows(tab, replace: true);
}
void _generateRows(_ToolTabConfig tab, {required bool replace}) {
final rows = replace ? <Map<String, dynamic>>[] : _rows(tab);
final bacteria =
widget.textControllers[tab.bacteriaField]?.text.trim() ?? '';
final resistance = widget.selectValues[tab.sirField]?.trim() ?? '';
final setName = tab.antibioticSetField == null
? 'otomatis'
: widget.selectValues[tab.antibioticSetField!]?.trim() ?? 'default';
final antibiotics = _antibioticsFor(tab, bacteria, resistance, setName);
for (var i = 0; i < antibiotics.length; i += 1) {
final antibiotic = antibiotics[i];
rows.add({
'id': '${tab.rowField}_${DateTime.now().microsecondsSinceEpoch}_$i',
'antibiotic': antibiotic,
'value': '',
'interpretation': '',
'batasatas': 'S',
'midrange': 'I',
'batasbawah': 'R',
'printrow': true,
'printcol': true,
'bacteria': bacteria,
'resistance': resistance,
'set': setName,
});
}
_saveRows(tab, rows);
setState(() {});
}
List<String> _antibioticsFor(
_ToolTabConfig tab,
String bacteria,
String resistance,
String setName,
) {
final base = tab.automatic
? _vitekAntibiotics
: bacteria.toLowerCase().contains('candida') ||
bacteria.toLowerCase().contains('yeast') ||
bacteria.toLowerCase().contains('jamur')
? _fungalAntibiotics
: _manualAntibiotics;
if (resistance.contains('Carbapenem')) {
return [...base, 'ETP', 'DOR', 'IPM'];
}
if (resistance == 'MRSA') {
return ['FOX', 'OXA', 'VAN', 'LZD', 'CLI', 'ERY', ...base.take(5)];
}
if (setName.toLowerCase() != 'default') {
return [setName, ...base.where((item) => item != setName)];
}
return base;
}
void _setAllPrint(
_ToolTabConfig tab, {
required bool printRow,
required bool printMic,
}) {
final rows = _rows(tab)
.map((row) => {...row, 'printrow': printRow, 'printcol': printMic})
.toList();
_saveRows(tab, rows);
setState(() {});
}
void _clearRows(_ToolTabConfig tab) {
_saveRows(tab, <Map<String, dynamic>>[]);
setState(() {});
}
void _toggleBool(_ToolTabConfig tab, int index, String key) {
final rows = _rows(tab);
if (index < 0 || index >= rows.length) {
return;
}
rows[index][key] = rows[index][key] != true;
_saveRows(tab, rows);
setState(() {});
}
void _updateRow(_ToolTabConfig tab, int index, String key, String value) {
final rows = _rows(tab);
if (index < 0 || index >= rows.length) {
return;
}
rows[index][key] = value;
_saveRows(tab, rows);
}
void _deleteRow(_ToolTabConfig tab, int index) {
final rows = _rows(tab);
if (index < 0 || index >= rows.length) {
return;
}
rows.removeAt(index);
_saveRows(tab, rows);
setState(() {});
}
String _cell(Map<String, dynamic> row, String key) {
final value = row[key]?.toString() ?? '';
return value.isEmpty ? '-' : decodeHtmlEntities(value);
}
}
class _ToolTabConfig {
const _ToolTabConfig({
required this.label,
required this.tableId,
required this.rowField,
required this.bacteriaField,
required this.sirField,
required this.colonyField,
required this.colonyTextField,
required this.printField,
this.antibioticSetField,
this.automatic = false,
});
final String label;
final String tableId;
final String rowField;
final String bacteriaField;
final String sirField;
final String colonyField;
final String colonyTextField;
final String printField;
final String? antibioticSetField;
final bool automatic;
}
class _AntibioticMedia { class _AntibioticMedia {
const _AntibioticMedia({ const _AntibioticMedia({
required this.label, required this.label,
@@ -1106,6 +1756,88 @@ const List<String> _kumanOptions = [
'Kuman 5', 'Kuman 5',
]; ];
const List<String> _bacteriaOptions = [
'Kuman 1',
'Kuman 2',
'Kuman 3',
'Kuman 4',
'Kuman 5',
'Escherichia coli',
'Klebsiella pneumoniae',
'Pseudomonas aeruginosa',
'Acinetobacter baumannii',
'Staphylococcus aureus',
'Staphylococcus epidermidis',
'Enterococcus faecalis',
'Enterococcus faecium',
'Streptococcus pneumoniae',
'Candida albicans',
'Candida tropicalis',
'Candida glabrata',
];
const List<String> _antibioticSetOptions = [
'default',
'Gram Positive',
'Gram Negative',
'Urine',
'Blood',
'Respiratory',
'Candida',
];
const List<String> _interpretationOptions = [
'',
'S',
'I',
'R',
'Invalid',
'No Result',
'Error',
'SDD',
];
const List<String> _vitekAntibiotics = [
'AMK',
'AMP',
'AMC',
'CAZ',
'CIP',
'CTX',
'CRO',
'FEP',
'GEN',
'LEV',
'MEM',
'SXT',
];
const List<String> _manualAntibiotics = [
'AMP',
'AMC',
'SAM',
'TZP',
'CAZ',
'CTX',
'CRO',
'FEP',
'CIP',
'LEV',
'GEN',
'AMK',
'MEM',
'SXT',
];
const List<String> _fungalAntibiotics = [
'Fluconazole',
'Voriconazole',
'Itraconazole',
'Amphotericin B',
'Caspofungin',
'Micafungin',
];
const List<String> _fungalKumanOptions = [ const List<String> _fungalKumanOptions = [
'Bakteri Kuman 1', 'Bakteri Kuman 1',
'Yeast Kuman 1', 'Yeast Kuman 1',
@@ -1387,6 +2119,12 @@ const List<String> kAntibioticMediaRowFields = [
'media_tamlainnya_rows', 'media_tamlainnya_rows',
]; ];
const List<String> kToolAntibioticRowFields = [
'vitek_antibiotic_rows',
'malditof_antibiotic_rows',
'manual_antibiotic_rows',
];
class ExpertiseForm extends StatelessWidget { class ExpertiseForm extends StatelessWidget {
const ExpertiseForm({ const ExpertiseForm({
super.key, super.key,
@@ -97,6 +97,11 @@ class _ExpertiseScreenState extends State<ExpertiseScreen> {
text: components[name]?.toString() ?? '', text: components[name]?.toString() ?? '',
); );
} }
for (final name in kToolAntibioticRowFields) {
_textControllers[name] = TextEditingController(
text: components[name]?.toString() ?? '',
);
}
} }
Future<void> _setTemplate(String dlp) async { Future<void> _setTemplate(String dlp) async {
@@ -303,35 +303,10 @@ class _KulturExpertiseWizardState extends State<KulturExpertiseWizard> {
} }
Widget _toolData() { Widget _toolData() {
return Column( return ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
); );
} }
@@ -417,6 +392,7 @@ class _KulturExpertiseWizardState extends State<KulturExpertiseWizard> {
); );
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,
@@ -131,35 +131,10 @@ class _LeptospiraExpertiseWizardState extends State<LeptospiraExpertiseWizard> {
} }
Widget _toolData() { Widget _toolData() {
return Column( return ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
); );
} }
@@ -235,6 +210,7 @@ class _LeptospiraExpertiseWizardState extends State<LeptospiraExpertiseWizard> {
); );
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,
@@ -241,35 +241,10 @@ class _PewarnaanLangsungExpertiseWizardState
} }
Widget _toolData() { Widget _toolData() {
return Column( return ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
); );
} }
@@ -355,6 +330,7 @@ class _PewarnaanLangsungExpertiseWizardState
); );
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,
@@ -367,35 +367,10 @@ class _TbcExpertiseWizardState extends State<TbcExpertiseWizard> {
} }
Widget _toolData() { Widget _toolData() {
return Column( return ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
); );
} }
@@ -471,6 +446,7 @@ class _TbcExpertiseWizardState extends State<TbcExpertiseWizard> {
); );
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,
@@ -144,35 +144,10 @@ class _ViralLoadExpertiseWizardState extends State<ViralLoadExpertiseWizard> {
} }
Widget _toolData() { Widget _toolData() {
return Column( return ToolDataPanel(
children: [ textControllers: widget.textControllers,
_toolSection( selectValues: widget.selectValues,
title: 'Vitek', onChanged: widget.onChanged,
bacteriaField: 'bakteri',
sirField: 'bakterisir',
colonyField: 'id_bakterihitungkol',
colonyTextField: 'id_bakterihitungkolteks',
printField: 'id_baktericetak',
),
_toolSection(
title: 'MALDITOF',
bacteriaField: 'id_bakteri01',
antibioticField: 'id_antibiotikmanual1',
sirField: 'id_bakterisir01',
colonyField: 'id_bakterihitungkol01',
colonyTextField: 'id_bakterihitungkolteks01',
printField: 'id_bakteri01cetak',
),
_toolSection(
title: 'Bakteri Manual I',
bacteriaField: 'id_bakteri02',
antibioticField: 'id_antibiotikmanual2',
sirField: 'id_bakterisir02',
colonyField: 'id_bakterihitungkol02',
colonyTextField: 'id_bakterihitungkolteks02',
printField: 'id_bakteri02cetak',
),
],
); );
} }
@@ -258,6 +233,7 @@ class _ViralLoadExpertiseWizardState extends State<ViralLoadExpertiseWizard> {
); );
} }
// ignore: unused_element
Widget _toolSection({ Widget _toolSection({
required String title, required String title,
required String bacteriaField, required String bacteriaField,