diff --git a/ProcessMaker/Http/Controllers/CasesController.php b/ProcessMaker/Http/Controllers/CasesController.php index c6a0a94e44..0605f5ec60 100644 --- a/ProcessMaker/Http/Controllers/CasesController.php +++ b/ProcessMaker/Http/Controllers/CasesController.php @@ -53,9 +53,9 @@ public function show($case_number) // "Initialload.js" file causes an issue related to SVG in the modeler // The other scripts are not needed in the case detail $scriptsDisabled = ['package-slideshow', 'package-process-optimization', 'package-ab-testing', 'package-testing', 'initialLoad']; - $managerModelerScripts = array_filter($managerModeler->getScripts(), function ($script) use ($scriptsDisabled) { + $managerModelerScripts = array_filter($managerModeler->getScriptWithParams(), function ($script) use ($scriptsDisabled) { foreach ($scriptsDisabled as $enabledScript) { - if (strpos($script, $enabledScript) !== false) { + if (strpos($script['src'], $enabledScript) !== false) { return false; } } diff --git a/ProcessMaker/Http/Controllers/RequestController.php b/ProcessMaker/Http/Controllers/RequestController.php index c9a1e6a41d..37723a2918 100644 --- a/ProcessMaker/Http/Controllers/RequestController.php +++ b/ProcessMaker/Http/Controllers/RequestController.php @@ -180,9 +180,12 @@ public function show(ProcessRequest $request, Media $mediaItems) event(new ModelerStarting($managerModeler)); $scriptsEnabled = ['package-slideshow', 'package-process-optimization', 'package-ab-testing', 'package-testing']; - $managerModelerScripts = array_filter($managerModeler->getScripts(), function ($script) use ($scriptsEnabled) { + $managerModelerScripts = array_filter($managerModeler->getScriptWithParams(), function ($script) use ($scriptsEnabled) { foreach ($scriptsEnabled as $enabledScript) { - if (strpos($script, $enabledScript) !== false) { + if (empty($script['src'])) { + continue; + } + if (strpos($script['src'], $enabledScript) !== false) { return false; } } diff --git a/resources/jscomposition/cases/casesDetail/edit.js b/resources/jscomposition/cases/casesDetail/edit.js index 6a674debd1..4af2f9a5cc 100644 --- a/resources/jscomposition/cases/casesDetail/edit.js +++ b/resources/jscomposition/cases/casesDetail/edit.js @@ -13,170 +13,173 @@ import { Vue.globalStore.registerModule("core:cases", cases); -const caseDetail = new Vue({ - el: "#case-detail", - components: { - CaseDetail, Tabs, CollapsableContainer, Timeline, StageBar, - }, - data() { - return { - data, - request, - canCancel, - canViewPrint, - status: "ACTIVE", - userRequested: [], - errorLogs, - packages: [], - processId, - canViewComments, - disabled: false, - retryDisabled: false, - tabDefault: "details", - collapseContainer: true, - tabs: [ - { - name: "Details", - href: "#details", - current: "details", - show: true, - content: null, - }, - { - name: "Comments", - href: "#comments", - current: "comments", - show: true, - content: null, - }, - ], - headerModel: false, - progressStage: getProgressStage(), - stageName: getStageName(), - }; - }, - computed: { - /** - * Get the list of participants in the request. - * - */ - participants() { - return this.request.participants; +window.addEventListener("load", () => { + const caseDetail = new Vue({ + el: "#case-detail", + components: { + CaseDetail, Tabs, CollapsableContainer, Timeline, StageBar, }, - classStatusCard() { - const header = { - ACTIVE: "active-style", - COMPLETED: "active-style", - CANCELED: "canceled-style ", - ERROR: "canceled-style", - }; - return `tw-rounded-md text-status ${header[this.request.status.toUpperCase()]}`; - }, - labelDate() { - const label = { - ACTIVE: "In Progress Since", - COMPLETED: "Completed On", - CANCELED: "Canceled ", - ERROR: "Failed On", - }; - return label[this.request.status.toUpperCase()]; - }, - statusDate() { - const status = { - ACTIVE: this.request.created_at, - COMPLETED: this.request.completed_at, - CANCELED: this.request.updated_at, - ERROR: this.request.updated_at, + data() { + return { + data, + request, + canCancel, + canViewPrint, + status: "ACTIVE", + userRequested: [], + errorLogs, + packages: [], + processId, + canViewComments, + disabled: false, + retryDisabled: false, + tabDefault: "details", + collapseContainer: true, + tabs: [ + { + name: "Details", + href: "#details", + current: "details", + show: true, + content: null, + }, + { + name: "Comments", + href: "#comments", + current: "comments", + show: true, + content: null, + }, + ], + headerModel: false, + progressStage: getProgressStage(), + stageName: getStageName(), }; - - return status[this.request.status.toUpperCase()]; }, - statusLabel() { - const status = { - ACTIVE: this.$t("In Progress"), - COMPLETED: this.$t("Completed"), - CANCELED: this.$t("Canceled"), - ERROR: this.$t("Error"), - }; + computed: { + /** + * Get the list of participants in the request. + * + */ + participants() { + return this.request.participants; + }, + classStatusCard() { + const header = { + ACTIVE: "active-style", + COMPLETED: "active-style", + CANCELED: "canceled-style ", + ERROR: "canceled-style", + }; + return `tw-rounded-md text-status ${header[this.request.status.toUpperCase()]}`; + }, + labelDate() { + const label = { + ACTIVE: "In Progress Since", + COMPLETED: "Completed On", + CANCELED: "Canceled ", + ERROR: "Failed On", + }; + return label[this.request.status.toUpperCase()]; + }, + statusDate() { + const status = { + ACTIVE: this.request.created_at, + COMPLETED: this.request.completed_at, + CANCELED: this.request.updated_at, + ERROR: this.request.updated_at, + }; - return status[this.request.status.toUpperCase()]; - }, - requestBy() { - return [this.request.user]; - }, - panCommentInVueOptionsComponents() { - return "pan-comment" in Vue.options.components; - }, + return status[this.request.status.toUpperCase()]; + }, + statusLabel() { + const status = { + ACTIVE: this.$t("In Progress"), + COMPLETED: this.$t("Completed"), + CANCELED: this.$t("Canceled"), + ERROR: this.$t("Error"), + }; - }, - async mounted() { - const store = useStore(); - this.packages = window.ProcessMaker.requestShowPackages; + return status[this.request.status.toUpperCase()]; + }, + requestBy() { + return [this.request.user]; + }, + panCommentInVueOptionsComponents() { + return "pan-comment" in Vue.options.components; + }, - const response = await this.getUserConf(); - - store.commit("core:cases/updateUserConfiguration", response); - this.collapseContainer = store.getters["core:cases/getCollapseContainer"]; - }, - methods: { - onCancel() { - ProcessMaker.confirmModal( - this.$t("Caution!"), - this.$t("Are you sure you want cancel this request?"), - "", - () => { - this.okCancel(); - }, - ); }, - async onToogleContainer(value) { + async mounted() { const store = useStore(); - store.commit("core:cases/updateCollapseContainer", value); + this.packages = window.ProcessMaker.requestShowPackages; - const userConf = store.getters["core:cases/getUserConfiguration"]; + const response = await this.getUserConf(); - const response = await updateUserConfiguration({ - user_id: userConf.user_id, - ui_configuration: userConf.ui_configuration, - }); + store.commit("core:cases/updateUserConfiguration", response); + this.collapseContainer = store.getters["core:cases/getCollapseContainer"]; }, - getUserConf: async () => { - const response = await getUserConfiguration(); + methods: { + onCancel() { + ProcessMaker.confirmModal( + this.$t("Caution!"), + this.$t("Are you sure you want cancel this request?"), + "", + () => { + this.okCancel(); + }, + ); + }, + async onToogleContainer(value) { + const store = useStore(); + store.commit("core:cases/updateCollapseContainer", value); - return { - user_id: response.user_id, - ui_configuration: JSON.parse(response.ui_configuration), - }; - }, - getCommentsData: async () => { - const request = getRequest(); + const userConf = store.getters["core:cases/getUserConfiguration"]; - const response = await getCommentsData({ - params: { - type: "COMMENT,REPLY", - order_direction: "desc", - case_number: request.case_number, - }, - }); + const response = await updateUserConfiguration({ + user_id: userConf.user_id, + ui_configuration: userConf.ui_configuration, + }); + }, + getUserConf: async () => { + const response = await getUserConfiguration(); - return response; - }, - async okCancel() { - // single click - if (this.disabled) { - return; - } - this.disabled = true; - try { - await updateRequest(getRequestId(), { - status: "CANCELED", + return { + user_id: response.user_id, + ui_configuration: JSON.parse(response.ui_configuration), + }; + }, + getCommentsData: async () => { + const request = getRequest(); + + const response = await getCommentsData({ + params: { + type: "COMMENT,REPLY", + order_direction: "desc", + case_number: request.case_number, + }, }); - ProcessMaker.alert(this.$t("The request was canceled."), "success"); - window.location.reload(); - } catch (error) { - this.disabled = false; - } + return response; + }, + async okCancel() { + // single click + if (this.disabled) { + return; + } + this.disabled = true; + try { + await updateRequest(getRequestId(), { + status: "CANCELED", + }); + + ProcessMaker.alert(this.$t("The request was canceled."), "success"); + window.location.reload(); + } catch (error) { + this.disabled = false; + } + }, }, - }, + }); }); + diff --git a/resources/views/cases/edit.blade.php b/resources/views/cases/edit.blade.php index d9e57e00c7..697467b176 100644 --- a/resources/views/cases/edit.blade.php +++ b/resources/views/cases/edit.blade.php @@ -184,8 +184,16 @@ class="tw-grow tw-overflow-hidden" @endforeach - @foreach($managerModelerScripts as $script) - + @foreach($managerModelerScripts as $params) + @endforeach @if (hasPackage('package-files')) diff --git a/resources/views/requests/show.blade.php b/resources/views/requests/show.blade.php index 5af0855553..9dbfcdd552 100644 --- a/resources/views/requests/show.blade.php +++ b/resources/views/requests/show.blade.php @@ -472,8 +472,16 @@ class="btn btn-outline-info btn-block" }; - @foreach($managerModelerScripts as $script) - + @foreach($managerModelerScripts as $params) + @endforeach @foreach($manager->getScripts() as $script) diff --git a/tests/Feature/RequestControllerShowTest.php b/tests/Feature/RequestControllerShowTest.php new file mode 100644 index 0000000000..fa9add2348 --- /dev/null +++ b/tests/Feature/RequestControllerShowTest.php @@ -0,0 +1,112 @@ +user = User::factory()->create([ + 'is_administrator' => true, + ]); + } + + /** + * Test that the show page renders managerModelerScripts correctly + * + * @return void + */ + public function testShowPageRendersManagerModelerScripts() + { + // Create a process + $process = Process::factory()->create([ + 'user_id' => $this->user->id, + ]); + + // Create a process request + $request = ProcessRequest::factory()->create([ + 'process_id' => $process->id, + 'user_id' => $this->user->id, + 'status' => 'ACTIVE', + ]); + + // Create a task token + ProcessRequestToken::factory()->create([ + 'process_request_id' => $request->id, + 'user_id' => $this->user->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + // Mock the ModelerManager to return test scripts + $mockManager = $this->createMock(ModelerManager::class); + $mockManager->method('getScriptWithParams') + ->willReturn([ + [ + 'src' => '/js/test-script-1.js', + 'type' => 'module', + 'async' => true, + ], + [ + 'src' => '/js/test-script-2.js', + 'type' => 'text/javascript', + 'defer' => true, + ], + [ + 'src' => '/js/package-slideshow.js', + 'type' => 'text/javascript', + ], + [ + 'src' => '/js/package-process-optimization.js', + 'type' => 'text/javascript', + ], + ]); + + $this->app->instance(ModelerManager::class, $mockManager); + + // Make the request to the show page + $response = $this->webCall('GET', '/requests/' . $request->id); + + // Assert the response is successful + $response->assertStatus(200); + $response->assertViewIs('requests.show'); + + // Get the filtered scripts (should exclude the disabled ones) + $managerModelerScripts = $response->viewData('managerModelerScripts'); + + // Assert that the filtered scripts contain only the allowed scripts + $this->assertCount(2, $managerModelerScripts); + + // Check that the disabled scripts are filtered out + $scriptSources = array_column($managerModelerScripts, 'src'); + $this->assertContains('/js/test-script-1.js', $scriptSources); + $this->assertContains('/js/test-script-2.js', $scriptSources); + $this->assertNotContains('/js/package-slideshow.js', $scriptSources); + $this->assertNotContains('/js/package-process-optimization.js', $scriptSources); + + // Assert that the scripts are rendered with the correct attributes in the HTML + $response->assertSee('/js/test-script-1.js'); + $response->assertSee('/js/test-script-2.js'); + $response->assertSee('type="module"', false); + $response->assertSee('async'); + $response->assertSee('defer'); + + // Assert that disabled scripts are not rendered + $response->assertDontSee('/js/package-slideshow.js'); + $response->assertDontSee('/js/package-process-optimization.js'); + } +}