diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt index 102d1c164b..fe8ec48195 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt @@ -13,6 +13,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.core.app.ActivityOptionsCompat import androidx.fragment.app.activityViewModels +import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.map import androidx.recyclerview.widget.DividerItemDecoration @@ -53,7 +54,9 @@ import org.dhis2.usescases.teiDashboard.dashboardfragments.teidata.teievents.Eve import org.dhis2.usescases.teiDashboard.dashboardfragments.teidata.teievents.EventCatComboOptionSelector import org.dhis2.usescases.teiDashboard.dashboardfragments.teidata.teievents.ui.mapper.TEIEventCardMapper import org.dhis2.usescases.teiDashboard.dialogs.scheduling.SchedulingDialog +import org.dhis2.usescases.teiDashboard.dialogs.scheduling.SchedulingDialog.Companion.PROGRAM_STAGE_UID import org.dhis2.usescases.teiDashboard.dialogs.scheduling.SchedulingDialog.Companion.SCHEDULING_DIALOG +import org.dhis2.usescases.teiDashboard.dialogs.scheduling.SchedulingDialog.Companion.SCHEDULING_DIALOG_RESULT import org.dhis2.usescases.teiDashboard.ui.TeiDetailDashboard import org.dhis2.usescases.teiDashboard.ui.mapper.InfoBarMapper import org.dhis2.usescases.teiDashboard.ui.mapper.TeiDashboardCardMapper @@ -159,6 +162,16 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View { setEvents(it) showLoadingProgress(false) } + + setFragmentResultListener(SCHEDULING_DIALOG_RESULT) { _, bundle -> + showToast( + resourceManager.formatWithEventLabel( + R.string.event_label_created, + bundle.getString(PROGRAM_STAGE_UID), + ), + ) + presenter.fetchEvents() + } }.root } @@ -374,18 +387,9 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View { override fun displayScheduleEvent() { val model = dashboardViewModel.dashboardModel.value if (model is DashboardEnrollmentModel) { - SchedulingDialog( + SchedulingDialog.newInstance( enrollment = model.currentEnrollment, programStages = presenter.filterAvailableStages(model.programStages), - onScheduled = { programStageUid -> - showToast( - resourceManager.formatWithEventLabel( - R.string.event_label_created, - programStageUid, - ), - ) - presenter.fetchEvents() - }, ).show(parentFragmentManager, SCHEDULING_DIALOG) } } diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialog.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialog.kt index dff422ad1a..987a86729d 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialog.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialog.kt @@ -8,6 +8,8 @@ import android.view.ViewGroup import android.widget.DatePicker import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.core.os.bundleOf +import androidx.fragment.app.setFragmentResult import androidx.fragment.app.viewModels import com.google.android.material.bottomsheet.BottomSheetDialogFragment import org.dhis2.bindings.app @@ -20,15 +22,26 @@ import org.hisp.dhis.android.core.program.ProgramStage import java.util.Date import javax.inject.Inject -class SchedulingDialog( - val enrollment: Enrollment, - val programStages: List, - val onScheduled: (String) -> Unit, -) : BottomSheetDialogFragment() { +class SchedulingDialog : BottomSheetDialogFragment() { companion object { const val SCHEDULING_DIALOG = "SCHEDULING_DIALOG" + const val SCHEDULING_DIALOG_RESULT = "SCHEDULING_DIALOG_RESULT" + const val PROGRAM_STAGE_UID = "PROGRAM_STAGE_UID" + + fun newInstance( + enrollment: Enrollment, + programStages: List, + ): SchedulingDialog { + return SchedulingDialog().apply { + this.enrollment = enrollment + this.programStages = programStages + } + } } + var enrollment: Enrollment? = null + var programStages: List? = null + @Inject lateinit var factory: SchedulingViewModelFactory val viewModel: SchedulingViewModel by viewModels { factory } @@ -40,12 +53,7 @@ class SchedulingDialog( override fun onAttach(context: Context) { super.onAttach(context) - app().userComponent()?.plus( - SchedulingModule( - enrollment, - programStages, - ), - )?.inject(this) + app().userComponent()?.plus(SchedulingModule())?.inject(this) } override fun onCreateView( @@ -53,6 +61,18 @@ class SchedulingDialog( container: ViewGroup?, savedInstanceState: Bundle?, ): View { + enrollment?.let { + viewModel.enrollment = it + } + programStages?.let { + viewModel.programStages = it + viewModel.setInitialProgramStage(it.first()) + } + viewModel.onEventScheduled = { + setFragmentResult(SCHEDULING_DIALOG_RESULT, bundleOf(PROGRAM_STAGE_UID to it)) + dismiss() + } + viewModel.showCalendar = { showCalendarDialog() } @@ -61,11 +81,6 @@ class SchedulingDialog( showPeriodDialog() } - viewModel.onEventScheduled = { - dismiss() - onScheduled(viewModel.programStage.value.uid()) - } - return ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed, @@ -73,8 +88,8 @@ class SchedulingDialog( setContent { SchedulingDialogUi( viewModel = viewModel, - programStages = programStages, - orgUnitUid = enrollment.organisationUnit(), + programStages = viewModel.programStages, + orgUnitUid = viewModel.enrollment.organisationUnit(), onDismiss = { dismiss() }, ) } diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialogUi.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialogUi.kt index 2b22cb7d37..4827df76ee 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialogUi.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingDialogUi.kt @@ -126,7 +126,7 @@ fun buttonTitle(scheduleNew: Boolean): String = when (scheduleNew) { fun ProvideScheduleNewEventForm( programStages: List, viewModel: SchedulingViewModel, - selectedProgramStage: ProgramStage, + selectedProgramStage: ProgramStage?, date: EventDate, catCombo: EventCatCombo, orgUnitUid: String?, @@ -136,7 +136,7 @@ fun ProvideScheduleNewEventForm( title = stringResource(id = R.string.program_stage), state = InputShellState.UNFOCUSED, dropdownItems = programStages.map { DropdownItem(it.displayName().orEmpty()) }, - selectedItem = DropdownItem(selectedProgramStage.displayName().orEmpty()), + selectedItem = DropdownItem(selectedProgramStage?.displayName().orEmpty()), onResetButtonClicked = {}, onItemSelected = { item -> programStages.find { it.displayName() == item.label } @@ -145,7 +145,7 @@ fun ProvideScheduleNewEventForm( ) } - if (willShowCalendar(selectedProgramStage.periodType())) { + if (willShowCalendar(selectedProgramStage?.periodType())) { ProvideInputDate( EventInputDateUiModel( eventDate = date, diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingModule.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingModule.kt index 80688227a8..3d5beb862b 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingModule.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingModule.kt @@ -6,14 +6,9 @@ import org.dhis2.commons.di.dagger.PerFragment import org.dhis2.commons.resources.DhisPeriodUtils import org.dhis2.commons.resources.ResourceManager import org.hisp.dhis.android.core.D2 -import org.hisp.dhis.android.core.enrollment.Enrollment -import org.hisp.dhis.android.core.program.ProgramStage @Module -class SchedulingModule( - val enrollment: Enrollment, - val programStages: List, -) { +class SchedulingModule { @Provides @PerFragment fun provideSchedulingViewModelFactory( @@ -21,5 +16,9 @@ class SchedulingModule( resourceManager: ResourceManager, periodUtils: DhisPeriodUtils, ): SchedulingViewModelFactory = - SchedulingViewModelFactory(enrollment, programStages, d2, resourceManager, periodUtils) + SchedulingViewModelFactory( + d2, + resourceManager, + periodUtils, + ) } diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModel.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModel.kt index e261d52861..33f095c82d 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModel.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModel.kt @@ -26,8 +26,6 @@ import java.util.Date import java.util.Locale class SchedulingViewModel( - val enrollment: Enrollment, - val programStages: List, val d2: D2, val resourceManager: ResourceManager, val periodUtils: DhisPeriodUtils, @@ -37,12 +35,15 @@ class SchedulingViewModel( lateinit var configureEventReportDate: ConfigureEventReportDate lateinit var configureEventCatCombo: ConfigureEventCatCombo - private val _programStage: MutableStateFlow = MutableStateFlow(programStages.first()) - val programStage: StateFlow get() = _programStage + lateinit var enrollment: Enrollment + lateinit var programStages: List + + private val _programStage: MutableStateFlow = MutableStateFlow(null) + val programStage: StateFlow get() = _programStage var showCalendar: (() -> Unit)? = null var showPeriods: (() -> Unit)? = null - var onEventScheduled: (() -> Unit)? = null + var onEventScheduled: ((String) -> Unit)? = null private val _eventDate: MutableStateFlow = MutableStateFlow(EventDate()) val eventDate: StateFlow get() = _eventDate @@ -50,16 +51,12 @@ class SchedulingViewModel( private val _eventCatCombo: MutableStateFlow = MutableStateFlow(EventCatCombo()) val eventCatCombo: StateFlow get() = _eventCatCombo - init { - loadConfiguration() - } - private fun loadConfiguration() { repository = EventDetailsRepository( d2 = d2, programUid = enrollment.program().orEmpty(), eventUid = null, - programStageUid = programStage.value.uid(), + programStageUid = programStage.value?.uid(), fieldFactory = null, eventCreationType = EventCreationType.SCHEDULE, onError = resourceManager::parseD2Error, @@ -68,14 +65,14 @@ class SchedulingViewModel( creationType = EventCreationType.SCHEDULE, resourceProvider = EventDetailResourcesProvider( enrollment.program().orEmpty(), - programStage.value.uid(), + programStage.value?.uid(), resourceManager, ), repository = repository, - periodType = programStage.value.periodType(), + periodType = programStage.value?.periodType(), periodUtils = periodUtils, enrollmentId = enrollment.uid(), - scheduleInterval = programStage.value.standardInterval() ?: 0, + scheduleInterval = programStage.value?.standardInterval() ?: 0, ) configureEventCatCombo = ConfigureEventCatCombo( repository = repository, @@ -142,7 +139,7 @@ class SchedulingViewModel( } fun showPeriodDialog() { - programStage.value.periodType()?.let { + programStage.value?.periodType()?.let { showPeriods?.invoke() } } @@ -171,10 +168,15 @@ class SchedulingViewModel( ).flowOn(Dispatchers.IO) .collect { if (it != null) { - onEventScheduled?.invoke() + onEventScheduled?.invoke(programStage.value?.uid() ?: "") } } } } } + + fun setInitialProgramStage(programStage: ProgramStage) { + _programStage.value = programStage + loadConfiguration() + } } diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelFactory.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelFactory.kt index 5fc494d23a..47654437e8 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelFactory.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelFactory.kt @@ -5,13 +5,9 @@ import androidx.lifecycle.ViewModelProvider import org.dhis2.commons.resources.DhisPeriodUtils import org.dhis2.commons.resources.ResourceManager import org.hisp.dhis.android.core.D2 -import org.hisp.dhis.android.core.enrollment.Enrollment -import org.hisp.dhis.android.core.program.ProgramStage @Suppress("UNCHECKED_CAST") class SchedulingViewModelFactory( - private val enrollment: Enrollment, - private val programStages: List, private val d2: D2, private val resourceManager: ResourceManager, private val periodUtils: DhisPeriodUtils, @@ -19,8 +15,6 @@ class SchedulingViewModelFactory( override fun create(modelClass: Class): T { return SchedulingViewModel( - enrollment, - programStages, d2, resourceManager, periodUtils, diff --git a/app/src/test/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelTest.kt b/app/src/test/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelTest.kt index 2eacb1f7e2..cf52fec2ad 100644 --- a/app/src/test/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelTest.kt +++ b/app/src/test/java/org/dhis2/usescases/teiDashboard/dialogs/scheduling/SchedulingViewModelTest.kt @@ -5,8 +5,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.setMain import org.hisp.dhis.android.core.arch.helpers.DateUtils -import org.hisp.dhis.android.core.enrollment.Enrollment -import org.hisp.dhis.android.core.program.ProgramStage import org.junit.Before import org.junit.Test import org.mockito.Mockito.spy @@ -15,9 +13,6 @@ import org.mockito.kotlin.verify class SchedulingViewModelTest { - private val enrollment = Enrollment.builder().uid("enrollmentUid").build() - private val programStage = ProgramStage.builder().uid("programStage").build() - private lateinit var schedulingViewModel: SchedulingViewModel private val testingDispatcher = StandardTestDispatcher() @@ -27,8 +22,6 @@ class SchedulingViewModelTest { fun setUp() { Dispatchers.setMain(testingDispatcher) schedulingViewModel = SchedulingViewModel( - enrollment = enrollment, - programStages = listOf(programStage), d2 = mock(), resourceManager = mock(), periodUtils = mock(),