From a9f4455aa6aa6079d0956076bc5029c9232e9cf3 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Thu, 9 May 2024 12:45:35 +0530 Subject: [PATCH 1/5] added view for large text --- .../ui/composeviews/FormScrollContent.kt | 17 +----- .../process/ui/utils/actionsReadOnlyField.kt | 58 +++++++++++++++++++ 2 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/composeviews/FormScrollContent.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/composeviews/FormScrollContent.kt index a7a88e3e..cf7e2af9 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/composeviews/FormScrollContent.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/composeviews/FormScrollContent.kt @@ -31,6 +31,7 @@ import com.alfresco.content.process.ui.components.ReadOnlyField import com.alfresco.content.process.ui.components.SingleLineInputField import com.alfresco.content.process.ui.fragments.FormViewModel import com.alfresco.content.process.ui.fragments.FormViewState +import com.alfresco.content.process.ui.utils.actionsReadOnlyField import com.alfresco.content.process.ui.utils.amountInputError import com.alfresco.content.process.ui.utils.booleanInputError import com.alfresco.content.process.ui.utils.dateTimeInputError @@ -183,21 +184,7 @@ fun FormScrollContent(field: FieldsData, viewModel: FormViewModel, state: FormVi viewModel = viewModel, fieldsData = field, onUserTap = { - if (it && field.value is List<*> && (field.value as List<*>).isNotEmpty()) { - val bundle = Bundle().apply { - putParcelable( - Mavericks.KEY_ARG, - UploadData( - field = field, - process = state.parent, - ), - ) - } - navController.navigate( - R.id.action_nav_process_form_to_nav_attach_files, - bundle, - ) - } + actionsReadOnlyField(it, field, navController, state, context) }, ) } diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt new file mode 100644 index 00000000..234b4dc9 --- /dev/null +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt @@ -0,0 +1,58 @@ +package com.alfresco.content.process.ui.utils + +import android.content.Context +import android.os.Bundle +import androidx.navigation.NavController +import com.airbnb.mvrx.Mavericks +import com.alfresco.content.component.ComponentBuilder +import com.alfresco.content.component.ComponentData +import com.alfresco.content.component.ComponentType +import com.alfresco.content.data.payloads.FieldType +import com.alfresco.content.data.payloads.FieldsData +import com.alfresco.content.data.payloads.UploadData +import com.alfresco.content.process.R +import com.alfresco.content.process.ui.fragments.FormViewState + +fun actionsReadOnlyField( + isTapped: Boolean, field: FieldsData, navController: NavController, + state: FormViewState, context: Context +) { + when (field.params?.field?.type?.lowercase()) { + FieldType.UPLOAD.value() -> { + if (isTapped && field.value is List<*> && (field.value as List<*>).isNotEmpty()) { + val bundle = Bundle().apply { + putParcelable( + Mavericks.KEY_ARG, + UploadData( + field = field, + process = state.parent, + ), + ) + } + navController.navigate( + R.id.action_nav_process_form_to_nav_attach_files, + bundle, + ) + } + } + + FieldType.TEXT.value(), FieldType.MULTI_LINE_TEXT.value() -> { + ComponentBuilder( + context, + ComponentData( + name = field.name, + query = "", + value = field.value as? String ?: "", + selector = ComponentType.VIEW_TEXT.value, + ), + ) + .onApply { name, query, _ -> + } + .onReset { name, query, _ -> + } + .onCancel { + } + .show() + } + } +} \ No newline at end of file From c7df266336f0f5e53294913f7e8dc53917ebc477 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Thu, 9 May 2024 14:08:20 +0530 Subject: [PATCH 2/5] upadte date format --- .../kotlin/com/alfresco/content/ZoneDateTimeExt.kt | 2 +- .../com/alfresco/content/data/payloads/FieldsData.kt | 10 ++++++++++ .../content/process/ui/components/DateTimeField.kt | 11 +++++------ .../content/process/ui/fragments/FormViewModel.kt | 6 ++++-- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/common/src/main/kotlin/com/alfresco/content/ZoneDateTimeExt.kt b/common/src/main/kotlin/com/alfresco/content/ZoneDateTimeExt.kt index 5c4b094d..c3591cce 100644 --- a/common/src/main/kotlin/com/alfresco/content/ZoneDateTimeExt.kt +++ b/common/src/main/kotlin/com/alfresco/content/ZoneDateTimeExt.kt @@ -12,7 +12,7 @@ const val DATE_FORMAT_3 = "yyyy-MM-dd'T'hh:mm:ss.SSSZ" const val DATE_FORMAT_3_1 = "yyyy-MM-dd'T'hh:mm:ssZ" const val DATE_FORMAT_4 = "dd MMM yyyy" const val DATE_FORMAT_4_1 = "dd MMM yyyy hh:mm a" -const val DATE_FORMAT_5 = "yyyy-MM-dd'T'HH:mm:ss'Z'" +const val DATE_FORMAT_5 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" const val DATE_FORMAT_6 = "yyyy-MM-dd'T'HH:mm:ss" const val DATE_FORMAT_7 = "dd MMM,yyyy hh:mm:ss a" const val DATE_FORMAT_8 = "dd-MM-yyyy hh:mm:ss a" diff --git a/data/src/main/kotlin/com/alfresco/content/data/payloads/FieldsData.kt b/data/src/main/kotlin/com/alfresco/content/data/payloads/FieldsData.kt index 261e8f05..fcd9cbc5 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/payloads/FieldsData.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/payloads/FieldsData.kt @@ -73,6 +73,16 @@ data class FieldsData( return userGroupDetails } + fun getDate(serverFormat: String, localFormat: String): Pair { + val dateTime = value as? String ?: "" + + if (dateTime.isNotEmpty() && dateTime.contains("T")) { + return Pair(dateTime.split("T").firstOrNull() ?: "", serverFormat) + } + + return Pair(dateTime, localFormat) + } + companion object { /** * returns the FieldsData obj by using Fields obj diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt index 5460ef66..4a9f4708 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt @@ -37,13 +37,12 @@ fun DateTimeField( when (fieldsData.type.lowercase()) { FieldType.DATE.value() -> { - if (dateTime.isNotEmpty() && dateTime.contains("T")) { - val date = dateTime.split("T").firstOrNull() ?: "" - if (date.isNotEmpty()) { - val dateFormat = updateDateFormat(fieldsData.params?.field?.dateDisplayFormat) ?: DATE_FORMAT_2_1 - dateTime = date.getLocalFormattedDate(DATE_FORMAT_1, dateFormat) - } + val date = fieldsData.getDate(DATE_FORMAT_1, DATE_FORMAT_2_1) + if (date.first.isNotEmpty()) { + val dateFormat = updateDateFormat(fieldsData.params?.field?.dateDisplayFormat) ?: DATE_FORMAT_2_1 + dateTime = date.first.getLocalFormattedDate(date.second, dateFormat) } + } } diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt index 65689678..fef9b967 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt @@ -9,6 +9,7 @@ import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext +import com.alfresco.content.DATE_FORMAT_1 import com.alfresco.content.DATE_FORMAT_2_1 import com.alfresco.content.DATE_FORMAT_4_1 import com.alfresco.content.DATE_FORMAT_5 @@ -495,7 +496,7 @@ class FormViewModel( FieldType.PEOPLE.value(), FieldType.FUNCTIONAL_GROUP.value() -> { when { field.value != null -> { - values[field.id] = convertModelToMapValues(field.value as? UserGroupDetails) + values[field.id] = convertModelToMapValues(field.getUserGroupDetails(getAPSUser())) } else -> { @@ -510,7 +511,8 @@ class FormViewModel( } FieldType.DATE.value() -> { - val convertedDate = (field.value as? String)?.getFormattedDate(DATE_FORMAT_2_1, DATE_FORMAT_5) + val date = field.getDate(DATE_FORMAT_1, DATE_FORMAT_2_1) + val convertedDate = date.first.getFormattedDate(date.second, DATE_FORMAT_5) values[field.id] = convertedDate } From 9ee018e31d58ca80e783340f968a2a9481eeb10e Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Thu, 9 May 2024 16:04:15 +0530 Subject: [PATCH 3/5] added message if selected content is not uploaded --- .../process/ui/fragments/FormViewModel.kt | 2 +- .../process/ui/fragments/ProcessFragment.kt | 20 ++++++++++++------- process-app/src/main/res/values/strings.xml | 1 + 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt index fef9b967..2b4afddc 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/FormViewModel.kt @@ -512,7 +512,7 @@ class FormViewModel( FieldType.DATE.value() -> { val date = field.getDate(DATE_FORMAT_1, DATE_FORMAT_2_1) - val convertedDate = date.first.getFormattedDate(date.second, DATE_FORMAT_5) + val convertedDate = date.first.takeIf { it.isNotEmpty() }?.getFormattedDate(date.second, DATE_FORMAT_5) ?: "" values[field.id] = convertedDate } diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt index d66b2eac..0a4c12b9 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt @@ -48,14 +48,20 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { private var menu: Menu? = null private var isExecuted = false private var confirmContentQueueDialog = WeakReference(null) + private var oldSnackbar: Snackbar? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) } - fun showSnackBar(message: String) { - Snackbar.make(binding.root, message, Snackbar.LENGTH_SHORT).show() + private fun showSnackBar(message: String) { + val snackbar = Snackbar.make(binding.flComposeParent, message, Snackbar.LENGTH_SHORT) + if (oldSnackbar == null || oldSnackbar?.isShownOrQueued == false) { + oldSnackbar?.dismiss() + snackbar.show() + oldSnackbar = snackbar + } } override fun onCreateView( @@ -153,12 +159,12 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { override fun invalidate() = withState(viewModel) { state -> binding.loading.isVisible = state.requestForm is Loading || state.requestStartWorkflow is Loading || - state.requestSaveForm is Loading || state.requestOutcomes is Loading || state.requestProfile is Loading || - state.requestAccountInfo is Loading || state.requestContent is Loading + state.requestSaveForm is Loading || state.requestOutcomes is Loading || state.requestProfile is Loading || + state.requestAccountInfo is Loading || state.requestContent is Loading when { state.requestStartWorkflow is Success || state.requestSaveForm is Success || - state.requestOutcomes is Success || state.requestClaimRelease is Success -> { + state.requestOutcomes is Success || state.requestClaimRelease is Success -> { viewModel.updateProcessList() requireActivity().finish() } @@ -169,6 +175,8 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { if (hasUploadField && state.parent.defaultEntries.isNotEmpty()) { viewModel.fetchUserProfile() viewModel.fetchAccountInfo() + } else { + showSnackBar(getString(R.string.error_no_upload_fields)) } if (hasUploadField) { @@ -218,8 +226,6 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { override fun onAttachFiles(field: FieldsData) = withState(viewModel) { state -> if (isAdded && field.type == FieldType.UPLOAD.value()) { -// val serverUploads = field.getContentList().filter { it.uploadServer == UploadServerType.UPLOAD_TO_PROCESS } -// .filterNot { item -> deletedFiles.any { it.value.id == item.id } } val listContents = mergeInUploads(field.getContentList(state.parent.processDefinitionId), viewModel.getContents(state, field.id)) val isError = field.required && listContents.isEmpty() diff --git a/process-app/src/main/res/values/strings.xml b/process-app/src/main/res/values/strings.xml index 9423848a..c49a69d8 100644 --- a/process-app/src/main/res/values/strings.xml +++ b/process-app/src/main/res/values/strings.xml @@ -16,4 +16,5 @@ Looks like you haven’t\nadded any files yet. Search Folder %1$s has Invalid URL + Not able to attach the selected content in this form. From 51aafbbe2a4af72cfb5c477e42f7e8f07a5daef7 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Thu, 9 May 2024 17:07:46 +0530 Subject: [PATCH 4/5] fixed crash related to the test app --- .../data/payloads/ConvertDataToMapValues.kt | 3 +++ .../process/ui/components/DateTimeField.kt | 1 - .../process/ui/fragments/ProcessFragment.kt | 19 ++++++++++--------- ...adOnlyField.kt => ActionsReadOnlyField.kt} | 9 ++++++--- 4 files changed, 19 insertions(+), 13 deletions(-) rename process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/{actionsReadOnlyField.kt => ActionsReadOnlyField.kt} (93%) diff --git a/data/src/main/kotlin/com/alfresco/content/data/payloads/ConvertDataToMapValues.kt b/data/src/main/kotlin/com/alfresco/content/data/payloads/ConvertDataToMapValues.kt index e574920b..e85ac1d7 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/payloads/ConvertDataToMapValues.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/payloads/ConvertDataToMapValues.kt @@ -23,6 +23,9 @@ fun convertModelToMapValues(data: UserGroupDetails?) = } fun convertModelToMapValues(data: FieldsData): Map { + if (data.value == null) { + return mapOf() + } val id = data.options.find { it.name == data.value }?.id requireNotNull(id) return mapOf( diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt index 4a9f4708..3f8bac95 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/components/DateTimeField.kt @@ -42,7 +42,6 @@ fun DateTimeField( val dateFormat = updateDateFormat(fieldsData.params?.field?.dateDisplayFormat) ?: DATE_FORMAT_2_1 dateTime = date.first.getLocalFormattedDate(date.second, dateFormat) } - } } diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt index 0a4c12b9..866d4f28 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/fragments/ProcessFragment.kt @@ -159,12 +159,12 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { override fun invalidate() = withState(viewModel) { state -> binding.loading.isVisible = state.requestForm is Loading || state.requestStartWorkflow is Loading || - state.requestSaveForm is Loading || state.requestOutcomes is Loading || state.requestProfile is Loading || - state.requestAccountInfo is Loading || state.requestContent is Loading + state.requestSaveForm is Loading || state.requestOutcomes is Loading || state.requestProfile is Loading || + state.requestAccountInfo is Loading || state.requestContent is Loading when { state.requestStartWorkflow is Success || state.requestSaveForm is Success || - state.requestOutcomes is Success || state.requestClaimRelease is Success -> { + state.requestOutcomes is Success || state.requestClaimRelease is Success -> { viewModel.updateProcessList() requireActivity().finish() } @@ -172,11 +172,13 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { state.requestForm is Success -> { val hasUploadField = state.formFields.any { it.type == FieldType.UPLOAD.value() } - if (hasUploadField && state.parent.defaultEntries.isNotEmpty()) { - viewModel.fetchUserProfile() - viewModel.fetchAccountInfo() - } else { - showSnackBar(getString(R.string.error_no_upload_fields)) + if (state.parent.defaultEntries.isNotEmpty()) { + if (hasUploadField) { + viewModel.fetchUserProfile() + viewModel.fetchAccountInfo() + } else { + showSnackBar(getString(R.string.error_no_upload_fields)) + } } if (hasUploadField) { @@ -226,7 +228,6 @@ class ProcessFragment : Fragment(), MavericksView, EntryListener { override fun onAttachFiles(field: FieldsData) = withState(viewModel) { state -> if (isAdded && field.type == FieldType.UPLOAD.value()) { - val listContents = mergeInUploads(field.getContentList(state.parent.processDefinitionId), viewModel.getContents(state, field.id)) val isError = field.required && listContents.isEmpty() diff --git a/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt b/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/ActionsReadOnlyField.kt similarity index 93% rename from process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt rename to process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/ActionsReadOnlyField.kt index 234b4dc9..bc5fbfd5 100644 --- a/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/actionsReadOnlyField.kt +++ b/process-app/src/main/kotlin/com/alfresco/content/process/ui/utils/ActionsReadOnlyField.kt @@ -14,8 +14,11 @@ import com.alfresco.content.process.R import com.alfresco.content.process.ui.fragments.FormViewState fun actionsReadOnlyField( - isTapped: Boolean, field: FieldsData, navController: NavController, - state: FormViewState, context: Context + isTapped: Boolean, + field: FieldsData, + navController: NavController, + state: FormViewState, + context: Context, ) { when (field.params?.field?.type?.lowercase()) { FieldType.UPLOAD.value() -> { @@ -55,4 +58,4 @@ fun actionsReadOnlyField( .show() } } -} \ No newline at end of file +} From 2d9bfec01c8e6fe52c293bc496fbcb032a4623b5 Mon Sep 17 00:00:00 2001 From: Amanpal Singh <87360222+aman-alfresco@users.noreply.github.com> Date: Fri, 10 May 2024 12:34:32 +0530 Subject: [PATCH 5/5] fixed date issue and description crash --- .../browse/processes/details/ProcessDetailViewModel.kt | 7 +++---- .../com/alfresco/content/component/DatePickerBuilder.kt | 2 +- .../src/main/kotlin/com/alfresco/content/data/TaskEntry.kt | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailViewModel.kt b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailViewModel.kt index 4c942332..f4bee732 100644 --- a/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailViewModel.kt +++ b/browse/src/main/kotlin/com/alfresco/content/browse/processes/details/ProcessDetailViewModel.kt @@ -9,7 +9,6 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import com.alfresco.content.actions.Action import com.alfresco.content.actions.ActionOpenWith -import com.alfresco.content.actions.ActionUpdateNameDescription import com.alfresco.content.common.EntryListener import com.alfresco.content.component.ComponentMetaData import com.alfresco.content.data.Entry @@ -48,9 +47,9 @@ class ProcessDetailViewModel( entryListener?.onEntryCreated(it.entry) } } - viewModelScope.on { - setState { copy(parent = it.entry as ProcessEntry) } - } +// viewModelScope.on { +// setState { copy(parent = it.entry as ProcessEntry) } +// } fetchUserProfile() fetchAccountInfo() diff --git a/component/src/main/java/com/alfresco/content/component/DatePickerBuilder.kt b/component/src/main/java/com/alfresco/content/component/DatePickerBuilder.kt index 8ef6be7d..9b855f96 100644 --- a/component/src/main/java/com/alfresco/content/component/DatePickerBuilder.kt +++ b/component/src/main/java/com/alfresco/content/component/DatePickerBuilder.kt @@ -100,7 +100,7 @@ data class DatePickerBuilder( if (fieldsData?.type == FieldType.DATETIME.value()) { stringDateTime = getFormatDate(date) timePicker.show(fragmentManager, DatePickerBuilder::class.java.name) - } else if (fieldsData?.type == FieldType.DATE.value()) { + } else { onSuccess?.invoke(getFormatDate(date)) } } 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 85258a45..2031c535 100644 --- a/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt +++ b/data/src/main/kotlin/com/alfresco/content/data/TaskEntry.kt @@ -60,6 +60,7 @@ data class TaskEntry( processDefinitionId = data.processDefinitionId, processInstanceStartUserId = data.processInstanceStartUserId, memberOfCandidateGroup = data.memberOfCandidateGroup, + formattedDueDate = data.dueDate?.toLocalDate()?.toString(), ) }