diff --git a/ProcessMaker/Helpers/MobileHelper.php b/ProcessMaker/Helpers/MobileHelper.php
index f577f4284f..2d8254f763 100644
--- a/ProcessMaker/Helpers/MobileHelper.php
+++ b/ProcessMaker/Helpers/MobileHelper.php
@@ -13,4 +13,9 @@ public static function isMobile($userAgent)
return false;
}
+
+ public static function detectMobile()
+ {
+ return isset($_SERVER['HTTP_USER_AGENT']) && self::isMobile($_SERVER['HTTP_USER_AGENT']);
+ }
}
diff --git a/ProcessMaker/Http/Controllers/Api/ProcessLaunchpadController.php b/ProcessMaker/Http/Controllers/Api/ProcessLaunchpadController.php
index a25e7452e6..6346f0486f 100644
--- a/ProcessMaker/Http/Controllers/Api/ProcessLaunchpadController.php
+++ b/ProcessMaker/Http/Controllers/Api/ProcessLaunchpadController.php
@@ -24,7 +24,9 @@ public function getProcesses(Request $request)
$processes = Process::nonSystem()->active();
// Filter by category
$category = $request->input('category', null);
- if (!empty($category)) {
+ if ($category === 'recent') {
+ $processes->orderByRecentRequests();
+ } elseif (!empty($category)) {
$processes->processCategory($category);
}
// Filter pmql
@@ -44,6 +46,7 @@ public function getProcesses(Request $request)
// Get the processes
$processes = $processes
->select('processes.*')
+ ->withRequestCount()
->orderBy('processes.name', 'asc')
->paginate($perPage);
@@ -120,9 +123,9 @@ public function destroy(ProcessLaunchpad $launch)
return response([], 204);
}
- /**
- * Store the elements related to the carousel [IMAGE, EMBED URL]
- */
+ /**
+ * Store the elements related to the carousel [IMAGE, EMBED URL]
+ */
public function saveContentCarousel(Request $request, Process $process)
{
$contentCarousel = $request->input('imagesCarousel');
@@ -144,7 +147,6 @@ public function saveContentCarousel(Request $request, Process $process)
// Nothing
break;
}
-
}
}
}
diff --git a/ProcessMaker/Http/Controllers/ProcessesCatalogueController.php b/ProcessMaker/Http/Controllers/ProcessesCatalogueController.php
index 7e333e24a7..4c394861f8 100644
--- a/ProcessMaker/Http/Controllers/ProcessesCatalogueController.php
+++ b/ProcessMaker/Http/Controllers/ProcessesCatalogueController.php
@@ -5,12 +5,13 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use ProcessMaker\Events\ScreenBuilderStarting;
+use ProcessMaker\Helpers\MobileHelper;
use ProcessMaker\Http\Controllers\Controller;
use ProcessMaker\Managers\ScreenBuilderManager;
-use ProcessMaker\Models\Process;
use ProcessMaker\Models\Bookmark;
-use ProcessMaker\Models\ProcessLaunchpad;
+use ProcessMaker\Models\Process;
use ProcessMaker\Models\ProcessCategory;
+use ProcessMaker\Models\ProcessLaunchpad;
use ProcessMaker\Traits\HasControllerAddons;
/**
@@ -22,7 +23,7 @@
class ProcessesCatalogueController extends Controller
{
use HasControllerAddons;
-
+
public function index(Request $request, Process $process = null)
{
$manager = app(ScreenBuilderManager::class);
@@ -33,6 +34,13 @@ public function index(Request $request, Process $process = null)
$process->launchpad = ProcessLaunchpad::getLaunchpad(true, $process->id);
$process->bookmark_id = Bookmark::getBookmarked(true, $process->id, $currentUser['id']);
}
+
+ if (MobileHelper::detectMobile()) {
+ $title = __('Process Browser');
+
+ return view('processes-catalogue.mobile', compact('title', 'process', 'currentUser', 'manager'));
+ }
+
return view('processes-catalogue.index', compact('process', 'currentUser', 'manager'));
}
}
diff --git a/ProcessMaker/Models/Process.php b/ProcessMaker/Models/Process.php
index efa6d91c04..111b637904 100644
--- a/ProcessMaker/Models/Process.php
+++ b/ProcessMaker/Models/Process.php
@@ -1162,29 +1162,34 @@ public function manageCustomRoutes()
break;
default:
- if ($webEntryProperties->webentryRouteConfig->firstUrlSegment !== '') {
- $webentryRouteConfig = $webEntryProperties->webentryRouteConfig;
- try {
- WebentryRoute::updateOrCreate(
- [
- 'process_id' => $this->id,
- 'node_id' => $webentryRouteConfig->nodeId,
- ],
- [
- 'first_segment' => $webentryRouteConfig->firstUrlSegment,
- 'params' => $webentryRouteConfig->parameters,
- ]
- );
- } catch (\Exception $e) {
- \Log::info('*** Error: ' . $e->getMessage());
- }
- }
+ $this->manageWebentryRoute($webEntryProperties);
break;
}
}
}
}
+ private function manageWebentryRoute($webEntryProperties)
+ {
+ if ($webEntryProperties->webentryRouteConfig->firstUrlSegment !== '') {
+ $webentryRouteConfig = $webEntryProperties->webentryRouteConfig;
+ try {
+ WebentryRoute::updateOrCreate(
+ [
+ 'process_id' => $this->id,
+ 'node_id' => $webentryRouteConfig->nodeId,
+ ],
+ [
+ 'first_segment' => $webentryRouteConfig->firstUrlSegment,
+ 'params' => $webentryRouteConfig->parameters,
+ ]
+ );
+ } catch (Exception $e) {
+ \Log::info('*** Error: ' . $e->getMessage());
+ }
+ }
+ }
+
/**
* Get node element attributes
*
@@ -1250,7 +1255,7 @@ private function getStartEventPermissions(User $user)
/**
* Process events relationship.
*
- * @return \ProcessMaker\Models\ProcessEvents
+ * @return ProcessEvents
*/
public function events()
{
@@ -1287,7 +1292,7 @@ public function launchpad()
/**
* Assignments of the process.
*
- * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ * @return HasMany
*/
public function assignments()
{
@@ -1616,7 +1621,7 @@ private function validateSchema(BpmnDocument $document)
private function deleteUnusedCustomRoutes($url, $processId, $nodeId)
{
// Delete unused custom routes
- $customRoute = webentryRoute::where('process_id', $processId)->where('node_id', $nodeId)->first();
+ $customRoute = WebentryRoute::where('process_id', $processId)->where('node_id', $nodeId)->first();
if ($customRoute) {
$customRoute->delete();
}
@@ -1751,9 +1756,9 @@ public function scopeFilter($query, $filterStr)
->orWhere('processes.description', 'like', $filter)
->orWhere('processes.status', '=', $filterStr)
->orWhereHas('user', function ($query) use ($filter) {
- $query->where('firstname', 'like', $filter)
- ->orWhere('lastname', 'like', $filter);
- })
+ $query->where('firstname', 'like', $filter)
+ ->orWhere('lastname', 'like', $filter);
+ })
->orWhereIn('processes.id', function ($qry) use ($filter) {
$qry->select('assignable_id')
->from('category_assignments')
@@ -1797,4 +1802,29 @@ public function hasAlternative()
{
return true;
}
+
+ public function scopeOrderByRecentRequests($query)
+ {
+ return $query->orderByDesc(
+ ProcessRequest::select('id')
+ // User has participated
+ ->whereHas('tokens', function ($q) {
+ $q->where('user_id', Auth::user()->id);
+ })
+ ->whereColumn('process_id', 'processes.id')
+ ->orderByDesc('id') // using ID because created_at is not indexed
+ ->limit(1)
+ );
+ }
+
+ public function scopeWithRequestCount($query)
+ {
+ return $query->withCount(['requests' => function ($query) {
+ return $query->where('status', 'ACTIVE')
+ // User has participated
+ ->whereHas('tokens', function ($q) {
+ $q->where('user_id', Auth::user()->id);
+ });
+ }]);
+ }
}
diff --git a/resources/js/app-layout.js b/resources/js/app-layout.js
index fd51785742..0eb36d34ae 100644
--- a/resources/js/app-layout.js
+++ b/resources/js/app-layout.js
@@ -222,6 +222,17 @@ if (isMobileNavbar === "true") {
return {
};
},
+ computed: {
+ visible() {
+
+
+
+// wont work because of replaceState. Maybe replace state listener???
+
+ // Do not show on process details page
+ return !(/process-browser\/\d+/.test(window.location.href));
+ }
+ },
mounted() {
if (this.$cookies.get("firstMounted") === "true") {
$("#welcomeModal").modal("show");
diff --git a/resources/js/processes-catalogue/components/CardProcess.vue b/resources/js/processes-catalogue/components/CardProcess.vue
index f8ad2b7dac..49111e1425 100644
--- a/resources/js/processes-catalogue/components/CardProcess.vue
+++ b/resources/js/processes-catalogue/components/CardProcess.vue
@@ -154,10 +154,16 @@ export default {
};
-
diff --git a/resources/js/processes-catalogue/components/ProcessesCarousel.vue b/resources/js/processes-catalogue/components/ProcessesCarousel.vue
index 603ebbaf6f..4511de3101 100644
--- a/resources/js/processes-catalogue/components/ProcessesCarousel.vue
+++ b/resources/js/processes-catalogue/components/ProcessesCarousel.vue
@@ -1,37 +1,64 @@
-