From a2db5e1ddc73b1cf3f99edde95ccf9dc810aa48f Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Mon, 12 Jun 2023 22:08:48 +0530 Subject: [PATCH 1/6] added outcome UI and api integration --- .../details/ProcessDetailExtension.kt | 9 +++---- .../browse/tasks/BaseDetailFragment.kt | 8 ++++++ .../tasks/detail/TaskDetailExtension.kt | 25 ++++++++++++++++++- .../browse/tasks/detail/TaskDetailFragment.kt | 24 ++++++------------ .../tasks/detail/TaskDetailViewModel.kt | 23 +++++++++++++++++ .../detail/TaskDetailViewModelExtension.kt | 2 ++ .../tasks/detail/TaskDetailViewState.kt | 3 ++- .../browse/tasks/list/TasksFragment.kt | 1 - .../main/res/layout/fragment_task_detail.xml | 10 ++++++++ .../main/res/layout/view_layout_outcomes.xml | 8 ++++++ browse/src/main/res/values/strings.xml | 2 +- .../com/alfresco/content/data/OptionsModel.kt | 12 +++++++++ .../alfresco/content/data/ResponseListForm.kt | 6 +++-- .../com/alfresco/content/data/TaskEntry.kt | 14 ++++++----- .../alfresco/content/data/TaskRepository.kt | 22 +++++++++++++--- 15 files changed, 131 insertions(+), 38 deletions(-) create mode 100644 browse/src/main/res/layout/view_layout_outcomes.xml diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt index b1568dcda..dbb9ea86b 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt @@ -24,11 +24,10 @@ import com.alfresco.content.getFormattedDate import com.alfresco.content.getLocalizedName import com.alfresco.content.parseDate import com.alfresco.content.setSafeOnClickListener -import com.google.android.material.snackbar.Snackbar +import kotlinx.coroutines.launch import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine -import kotlinx.coroutines.launch internal fun ProcessDetailFragment.showStartFormView() { binding.clStatus.isVisible = false @@ -107,11 +106,9 @@ internal fun ProcessDetailFragment.setListeners() { withState(viewModel) { state -> val entry = state.listContents.find { it.isUpload } if (state.parent?.startedBy == null) { - Snackbar.make( + showSnackar( binding.root, - getString(R.string.error_select_assignee), - Snackbar.LENGTH_SHORT - ).show() + getString(R.string.error_select_assignee)) } else if (entry != null) { confirmContentQueuePrompt() } else { diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt index f6573131d..b63e69b9b 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt @@ -2,6 +2,7 @@ package com.alfresco.content.browse.tasks import android.content.Intent import android.os.Bundle +import android.view.View import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import com.alfresco.content.REMOTE @@ -15,6 +16,7 @@ import com.alfresco.content.data.Entry import com.alfresco.content.data.EventName import com.alfresco.content.viewer.ViewerActivity import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import java.lang.ref.WeakReference /** @@ -83,6 +85,12 @@ abstract class BaseDetailFragment : Fragment(), DeleteContentListener { Intent(requireActivity(), LocalPreviewActivity::class.java) .putExtra(LocalPreviewActivity.KEY_ENTRY_OBJ, contentEntry) ) + + fun showSnackar(snackView: View, message: String) = Snackbar.make( + snackView, + message, + Snackbar.LENGTH_SHORT + ).show() } /** diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt index a0c7f81fd..351e0bf77 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt @@ -22,9 +22,10 @@ import com.alfresco.content.formatDate import com.alfresco.content.getFormattedDate import com.alfresco.content.parseDate import com.alfresco.content.setSafeOnClickListener +import com.google.android.material.button.MaterialButton +import kotlinx.coroutines.launch import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine -import kotlinx.coroutines.launch internal fun TaskDetailFragment.updateTaskDetailUI(isEdit: Boolean) = withState(viewModel) { state -> viewModel.hasTaskEditMode = isEdit @@ -92,6 +93,7 @@ internal fun TaskDetailFragment.setTaskDetailAfterResponse(dataObj: TaskEntry) = View.VISIBLE } else View.GONE } else { + makeOutcomes() binding.clCompleted.visibility = View.GONE (binding.clDueDate.layoutParams as ConstraintLayout.LayoutParams).apply { topMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics).toInt() @@ -230,3 +232,24 @@ internal fun TaskDetailFragment.showTitleDescriptionComponent() = withState(view ) } } + +internal fun TaskDetailFragment.makeOutcomes() = withState(viewModel) { state -> + if (binding.parentOutcomes.childCount == 0) + state.parent?.outcomes?.forEach { outcome -> + val button = this.layoutInflater.inflate(R.layout.view_layout_outcomes, binding.parentOutcomes, false) as MaterialButton + button.text = outcome.name + button.setOnClickListener { + withState(viewModel) { newState -> + if (viewModel.hasTaskStatusEnabled(newState) && (newState.parent?.taskFormStatus == + newState.parent?.statusOption?.find { option -> option.id == "empty" }?.name)) + showSnackar( + binding.root, + getString(R.string.error_select_status) + ) + else viewModel.actionOutcome((it as MaterialButton).text.toString()) + + } + } + binding.parentOutcomes.addView(button) + } +} diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt index 4ded978bf..f39cd5aae 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt @@ -1,7 +1,6 @@ package com.alfresco.content.browse.tasks.detail import android.content.Context -import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper @@ -26,8 +25,6 @@ import com.alfresco.content.actions.ActionOpenWith import com.alfresco.content.browse.R import com.alfresco.content.browse.databinding.FragmentTaskDetailBinding import com.alfresco.content.browse.databinding.ViewListCommentRowBinding -import com.alfresco.content.browse.preview.LocalPreviewActivity -import com.alfresco.content.browse.preview.LocalPreviewActivity.Companion.KEY_ENTRY_OBJ import com.alfresco.content.browse.tasks.BaseDetailFragment import com.alfresco.content.browse.tasks.TaskViewerActivity import com.alfresco.content.browse.tasks.attachments.listViewAttachmentRow @@ -51,13 +48,13 @@ import com.alfresco.content.mimetype.MimeType import com.alfresco.content.simpleController import com.alfresco.ui.getDrawableForAttribute import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import java.lang.ref.WeakReference import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext /** * Marked as TaskDetailFragment class @@ -177,7 +174,8 @@ class TaskDetailFragment : BaseDetailFragment(), MavericksView, EntryListener { (state.requestComments is Loading && state.listComments.isEmpty()) || (state.requestContents is Loading && state.listContents.isEmpty()) || (state.requestCompleteTask is Loading) || (state.requestUpdateTask is Loading) || - (state.requestDeleteContent is Loading) || (state.requestTaskForm is Loading) + (state.requestDeleteContent is Loading) || (state.requestTaskForm is Loading) || + (state.requestOutcomes is Loading) setData(state) @@ -186,7 +184,7 @@ class TaskDetailFragment : BaseDetailFragment(), MavericksView, EntryListener { binding.completeButton.visibility = if (viewModel.isCompleteButtonVisible(state)) View.VISIBLE else View.GONE when { - state.requestCompleteTask.invoke()?.code() == 200 -> { + (state.requestCompleteTask.invoke()?.code() == 200) || (state.requestOutcomes.invoke()?.code() == 200) -> { viewModel.updateTaskList() requireActivity().onBackPressed() } @@ -318,10 +316,7 @@ class TaskDetailFragment : BaseDetailFragment(), MavericksView, EntryListener { remoteViewerIntent(entry) else viewModel.executePreview(ActionOpenWith(entry)) - } else startActivity( - Intent(requireActivity(), LocalPreviewActivity::class.java) - .putExtra(KEY_ENTRY_OBJ, contentEntry) - ) + } else localViewerIntent(contentEntry) } internal fun taskCompletePrompt(filesInQueue: Boolean) { @@ -361,10 +356,7 @@ class TaskDetailFragment : BaseDetailFragment(), MavericksView, EntryListener { override fun onEntryCreated(entry: ParentEntry) { if (isAdded) - startActivity( - Intent(requireActivity(), LocalPreviewActivity::class.java) - .putExtra(KEY_ENTRY_OBJ, entry as Entry) - ) + localViewerIntent(entry as Entry) } internal suspend fun showComponentSheetDialog( diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt index e45ca316f..9832b1153 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt @@ -25,6 +25,7 @@ import com.alfresco.content.getFormattedDate import com.alfresco.content.listview.EntryListener import com.alfresco.coroutines.asFlow import com.alfresco.events.on +import com.alfresco.process.models.ValuesModel import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch @@ -415,6 +416,28 @@ class TaskDetailViewModel( } } + fun actionOutcome(outcome: String) = withState { state -> + requireNotNull(state.parent) + viewModelScope.launch { + repository::actionOutcomes.asFlow(outcome,state.parent).execute { + when (it) { + is Loading -> copy(requestOutcomes = Loading()) + is Fail -> { + copy(requestOutcomes = Fail(it.error)) + } + + is Success -> { + copy(requestOutcomes = Success(it())) + } + + else -> { + this + } + } + } + } + } + companion object : MavericksViewModelFactory { override fun create( diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt index 9cb7e4102..792853a96 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt @@ -1,6 +1,7 @@ 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 @@ -15,6 +16,7 @@ import kotlinx.coroutines.launch internal fun TaskDetailViewModel.updateTaskList() { viewModelScope.launch { EventBus.default.send(UpdateTasksData(isRefresh = true)) + EventBus.default.send(UpdateProcessData(isRefresh = true)) } } diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt index 9dd5398cc..0c2a19450 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt @@ -29,7 +29,8 @@ data class TaskDetailViewState( val requestAddComment: Async = Uninitialized, val requestCompleteTask: Async> = Uninitialized, val requestDeleteContent: Async> = Uninitialized, - val requestTaskForm: Async = Uninitialized + val requestTaskForm: Async = Uninitialized, + val requestOutcomes: Async> = Uninitialized ) : MavericksState { constructor(target: TaskEntry) : this(parent = target) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/list/TasksFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/list/TasksFragment.kt index 2b6a6d977..b30173aed 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/list/TasksFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/list/TasksFragment.kt @@ -191,7 +191,6 @@ class TasksFragment : TaskListFragment() { ) = continuation.resume(ComponentMetaData(name = name, query = query, queryMap = queryMap)) override fun onItemClicked(entry: TaskEntry) { - if (viewModel.isWorkflowTask) return startActivity( Intent(requireActivity(), TaskViewerActivity::class.java) .putExtra(Mavericks.KEY_ARG, entry) diff --git a/browse/src/main/res/layout/fragment_task_detail.xml b/browse/src/main/res/layout/fragment_task_detail.xml index eb1d5f92b..768cc55d3 100644 --- a/browse/src/main/res/layout/fragment_task_detail.xml +++ b/browse/src/main/res/layout/fragment_task_detail.xml @@ -820,4 +820,14 @@ android:text="@string/text_mark_as_complete" android:visibility="gone" /> + + diff --git a/browse/src/main/res/layout/view_layout_outcomes.xml b/browse/src/main/res/layout/view_layout_outcomes.xml new file mode 100644 index 000000000..6e87acf1b --- /dev/null +++ b/browse/src/main/res/layout/view_layout_outcomes.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/browse/src/main/res/values/strings.xml b/browse/src/main/res/values/strings.xml index ad59caad2..ac4895b16 100644 --- a/browse/src/main/res/values/strings.xml +++ b/browse/src/main/res/values/strings.xml @@ -115,7 +115,7 @@ Workflow Please select assignee Select assignee - Select status + Please select status Tasks icon diff --git a/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt b/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt index 630aae3ae..150914350 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt @@ -1,6 +1,7 @@ package com.alfresco.content.data import android.os.Parcelable +import com.alfresco.process.models.CommonOptionModel import com.alfresco.process.models.Options import kotlinx.parcelize.Parcelize @@ -28,5 +29,16 @@ data class OptionsModel( name = raw.name ?: "" ) } + + /** + * return the updated OptionsModel obj by using CommonOptionModel obj + * @param raw + */ + fun with(raw: CommonOptionModel): OptionsModel { + return OptionsModel( + id = raw.id ?: "", + name = raw.name ?: "" + ) + } } } diff --git a/data/src/main/kotlin/com/alfresco/content/data/ResponseListForm.kt b/data/src/main/kotlin/com/alfresco/content/data/ResponseListForm.kt index 311a7aa9c..451fae0ed 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/ResponseListForm.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/ResponseListForm.kt @@ -18,7 +18,8 @@ data class ResponseListForm( val taskId: String? = null, val taskName: String? = null, val taskDefinitionKey: String? = null, - val fields: List = emptyList() + val fields: List = emptyList(), + val outcomes: List = emptyList() ) : Parcelable { companion object { /** @@ -34,7 +35,8 @@ data class ResponseListForm( taskId = raw.taskId ?: "", taskName = raw.taskName ?: "", taskDefinitionKey = raw.taskDefinitionKey ?: "", - fields = raw.fields?.map { FieldsData.with(it) } ?: emptyList() + fields = raw.fields?.map { FieldsData.with(it) } ?: emptyList(), + outcomes = raw.outcomes?.map { OptionsModel.with(it) } ?: emptyList() ) } } diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt index 62badaeb1..70068f055 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt @@ -2,9 +2,9 @@ package com.alfresco.content.data import android.os.Parcelable import com.alfresco.process.models.TaskDataEntry -import java.time.ZonedDateTime import kotlinx.parcelize.Parcelize import org.json.JSONObject +import java.time.ZonedDateTime /** * Marked as TaskEntry class @@ -27,6 +27,7 @@ data class TaskEntry( val processInstanceId: String? = null, val statusOption: List = emptyList(), val listContents: List = emptyList(), + val outcomes: List = emptyList(), val comment: String? = null ) : ParentEntry(), Parcelable { @@ -61,7 +62,7 @@ data class TaskEntry( */ fun withTaskForm(response: ResponseListForm, parent: TaskEntry): TaskEntry { val formFields = response.fields.first().fields - var description = "" + var description: String? = null var comment: String? = null var taskDueDate: String? = null var priority = -1 @@ -72,7 +73,7 @@ data class TaskEntry( formFields.forEach { when (it.id.lowercase()) { TaskFields.MESSAGE.value() -> { - description = it.value as String + description = it.value as? String } TaskFields.PRIORITY.value() -> { @@ -95,9 +96,9 @@ data class TaskEntry( } TaskFields.ITEMS.value() -> { - listContents = (it.value as? List<*>)?.map { + listContents = (it.value as? List<*>)?.map { mapData -> gson.fromJson( - JSONObject(it as Map).toString(), + JSONObject(mapData as Map).toString(), Entry::class.java ) } ?: emptyList() @@ -119,7 +120,8 @@ data class TaskEntry( assignee = parent.assignee, endDate = parent.endDate, duration = parent.duration, - processInstanceId = parent.processInstanceId + processInstanceId = parent.processInstanceId, + outcomes = response.outcomes ) } diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt index 48873ee0e..809faab4f 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt @@ -12,24 +12,25 @@ import com.alfresco.content.session.SessionManager 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.PriorityModel import com.alfresco.process.models.ProfileData import com.alfresco.process.models.RequestComment import com.alfresco.process.models.RequestLinkContent +import com.alfresco.process.models.RequestOutcomes import com.alfresco.process.models.RequestProcessInstances import com.alfresco.process.models.RequestProcessInstancesQuery 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 java.io.File -import java.net.URL import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody +import java.io.File +import java.net.URL /** * Marked as TaskRepository class @@ -360,7 +361,7 @@ class TaskRepository(val session: Session = SessionManager.requireSession) { values = ValuesModel( due = processEntry?.formattedDueDate, message = processEntry?.description, - priority = if (processEntry?.priority != -1) PriorityModel( + priority = if (processEntry?.priority != -1) CommonOptionModel( id = getTaskPriority(processEntry?.priority ?: 0).name, name = getTaskPriority(processEntry?.priority ?: 0).name ) else null, @@ -417,6 +418,19 @@ class TaskRepository(val session: Session = SessionManager.requireSession) { * Call to fetch the task's form related to workflow */ suspend fun getTaskForm(taskID: String) = ResponseListForm.with(tasksService.taskForm(taskID)) + suspend fun actionOutcomes(outcome: String, taskEntry: TaskEntry) = tasksService.taskFormAction( + taskEntry.id, + RequestOutcomes( + outcome = outcome, + values = if (taskEntry.taskFormStatus != null) ValuesModel( + status = CommonOptionModel( + id = taskEntry.taskFormStatus, + name = taskEntry.taskFormStatus, + ), + comment = taskEntry.comment + ) else null + ) + ) companion object { const val KEY_PROCESS_USER_ID = "process_user_id" From 4c57ce8a5f989948dfa2f1f718d435747d71f199 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Tue, 13 Jun 2023 15:25:43 +0530 Subject: [PATCH 2/6] added save-form and outcome api integration --- .../details/ProcessDetailExtension.kt | 2 +- .../processes/status/TaskStatusFragment.kt | 15 +++++++--- .../tasks/detail/TaskDetailExtension.kt | 11 ++++---- .../tasks/detail/TaskDetailViewModel.kt | 28 +++++++++++++++++++ .../tasks/detail/TaskDetailViewState.kt | 3 +- .../main/res/layout/fragment_task_detail.xml | 2 +- .../main/res/layout/fragment_task_status.xml | 18 ++++++++++-- .../main/res/layout/view_layout_outcomes.xml | 6 ++-- browse/src/main/res/values-de/strings.xml | 4 +-- browse/src/main/res/values-es/strings.xml | 4 +-- browse/src/main/res/values-fr/strings.xml | 4 +-- browse/src/main/res/values-it/strings.xml | 4 +-- browse/src/main/res/values-nl/strings.xml | 4 +-- browse/src/main/res/values/strings.xml | 4 +-- .../com/alfresco/content/data/OptionsModel.kt | 6 ++++ .../alfresco/content/data/TaskRepository.kt | 21 ++++++++++++++ 16 files changed, 106 insertions(+), 30 deletions(-) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt index dbb9ea86b..7c92b2010 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt @@ -173,7 +173,7 @@ internal fun ProcessDetailFragment.setData(state: ProcessDetailViewState) { binding.tvDueDateTitle.text = getString(R.string.title_start_date) binding.tvAssignedTitle.text = getString(R.string.title_started_by) binding.tvDueDateValue.text = dataEntry?.started?.toLocalDate()?.toString()?.getFormattedDate(DATE_FORMAT_1, DATE_FORMAT_4) - binding.tvStatusValue.text = if (dataEntry?.ended != null) getString(R.string.status_completed) else getString(R.string.status_running) + binding.tvStatusValue.text = if (dataEntry?.ended != null) getString(R.string.status_completed) else getString(R.string.status_active) binding.tvTasksValue.text = if (state.listTask.isNotEmpty()) state.listTask.size.toString() else "0" } } diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt index 19ce1e9c7..016b74114 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt @@ -9,8 +9,10 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope +import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksView import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState @@ -105,10 +107,7 @@ class TaskStatusFragment : Fragment(), MavericksView { override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_save -> { - withState(viewModel) { state -> - viewModel.updateTaskStatusAndName(state.parent?.taskFormStatus, binding.commentInput.text.toString().trim()) - } - requireActivity().onBackPressed() + viewModel.saveForm() true } @@ -156,6 +155,14 @@ class TaskStatusFragment : Fragment(), MavericksView { } override fun invalidate() = withState(viewModel) { state -> + + binding.loading.isVisible = (state.requestSaveForm is Loading) + + if (state.requestSaveForm.invoke()?.code() == 200){ + viewModel.updateTaskStatusAndName(state.parent?.taskFormStatus, binding.commentInput.text.toString().trim()) + requireActivity().onBackPressed() + } + binding.tvStatus.text = state.parent?.taskFormStatus } } diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt index 351e0bf77..b8b09779d 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt @@ -20,6 +20,7 @@ import com.alfresco.content.component.DatePickerBuilder import com.alfresco.content.data.TaskEntry import com.alfresco.content.formatDate import com.alfresco.content.getFormattedDate +import com.alfresco.content.getLocalizedName import com.alfresco.content.parseDate import com.alfresco.content.setSafeOnClickListener import com.google.android.material.button.MaterialButton @@ -235,19 +236,19 @@ internal fun TaskDetailFragment.showTitleDescriptionComponent() = withState(view internal fun TaskDetailFragment.makeOutcomes() = withState(viewModel) { state -> if (binding.parentOutcomes.childCount == 0) - state.parent?.outcomes?.forEach { outcome -> + state.parent?.outcomes?.forEach { dataObj -> val button = this.layoutInflater.inflate(R.layout.view_layout_outcomes, binding.parentOutcomes, false) as MaterialButton - button.text = outcome.name + button.text = requireContext().getLocalizedName(dataObj.name) button.setOnClickListener { withState(viewModel) { newState -> if (viewModel.hasTaskStatusEnabled(newState) && (newState.parent?.taskFormStatus == - newState.parent?.statusOption?.find { option -> option.id == "empty" }?.name)) + newState.parent?.statusOption?.find { option -> option.id == "empty" }?.name) + ) showSnackar( binding.root, getString(R.string.error_select_status) ) - else viewModel.actionOutcome((it as MaterialButton).text.toString()) - + else viewModel.actionOutcome(dataObj.outcome) } } binding.parentOutcomes.addView(button) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt index 9832b1153..e4059944b 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt @@ -416,6 +416,9 @@ class TaskDetailViewModel( } } + /** + * execute the outcome api + */ fun actionOutcome(outcome: String) = withState { state -> requireNotNull(state.parent) viewModelScope.launch { @@ -438,6 +441,31 @@ class TaskDetailViewModel( } } + /** + * execute the save-form api + */ + fun saveForm() = withState { state -> + requireNotNull(state.parent) + viewModelScope.launch { + repository::saveForm.asFlow(state.parent).execute { + when (it) { + is Loading -> copy(requestSaveForm = Loading()) + is Fail -> { + copy(requestSaveForm = Fail(it.error)) + } + + is Success -> { + copy(requestSaveForm = Success(it())) + } + + else -> { + this + } + } + } + } + } + companion object : MavericksViewModelFactory { override fun create( diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt index 0c2a19450..7d311caf7 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewState.kt @@ -30,7 +30,8 @@ data class TaskDetailViewState( val requestCompleteTask: Async> = Uninitialized, val requestDeleteContent: Async> = Uninitialized, val requestTaskForm: Async = Uninitialized, - val requestOutcomes: Async> = Uninitialized + val requestOutcomes: Async> = Uninitialized, + val requestSaveForm: Async> = Uninitialized ) : MavericksState { constructor(target: TaskEntry) : this(parent = target) diff --git a/browse/src/main/res/layout/fragment_task_detail.xml b/browse/src/main/res/layout/fragment_task_detail.xml index 768cc55d3..0fcd0b020 100644 --- a/browse/src/main/res/layout/fragment_task_detail.xml +++ b/browse/src/main/res/layout/fragment_task_detail.xml @@ -827,7 +827,7 @@ android:layout_marginEnd="@dimen/list_layout_margin_button" android:layout_marginBottom="@dimen/list_layout_margin_button" android:layout_alignParentBottom="true" - android:orientation="vertical" + android:orientation="horizontal" android:layout_height="wrap_content"/> diff --git a/browse/src/main/res/layout/fragment_task_status.xml b/browse/src/main/res/layout/fragment_task_status.xml index 2098255ec..048f8e338 100644 --- a/browse/src/main/res/layout/fragment_task_status.xml +++ b/browse/src/main/res/layout/fragment_task_status.xml @@ -14,6 +14,19 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + - diff --git a/browse/src/main/res/layout/view_layout_outcomes.xml b/browse/src/main/res/layout/view_layout_outcomes.xml index 6e87acf1b..fba9f7c4e 100644 --- a/browse/src/main/res/layout/view_layout_outcomes.xml +++ b/browse/src/main/res/layout/view_layout_outcomes.xml @@ -2,7 +2,7 @@ \ No newline at end of file + android:layout_margin="4dp" + android:layout_weight="1" /> \ No newline at end of file diff --git a/browse/src/main/res/values-de/strings.xml b/browse/src/main/res/values-de/strings.xml index c6c41d1e6..0b2461fdb 100755 --- a/browse/src/main/res/values-de/strings.xml +++ b/browse/src/main/res/values-de/strings.xml @@ -104,8 +104,8 @@ Workflows werden hier angezeigt, wenn sie erstellt werden. Warnung Das Hochladen von Dateien ist in Bearbeitung. Tippen Sie auf Bestätigen, um ohne laufende Dateien fortzufahren. - Genehmigen - Ablehnen + Genehmigen + Ablehnen Erneut zur Genehmigung senden Genehmigungsanfrage stoppen Kommentar diff --git a/browse/src/main/res/values-es/strings.xml b/browse/src/main/res/values-es/strings.xml index bae7faa00..2efcd74a2 100755 --- a/browse/src/main/res/values-es/strings.xml +++ b/browse/src/main/res/values-es/strings.xml @@ -104,8 +104,8 @@ Los flujos de trabajo aparecerán aquí cuando sean creados Advertencia La carga de ficheros está en curso. Toque Confirmar para continuar sin los ficheros en curso. - Aprobar - Rechazar + Aprobar + Rechazar Enviar para aprobación otra vez Detener solicitud de aprobación Comentario diff --git a/browse/src/main/res/values-fr/strings.xml b/browse/src/main/res/values-fr/strings.xml index 8eca0c73f..7526a3893 100755 --- a/browse/src/main/res/values-fr/strings.xml +++ b/browse/src/main/res/values-fr/strings.xml @@ -104,8 +104,8 @@ Les workflows apparaîtront ici lorsqu\'ils seront créés. Avertissement Le téléchargement des fichiers est en cours. Tapez sur Confirmer pour continuer sans fichiers en cours. - Approuver - Rejeter + Approuver + Rejeter Envoyer à nouveau pour approbation Arrêter la demande d\'approbation Commentaire diff --git a/browse/src/main/res/values-it/strings.xml b/browse/src/main/res/values-it/strings.xml index 27d78a214..fe54a0fc5 100755 --- a/browse/src/main/res/values-it/strings.xml +++ b/browse/src/main/res/values-it/strings.xml @@ -104,8 +104,8 @@ Una volta creati, i workflow verrano visualizzati qui. Avviso Il caricamento dei file è in corso. Toccare su Conferma per continuare senza questi file. - Approva - Respingi + Approva + Respingi Invia di nuovo per approvazione Interrompi richiesta di approvazione Commento diff --git a/browse/src/main/res/values-nl/strings.xml b/browse/src/main/res/values-nl/strings.xml index 99816bec5..ef85d41e7 100755 --- a/browse/src/main/res/values-nl/strings.xml +++ b/browse/src/main/res/values-nl/strings.xml @@ -104,8 +104,8 @@ Wanneer workflows zijn gemaakt, worden deze hier weergegeven. Waarschuwing Er worden bestanden geüpload. Tik om te bevestigen dat u wilt doorgaan zonder de bestanden in uitvoering. - Goedkeuren - Afwijzen + Goedkeuren + Afwijzen Nogmaals verzenden voor goedkeuring Goedkeuringsaanvraag stoppen Opmerking diff --git a/browse/src/main/res/values/strings.xml b/browse/src/main/res/values/strings.xml index ac4895b16..9c5d36f34 100644 --- a/browse/src/main/res/values/strings.xml +++ b/browse/src/main/res/values/strings.xml @@ -104,8 +104,8 @@ Workflows will appear here when created. Warning Files uploading is in progress. Tap on Confirm to continue without in-progress files. - Approve - Reject + Approve + Reject Send for Approval Again Stop Approval Request Comment diff --git a/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt b/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt index 150914350..91a25527c 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt @@ -17,8 +17,14 @@ data class OptionsModel( val value: String = "", val default: Boolean = false ) : Parcelable { + + + val outcome: String + get() = name + companion object { + /** * return the updated OptionsModel obj by using Options obj * @param raw diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt index 809faab4f..8d2631fd6 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt @@ -20,6 +20,7 @@ import com.alfresco.process.models.RequestLinkContent import com.alfresco.process.models.RequestOutcomes import com.alfresco.process.models.RequestProcessInstances 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 @@ -418,6 +419,10 @@ class TaskRepository(val session: Session = SessionManager.requireSession) { * Call to fetch the task's form related to workflow */ suspend fun getTaskForm(taskID: String) = ResponseListForm.with(tasksService.taskForm(taskID)) + + /** + * Call to perform the outcomes + */ suspend fun actionOutcomes(outcome: String, taskEntry: TaskEntry) = tasksService.taskFormAction( taskEntry.id, RequestOutcomes( @@ -432,6 +437,22 @@ class TaskRepository(val session: Session = SessionManager.requireSession) { ) ) + /** + * Call to save the form data + */ + suspend fun saveForm(taskEntry: TaskEntry) = tasksService.saveForm( + taskEntry.id, + RequestSaveForm( + values = ValuesModel( + status = CommonOptionModel( + id = taskEntry.taskFormStatus, + name = taskEntry.taskFormStatus, + ), + comment = taskEntry.comment + ) + ) + ) + companion object { const val KEY_PROCESS_USER_ID = "process_user_id" const val KEY_PROCESS_USER_FULL_NAME = "process_user_full_name" From 3eb6707432850bced075be1da9d6dbc78fb01aae Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:00:24 +0530 Subject: [PATCH 3/6] added checks before selecting outcone --- .../browse/processes/details/ProcessDetailExtension.kt | 2 +- .../content/browse/processes/status/TaskStatusFragment.kt | 2 +- .../content/browse/tasks/detail/TaskDetailExtension.kt | 5 ++--- .../content/browse/tasks/detail/TaskDetailFragment.kt | 6 +++--- .../content/browse/tasks/detail/TaskDetailViewModel.kt | 5 ++--- .../browse/tasks/detail/TaskDetailViewModelExtension.kt | 2 ++ browse/src/main/res/layout/view_layout_outcomes.xml | 2 +- browse/src/main/res/values/strings.xml | 6 ++++++ .../kotlin/com/alfresco/content/common/TextViewExt.kt | 3 ++- common/src/main/res/values/strings.xml | 1 + .../com/alfresco/content/component/ComponentOptions.kt | 2 +- .../main/kotlin/com/alfresco/content/data/OptionsModel.kt | 2 -- .../main/kotlin/com/alfresco/content/data/TaskEntry.kt | 2 +- .../kotlin/com/alfresco/content/data/TaskRepository.kt | 8 ++++---- 14 files changed, 27 insertions(+), 21 deletions(-) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt index 7c92b2010..31cbcfe15 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailExtension.kt @@ -24,10 +24,10 @@ import com.alfresco.content.getFormattedDate import com.alfresco.content.getLocalizedName import com.alfresco.content.parseDate import com.alfresco.content.setSafeOnClickListener -import kotlinx.coroutines.launch import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +import kotlinx.coroutines.launch internal fun ProcessDetailFragment.showStartFormView() { binding.clStatus.isVisible = false diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt index 016b74114..563b72341 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt @@ -158,7 +158,7 @@ class TaskStatusFragment : Fragment(), MavericksView { binding.loading.isVisible = (state.requestSaveForm is Loading) - if (state.requestSaveForm.invoke()?.code() == 200){ + if (state.requestSaveForm.invoke()?.code() == 200) { viewModel.updateTaskStatusAndName(state.parent?.taskFormStatus, binding.commentInput.text.toString().trim()) requireActivity().onBackPressed() } diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt index b8b09779d..f0d8ac4c7 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt @@ -24,9 +24,9 @@ import com.alfresco.content.getLocalizedName import com.alfresco.content.parseDate import com.alfresco.content.setSafeOnClickListener import com.google.android.material.button.MaterialButton -import kotlinx.coroutines.launch import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +import kotlinx.coroutines.launch internal fun TaskDetailFragment.updateTaskDetailUI(isEdit: Boolean) = withState(viewModel) { state -> viewModel.hasTaskEditMode = isEdit @@ -241,8 +241,7 @@ internal fun TaskDetailFragment.makeOutcomes() = withState(viewModel) { state -> button.text = requireContext().getLocalizedName(dataObj.name) button.setOnClickListener { withState(viewModel) { newState -> - if (viewModel.hasTaskStatusEnabled(newState) && (newState.parent?.taskFormStatus == - newState.parent?.statusOption?.find { option -> option.id == "empty" }?.name) + if (viewModel.hasTaskStatusEnabled(newState) && !viewModel.hasTaskStatusValue(newState) ) showSnackar( binding.root, diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt index f39cd5aae..0c9abcf18 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt @@ -48,13 +48,13 @@ import com.alfresco.content.mimetype.MimeType import com.alfresco.content.simpleController import com.alfresco.ui.getDrawableForAttribute import com.google.android.material.dialog.MaterialAlertDialogBuilder -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import java.lang.ref.WeakReference import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext /** * Marked as TaskDetailFragment class diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt index e4059944b..def977277 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModel.kt @@ -25,7 +25,6 @@ import com.alfresco.content.getFormattedDate import com.alfresco.content.listview.EntryListener import com.alfresco.coroutines.asFlow import com.alfresco.events.on -import com.alfresco.process.models.ValuesModel import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch @@ -422,7 +421,7 @@ class TaskDetailViewModel( fun actionOutcome(outcome: String) = withState { state -> requireNotNull(state.parent) viewModelScope.launch { - repository::actionOutcomes.asFlow(outcome,state.parent).execute { + repository::actionOutcomes.asFlow(outcome, state.parent).execute { when (it) { is Loading -> copy(requestOutcomes = Loading()) is Fail -> { @@ -444,7 +443,7 @@ class TaskDetailViewModel( /** * execute the save-form api */ - fun saveForm() = withState { state -> + fun saveForm() = withState { state -> requireNotNull(state.parent) viewModelScope.launch { repository::saveForm.asFlow(state.parent).execute { diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt index 792853a96..9ad9215e0 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt @@ -51,6 +51,8 @@ fun TaskDetailViewModel.isCompleteButtonVisible(state: TaskDetailViewState): Boo return state.parent?.assignee?.id == repository.getAPSUser().id } +fun TaskDetailViewModel.hasTaskStatusValue(state: TaskDetailViewState) = state.parent?.taskFormStatus != state.parent?.statusOption?.find { option -> option.id == "empty" }?.name + /** * return true if uploading files are in queue otherwise false */ diff --git a/browse/src/main/res/layout/view_layout_outcomes.xml b/browse/src/main/res/layout/view_layout_outcomes.xml index fba9f7c4e..74fcf8060 100644 --- a/browse/src/main/res/layout/view_layout_outcomes.xml +++ b/browse/src/main/res/layout/view_layout_outcomes.xml @@ -5,4 +5,4 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="4dp" - android:layout_weight="1" /> \ No newline at end of file + android:layout_weight="1" /> diff --git a/browse/src/main/res/values/strings.xml b/browse/src/main/res/values/strings.xml index 9c5d36f34..cf040bced 100644 --- a/browse/src/main/res/values/strings.xml +++ b/browse/src/main/res/values/strings.xml @@ -117,6 +117,12 @@ Select assignee Please select status Tasks icon + Choose one… + Not Yet Started + In Progress + On Hold + Cancelled + Completed diff --git a/common/src/main/kotlin/com/alfresco/content/common/TextViewExt.kt b/common/src/main/kotlin/com/alfresco/content/common/TextViewExt.kt index acbedccf2..c12a39008 100644 --- a/common/src/main/kotlin/com/alfresco/content/common/TextViewExt.kt +++ b/common/src/main/kotlin/com/alfresco/content/common/TextViewExt.kt @@ -40,8 +40,9 @@ fun TextView.updatePriorityView(priority: Int) { } TaskPriority.RESET -> { + text = context.getString(R.string.none) + setPadding(0, 0, 0, 0) setTextColor(ContextCompat.getColor(context, R.color.colorGray1)) - background = ContextCompat.getDrawable(context, R.drawable.bg_priority_reset) } else -> text = context.getString(R.string.priority_none) diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 43ecc327a..50ab5c925 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -26,4 +26,5 @@ Individual Group The upload is currently in progress. Do you want to continue without uploading? + None diff --git a/component/src/main/java/com/alfresco/content/component/ComponentOptions.kt b/component/src/main/java/com/alfresco/content/component/ComponentOptions.kt index 9d479e2a3..1d6d0759a 100644 --- a/component/src/main/java/com/alfresco/content/component/ComponentOptions.kt +++ b/component/src/main/java/com/alfresco/content/component/ComponentOptions.kt @@ -38,7 +38,7 @@ data class ComponentOptions( */ fun withTaskStatus(optionsModel: OptionsModel): ComponentOptions { return ComponentOptions( - label = optionsModel.name, + label = optionsModel.name.replace(" ", "_"), query = optionsModel.id, default = optionsModel.default ) diff --git a/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt b/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt index 91a25527c..0739978e7 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/OptionsModel.kt @@ -18,13 +18,11 @@ data class OptionsModel( val default: Boolean = false ) : Parcelable { - val outcome: String get() = name companion object { - /** * return the updated OptionsModel obj by using Options obj * @param raw diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt index 70068f055..ee479cc6e 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt @@ -2,9 +2,9 @@ package com.alfresco.content.data import android.os.Parcelable import com.alfresco.process.models.TaskDataEntry +import java.time.ZonedDateTime import kotlinx.parcelize.Parcelize import org.json.JSONObject -import java.time.ZonedDateTime /** * Marked as TaskEntry class diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt index 8d2631fd6..582aa1924 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskRepository.kt @@ -25,13 +25,13 @@ 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 java.io.File +import java.net.URL import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import java.io.File -import java.net.URL /** * Marked as TaskRepository class @@ -430,7 +430,7 @@ class TaskRepository(val session: Session = SessionManager.requireSession) { values = if (taskEntry.taskFormStatus != null) ValuesModel( status = CommonOptionModel( id = taskEntry.taskFormStatus, - name = taskEntry.taskFormStatus, + name = taskEntry.taskFormStatus ), comment = taskEntry.comment ) else null @@ -446,7 +446,7 @@ class TaskRepository(val session: Session = SessionManager.requireSession) { values = ValuesModel( status = CommonOptionModel( id = taskEntry.taskFormStatus, - name = taskEntry.taskFormStatus, + name = taskEntry.taskFormStatus ), comment = taskEntry.comment ) From cd070dc87ce320c9044ee546446bb088b18324fd Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Tue, 13 Jun 2023 18:43:00 +0530 Subject: [PATCH 4/6] codacy correction --- .../content/browse/processes/status/TaskStatusFragment.kt | 2 +- .../com/alfresco/content/browse/tasks/BaseDetailFragment.kt | 3 +++ .../content/browse/tasks/detail/TaskDetailExtension.kt | 6 +++++- .../content/browse/tasks/detail/TaskDetailFragment.kt | 2 +- .../browse/tasks/detail/TaskDetailViewModelExtension.kt | 3 +++ .../kotlin/com/alfresco/content/data/AnalyticsRepository.kt | 3 ++- 6 files changed, 15 insertions(+), 4 deletions(-) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt index 563b72341..924cdd44a 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/status/TaskStatusFragment.kt @@ -62,7 +62,7 @@ class TaskStatusFragment : Fragment(), MavericksView { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - AnalyticsManager().screenViewEvent(PageView.TaskStatusView) + AnalyticsManager().screenViewEvent(PageView.WorkflowTaskStatusView) var instanceActivity: AppCompatActivity? = null when (requireActivity()) { diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt index b63e69b9b..a5e2a8f65 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/BaseDetailFragment.kt @@ -86,6 +86,9 @@ abstract class BaseDetailFragment : Fragment(), DeleteContentListener { .putExtra(LocalPreviewActivity.KEY_ENTRY_OBJ, contentEntry) ) + /** + * showing Snackbar + */ fun showSnackar(snackView: View, message: String) = Snackbar.make( snackView, message, diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt index f0d8ac4c7..8c5505275 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailExtension.kt @@ -17,6 +17,7 @@ import com.alfresco.content.common.updatePriorityView import com.alfresco.content.component.ComponentData import com.alfresco.content.component.ComponentType import com.alfresco.content.component.DatePickerBuilder +import com.alfresco.content.data.AnalyticsManager import com.alfresco.content.data.TaskEntry import com.alfresco.content.formatDate import com.alfresco.content.getFormattedDate @@ -247,7 +248,10 @@ internal fun TaskDetailFragment.makeOutcomes() = withState(viewModel) { state -> binding.root, getString(R.string.error_select_status) ) - else viewModel.actionOutcome(dataObj.outcome) + else { + AnalyticsManager().taskFiltersEvent(dataObj.outcome) + viewModel.actionOutcome(dataObj.outcome) + } } } binding.parentOutcomes.addView(button) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt index 0c9abcf18..1f1d45801 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt @@ -86,7 +86,7 @@ class TaskDetailFragment : BaseDetailFragment(), MavericksView, EntryListener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - AnalyticsManager().screenViewEvent(PageView.TaskView) + AnalyticsManager().screenViewEvent(if (viewModel.isWorkflowTask) PageView.WorkflowTaskView else PageView.TaskView) (requireActivity() as TaskViewerActivity).setSupportActionBar(binding.toolbar) withState(viewModel) { state -> if (!viewModel.isWorkflowTask && !viewModel.isTaskCompleted(state)) { diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt index 9ad9215e0..7a88ce00c 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailViewModelExtension.kt @@ -51,6 +51,9 @@ fun TaskDetailViewModel.isCompleteButtonVisible(state: TaskDetailViewState): Boo return state.parent?.assignee?.id == repository.getAPSUser().id } +/** + * returns true if taskFormStatus has value otherwise false + */ fun TaskDetailViewModel.hasTaskStatusValue(state: TaskDetailViewState) = state.parent?.taskFormStatus != state.parent?.statusOption?.find { option -> option.id == "empty" }?.name /** diff --git a/data/src/main/kotlin/com/alfresco/content/data/AnalyticsRepository.kt b/data/src/main/kotlin/com/alfresco/content/data/AnalyticsRepository.kt index 800176740..ae899da64 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/AnalyticsRepository.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/AnalyticsRepository.kt @@ -139,7 +139,8 @@ enum class PageView(val value: String) { AttachedFiles("page_view_attached_files"), Workflows("page_view_workflows"), WorkflowView("page_view_workflow_view"), - TaskStatusView("page_view_task_status"), + WorkflowTaskView("page_view_workflow_task_view"), + WorkflowTaskStatusView("page_view_workflow_task_status"), None("none") } From 0f605ce5e7e15d3cae025ea02238e39235fbd655 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:55:55 +0530 Subject: [PATCH 5/6] fixed delete icon issue --- .../tasks/attachments/ListViewAttachmentRow.kt | 10 +--------- .../browse/tasks/detail/TaskDetailFragment.kt | 1 - data/objectbox-models/default.json | 7 ++++++- .../kotlin/com/alfresco/content/data/Entry.kt | 16 +++++++++++++++- .../com/alfresco/content/data/TaskEntry.kt | 5 +++-- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/attachments/ListViewAttachmentRow.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/attachments/ListViewAttachmentRow.kt index e7517b3ce..eb07af466 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/attachments/ListViewAttachmentRow.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/attachments/ListViewAttachmentRow.kt @@ -87,7 +87,7 @@ class ListViewAttachmentRow @JvmOverloads constructor( private fun actionButtonVisibility(entry: Entry) = !entry.isLink && !entry.isUpload && // Child folder in offline tab - !(entry.isFolder && entry.hasOfflineStatus && !entry.isOffline) + !(entry.isFolder && entry.hasOfflineStatus && !entry.isOffline) && !entry.isReadOnly /** * list row click listener @@ -97,14 +97,6 @@ class ListViewAttachmentRow @JvmOverloads constructor( setOnClickListener(listener) } - /** - * It will hide the delete button if it's workflow task. - */ - @ModelProp - fun setDeleteButtonVisibility(hasDeleteOption: Boolean) { - binding.deleteContentButton.isVisible = hasDeleteOption - } - /** * delete icon click listener */ diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt index 1f1d45801..d8038809b 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/tasks/detail/TaskDetailFragment.kt @@ -282,7 +282,6 @@ class TaskDetailFragment : BaseDetailFragment(), MavericksView, EntryListener { listViewAttachmentRow { id(stableId(obj)) data(obj) - deleteButtonVisibility(!viewModel.isWorkflowTask) clickListener { model, _, _, _ -> onItemClicked(model.data()) } deleteContentClickListener { model, _, _, _ -> deleteContentPrompt(model.data()) } } diff --git a/data/objectbox-models/default.json b/data/objectbox-models/default.json index 0ee140335..16f1c25a2 100644 --- a/data/objectbox-models/default.json +++ b/data/objectbox-models/default.json @@ -5,7 +5,7 @@ "entities": [ { "id": "1:3882697123829827748", - "lastPropertyId": "28:949912739494302928", + "lastPropertyId": "29:1086618494346593047", "name": "Entry", "properties": [ { @@ -138,6 +138,11 @@ "id": "27:4514687495334138822", "name": "uploadServer", "type": 9 + }, + { + "id": "29:1086618494346593047", + "name": "isReadOnly", + "type": 1 } ], "relations": [] diff --git a/data/src/main/kotlin/com/alfresco/content/data/Entry.kt b/data/src/main/kotlin/com/alfresco/content/data/Entry.kt index c79863aba..5b02d7e05 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/Entry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/Entry.kt @@ -87,7 +87,8 @@ data class Entry( val previewStatus: String? = "", val thumbnailStatus: String? = "", @Convert(converter = BoxUploadServerTypeConverter::class, dbType = String::class) - val uploadServer: UploadServerType = UploadServerType.DEFAULT + val uploadServer: UploadServerType = UploadServerType.DEFAULT, + val isReadOnly : Boolean = false ) : ParentEntry(), Parcelable { val isSynced: Boolean @@ -467,6 +468,19 @@ data class Entry( return map } + + fun withTaskForm(entry: Entry):Entry { + return Entry( + id = entry.id, + name = entry.name, + created = entry.created, + mimeType = entry.mimeType, + simpleType = entry.simpleType, + previewStatus = entry.previewStatus, + thumbnailStatus = entry.thumbnailStatus, + isReadOnly = true + ) + } } } diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt index ee479cc6e..82b11348e 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt @@ -2,9 +2,9 @@ package com.alfresco.content.data import android.os.Parcelable import com.alfresco.process.models.TaskDataEntry -import java.time.ZonedDateTime import kotlinx.parcelize.Parcelize import org.json.JSONObject +import java.time.ZonedDateTime /** * Marked as TaskEntry class @@ -114,7 +114,7 @@ data class TaskEntry( priority = priority, taskFormStatus = taskFormStatus, statusOption = listOptions, - listContents = listContents, + listContents = listContents.map { Entry.withTaskForm(it) }, formattedDueDate = taskDueDate, comment = comment, assignee = parent.assignee, @@ -262,6 +262,7 @@ enum class TaskFields { PRIORITY, DUEDATE, STATUS, + TYPE, COMMENT; /** From 88afecc8f84da9542f6743861f510dc4764b5583 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:58:22 +0530 Subject: [PATCH 6/6] codacy correction --- data/src/main/kotlin/com/alfresco/content/data/Entry.kt | 7 +++++-- .../src/main/kotlin/com/alfresco/content/data/TaskEntry.kt | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/data/src/main/kotlin/com/alfresco/content/data/Entry.kt b/data/src/main/kotlin/com/alfresco/content/data/Entry.kt index 5b02d7e05..b637ebbb0 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/Entry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/Entry.kt @@ -88,7 +88,7 @@ data class Entry( val thumbnailStatus: String? = "", @Convert(converter = BoxUploadServerTypeConverter::class, dbType = String::class) val uploadServer: UploadServerType = UploadServerType.DEFAULT, - val isReadOnly : Boolean = false + val isReadOnly: Boolean = false ) : ParentEntry(), Parcelable { val isSynced: Boolean @@ -469,7 +469,10 @@ data class Entry( return map } - fun withTaskForm(entry: Entry):Entry { + /** + * update existing entry with readOnly value. + */ + fun withTaskForm(entry: Entry): Entry { return Entry( id = entry.id, name = entry.name, diff --git a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt index 82b11348e..5477d8590 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt @@ -2,9 +2,9 @@ package com.alfresco.content.data import android.os.Parcelable import com.alfresco.process.models.TaskDataEntry +import java.time.ZonedDateTime import kotlinx.parcelize.Parcelize import org.json.JSONObject -import java.time.ZonedDateTime /** * Marked as TaskEntry class