From 700f0ac2a698140f13d4f5e23ec86da1760ebd5b Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Wed, 30 Oct 2024 16:52:16 -0400 Subject: [PATCH 01/31] Test the cases synchronization --- .../Feature/Cases/CaseSyncRepositoryTest.php | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 tests/Feature/Cases/CaseSyncRepositoryTest.php diff --git a/tests/Feature/Cases/CaseSyncRepositoryTest.php b/tests/Feature/Cases/CaseSyncRepositoryTest.php new file mode 100644 index 0000000000..c91cd2b4fa --- /dev/null +++ b/tests/Feature/Cases/CaseSyncRepositoryTest.php @@ -0,0 +1,143 @@ +create(); + $processRequest2 = ProcessRequest::factory()->create(['parent_request_id' => $processRequest1->id, 'case_number' => $processRequest1->case_number]); + + // Create some tokens for both ProcessRequest instances + $processRequest1->tokens()->createMany([ + ProcessRequestToken::factory()->make([ + 'element_name' => 'Task 1', + 'element_type' => 'task', + 'status' => 'ACTIVE', + 'element_id' => 'task-1', + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id + ])->toArray(), + ProcessRequestToken::factory()->make([ + 'element_name' => 'Task 2', + 'element_type' => 'task', + 'status' => 'CLOSED', + 'element_id' => 'task-2', + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id + ])->toArray(), + ProcessRequestToken::factory()->make([ + 'element_name' => 'Task 3', + 'element_type' => 'callActivity', + 'status' => 'ACTIVE', + 'element_id' => 'call-activity-1', + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id + ])->toArray(), + ]); + + $processRequest2->tokens()->createMany([ + ProcessRequestToken::factory()->make([ + 'element_name' => 'Task 4', + 'element_type' => 'scriptTask', + 'status' => 'CLOSED', + 'element_id' => 'task-4', + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id + ])->toArray(), + ProcessRequestToken::factory()->make([ + 'element_name' => 'Task 5', + 'element_type' => 'task', + 'status' => 'ACTIVE', + 'element_id' => 'task-5', + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id + ])->toArray(), + ]); + + // Call the syncCases method + $result = CaseSyncRepository::syncCases([$processRequest1->id, $processRequest2->id]); + + // Assert that the response contains the correct data + $this->assertArrayHasKey('successes', $result); + $this->assertArrayHasKey('errors', $result); + + // Check that the successes array contains the case numbers + $this->assertContains($processRequest1->case_number, $result['successes']); + $this->assertContains($processRequest2->case_number, $result['successes']); + + // Check that the CaseStarted records were created + $caseStarted = DB::table('cases_started')->where('case_number', $processRequest1->case_number)->first(); + $tasks = json_decode($caseStarted->tasks, true); + $participants = json_decode($caseStarted->participants, true); + + $expectedTasks = [ + [ + 'id' => $processRequest2->tokens()->where('element_id', 'task-5')->first()->id, + 'name' => 'Task 5', + 'status' => 'ACTIVE', + 'element_id' => 'task-5', + 'process_id' => $processRequest2->process_id + ], + [ + 'id' => $processRequest1->tokens()->where('element_id', 'task-2')->first()->id, + 'name' => 'Task 2', + 'status' => 'CLOSED', + 'element_id' => 'task-2', + 'process_id' => $processRequest1->process_id + ], + [ + 'id' => $processRequest1->tokens()->where('element_id', 'task-1')->first()->id, + 'name' => 'Task 1', + 'status' => 'ACTIVE', + 'element_id' => 'task-1', + 'process_id' => $processRequest1->process_id + ], + ]; + $expectedParticipants = [ + $processRequest1->tokens()->where('element_id', 'task-1')->first()->user_id, + $processRequest1->tokens()->where('element_id', 'task-2')->first()->user_id, + $processRequest2->tokens()->where('element_id', 'task-5')->first()->user_id, + ]; + + $this->assertEquals($expectedTasks, $tasks); + $this->assertEquals($expectedParticipants, $participants); + + // There are 3 case_participated records created + $this->assertDatabaseCount('cases_participated', 3); + + // participant assigned to task-1 + $caseParticipated = DB::table('cases_participated') + ->where('case_number', $processRequest1->case_number) + ->where('user_id', $processRequest1->tokens()->where('element_id', 'task-1')->first()->user_id) + ->first(); + $participatedTasks = json_decode($caseParticipated->tasks, true); + $participants = json_decode($caseParticipated->participants, true); + $this->assertEquals($expectedTasks, $participatedTasks); + $this->assertEquals($expectedParticipants, $participants); + + // participant assigned to task-2 + $caseParticipated = DB::table('cases_participated') + ->where('case_number', $processRequest1->case_number) + ->where('user_id', $processRequest1->tokens()->where('element_id', 'task-2')->first()->user_id) + ->first(); + $participatedTasks = json_decode($caseParticipated->tasks, true); + $participants = json_decode($caseParticipated->participants, true); + $this->assertEquals($expectedTasks, $participatedTasks); + $this->assertEquals($expectedParticipants, $participants); + + // participant assigned to task-4 + $caseParticipated = DB::table('cases_participated') + ->where('case_number', $processRequest2->case_number) + ->where('user_id', $processRequest2->tokens()->where('element_id', 'task-4')->first()->user_id) + ->first(); + } +} From ebe54dae4aa47b8b663ce76c363f3454e2875501 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Wed, 30 Oct 2024 16:52:55 -0400 Subject: [PATCH 02/31] Improve synchronization --- .../Repositories/CaseSyncRepository.php | 94 +++++++++++++------ ProcessMaker/Repositories/CaseUtils.php | 1 + 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/ProcessMaker/Repositories/CaseSyncRepository.php b/ProcessMaker/Repositories/CaseSyncRepository.php index ba1dd3a9d4..311d68b4d6 100644 --- a/ProcessMaker/Repositories/CaseSyncRepository.php +++ b/ProcessMaker/Repositories/CaseSyncRepository.php @@ -3,6 +3,7 @@ namespace ProcessMaker\Repositories; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\DB; use ProcessMaker\Models\CaseParticipated; use ProcessMaker\Models\CaseStarted; use ProcessMaker\Models\ProcessRequest; @@ -39,7 +40,7 @@ public static function syncCases(array $requestIds): array $caseStartedRequests = CaseUtils::storeRequests(collect(), $requestData); $caseStartedRequestTokens = collect(); $caseStartedTasks = collect(); - $participants = $instance->participants->pluck('id'); + $participants = self::getParticipantsFromInstance($instance); $status = CaseUtils::getStatus($instance->status); $caseParticipatedData = self::prepareCaseStartedData($instance, $status, $participants); @@ -67,6 +68,24 @@ public static function syncCases(array $requestIds): array 'keywords' => CaseUtils::getKeywords($dataKeywords), ], ); + // copy all the columns from cases_started to cases_participated, except for the user_id + $sql = "UPDATE cases_participated AS cp + INNER JOIN cases_started AS cs ON cp.case_number = cs.case_number + SET + cp.case_title = cs.case_title, + cp.case_title_formatted = cs.case_title_formatted, + cp.case_status = cs.case_status, + cp.processes = cs.processes, + cp.requests = cs.requests, + cp.request_tokens = cs.request_tokens, + cp.tasks = cs.tasks, + cp.participants = cs.participants, + cp.initiated_at = cs.initiated_at, + cp.completed_at = cs.completed_at, + cp.keywords = cs.keywords + WHERE cp.case_number = '{$instance->case_number}'; + "; + DB::statement($sql); $successes[] = $caseStarted->case_number; } catch (\Exception $e) { @@ -80,6 +99,19 @@ public static function syncCases(array $requestIds): array ]; } + /** + * Get the participants from the instance. + * + * @param ProcessRequest|\Illuminate\Database\Eloquent\Builder $instance + * @return Collection + */ + private static function getParticipantsFromInstance(ProcessRequest|\Illuminate\Database\Eloquent\Builder $instance) + { + return $instance->participants() + ->whereIn('process_request_tokens.element_type', CaseUtils::ALLOWED_ELEMENT_TYPES) + ->pluck('process_request_tokens.user_id'); + } + /** * Prepare the case started data. * @@ -120,38 +152,39 @@ private static function prepareCaseStartedData($instance, $status, $participants */ private static function processTokens($instance, &$caseParticipatedData, &$caseStartedRequestTokens, &$caseStartedTasks) { - foreach ($instance->tokens as $token) { - if (in_array($token->element_type, CaseUtils::ALLOWED_REQUEST_TOKENS)) { - $processData = [ - 'id' => $instance->process->id, - 'name' => $instance->process->name, - ]; + $tokens = $instance->tokens()->select('id', 'element_id', 'element_name', 'process_id', 'element_type', 'status', 'user_id') + ->whereIn('element_type', CaseUtils::ALLOWED_ELEMENT_TYPES) + ->get(); + foreach ($tokens as $token) { + $processData = [ + 'id' => $instance->process->id, + 'name' => $instance->process->name, + ]; - $requestData = [ - 'id' => $instance->id, - 'name' => $instance->name, - 'parent_request_id' => $instance?->parentRequest?->id, - ]; + $requestData = [ + 'id' => $instance->id, + 'name' => $instance->name, + 'parent_request_id' => $instance?->parent_request_id, + ]; - $taskData = [ - 'id' => $token->getKey(), - 'element_id' => $token->element_id, - 'name' => $token->element_name, - 'process_id' => $token->process_id, - 'element_type' => $token->element_type, - 'status' => $token->status, - ]; + $taskData = [ + 'id' => $token->getKey(), + 'element_id' => $token->element_id, + 'name' => $token->element_name, + 'process_id' => $token->process_id, + 'element_type' => $token->element_type, + 'status' => $token->status, + ]; - $caseParticipatedData['processes'] = CaseUtils::storeProcesses($caseParticipatedData['processes'], $processData); - $caseParticipatedData['requests'] = CaseUtils::storeRequests($caseParticipatedData['requests'], $requestData); - $caseParticipatedData['request_tokens'] = CaseUtils::storeRequestTokens($caseParticipatedData['request_tokens'], $token->getKey()); - $caseParticipatedData['tasks'] = CaseUtils::storeTasks($caseParticipatedData['tasks'], $taskData); + $caseParticipatedData['processes'] = CaseUtils::storeProcesses($caseParticipatedData['processes'], $processData); + $caseParticipatedData['requests'] = CaseUtils::storeRequests($caseParticipatedData['requests'], $requestData); + $caseParticipatedData['request_tokens'] = CaseUtils::storeRequestTokens($caseParticipatedData['request_tokens'], $token->getKey()); + $caseParticipatedData['tasks'] = CaseUtils::storeTasks($caseParticipatedData['tasks'], $taskData); - $caseStartedRequestTokens = CaseUtils::storeRequestTokens($caseStartedRequestTokens, $token->getKey()); - $caseStartedTasks = CaseUtils::storeTasks($caseStartedTasks, $taskData); + $caseStartedRequestTokens = CaseUtils::storeRequestTokens($caseStartedRequestTokens, $token->getKey()); + $caseStartedTasks = CaseUtils::storeTasks($caseStartedTasks, $taskData); - self::syncCasesParticipated($instance->case_number, $token->user_id, $caseParticipatedData); - } + self::syncCasesParticipated($instance->case_number, $token->user_id, $caseParticipatedData); } } @@ -183,7 +216,7 @@ private static function processChildRequests( $caseStartedRequests = CaseUtils::storeRequests($caseStartedRequests, $requestData); $participants = $participants - ->merge($subProcess->participants->pluck('id')) + ->merge(self::getParticipantsFromInstance($subProcess)) ->unique() ->values(); @@ -194,9 +227,10 @@ private static function processChildRequests( 'name' => $spToken->element_name, 'process_id' => $spToken->process_id, 'element_type' => $spToken->element_type, + 'status' => $spToken->status, ]; - if (in_array($spToken->element_type, CaseUtils::ALLOWED_REQUEST_TOKENS)) { + if (in_array($spToken->element_type, CaseUtils::ALLOWED_ELEMENT_TYPES)) { $caseParticipatedData['processes'] = CaseUtils::storeProcesses($caseParticipatedData['processes'], $processData); $caseParticipatedData['requests'] = CaseUtils::storeRequests($caseParticipatedData['requests'], $requestData); $caseParticipatedData['request_tokens'] = CaseUtils::storeRequestTokens($caseParticipatedData['request_tokens'], $spToken->getKey()); diff --git a/ProcessMaker/Repositories/CaseUtils.php b/ProcessMaker/Repositories/CaseUtils.php index a7413f7f50..552c994e3b 100644 --- a/ProcessMaker/Repositories/CaseUtils.php +++ b/ProcessMaker/Repositories/CaseUtils.php @@ -152,6 +152,7 @@ public static function storeTasks(Collection $tasks, ?array $taskData = []): Col && in_array($taskData['element_type'], self::ALLOWED_ELEMENT_TYPES) ) { unset($taskData['element_type']); + // This field is converted to string because: The Json_Search in MySQL only works with strings $taskData['id'] = (string)$taskData['id']; $tasks->prepend($taskData); } From 10ae340f1ea5ad7b67a384e37fd2ffd2a90966de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Bascop=C3=A9?= Date: Wed, 30 Oct 2024 16:56:11 -0400 Subject: [PATCH 03/31] Fix edit and delete modal styles --- devhub/pm-font/svg/trash.svg | 3 + resources/fonts/pm-font/index.html | 4 +- resources/fonts/pm-font/processmaker-font.css | 15 +-- resources/fonts/pm-font/processmaker-font.eot | Bin 15660 -> 16132 bytes .../fonts/pm-font/processmaker-font.less | 15 +-- .../pm-font/processmaker-font.module.less | 15 +-- .../fonts/pm-font/processmaker-font.scss | 18 ++-- .../fonts/pm-font/processmaker-font.styl | 15 +-- resources/fonts/pm-font/processmaker-font.svg | 5 +- .../pm-font/processmaker-font.symbol.svg | 2 +- resources/fonts/pm-font/processmaker-font.ttf | Bin 15456 -> 15928 bytes .../fonts/pm-font/processmaker-font.woff | Bin 10232 -> 10556 bytes .../fonts/pm-font/processmaker-font.woff2 | Bin 9076 -> 9344 bytes resources/fonts/pm-font/symbol.html | 9 +- resources/fonts/pm-font/unicode.html | 12 +-- .../admin/devlink/components/BundleModal.vue | 38 ++++--- .../admin/devlink/components/DeleteModal.vue | 97 ++++++++++++++++++ .../js/admin/devlink/components/Index.vue | 28 ++--- .../admin/devlink/components/LocalBundles.vue | 51 ++++++--- resources/lang/en.json | 2 + resources/sass/components/modal.scss | 34 ++++++ 21 files changed, 280 insertions(+), 83 deletions(-) create mode 100644 devhub/pm-font/svg/trash.svg create mode 100644 resources/js/admin/devlink/components/DeleteModal.vue create mode 100644 resources/sass/components/modal.scss diff --git a/devhub/pm-font/svg/trash.svg b/devhub/pm-font/svg/trash.svg new file mode 100644 index 0000000000..163615e4f1 --- /dev/null +++ b/devhub/pm-font/svg/trash.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/fonts/pm-font/index.html b/resources/fonts/pm-font/index.html index ac553e936e..2f24bf8009 100644 --- a/resources/fonts/pm-font/index.html +++ b/resources/fonts/pm-font/index.html @@ -103,7 +103,7 @@
-

