update
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user