Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADST-31 #320

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class ProcessDetailViewModel(
fun startWorkflow() = withState { state ->
val items = state.listContents.joinToString(separator = ",") { it.id }
viewModelScope.launch {
repository::startWorkflow.asFlow(state.parent, items).execute {
repository::startWorkflow.asFlow(state.parent, items, emptyList()).execute {
when (it) {
is Loading -> copy(requestStartWorkflow = Loading())
is Fail -> copy(requestStartWorkflow = Fail(it.error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.alfresco.content.browse.processes.details

import com.alfresco.content.browse.processes.list.UpdateProcessData
import com.alfresco.content.browse.tasks.list.UpdateTasksData
import com.alfresco.content.process.ui.UpdateProcessData
import com.alfresco.events.EventBus
import kotlinx.coroutines.launch

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.alfresco.content.data.payloads.TaskProcessFiltersPayload
import com.alfresco.content.getLocalizedName
import com.alfresco.content.listview.processes.ProcessListViewModel
import com.alfresco.content.listview.processes.ProcessListViewState
import com.alfresco.content.process.ui.UpdateProcessData
import com.alfresco.coroutines.asFlow
import com.alfresco.events.on
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -117,8 +118,3 @@ class ProcessesViewModel(
fetchInitial()
}
}

/**
* Mark as UpdateProcessData data class
*/
data class UpdateProcessData(val isRefresh: Boolean)
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.alfresco.content.browse.tasks.detail

import com.alfresco.content.actions.Action
import com.alfresco.content.browse.processes.list.UpdateProcessData
import com.alfresco.content.browse.tasks.list.UpdateTasksData
import com.alfresco.content.data.Entry
import com.alfresco.content.data.OfflineRepository
import com.alfresco.content.data.UserGroupDetails
import com.alfresco.content.process.ui.UpdateProcessData
import com.alfresco.events.EventBus
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ class ComponentSheet : BottomSheetDialogFragment(), MavericksView {
id(bucket.hashCode())
data(bucket)
clickListener { model, _, _, _ ->
onApply?.invoke("", "", mapOf())
dismiss()
}
}
Expand Down
69 changes: 30 additions & 39 deletions data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import com.alfresco.content.data.Settings.Companion.IS_PROCESS_ENABLED_KEY
import com.alfresco.content.data.payloads.CommentPayload
import com.alfresco.content.data.payloads.FieldType
import com.alfresco.content.data.payloads.FieldsData
import com.alfresco.content.data.payloads.LinkContentPayload
import com.alfresco.content.data.payloads.SystemPropertiesEntry
import com.alfresco.content.data.payloads.TaskProcessFiltersPayload
Expand All @@ -16,7 +18,6 @@ import com.alfresco.process.apis.ProcessAPI
import com.alfresco.process.apis.TaskAPI
import com.alfresco.process.models.AssignUserBody
import com.alfresco.process.models.CommonOptionModel
import com.alfresco.process.models.GroupInfo
import com.alfresco.process.models.ProfileData
import com.alfresco.process.models.RequestComment
import com.alfresco.process.models.RequestLinkContent
Expand All @@ -26,7 +27,6 @@ import com.alfresco.process.models.RequestProcessInstancesQuery
import com.alfresco.process.models.RequestSaveForm
import com.alfresco.process.models.RequestTaskFilters
import com.alfresco.process.models.TaskBodyCreate
import com.alfresco.process.models.UserInfo
import com.alfresco.process.models.ValuesModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -383,55 +383,46 @@ class TaskRepository {
/**
* Execute the start flow integration
*/
suspend fun startWorkflow(processEntry: ProcessEntry?, items: String) = ProcessEntry.with(
suspend fun startWorkflow(processEntry: ProcessEntry?, items: String, fields: List<FieldsData>) = ProcessEntry.with(
processesService.createProcessInstance(
RequestProcessInstances(
name = processEntry?.name,
processDefinitionId = processEntry?.id,
values = ValuesModel(
due = processEntry?.formattedDueDate,
message = processEntry?.description,
priority = if (processEntry?.priority != -1) {
CommonOptionModel(
id = getTaskPriority(processEntry?.priority ?: 0).name,
name = getTaskPriority(processEntry?.priority ?: 0).name,
)
} else {
null
},
reviewer = getUser(processEntry?.startedBy),
reviewGroups = getGroup(processEntry?.startedBy),
items = items,
sendEmailNotifications = false,
),
values = convertFieldsToValues(fields),
),
),
)

private fun getUser(userGroupInfo: UserGroupDetails?): UserInfo? {
return if (userGroupInfo?.isGroup == true) {
null
} else {
UserInfo(
id = userGroupInfo?.id,
firstName = userGroupInfo?.firstName,
lastName = userGroupInfo?.lastName,
email = userGroupInfo?.email,
)
private fun convertFieldsToValues(fields: List<FieldsData>): Map<String, Any?> {
val values = mutableMapOf<String, Any?>()

fields.forEach {
if (it.type == FieldType.PEOPLE.value() || it.type == FieldType.FUNCTIONAL_GROUP.value()) {
values[it.id] = getUserOrGroup(it.value as UserGroupDetails)
} else {
values[it.id] = it.value
}
}

return values
}

private fun getGroup(userGroupInfo: UserGroupDetails?): GroupInfo? {
return if (userGroupInfo?.isGroup == false) {
null
private fun getUserOrGroup(userGroupInfo: UserGroupDetails?): Map<String, Any?> {
return if (userGroupInfo?.isGroup == true) {
mapOf<String, Any?>(
"id" to userGroupInfo.id,
"name" to userGroupInfo.name,
"externalId" to userGroupInfo.externalId,
"status" to userGroupInfo.status,
"parentGroupId" to userGroupInfo.parentGroupId,
"groups" to userGroupInfo.groups,
)
} else {
GroupInfo(
id = userGroupInfo?.id,
name = userGroupInfo?.name,
externalId = userGroupInfo?.externalId,
status = userGroupInfo?.status,
parentGroupId = userGroupInfo?.parentGroupId,
groups = userGroupInfo?.groups,
mapOf<String, Any?>(
"id" to userGroupInfo?.id,
"firstName" to userGroupInfo?.firstName,
"lastName" to userGroupInfo?.lastName,
"email" to userGroupInfo?.email,
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ui-tooling = "1.5.4"
alfresco-auth = "com.alfresco.android:auth:0.8.1-SNAPSHOT"
alfresco-content = "com.alfresco.android:content:0.3.4-SNAPSHOT"
alfresco-contentKtx = "com.alfresco.android:content-ktx:0.3.2-SNAPSHOT"
alfresco-process = "com.alfresco.android:process:0.1.2-SNAPSHOT"
alfresco-process = "com.alfresco.android:process:0.1.3-SNAPSHOT"

android-desugar = "com.android.tools:desugar_jdk_libs:2.0.3"
android-gradle = "com.android.tools.build:gradle:8.0.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ data class FormViewState(
val formFields: List<FieldsData> = emptyList(),
val processOutcomes: List<OptionsModel> = emptyList(),
val enabledOutcomes: Boolean = false,
val requestStartWorkflow: Async<ProcessEntry> = Uninitialized,
) : MavericksState {
constructor(target: ProcessEntry) : this(parent = target)

Expand Down Expand Up @@ -85,6 +86,7 @@ class FormViewModel(

is Success -> {
copy(
parent = processEntry,
formFields = it().fields.flatMap { listData -> listData.fields },
processOutcomes = it().outcomes,
requestStartForm = Success(it()),
Expand Down Expand Up @@ -129,6 +131,19 @@ class FormViewModel(
setState { updatedState.copy(enabledOutcomes = hasAllRequiredData) }
}

fun startWorkflow() = withState { state ->
viewModelScope.launch {
repository::startWorkflow.asFlow(state.parent, "", state.formFields).execute {
when (it) {
is Loading -> copy(requestStartWorkflow = Loading())
is Fail -> copy(requestStartWorkflow = Fail(it.error))
is Success -> copy(requestStartWorkflow = Success(it()))
else -> this
}
}
}
}

private fun hasFieldRequiredData(state: FormViewState): Boolean {
return !state.formFields.filter { it.required }.any { it.value == null }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fun FormDetailScreen(state: FormViewState, viewModel: FormViewModel, outcomes: L
.fillMaxWidth()
.align(alignment = Alignment.CenterHorizontally),
) {
Outcomes(outcomes = outcomes, state.enabledOutcomes)
Outcomes(outcomes = outcomes, state.enabledOutcomes, viewModel)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.alfresco.content.process.ui

/**
* Mark as UpdateProcessData data class
*/
data class UpdateProcessData(val isRefresh: Boolean)
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import androidx.compose.ui.res.stringResource
import com.alfresco.content.component.ComponentBuilder
import com.alfresco.content.component.ComponentData
import com.alfresco.content.data.OptionsModel
import com.alfresco.content.process.FormViewModel
import com.alfresco.content.process.R

@Composable
fun FloatingActionButton(outcomes: List<OptionsModel>, enabledOutcomes: Boolean) {
fun FloatingActionButton(outcomes: List<OptionsModel>, enabledOutcomes: Boolean, viewModel: FormViewModel) {
val context = LocalContext.current

ExtendedFloatingActionButton(
Expand All @@ -28,6 +29,8 @@ fun FloatingActionButton(outcomes: List<OptionsModel>, enabledOutcomes: Boolean)
)
ComponentBuilder(context, componentData)
.onApply { name, query, _ ->

viewModel.startWorkflow()
}
.onReset { name, query, _ ->
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.alfresco.content.process.ui.components

import ComposeTopBar
import android.app.Activity
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.FabPosition
Expand All @@ -9,9 +10,11 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksActivityViewModel
import com.alfresco.content.data.OptionsModel
Expand All @@ -24,6 +27,12 @@ fun FormScreen(navController: NavController) {
// This will get or create a ViewModel scoped to the Activity.
val viewModel: FormViewModel = mavericksActivityViewModel()
val state by viewModel.collectAsState()
val context = LocalContext.current

if (state.requestStartWorkflow is Success) {
viewModel.updateProcessList()
(context as Activity).finish()
}

val customOutcomes = when {
state.formFields.isNotEmpty() && state.processOutcomes.isEmpty() -> {
Expand Down Expand Up @@ -62,7 +71,7 @@ fun FormScreen(navController: NavController) {
else -> {
Scaffold(
topBar = { ComposeTopBar() },
floatingActionButton = { FloatingActionButton(customOutcomes, state.enabledOutcomes) },
floatingActionButton = { FloatingActionButton(customOutcomes, state.enabledOutcomes, viewModel) },
floatingActionButtonPosition = FabPosition.End,
) { padding ->
val colorScheme = MaterialTheme.colorScheme
Expand All @@ -74,7 +83,7 @@ fun FormScreen(navController: NavController) {
color = colorScheme.background,
contentColor = colorScheme.onBackground,
) {
if (state.requestStartForm is Loading) {
if (state.requestStartForm is Loading || state.requestStartWorkflow is Loading) {
CustomLinearProgressIndicator(padding)
}
FormDetailScreen(state, viewModel, emptyList())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.alfresco.content.process.ui.components

import com.alfresco.content.process.FormViewModel
import com.alfresco.content.process.ui.UpdateProcessData
import com.alfresco.events.EventBus
import kotlinx.coroutines.launch

/**
* update the list of workflow if new entry created
*/
fun FormViewModel.updateProcessList() {
viewModelScope.launch {
EventBus.default.send(UpdateProcessData(isRefresh = true))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.alfresco.content.data.OptionsModel
import com.alfresco.content.process.FormViewModel

@Composable
fun Outcomes(outcomes: List<OptionsModel>, enabledOutcomes: Boolean) {
fun Outcomes(outcomes: List<OptionsModel>, enabledOutcomes: Boolean, viewModel: FormViewModel) {
outcomes.forEach {
Button(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 4.dp),
onClick = { },
onClick = {
viewModel.startWorkflow()
},
shape = RoundedCornerShape(6.dp),
enabled = enabledOutcomes,
colors = ButtonDefaults.buttonColors(
Expand Down
Loading