-
Notifications
You must be signed in to change notification settings - Fork 582
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into collection_sheet_details
- Loading branch information
Showing
21 changed files
with
1,553 additions
and
515 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...d/online/grouplist/GroupListRepository.kt → ...re/data/repository/GroupListRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 2 additions & 1 deletion
3
...nline/grouplist/GroupListRepositoryImp.kt → .../repository_imp/GroupListRepositoryImp.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
core/domain/src/main/java/com/mifos/core/domain/use_cases/GetGroupsByCenterUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.mifos.core.domain.use_cases | ||
|
||
import com.mifos.core.common.utils.Resource | ||
import com.mifos.core.data.repository.GroupListRepository | ||
import com.mifos.core.objects.group.CenterWithAssociations | ||
import kotlinx.coroutines.channels.awaitClose | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.callbackFlow | ||
import rx.Subscriber | ||
import rx.android.schedulers.AndroidSchedulers | ||
import rx.schedulers.Schedulers | ||
import javax.inject.Inject | ||
|
||
class GetGroupsByCenterUseCase @Inject constructor(private val repository: GroupListRepository) { | ||
|
||
suspend operator fun invoke(id: Int): Flow<Resource<CenterWithAssociations>> = callbackFlow { | ||
try { | ||
trySend(Resource.Loading()) | ||
repository.getGroupsByCenter(id) | ||
.observeOn(AndroidSchedulers.mainThread()) | ||
.subscribeOn(Schedulers.io()) | ||
.subscribe(object : Subscriber<CenterWithAssociations>() { | ||
override fun onCompleted() { | ||
} | ||
|
||
override fun onError(e: Throwable) { | ||
trySend(Resource.Error(e.message.toString())) | ||
} | ||
|
||
override fun onNext(centerWithAssociations: CenterWithAssociations) { | ||
trySend(Resource.Success(centerWithAssociations)) | ||
} | ||
}) | ||
|
||
awaitClose { channel.close() } | ||
} catch (exception: Exception) { | ||
send(Resource.Error(exception.message.toString())) | ||
} | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
core/domain/src/main/java/com/mifos/core/domain/use_cases/GetGroupsUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.mifos.core.domain.use_cases | ||
|
||
import com.mifos.core.common.utils.Resource | ||
import com.mifos.core.data.repository.GroupListRepository | ||
import com.mifos.core.objects.group.GroupWithAssociations | ||
import kotlinx.coroutines.channels.awaitClose | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.callbackFlow | ||
import rx.Subscriber | ||
import rx.android.schedulers.AndroidSchedulers | ||
import rx.schedulers.Schedulers | ||
import javax.inject.Inject | ||
|
||
class GetGroupsUseCase @Inject constructor(private val repository: GroupListRepository) { | ||
|
||
suspend operator fun invoke(groupId: Int): Flow<Resource<GroupWithAssociations>> = | ||
callbackFlow { | ||
try { | ||
trySend(Resource.Loading()) | ||
repository.getGroups(groupId) | ||
.observeOn(AndroidSchedulers.mainThread()) | ||
.subscribeOn(Schedulers.io()) | ||
.subscribe(object : Subscriber<GroupWithAssociations>() { | ||
override fun onCompleted() {} | ||
|
||
override fun onError(exception: Throwable) { | ||
trySend(Resource.Error(exception.message.toString())) | ||
} | ||
|
||
override fun onNext(groupWithAssociations: GroupWithAssociations) { | ||
trySend(Resource.Success(groupWithAssociations)) | ||
} | ||
}) | ||
|
||
awaitClose { channel.close() } | ||
} catch (exception: Exception) { | ||
trySend(Resource.Error(exception.message.toString())) | ||
} | ||
} | ||
} |
218 changes: 218 additions & 0 deletions
218
feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
package com.mifos.feature.center.center_group_list | ||
|
||
import androidx.compose.foundation.Canvas | ||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.Row | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.layout.size | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.items | ||
import androidx.compose.foundation.shape.RoundedCornerShape | ||
import androidx.compose.material3.Card | ||
import androidx.compose.material3.CardDefaults | ||
import androidx.compose.material3.HorizontalDivider | ||
import androidx.compose.material3.MaterialTheme | ||
import androidx.compose.material3.SnackbarHostState | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import androidx.compose.ui.tooling.preview.PreviewParameter | ||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider | ||
import androidx.compose.ui.unit.dp | ||
import androidx.hilt.navigation.compose.hiltViewModel | ||
import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
import com.mifos.core.designsystem.component.MifosCircularProgress | ||
import com.mifos.core.designsystem.component.MifosScaffold | ||
import com.mifos.core.designsystem.component.MifosSweetError | ||
import com.mifos.core.designsystem.icon.MifosIcons | ||
import com.mifos.core.objects.client.Client | ||
import com.mifos.core.objects.client.Status | ||
import com.mifos.core.objects.group.CenterWithAssociations | ||
import com.mifos.core.objects.group.Group | ||
import com.mifos.core.ui.components.MifosEmptyUi | ||
import com.mifos.feature.center.R | ||
|
||
@Composable | ||
fun GroupListScreen( | ||
centerId: Int, | ||
onBackPressed: () -> Unit, | ||
loadClientsOfGroup: (List<Client>) -> Unit | ||
) { | ||
|
||
val viewModel: GroupListViewModel = hiltViewModel() | ||
val state by viewModel.groupListUiState.collectAsStateWithLifecycle() | ||
val groupAssociationState by viewModel.groupAssociationState.collectAsStateWithLifecycle() | ||
var groupClicked by remember { mutableStateOf(false) } | ||
|
||
LaunchedEffect(key1 = groupAssociationState) { | ||
groupAssociationState?.let { | ||
if (groupClicked) { | ||
loadClientsOfGroup(it.clientMembers) | ||
} | ||
} | ||
} | ||
|
||
LaunchedEffect(key1 = Unit) { | ||
viewModel.loadGroupByCenter(centerId) | ||
} | ||
|
||
GroupListScreen( | ||
state = state, | ||
onBackPressed = onBackPressed, | ||
onGroupClick = { | ||
groupClicked = true | ||
viewModel.loadGroups(it) | ||
}, | ||
onRetry = { | ||
viewModel.loadGroupByCenter(centerId) | ||
} | ||
) | ||
} | ||
|
||
@Composable | ||
fun GroupListScreen( | ||
state: GroupListUiState, | ||
onBackPressed: () -> Unit, | ||
onRetry: () -> Unit, | ||
onGroupClick: (Int) -> Unit | ||
) { | ||
val snackbarHostState = remember { SnackbarHostState() } | ||
|
||
MifosScaffold( | ||
icon = MifosIcons.arrowBack, | ||
title = stringResource(id = R.string.feature_center_groups), | ||
onBackPressed = onBackPressed, | ||
snackbarHostState = snackbarHostState | ||
) { paddingValues -> | ||
Column(modifier = Modifier.padding(paddingValues)) { | ||
when (state) { | ||
is GroupListUiState.Error -> MifosSweetError(message = stringResource(id = state.message)) { | ||
onRetry() | ||
} | ||
|
||
is GroupListUiState.Loading -> MifosCircularProgress() | ||
|
||
is GroupListUiState.GroupList -> { | ||
if (state.centerWithAssociations.groupMembers.isEmpty()) { | ||
MifosEmptyUi( | ||
text = stringResource(id = R.string.feature_center_no_group_list_to_show), | ||
icon = MifosIcons.fileTask | ||
) | ||
} else { | ||
GroupListContent( | ||
centerWithAssociations = state.centerWithAssociations, | ||
onGroupClick = onGroupClick | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
@Composable | ||
fun GroupListContent( | ||
centerWithAssociations: CenterWithAssociations, | ||
onGroupClick: (Int) -> Unit | ||
) { | ||
LazyColumn { | ||
items(centerWithAssociations.groupMembers) { group -> | ||
GroupItem(group = group, onGroupClick = onGroupClick) | ||
} | ||
} | ||
} | ||
|
||
|
||
@Composable | ||
fun GroupItem( | ||
group: Group, | ||
onGroupClick: (Int) -> Unit | ||
) { | ||
Card( | ||
modifier = Modifier | ||
.fillMaxWidth(), | ||
shape = RoundedCornerShape(0.dp), | ||
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), | ||
colors = CardDefaults.cardColors( | ||
containerColor = Color.White | ||
), | ||
onClick = { group.id?.let { onGroupClick(it) } } | ||
) { | ||
Column(modifier = Modifier.padding(8.dp)) { | ||
Row( | ||
modifier = Modifier | ||
.fillMaxWidth(), | ||
horizontalArrangement = Arrangement.SpaceBetween, | ||
verticalAlignment = Alignment.CenterVertically | ||
) { | ||
Text( | ||
modifier = Modifier | ||
.padding(8.dp), | ||
text = group.name.toString(), | ||
style = MaterialTheme.typography.bodyMedium | ||
) | ||
Text( | ||
modifier = Modifier.padding(8.dp), | ||
text = group.officeName.toString(), | ||
style = MaterialTheme.typography.bodyMedium, | ||
) | ||
} | ||
Row(verticalAlignment = Alignment.CenterVertically) { | ||
Text( | ||
modifier = Modifier.padding(8.dp), | ||
style = MaterialTheme.typography.bodySmall, | ||
text = if (group.status?.value?.let { Status.isActive(it) } == true) { | ||
stringResource(id = R.string.feature_center_active) | ||
} else { | ||
stringResource(id = R.string.feature_center_inactive) | ||
} | ||
) | ||
Canvas(modifier = Modifier.size(16.dp)) { | ||
if (group.status?.value?.let { Status.isActive(it) } == true) { | ||
drawRect(Color.Green) | ||
} else { | ||
drawRect(Color.Red) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
HorizontalDivider() | ||
} | ||
|
||
class GroupListUiStateProvider : PreviewParameterProvider<GroupListUiState> { | ||
|
||
override val values: Sequence<GroupListUiState> | ||
get() = sequenceOf( | ||
GroupListUiState.Loading, | ||
GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list), | ||
GroupListUiState.GroupList(sampleCenterWithAssociations) | ||
) | ||
} | ||
|
||
@Preview(showBackground = true) | ||
@Composable | ||
private fun GroupListScreenPreview( | ||
@PreviewParameter(GroupListUiStateProvider::class) state: GroupListUiState | ||
) { | ||
GroupListScreen( | ||
state = state, | ||
onBackPressed = {}, | ||
onGroupClick = {}, | ||
onRetry = {} | ||
) | ||
} | ||
|
||
val sampleCenterWithAssociations = CenterWithAssociations() |
15 changes: 15 additions & 0 deletions
15
feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListUiState.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.mifos.feature.center.center_group_list | ||
|
||
import com.mifos.core.objects.group.CenterWithAssociations | ||
|
||
/** | ||
* Created by Aditya Gupta on 06/08/23. | ||
*/ | ||
sealed class GroupListUiState { | ||
|
||
data object Loading : GroupListUiState() | ||
|
||
data class Error(val message: Int) : GroupListUiState() | ||
|
||
data class GroupList(val centerWithAssociations: CenterWithAssociations) : GroupListUiState() | ||
} |
Oops, something went wrong.