ProcessMaker Icons4.12.0+alpha-2

+

ProcessMaker Icons4.12.0+alpha-3

Icons generated with svgtofont. For add new icons, please check the README file
@@ -115,7 +115,7 @@

ProcessMaker Icons4.12.0+alpha-2

    -
  • bpmn-action-by-email

  • bpmn-data-connector

  • bpmn-data-object

  • bpmn-data-store

  • bpmn-docusign

  • bpmn-end-event

  • bpmn-flowgenie

  • bpmn-gateway

  • bpmn-generic-gateway

  • bpmn-idp

  • bpmn-intermediate-event

  • bpmn-pool

  • bpmn-send-email

  • bpmn-start-event

  • bpmn-task

  • bpmn-text-annotation

  • brush-icon

  • close

  • cloud-download-outline

  • copy

  • css-icon

  • desktop

  • eye

  • fields-icon

  • flowgenie-outline

  • folder-outline

  • fullscreen

  • github

  • layout-icon

  • map

  • mobile

  • pdf

  • play-outline

  • plus

  • screen-outline

  • script-outline

  • slack-notification

  • slack

  • slideshow

  • table

  • unlink

  • +
  • bpmn-action-by-email

  • bpmn-data-connector

  • bpmn-data-object

  • bpmn-data-store

  • bpmn-docusign

  • bpmn-end-event

  • bpmn-flowgenie

  • bpmn-gateway

  • bpmn-generic-gateway

  • bpmn-idp

  • bpmn-intermediate-event

  • bpmn-pool

  • bpmn-send-email

  • bpmn-start-event

  • bpmn-task

  • bpmn-text-annotation

  • brush-icon

  • close

  • cloud-download-outline

  • copy

  • css-icon

  • desktop

  • eye

  • fields-icon

  • flowgenie-outline

  • folder-outline

  • fullscreen

  • github

  • layout-icon

  • map

  • mobile

  • pdf

  • play-outline

  • plus

  • screen-outline

  • script-outline

  • slack-notification

  • slack

  • slideshow

  • table

  • trash

  • unlink

