Skip to content
4 changes: 3 additions & 1 deletion ProcessMaker/Http/Controllers/CasesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ class CasesController extends Controller
*/
public function index()
{
$manager = app(ScreenBuilderManager::class);
event(new ScreenBuilderStarting($manager, 'FORM'));
$currentUser = Auth::user()->only(['id', 'username', 'fullname', 'firstname', 'lastname', 'avatar']);

// This is a temporary API the engine team will provide the new
return view('cases.casesMain', compact('currentUser'));
return view('cases.casesMain', compact('currentUser', 'manager'));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/TreeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default {
},
},
mounted() {
const jsonCrackEmbed = this.$refs.jsonCrackEmbed;
const { jsonCrackEmbed } = this.$refs;
const json = this.jsonData === "" ? "{}" : this.jsonData;
const options = {
theme: "light",
Expand Down
53 changes: 53 additions & 0 deletions resources/js/next/badPractices.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* BAD PRACTICES
*/

// Use multiple forms of an event bus.
window.ProcessMaker = {
EventBus: new Vue(),
events: new Vue()
};

// Force to overload the vue object
window.Vue.prototype.moment = moment;

// Load all statements in a single file bootstrap.js

// Overload the window.ProcessMaker variable without using the setGlobalVariable function

// Use local variables instead of window.ProcessMaker
window.ProcessMaker.removeNotifications = (messageIds = [], urls = []) => {
return window.ProcessMaker.apiClient.put("/read_notifications", { message_ids: messageIds, routes: urls }).then(() => {
messageIds.forEach((messageId) => {
ProcessMaker.notifications.splice(ProcessMaker.notifications.findIndex((x) => x.id === messageId), 1);
});

urls.forEach((url) => {
const messageIndex = ProcessMaker.notifications.findIndex((x) => x.url === url);
if (messageIndex >= 0) {
ProcessMaker.removeNotification(ProcessMaker.notifications[messageIndex].id);
}
});
});
};

// Remove the saved search unneeded
class InjectJavascript
{
public function handle($request, Closure $next)
{
$response = $next($request);
if (get_class($response) !== Response::class) {
return $response;
}
$content = $response->getContent();
$tag = '';
$tag .= '<script src="' . mix('/js/addSaveButton.js', 'vendor/processmaker/packages/package-savedsearch') . '"></script>';
$tag .= '<script src="' . mix('/js/listenForRecounts.js', 'vendor/processmaker/packages/package-savedsearch') . '"></script>';
$content = str_replace('</body>', $tag . "\n</body>", $content);
$response->setContent($content);

return $response;
}
}

112 changes: 112 additions & 0 deletions resources/js/next/components/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { getGlobalVariable } from "../globalVariables";

// Multiselect

const Vue = getGlobalVariable("Vue");

const pmComponents = {
// Components folder
AvatarImage: () => import("../../components/AvatarImage.vue"),
Breadcrumbs: () => import("../../components/Breadcrumbs.vue"),
Confirm: () => import("../../components/Confirm.vue"),
CustomActions: () => import("../../components/CustomActions.vue"),
DetailRow: () => import("../../components/DetailRow.vue"),
FilterBar: () => import("../../components/FilterBar.vue"),
Menu: () => import("../../components/Menu.vue"),
Message: () => import("../../components/Message.vue"),
NavbarProfile: () => import("../../components/NavbarProfile.vue"),
PMBadgesFilters: () => import("../../components/PMBadgesFilters.vue"),
PMDatetimePicker: () => import("../../components/PMDatetimePicker.vue"),
PMDropdownSuggest: () => import("../../components/PMDropdownSuggest.vue"),
PMFloatingButtons: () => import("../../components/PMFloatingButtons.vue"),
PMFormSelectSuggest: () => import("../../components/PMFormSelectSuggest.vue"),
PMMessageResults: () => import("../../components/PMMessageResults.vue"),
PMMessageScreen: () => import("../../components/PMMessageScreen.vue"),
PMPanelWithCustomHeader: () => import("../../components/PMPanelWithCustomHeader.vue"),
PMPopoverConfirmation: () => import("../../components/PMPopoverConfirmation.vue"),
PMSearchBar: () => import("../../components/PMSearchBar.vue"),
PMTable: () => import("../../components/PMTable.vue"),
PMTabs: () => import("../../components/PMTabs.vue"),
Recommendations: () => import("../../components/Recommendations.vue"),
SelectFromApi: () => import("../../components/SelectFromApi.vue"),
SelectLanguage: () => import("../../components/SelectLanguage.vue"),
SelectScreen: () => import("../../components/SelectScreen.vue"),
SelectStatus: () => import("../../components/SelectStatus.vue"),
SelectUser: () => import("../../components/SelectUser.vue"),
SelectUserGroup: () => import("../../components/SelectUserGroup.vue"),
Session: () => import("../../components/Session.vue"),
Sidebaricon: () => import("../../components/Sidebaricon.vue"),
Timeline: () => import("../../components/Timeline.vue"),
TimelineItem: () => import("../../components/TimelineItem.vue"),
TreeView: () => import("../../components/TreeView.vue"),
// Shared components folder
AddToBundle: () => import("../../components/shared/AddToBundle"),
AddToProjectModal: () => import("../../components/shared/AddToProjectModal"),
AssetDependentTreeModal: () => import("../../components/shared/AssetDependentTreeModal.vue"),
AssetTreeModal: () => import("../../components/shared/AssetTreeModal.vue"),
BackendSelect: () => import("../../components/shared/BackendSelect.vue"),
BasicSearch: () => import("../../components/shared/BasicSearch.vue"),
CategorySelect: () => import("../../components/shared/CategorySelect.vue"),
ChangeLog: () => import("../../components/shared/ChangeLog.vue"),
ColorSchemeSelector: () => import("../../components/shared/ColorSchemeSelector.vue"),
Column: () => import("../../components/shared/Column.vue"),
ColumnChooser: () => import("../../components/shared/ColumnChooser.vue"),
ColumnConfig: () => import("../../components/shared/ColumnConfig.vue"),
DataCard: () => import("../../components/shared/DataCard.vue"),
DataFormatSelector: () => import("../../components/shared/DataFormatSelector.vue"),
DataMaskSelector: () => import("../../components/shared/DataMaskSelector.vue"),
DataNode: () => import("../../components/shared/DataNode.vue"),
DataTree: () => import("../../components/shared/DataTree.vue"),
DownloadSvgButton: () => import("../../components/shared/DownloadSvgButton.vue"),
DraggableFileUpload: () => import("../../components/shared/DraggableFileUpload.vue"),
EllipsisMenu: () => import("../../components/shared/EllipsisMenu.vue"),
FileUploadButton: () => import("../../components/shared/FileUploadButton.vue"),
FilterTable: () => import("../../components/shared/FilterTable.vue"),
IconDropdown: () => import("../../components/shared/IconDropdown.vue"),
IconSelector: () => import("../../components/shared/IconSelector.vue"),
InputImageCarousel: () => import("../../components/shared/InputImageCarousel.vue"),
LaunchpadSettingsModal: () => import("../../components/shared/LaunchpadSettingsModal.vue"),
Modal: () => import("../../components/shared/Modal.vue"),
ModalSaveVersion: () => import("../../components/shared/ModalSaveVersion.vue"),
MultiThumbnailFileUploader: () => import("../../components/shared/MultiThumbnailFileUploader.vue"),
PaginationTable: () => import("../../components/shared/PaginationTable.vue"),
PmqlInput: () => import("../../components/shared/PmqlInput.vue"),
PmqlInputFilters: () => import("../../components/shared/PmqlInputFilters.vue"),
ProjectSelect: () => import("../../components/shared/ProjectSelect.vue"),
PTab: () => import("../../components/shared/PTab.vue"),
PTabs: () => import("../../components/shared/PTabs.vue"),
Required: () => import("../../components/shared/Required.vue"),
SidebarButton: () => import("../../components/shared/SidebarButton.vue"),
SidebarNav: () => import("../../components/shared/SidebarNav.vue"),
SliderWithInput: () => import("../../components/shared/SliderWithInput.vue"),
// Common components folder
DataTreeToggle: () => import("../../components/common/data-tree-toggle.vue"),
// Tasks components folder
MobileTasks: () => import("../../tasks/components/MobileTasks.vue"),
NavbarTaskMobile: () => import("../../tasks/components/NavbarTaskMobile.vue"),
QuickFillPreview: () => import("../../tasks/components/QuickFillPreview.vue"),
ReassignMobileModal: () => import("../../tasks/components/ReassignMobileModal.vue"),
SplitpaneContainer: () => import("../../tasks/components/SplitpaneContainer.vue"),
TaskDetailsMobile: () => import("../../tasks/components/TaskDetailsMobile.vue"),
TaskListRowButtons: () => import("../../tasks/components/TaskListRowButtons.vue"),
TaskLoading: () => import("../../tasks/components/TaskLoading.vue"),
TaskSaveNotification: () => import("../../tasks/components/TaskSaveNotification.vue"),
TaskSavePanel: () => import("../../tasks/components/TaskSavePanel.vue"),
TasksHome: () => import("../../tasks/components/TasksHome.vue"),
TasksList: () => import("../../tasks/components/TasksList.vue"),
TasksListCounter: () => import("../../tasks/components/TasksListCounter.vue"),
TasksPreview: () => import("../../tasks/components/TasksPreview.vue"),
TaskTooltip: () => import("../../tasks/components/TaskTooltip.vue"),
TaskView: () => import("../../tasks/components/TaskView.vue"),
};

Object.entries(pmComponents).forEach(([key, component]) => {
Vue.component(key, component);
});

// Multiselect
Vue.component("Multiselect", (resolve, reject) => {
import("@processmaker/vue-multiselect").then((Multiselect) => {
resolve(Multiselect.Multiselect);
}).catch(reject);
});
6 changes: 6 additions & 0 deletions resources/js/next/config/accesibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AccessibilityMixin from "./components/common/mixins/accessibility";
import { getGlobalVariable } from "../globalVariables";

const Vue = getGlobalVariable("Vue");

Vue.mixin(AccessibilityMixin);
59 changes: 59 additions & 0 deletions resources/js/next/config/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import i18next from "i18next";
import Backend from "i18next-chained-backend";
import LocalStorageBackend from "i18next-localstorage-backend";
import XHR from "i18next-xhr-backend";
import VueI18Next from "@panter/vue-i18next";
import { setGlobalPMVariable, getGlobalVariable } from "../globalVariables";

const Vue = getGlobalVariable("Vue");

const isProd = document.head.querySelector("meta[name=\"is-prod\"]")?.content === "true";
let translationsLoaded = false;

const mdates = JSON.parse(
document.head.querySelector("meta[name=\"i18n-mdate\"]")?.content,
);

const missingTranslations = new Set();
const missingTranslation = function (value) {
if (missingTranslations.has(value)) { return; }
missingTranslations.add(value);
if (!isProd) {
console.warn("Missing Translation:", value);
}
};

const i18nPromise = i18next.use(Backend).init({
lng: document.documentElement.lang,
fallbackLng: "en", // default language when no translations
returnEmptyString: false, // When a translation is an empty string, return the default language, not empty
nsSeparator: false,
keySeparator: false,
parseMissingKeyHandler(value) {
if (!translationsLoaded) { return value; }
// Report that a translation is missing
missingTranslation(value);
// Fallback to showing the english version
return value;
},
backend: {
backends: [
LocalStorageBackend, // Try cache first
XHR,
],
backendOptions: [
{ versions: mdates },
{ loadPath: "/i18next/fetch/{{lng}}/_default" },
],
},
});

i18nPromise.then(() => { translationsLoaded = true; });

Vue.use(VueI18Next);
Vue.mixin({ i18n: new VueI18Next(i18next) });

setGlobalPMVariable("i18n", i18next);
setGlobalPMVariable("i18nPromise", i18nPromise);
setGlobalPMVariable("missingTranslations", missingTranslations);
setGlobalPMVariable("missingTranslation", missingTranslation);
36 changes: 36 additions & 0 deletions resources/js/next/config/notifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { getGlobalPMVariable, setGlobalPMVariable } from "../globalVariables";

const apiClient = getGlobalPMVariable("apiClient");

const notifications = [];

const pushNotification = (notification) => {
if (notifications.filter((x) => x.id === notification).length === 0) {
notifications.push(notification);
}
};

const removeNotifications = (messageIds = [], urls = []) => apiClient.put("/read_notifications", { message_ids: messageIds, routes: urls }).then(() => {
messageIds.forEach((messageId) => {
notifications.splice(notifications.findIndex((x) => x.id === messageId), 1);
});

urls.forEach((url) => {
const messageIndex = notifications.findIndex((x) => x.url === url);
if (messageIndex >= 0) {
removeNotifications(notifications[messageIndex].id);
}
});
});

const unreadNotifications = (messageIds = [], urls = []) => apiClient.put("/unread_notifications", { message_ids: messageIds, routes: urls });

const $notifications = {
icons: {},
};

setGlobalPMVariable("notifications", notifications);
setGlobalPMVariable("pushNotification", pushNotification);
setGlobalPMVariable("removeNotifications", removeNotifications);
setGlobalPMVariable("unreadNotifications", unreadNotifications);
setGlobalPMVariable("$notifications", $notifications);
9 changes: 9 additions & 0 deletions resources/js/next/config/openAI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { setGlobalPMVariable } from "../globalVariables";

const openAi = document.head.querySelector("meta[name=\"open-ai-nlq-to-pmql\"]");

setGlobalPMVariable("openAi", openAi ? {
enabled: openAi.content,
} : {
enabled: false,
});
Loading