Skip to content

FOUR-20583: Improve vendors #7812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 18, 2024
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
Loading