ProcessMaker Icons4.12.0+alpha-2

+

ProcessMaker Icons4.12.0+alpha-3

Icons generated with svgtofont. For add new icons, please check the README file
@@ -394,6 +394,13 @@

fp-slideshow

fp-table

+
  • + +

    fp-trash

    +
  • +
  • -

    ProcessMaker Icons4.12.0+alpha-2

    +

    ProcessMaker Icons4.12.0+alpha-3

    Icons generated with svgtofont. For add new icons, please check the README file
    @@ -134,7 +134,7 @@

    ProcessMaker Icons4.12.0+alpha-2

      -
    • bpmn-action-by-email

      
    • bpmn-data-connector

      
    • bpmn-data-object

      
    • bpmn-data-store

      
    • bpmn-docusign

      
    • bpmn-end-event

      
    • bpmn-flowgenie

      
    • bpmn-gateway

      
    • bpmn-generic-gateway

      
    • bpmn-idp

      
    • bpmn-intermediate-event

      
    • bpmn-pool

      
    • bpmn-send-email

      
    • bpmn-start-event

      
    • bpmn-task

      
    • bpmn-text-annotation

      
    • brush-icon

      
    • close

      
    • cloud-download-outline

      
    • copy

      
    • css-icon

      
    • desktop

      
    • eye

      
    • fields-icon

      
    • flowgenie-outline

      
    • folder-outline

      
    • fullscreen

      
    • github

      
    • layout-icon

      
    • map

      
    • mobile

      
    • pdf

      
    • play-outline

      
    • plus

      
    • screen-outline

      
    • script-outline

      
    • slack-notification

      
    • slack

      
    • slideshow

      
    • table

      
    • unlink

      
    • +
    • bpmn-action-by-email

      
    • bpmn-data-connector

      
    • bpmn-data-object

      
    • bpmn-data-store

      
    • bpmn-docusign

      
    • bpmn-end-event

      
    • bpmn-flowgenie

      
    • bpmn-gateway

      
    • bpmn-generic-gateway

      
    • bpmn-idp

      
    • bpmn-intermediate-event

      
    • bpmn-pool

      
    • bpmn-send-email

      
    • bpmn-start-event

      
    • bpmn-task

      
    • bpmn-text-annotation

      
    • brush-icon

      
    • close

      
    • cloud-download-outline

      
    • copy

      
    • css-icon

      
    • desktop

      
    • eye

      
    • fields-icon

      
    • flowgenie-outline

      
    • folder-outline

      
    • fullscreen

      
    • github

      
    • layout-icon

      
    • map

      
    • mobile

      
    • pdf

      
    • play-outline

      
    • plus

      
    • screen-outline

      
    • script-outline

      
    • slack-notification

      
    • slack

      
    • slideshow

      
    • table

      
    • trash

      
    • unlink

      
    { router.push({ name: 'bundle-assets', params: { id: bundle.id } }); } -const deleteWaring = computed(() => { +const deleteWarning = computed(() => { const name = selected?.value.name; - return vue.$t('Are you sure you want to delete {{name}}?', { name }); + return vue.$t('Are you sure you want to delete {{name}}? The action is irreversible.', { name }); }); const confirmPublishNewVersionText = computed(() => { @@ -215,15 +217,8 @@ const confirmPublishNewVersionText = computed(() => {
    - -

    {{ deleteWaring }}'

    -
    + + @@ -295,6 +290,38 @@ const confirmPublishNewVersionText = computed(() => { } @import "styles/components/table"; +@import "styles/components/modal"; +::v-deep .delete-modal-style .modal-header .delete-icon { + width: 48px; + height: 48px; + background-color: #FEE6E5; + display: flex; + align-items: center; + justify-content: center; + border-radius: 8px; + color: #EC5962; + font-size: 26px; +} +::v-deep .delete-modal-style .modal-body-text { + font-size: 16px; + font-weight: 500; +} +::v-deep .delete-modal-style .modal-footer { + background-color: #FBFBFC; + border-top: 1px solid #E9ECF1; + border-bottom-left-radius: 16px; + border-bottom-right-radius: 16px; +} +::v-deep .delete-modal-style .modal-footer .btn-primary { + border: none; + background-color: #EC5962; + color: #FFFFFF; +} +::v-deep .delete-modal-style .modal-footer .btn-secondary { + border: 1px solid #D7DDE5; + background-color: #FFFFFF; + color: #20242A; +} .local-bundles-card { border-radius: 8px; diff --git a/resources/lang/en.json b/resources/lang/en.json index bfb39d394e..85c07b973f 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -143,6 +143,7 @@ "Are you sure you want to delete {{item}}? Deleting this asset will break any active tasks that are assigned.": "Are you sure you want to delete {{item}}? Deleting this asset will break any active tasks that are assigned.", "Are you sure you want to delete {{item}}?": "Are you sure you want to delete {{item}}?", "Are you sure you want to delete {{item}}": "Are your sure you want to delete {{item}}", + "Are you sure you want to delete {{name}}? The action is irreversible.": "Are you sure you want to delete {{name}}? The action is irreversible.", "Are you sure you want to delete expression {{item}}": "Are you sure you want to delete expression {{item}}", "Are you sure you want to delete the auth client": "Are you sure you want to delete the auth client", "Are you sure you want to delete the environment variable {{ name }} ?": "Are you sure you want to delete the environment variable {{ name }} ?", @@ -486,6 +487,7 @@ "Delete Categories": "Delete Categories", "Delete Category": "Delete Category", "Delete Comments": "Delete Comments", + "Delete Confirmation": "Delete Confirmation", "Delete Control": "Delete Control", "Delete Environment Variables": "Delete Environment Variables", "Delete Files": "Delete Files", diff --git a/resources/sass/components/modal.scss b/resources/sass/components/modal.scss new file mode 100644 index 0000000000..ab2d73f0bd --- /dev/null +++ b/resources/sass/components/modal.scss @@ -0,0 +1,34 @@ +::v-deep .modal-content { + border-radius: 16px; + border: 1px solid #E9ECF1; +} +::v-deep .modal-header { + border-bottom: none; +} +::v-deep .modal-title { + font-size: 24px; + font-weight: 500; +} +::v-deep .modal-body { + font-size: 14px; + font-weight: 400; +} +::v-deep .modal-footer { + border-top: none; + margin-top: 0px !important; +} +::v-deep .modal-footer .btn { + border-radius: 8px; + font-size: 14px; + font-weight: 500; +} +::v-deep .modal-footer .btn-secondary { + background-color: white; + border: none; + color: #20242A; + text-transform: none; +} +::v-deep .modal-footer .btn-primary { + background-color: #2773F3; + text-transform: none; +} \ No newline at end of file From 7f175d61d5cce7f6313b2be86210b3667148b490 Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Wed, 30 Oct 2024 14:22:30 -0700 Subject: [PATCH 04/31] Fix header positioning --- resources/js/admin/devlink/components/Header.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/js/admin/devlink/components/Header.vue b/resources/js/admin/devlink/components/Header.vue index 8dc94403fe..6465c80415 100644 --- a/resources/js/admin/devlink/components/Header.vue +++ b/resources/js/admin/devlink/components/Header.vue @@ -31,5 +31,6 @@ const props = defineProps({ \ No newline at end of file From 7350a24cfa148e5b3f0db7a9edc73ef5eb10dc5e Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Wed, 30 Oct 2024 14:22:51 -0700 Subject: [PATCH 05/31] Show loading for instance bundle list --- resources/js/admin/devlink/components/Instance.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/resources/js/admin/devlink/components/Instance.vue b/resources/js/admin/devlink/components/Instance.vue index 7edea5cb19..7a130aa3ec 100644 --- a/resources/js/admin/devlink/components/Instance.vue +++ b/resources/js/admin/devlink/components/Instance.vue @@ -10,6 +10,7 @@ const router = useRouter(); const route = useRoute(); const bundles = ref([]); +const loading = ref(true); const filter = ref(""); const warnings = ref([]); const showInstallModal = ref(false); @@ -66,6 +67,7 @@ const load = () => { .get(`/devlink/${route.params.id}/remote-bundles?filter=${filter.value}`) .then((result) => { bundles.value = result.data.data; + loading.value = false; }); }; @@ -114,7 +116,11 @@ const executeUpdate = (updateType) => {
    +
    + {{ $t("Loading...") }} +
    Date: Wed, 30 Oct 2024 14:23:18 -0700 Subject: [PATCH 06/31] Add open to ellipsis menu --- resources/js/admin/devlink/components/LocalBundles.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/js/admin/devlink/components/LocalBundles.vue b/resources/js/admin/devlink/components/LocalBundles.vue index a6b1d87f32..eba9ee696a 100644 --- a/resources/js/admin/devlink/components/LocalBundles.vue +++ b/resources/js/admin/devlink/components/LocalBundles.vue @@ -22,6 +22,7 @@ const updateBundle = ref(null); const updatesAvailable = reactive({}); const actions = [ + { value: "open-item", content: "Open" }, { value: "increase-item", content: "Publish New Version", conditional: "if(not(dev_link_id), true, false)" }, { value: "update-item", content: "Update Bundle", conditional: "if(update_available, true, false)" }, { value: "reinstall-item", content: "Reinstall Bundle", conditional: "if(dev_link_id, true, false)" }, @@ -100,6 +101,9 @@ const createNewBundle = () => { const onNavigate = (action, data, index) => { switch (action.value) { + case "open-item": + goToBundleAssets(data); + break; case "edit-item": edit(data); break; From 00ba5b1af4d5e6da867803eed30d9335144dfb9b Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Wed, 30 Oct 2024 18:32:06 -0400 Subject: [PATCH 07/31] Adding new component to ScreenComponents.php --- ProcessMaker/Templates/ScreenComponents.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ProcessMaker/Templates/ScreenComponents.php b/ProcessMaker/Templates/ScreenComponents.php index bd1176fbf3..9ac171b60f 100644 --- a/ProcessMaker/Templates/ScreenComponents.php +++ b/ProcessMaker/Templates/ScreenComponents.php @@ -29,6 +29,7 @@ public static function getComponents() 'FormRecordList', 'FormLoop', 'FormNestedScreen', + 'FormCollectionRecordControl', 'FormButton', 'FileUpload', 'FileDownload', From 370df01cb43ff29bb339b618636eb1f795a29534 Mon Sep 17 00:00:00 2001 From: Fabio Date: Thu, 31 Oct 2024 09:51:22 -0400 Subject: [PATCH 08/31] FOUR-19815:UI: The mouse over the links does not show the link --- .../jscomposition/system/table/cell/TruncatedOptionsCell.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/jscomposition/system/table/cell/TruncatedOptionsCell.vue b/resources/jscomposition/system/table/cell/TruncatedOptionsCell.vue index 2dd0e0a5ce..5b5489b160 100644 --- a/resources/jscomposition/system/table/cell/TruncatedOptionsCell.vue +++ b/resources/jscomposition/system/table/cell/TruncatedOptionsCell.vue @@ -44,7 +44,7 @@ {{ getValueOption(option, index) }} From 479bfca82a08f454abc876f840471d6ba60450fc Mon Sep 17 00:00:00 2001 From: Henry Jonas Date: Thu, 31 Oct 2024 11:07:25 -0400 Subject: [PATCH 09/31] FOUR-19924 : Title in cases pages is empty --- resources/views/cases/casesMain.blade.php | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/views/cases/casesMain.blade.php b/resources/views/cases/casesMain.blade.php index 5c945a6965..dd56200b0c 100644 --- a/resources/views/cases/casesMain.blade.php +++ b/resources/views/cases/casesMain.blade.php @@ -1,6 +1,7 @@ @extends('layouts.layout',['content_margin' => '', 'overflow-auto' => '']) @section('title') + {{ __('Cases') }} @endsection @section('sidebar') From a53f24756d94aa95ef6bb3bcec061b152feac86e Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Thu, 31 Oct 2024 15:02:41 -0400 Subject: [PATCH 10/31] feat: ref cases participated population --- .../CaseParticipatedRepository.php | 122 ++++++++---------- ProcessMaker/Repositories/CaseRepository.php | 18 +-- 2 files changed, 60 insertions(+), 80 deletions(-) diff --git a/ProcessMaker/Repositories/CaseParticipatedRepository.php b/ProcessMaker/Repositories/CaseParticipatedRepository.php index 7c50b6fb08..48a3b19f77 100644 --- a/ProcessMaker/Repositories/CaseParticipatedRepository.php +++ b/ProcessMaker/Repositories/CaseParticipatedRepository.php @@ -2,10 +2,10 @@ namespace ProcessMaker\Repositories; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use ProcessMaker\Models\CaseParticipated; use ProcessMaker\Models\CaseStarted; -use ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface; class CaseParticipatedRepository { @@ -20,74 +20,72 @@ class CaseParticipatedRepository * Store a new case participated. * * @param CaseStarted $case - * @param TokenInterface $token + * @param int $userId * @return void */ - public function create(CaseStarted $case, TokenInterface $token): void + public function create(CaseStarted $case, int $userId): void { - if ($this->checkIfCaseParticipatedExist($token->user->id, $case->case_number)) { - return; - } - try { - $processData = CaseUtils::extractData($token->processRequest->process, 'PROCESS'); - $requestData = CaseUtils::extractData($token->processRequest, 'REQUEST'); - $taskData = CaseUtils::extractData($token, 'TASK'); - - CaseParticipated::create([ - 'user_id' => $token->user->id, - 'case_number' => $case->case_number, - 'case_title' => $case->case_title, - 'case_title_formatted' => $case->case_title_formatted, - 'case_status' => $case->case_status, - 'processes' => CaseUtils::storeProcesses(collect(), $processData), - 'requests' => CaseUtils::storeRequests(collect(), $requestData), - 'request_tokens' => CaseUtils::storeRequestTokens(collect(), $token->getKey()), - 'tasks' => CaseUtils::storeTasks(collect(), $taskData), - 'participants' => $case->participants, - 'initiated_at' => $case->initiated_at, - 'completed_at' => null, - 'keywords' => $case->keywords, - ]); + CaseParticipated::updateOrCreate( + [ + 'case_number' => $case->case_number, + 'user_id' => $userId, + ], + $this->mapCaseToArray($case, $userId) + ); } catch (\Exception $e) { - Log::error('CaseException: ' . $e->getMessage()); - Log::error('CaseException: ' . $e->getTraceAsString()); + $this->logException($e); } } /** - * Update the case participated. + * Update the cases participated. * * @param CaseStarted $case - * @param TokenInterface $token * @return void */ - public function update(CaseStarted $case, TokenInterface $token) + public function update(CaseStarted $case): void { try { - if (!$this->checkIfCaseParticipatedExist($token->user->id, $case->case_number)) { - return; - } + CaseParticipated::where('case_number', $case->case_number) + ->update($this->mapCaseToArray($case)); + } catch (\Exception $e) { + $this->logException($e); + } + } - $processData = CaseUtils::extractData($token->processRequest->process, 'PROCESS'); - $requestData = CaseUtils::extractData($token->processRequest, 'REQUEST'); - $taskData = CaseUtils::extractData($token, 'TASK'); + /** + * Maps properties of a `CaseStarted` object to an array, optionally including a user ID. + * + * @param CaseStarted case Takes a `CaseStarted` object and parameter as input and returns an array with specific + * properties mapped from the `CaseStarted` object. + * @param int userId Takes an optional `userId` parameter. + * + * @return array An array containing various properties of a CaseStarted object. If a userId is + * provided, it will also include the user_id in the returned array. + */ + private function mapCaseToArray(CaseStarted $case, int $userId = null): array + { + $data = [ + 'case_number' => $case->case_number, + 'case_title' => $case->case_title, + 'case_title_formatted' => $case->case_title_formatted, + 'case_status' => $case->case_status, + 'processes' => $case->processes, + 'requests' => $case->requests, + 'request_tokens' => $case->request_tokens, + 'tasks' => $case->tasks, + 'participants' => $case->participants, + 'initiated_at' => $case->initiated_at, + 'completed_at' => $case->completed_at, + 'keywords' => $case->keywords, + ]; - $this->caseParticipated->updateOrFail([ - 'case_title' => $case->case_title, - 'case_title_formatted' => $case->case_title_formatted, - 'case_status' => $case->case_status, - 'processes' => CaseUtils::storeProcesses($this->caseParticipated->processes, $processData), - 'requests' => CaseUtils::storeRequests($this->caseParticipated->requests, $requestData), - 'request_tokens' => CaseUtils::storeRequestTokens($this->caseParticipated->request_tokens, $token->getKey()), - 'tasks' => CaseUtils::storeTasks($this->caseParticipated->tasks, $taskData), - 'participants' => $case->participants, - 'keywords' => $case->keywords, - ]); - } catch (\Exception $e) { - Log::error('CaseException: ' . $e->getMessage()); - Log::error('CaseException: ' . $e->getTraceAsString()); + if ($userId !== null) { + $data['user_id'] = $userId; } + + return $data; } /** @@ -103,27 +101,13 @@ public function updateStatus(int $caseNumber, array $statusData) CaseParticipated::where('case_number', $caseNumber) ->update($statusData); } catch (\Exception $e) { - Log::error('CaseException: ' . $e->getMessage()); - Log::error('CaseException: ' . $e->getTraceAsString()); + $this->logException($e); } } - /** - * Check if a case participated exists. - * If it exists, store the instance in the property. - * The property is used to update the JSON fields of the case participated. - * - * @param int $userId - * @param int $caseNumber - * - * @return bool - */ - private function checkIfCaseParticipatedExist(int $userId, int $caseNumber): bool + private function logException(\Exception $e): void { - $this->caseParticipated = CaseParticipated::where('user_id', $userId) - ->where('case_number', $caseNumber) - ->first(); - - return !is_null($this->caseParticipated); + Log::error('CaseException: ' . $e->getMessage()); + Log::error('CaseException: ' . $e->getTraceAsString()); } } diff --git a/ProcessMaker/Repositories/CaseRepository.php b/ProcessMaker/Repositories/CaseRepository.php index 21233a6111..48f758f182 100644 --- a/ProcessMaker/Repositories/CaseRepository.php +++ b/ProcessMaker/Repositories/CaseRepository.php @@ -131,7 +131,7 @@ public function updateStatus(ExecutionInstanceInterface $instance): void ]; if ($caseStatus === CaseStatusConstants::COMPLETED) { - $data['completed_at'] = Carbon::now(); + $data['completed_at'] = $instance->completed_at; } // Update the case started and case participated @@ -153,19 +153,13 @@ private function updateParticipants(TokenInterface $token): void { $user = $token->user; - if (!$user) { - return; - } - - $participantExists = $this->case->participants->contains($user->id); + $this->case->participants = CaseUtils::storeParticipants($this->case->participants, $user?->id); - if (!$participantExists) { - $this->case->participants->push($user->id); - - $this->caseParticipatedRepository->create($this->case, $token); + if (!is_null($user?->id)) { + $this->caseParticipatedRepository->create($this->case, $user->id); } - $this->caseParticipatedRepository->update($this->case, $token); + $this->caseParticipatedRepository->update($this->case); } /** @@ -206,6 +200,8 @@ private function updateSubProcesses(ExecutionInstanceInterface $instance): void $this->case->requests = CaseUtils::storeRequests($this->case->requests, $requestData); $this->case->saveOrFail(); + + $this->caseParticipatedRepository->update($this->case); } catch (\Exception $e) { Log::error('CaseException: ' . $e->getMessage()); Log::error('CaseException: ' . $e->getTraceAsString()); From b6d4362bd989d5c6155e1fd12cd4402abd8bc3c0 Mon Sep 17 00:00:00 2001 From: Paula Quispe Date: Thu, 31 Oct 2024 15:48:03 -0400 Subject: [PATCH 11/31] FOUR-19949 --- .../Commands/UpdateCommentsCaseNumber.php | 32 +++++++++++++------ ...8_113301_populate_comments_case_number.php | 32 +++++++++++++------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php b/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php index ca848f2433..544ba16a74 100644 --- a/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php +++ b/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php @@ -42,11 +42,17 @@ public function handle() ->select('comments.id', 'process_requests.case_number') ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { - foreach ($comments as $comment) { - // Update the comments.case_number with ptrocess_requests.case_number - DB::table('comments') - ->where('id', $comment->id) - ->update(['case_number' => $comment->case_number]); + $updates = $comments->mapWithKeys(function ($comment) { + return [$comment->id => ['case_number' => $comment->case_number]]; + })->toArray(); + // Execute in bath the update + if (!empty($updates)) { + $query = 'UPDATE comments SET case_number = CASE id'; + foreach ($updates as $id => $data) { + $query .= " WHEN {$id} THEN '{$data['case_number']}'"; + } + $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; + DB::statement($query); } }); // Update the comments related to ProcessRequest @@ -57,11 +63,17 @@ public function handle() ->select('comments.id', 'process_requests.case_number') ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { - foreach ($comments as $comment) { - // Update the comments.case_number with ptrocess_requests.case_number - DB::table('comments') - ->where('id', $comment->id) - ->update(['case_number' => $comment->case_number]); + $updates = $comments->mapWithKeys(function ($comment) { + return [$comment->id => ['case_number' => $comment->case_number]]; + })->toArray(); + // Execute in bath the update + if (!empty($updates)) { + $query = 'UPDATE comments SET case_number = CASE id'; + foreach ($updates as $id => $data) { + $query .= " WHEN {$id} THEN '{$data['case_number']}'"; + } + $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; + DB::statement($query); } }); diff --git a/upgrades/2024_10_08_113301_populate_comments_case_number.php b/upgrades/2024_10_08_113301_populate_comments_case_number.php index ae4da17747..cb58995a21 100644 --- a/upgrades/2024_10_08_113301_populate_comments_case_number.php +++ b/upgrades/2024_10_08_113301_populate_comments_case_number.php @@ -43,11 +43,17 @@ public function up(): void ->select('comments.id', 'process_requests.case_number') ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { - foreach ($comments as $comment) { - // Update the comments.case_number with ptrocess_requests.case_number - DB::table('comments') - ->where('id', $comment->id) - ->update(['case_number' => $comment->case_number]); + $updates = $comments->mapWithKeys(function ($comment) { + return [$comment->id => ['case_number' => $comment->case_number]]; + })->toArray(); + // Execute in bath the update + if (!empty($updates)) { + $query = 'UPDATE comments SET case_number = CASE id'; + foreach ($updates as $id => $data) { + $query .= " WHEN {$id} THEN '{$data['case_number']}'"; + } + $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; + DB::statement($query); } }); // Update the comments related to ProcessRequest @@ -58,11 +64,17 @@ public function up(): void ->select('comments.id', 'process_requests.case_number') ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { - foreach ($comments as $comment) { - // Update the comments.case_number with ptrocess_requests.case_number - DB::table('comments') - ->where('id', $comment->id) - ->update(['case_number' => $comment->case_number]); + $updates = $comments->mapWithKeys(function ($comment) { + return [$comment->id => ['case_number' => $comment->case_number]]; + })->toArray(); + // Execute in bath the update + if (!empty($updates)) { + $query = 'UPDATE comments SET case_number = CASE id'; + foreach ($updates as $id => $data) { + $query .= " WHEN {$id} THEN '{$data['case_number']}'"; + } + $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; + DB::statement($query); } }); } From 73a059dfabaaf0b8431fee261195491ff1ff10fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Bascop=C3=A9?= Date: Thu, 31 Oct 2024 16:25:22 -0400 Subject: [PATCH 12/31] fix the edit modal styles --- resources/js/admin/devlink/components/BundleModal.vue | 2 +- resources/js/admin/devlink/components/DeleteModal.vue | 3 +++ resources/sass/components/modal.scss | 8 +++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/resources/js/admin/devlink/components/BundleModal.vue b/resources/js/admin/devlink/components/BundleModal.vue index 53dab34878..abc1c3ae41 100644 --- a/resources/js/admin/devlink/components/BundleModal.vue +++ b/resources/js/admin/devlink/components/BundleModal.vue @@ -36,7 +36,7 @@ }); const canEdit = (bundle) => { - return bundle.dev_link === null; + return bundle.dev_link_id === null; }; const onOk = () => { diff --git a/resources/js/admin/devlink/components/DeleteModal.vue b/resources/js/admin/devlink/components/DeleteModal.vue index 748331ef89..2513bca087 100644 --- a/resources/js/admin/devlink/components/DeleteModal.vue +++ b/resources/js/admin/devlink/components/DeleteModal.vue @@ -89,6 +89,9 @@ export default { background-color: #EC5962; color: #FFFFFF; } +::v-deep .modal-footer .btn-primary:hover { + background-color: #c74a51; /* Color más oscuro para el hover */ +} ::v-deep .modal-footer .btn-secondary { border: 1px solid #D7DDE5; background-color: #FFFFFF; diff --git a/resources/sass/components/modal.scss b/resources/sass/components/modal.scss index ab2d73f0bd..91b412377a 100644 --- a/resources/sass/components/modal.scss +++ b/resources/sass/components/modal.scss @@ -28,7 +28,13 @@ color: #20242A; text-transform: none; } +::v-deep .modal-footer .btn-secondary:hover { + background-color: #E9ECF1; +} ::v-deep .modal-footer .btn-primary { background-color: #2773F3; text-transform: none; -} \ No newline at end of file +} +::v-deep .modal-footer .btn-primary:hover { + background-color: #1E5AC7; +} From 5f025b8764463c1e86421a15688090e2f4c020ba Mon Sep 17 00:00:00 2001 From: Paula Quispe Date: Thu, 31 Oct 2024 16:46:39 -0400 Subject: [PATCH 13/31] adding some validations --- .../Commands/UpdateCommentsCaseNumber.php | 17 +++++++++++++---- ..._08_113301_populate_comments_case_number.php | 11 +++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php b/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php index 544ba16a74..4f0ae7f986 100644 --- a/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php +++ b/ProcessMaker/Console/Commands/UpdateCommentsCaseNumber.php @@ -4,11 +4,10 @@ use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; -use ProcessMaker\Models\Comment; class UpdateCommentsCaseNumber extends Command { - const CHUNK_SIZE = 5000; + const CHUNK_SIZE = 2000; /** * The name and signature of the console command. @@ -43,7 +42,11 @@ public function handle() ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { $updates = $comments->mapWithKeys(function ($comment) { - return [$comment->id => ['case_number' => $comment->case_number]]; + if (!is_null($comment->case_number) && !empty($comment->case_number)) { + return [$comment->id => ['case_number' => $comment->case_number]]; + } + + return []; })->toArray(); // Execute in bath the update if (!empty($updates)) { @@ -53,6 +56,7 @@ public function handle() } $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; DB::statement($query); + $this->info(count($updates) . ' comments updated in this chunk related to ProcessRequestToken'); } }); // Update the comments related to ProcessRequest @@ -64,7 +68,11 @@ public function handle() ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { $updates = $comments->mapWithKeys(function ($comment) { - return [$comment->id => ['case_number' => $comment->case_number]]; + if (!is_null($comment->case_number) && !empty($comment->case_number)) { + return [$comment->id => ['case_number' => $comment->case_number]]; + } + + return []; })->toArray(); // Execute in bath the update if (!empty($updates)) { @@ -74,6 +82,7 @@ public function handle() } $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; DB::statement($query); + $this->info(count($updates) . ' comments updated in this chunk related to ProcessRequest'); } }); diff --git a/upgrades/2024_10_08_113301_populate_comments_case_number.php b/upgrades/2024_10_08_113301_populate_comments_case_number.php index cb58995a21..55cfca4b53 100644 --- a/upgrades/2024_10_08_113301_populate_comments_case_number.php +++ b/upgrades/2024_10_08_113301_populate_comments_case_number.php @@ -1,11 +1,12 @@ orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { $updates = $comments->mapWithKeys(function ($comment) { - return [$comment->id => ['case_number' => $comment->case_number]]; + if (!is_null($comment->case_number) && !empty($comment->case_number)) { + return [$comment->id => ['case_number' => $comment->case_number]]; + } + + return []; })->toArray(); // Execute in bath the update if (!empty($updates)) { @@ -54,6 +59,7 @@ public function up(): void } $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; DB::statement($query); + Log::info(count($updates) . ' comments updated in this chunk related to ProcessRequestToken'); } }); // Update the comments related to ProcessRequest @@ -75,6 +81,7 @@ public function up(): void } $query .= ' END WHERE id IN (' . implode(',', array_keys($updates)) . ')'; DB::statement($query); + Log::info(count($updates) . ' comments updated in this chunk related to ProcessRequest'); } }); } From 017a4bfa1497905acddf4c5b8814131b64d7f1fc Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Thu, 31 Oct 2024 17:41:04 -0400 Subject: [PATCH 14/31] fix: refactor cases participated upgrade --- ..._09_152947_populate_cases_participated.php | 126 ++++++++++++++---- 1 file changed, 99 insertions(+), 27 deletions(-) diff --git a/upgrades/2024_10_09_152947_populate_cases_participated.php b/upgrades/2024_10_09_152947_populate_cases_participated.php index 4363a834a8..a2b63d838d 100644 --- a/upgrades/2024_10_09_152947_populate_cases_participated.php +++ b/upgrades/2024_10_09_152947_populate_cases_participated.php @@ -18,6 +18,10 @@ public function up() try { DB::table('cases_participated')->truncate(); + $this->createProcessRequestsTempTable(); + $this->createProcessRequestTokensTempTable(); + $this->process_request_participants_temp(); + $this->getProcessRequests() ->chunk(1000, function ($rows) { $casesParticipated = []; @@ -73,45 +77,113 @@ public function down() DB::table('cases_participated')->truncate(); } + protected function createProcessRequestsTempTable(): void + { + DB::statement('DROP TEMPORARY TABLE IF EXISTS process_requests_temp'); + + $query = DB::table('process_requests as pr') + ->select( + 'pr.id', + 'pr.name', + 'pr.case_number', + 'pr.case_title', + 'pr.case_title_formatted', + 'pr.status', + 'pr.parent_request_id', + 'pr.initiated_at', + 'pr.completed_at', + 'pr.created_at', + 'pr.updated_at', + 'pc.id as process_id', + 'pc.name as process_name' + ) + ->join('processes as pc', 'pr.process_id', '=', 'pc.id') + ->whereIn('pr.status', ['ACTIVE', 'COMPLETED']) + ->whereNotNull('pr.case_number'); + + DB::statement("CREATE TEMPORARY TABLE IF NOT EXISTS process_requests_temp AS ({$query->toSql()})", $query->getBindings()); + } + + protected function createProcessRequestTokensTempTable(): void + { + DB::statement('DROP TEMPORARY TABLE IF EXISTS process_request_tokens_temp'); + + $query = DB::table('process_request_tokens as prt') + ->select([ + 'prt.id', + DB::raw('CAST(prt.id AS CHAR(50)) as task_id'), + 'prt.element_name', + 'prt.element_id', + 'prt.element_type', + 'prt.process_id', + 'prt.status', + 'prt.user_id', + 'prt.process_request_id', + ]) + ->join('process_requests_temp as prt2', 'prt.process_request_id', '=', 'prt2.id') + ->whereIn('prt.element_type', ['task', 'callActivity', 'scriptTask']) + ->whereNotNull('prt.user_id'); + + DB::statement("CREATE TEMPORARY TABLE IF NOT EXISTS process_request_tokens_temp AS ({$query->toSql()})", $query->getBindings()); + } + + protected function process_request_participants_temp(): void + { + DB::statement('DROP TEMPORARY TABLE IF EXISTS process_request_participants_temp'); + + $query = DB::table('process_request_tokens_temp as prt2') + ->select([ + DB::raw('JSON_ARRAYAGG(prt2.user_id) as participants'), + 'pr2.case_number' + ]) + ->join('process_requests_temp as pr2', 'prt2.process_request_id', '=', 'pr2.id') + ->groupBy('pr2.case_number'); + + DB::statement("CREATE TEMPORARY TABLE IF NOT EXISTS process_request_participants_temp AS ({$query->toSql()})", $query->getBindings()); + } + protected function getProcessRequests(): Builder { - return DB::table('process_requests as pr') + return DB::table('process_requests_temp as pr') ->select([ - 'u.id as user_id', + 'prt.user_id', 'pr.case_number', 'pr.case_title', 'pr.case_title_formatted', DB::raw("IF(pr.status = 'ACTIVE', 'IN_PROGRESS', pr.status) as case_status"), - DB::raw('JSON_ARRAYAGG(JSON_OBJECT("id", pc.id, "name", pc.name)) as processes'), - DB::raw('JSON_ARRAYAGG(JSON_OBJECT("id", pr.id, "name", pc.name, "parent_request_id", pr.parent_request_id)) as requests'), - DB::raw('JSON_ARRAYAGG(prt.id) as request_tokens'), - DB::raw('JSON_ARRAYAGG(IF(prt.element_type != "callActivity", JSON_OBJECT("id", prt.id, "name", prt.element_name, "element_id", prt.element_id, "process_id", prt.process_id), NULL)) as tasks'), + DB::raw("JSON_ARRAYAGG(JSON_OBJECT('id', pr.process_id, 'name', pr.process_name)) as processes"), + DB::raw("JSON_ARRAYAGG(JSON_OBJECT('id', pr.id, 'name', pr.name, 'parent_request_id', pr.parent_request_id)) as requests"), + DB::raw("JSON_ARRAYAGG(prt.id) as request_tokens"), + DB::raw("JSON_ARRAYAGG( + IF(prt.element_type != 'callActivity', + JSON_OBJECT( + 'id', prt.task_id, + 'name', prt.element_name, + 'element_id', prt.element_id, + 'process_id', prt.process_id, + 'status', prt.status + ), JSON_OBJECT()) + ) as tasks"), 'par.participants', 'pr.initiated_at', 'pr.completed_at', 'pr.created_at', - 'pr.updated_at', + 'pr.updated_at' ]) - ->join('process_request_tokens as prt', 'pr.id', '=', 'prt.process_request_id') - ->join('users as u', 'prt.user_id', '=', 'u.id') - ->join('processes as pc', 'pr.process_id', '=', 'pc.id') - ->joinSub( - DB::table('users as u2') - ->selectRaw('JSON_ARRAYAGG(u2.id) as participants, pr2.case_number') - ->join('process_request_tokens as prt2', 'u2.id', '=', 'prt2.user_id') - ->join('process_requests as pr2', 'prt2.process_request_id', '=', 'pr2.id') - ->whereNotNull('pr2.case_number') - ->groupBy('pr2.case_number'), - 'par', - 'par.case_number', - '=', - 'pr.case_number' + ->join('process_request_tokens_temp as prt', 'pr.id', '=', 'prt.process_request_id') + ->join('process_request_participants_temp as par', 'pr.case_number', '=', 'par.case_number') + ->groupBy( + 'prt.user_id', + 'pr.case_number', + 'pr.case_title', + 'pr.case_title_formatted', + DB::raw("IF(pr.status = 'ACTIVE', 'IN_PROGRESS', pr.status)"), + 'par.participants', + 'pr.initiated_at', + 'pr.completed_at', + 'pr.created_at', + 'pr.updated_at' ) - ->whereIn('pr.status', ['ACTIVE', 'COMPLETED']) - ->whereIn('prt.element_type', ['task', 'callActivity', 'scriptTask']) - ->whereNotNull('pr.case_number') - ->groupBy('u.id', 'pr.id') - ->orderBy('pr.id') - ->orderBy('u.id'); + ->orderBy('pr.case_number'); } } From ecdb1c7c665bf66a1c4c8fee77a3e32d6c94f43a Mon Sep 17 00:00:00 2001 From: Paula Quispe Date: Thu, 31 Oct 2024 18:09:04 -0400 Subject: [PATCH 15/31] solving issue #2 --- .../2024_10_08_113301_populate_comments_case_number.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/upgrades/2024_10_08_113301_populate_comments_case_number.php b/upgrades/2024_10_08_113301_populate_comments_case_number.php index 55cfca4b53..ff17af603c 100644 --- a/upgrades/2024_10_08_113301_populate_comments_case_number.php +++ b/upgrades/2024_10_08_113301_populate_comments_case_number.php @@ -71,7 +71,11 @@ public function up(): void ->orderBy('comments.id', 'asc') ->chunk($chunkSize, function ($comments) { $updates = $comments->mapWithKeys(function ($comment) { - return [$comment->id => ['case_number' => $comment->case_number]]; + if (!is_null($comment->case_number) && !empty($comment->case_number)) { + return [$comment->id => ['case_number' => $comment->case_number]]; + } + + return []; })->toArray(); // Execute in bath the update if (!empty($updates)) { From 1910c2a48b54889fb4062ef608236c6fd83b6a16 Mon Sep 17 00:00:00 2001 From: Roly Gutierrez Date: Thu, 31 Oct 2024 19:21:24 -0400 Subject: [PATCH 16/31] FOUR-19937 `Reassignment field` does not have the correct UI --- .../components/ProcessesPermissions.vue | 42 +++++++++++++++---- resources/views/processes/edit.blade.php | 1 + 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/resources/js/processes/components/ProcessesPermissions.vue b/resources/js/processes/components/ProcessesPermissions.vue index 16403e6aa3..5167a70d56 100644 --- a/resources/js/processes/components/ProcessesPermissions.vue +++ b/resources/js/processes/components/ProcessesPermissions.vue @@ -1,7 +1,7 @@