Skip to content

Commit 60d8230

Browse files
authored
Merge pull request #7812 from ProcessMaker/feature/FOUR-20583-A
FOUR-20583: Improve vendors
2 parents a8ba708 + 78d6fa2 commit 60d8230

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2767
-1265
lines changed

ProcessMaker/Http/Controllers/CasesController.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ class CasesController extends Controller
2020
*/
2121
public function index()
2222
{
23+
$manager = app(ScreenBuilderManager::class);
24+
event(new ScreenBuilderStarting($manager, 'FORM'));
2325
$currentUser = Auth::user()->only(['id', 'username', 'fullname', 'firstname', 'lastname', 'avatar']);
2426

2527
// This is a temporary API the engine team will provide the new
26-
return view('cases.casesMain', compact('currentUser'));
28+
return view('cases.casesMain', compact('currentUser', 'manager'));
2729
}
2830

2931
/**

resources/js/components/TreeView.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default {
3737
},
3838
},
3939
mounted() {
40-
const jsonCrackEmbed = this.$refs.jsonCrackEmbed;
40+
const { jsonCrackEmbed } = this.$refs;
4141
const json = this.jsonData === "" ? "{}" : this.jsonData;
4242
const options = {
4343
theme: "light",

resources/js/next/badPractices.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* BAD PRACTICES
3+
*/
4+
5+
// Use multiple forms of an event bus.
6+
window.ProcessMaker = {
7+
EventBus: new Vue(),
8+
events: new Vue()
9+
};
10+
11+
// Force to overload the vue object
12+
window.Vue.prototype.moment = moment;
13+
14+
// Load all statements in a single file bootstrap.js
15+
16+
// Overload the window.ProcessMaker variable without using the setGlobalVariable function
17+
18+
// Use local variables instead of window.ProcessMaker
19+
window.ProcessMaker.removeNotifications = (messageIds = [], urls = []) => {
20+
return window.ProcessMaker.apiClient.put("/read_notifications", { message_ids: messageIds, routes: urls }).then(() => {
21+
messageIds.forEach((messageId) => {
22+
ProcessMaker.notifications.splice(ProcessMaker.notifications.findIndex((x) => x.id === messageId), 1);
23+
});
24+
25+
urls.forEach((url) => {
26+
const messageIndex = ProcessMaker.notifications.findIndex((x) => x.url === url);
27+
if (messageIndex >= 0) {
28+
ProcessMaker.removeNotification(ProcessMaker.notifications[messageIndex].id);
29+
}
30+
});
31+
});
32+
};
33+
34+
// Remove the saved search unneeded
35+
class InjectJavascript
36+
{
37+
public function handle($request, Closure $next)
38+
{
39+
$response = $next($request);
40+
if (get_class($response) !== Response::class) {
41+
return $response;
42+
}
43+
$content = $response->getContent();
44+
$tag = '';
45+
$tag .= '<script src="' . mix('/js/addSaveButton.js', 'vendor/processmaker/packages/package-savedsearch') . '"></script>';
46+
$tag .= '<script src="' . mix('/js/listenForRecounts.js', 'vendor/processmaker/packages/package-savedsearch') . '"></script>';
47+
$content = str_replace('</body>', $tag . "\n</body>", $content);
48+
$response->setContent($content);
49+
50+
return $response;
51+
}
52+
}
53+

resources/js/next/components/index.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { getGlobalVariable } from "../globalVariables";
2+
3+
// Multiselect
4+
5+
const Vue = getGlobalVariable("Vue");
6+
7+
const pmComponents = {
8+
// Components folder
9+
AvatarImage: () => import("../../components/AvatarImage.vue"),
10+
Breadcrumbs: () => import("../../components/Breadcrumbs.vue"),
11+
Confirm: () => import("../../components/Confirm.vue"),
12+
CustomActions: () => import("../../components/CustomActions.vue"),
13+
DetailRow: () => import("../../components/DetailRow.vue"),
14+
FilterBar: () => import("../../components/FilterBar.vue"),
15+
Menu: () => import("../../components/Menu.vue"),
16+
Message: () => import("../../components/Message.vue"),
17+
NavbarProfile: () => import("../../components/NavbarProfile.vue"),
18+
PMBadgesFilters: () => import("../../components/PMBadgesFilters.vue"),
19+
PMDatetimePicker: () => import("../../components/PMDatetimePicker.vue"),
20+
PMDropdownSuggest: () => import("../../components/PMDropdownSuggest.vue"),
21+
PMFloatingButtons: () => import("../../components/PMFloatingButtons.vue"),
22+
PMFormSelectSuggest: () => import("../../components/PMFormSelectSuggest.vue"),
23+
PMMessageResults: () => import("../../components/PMMessageResults.vue"),
24+
PMMessageScreen: () => import("../../components/PMMessageScreen.vue"),
25+
PMPanelWithCustomHeader: () => import("../../components/PMPanelWithCustomHeader.vue"),
26+
PMPopoverConfirmation: () => import("../../components/PMPopoverConfirmation.vue"),
27+
PMSearchBar: () => import("../../components/PMSearchBar.vue"),
28+
PMTable: () => import("../../components/PMTable.vue"),
29+
PMTabs: () => import("../../components/PMTabs.vue"),
30+
Recommendations: () => import("../../components/Recommendations.vue"),
31+
SelectFromApi: () => import("../../components/SelectFromApi.vue"),
32+
SelectLanguage: () => import("../../components/SelectLanguage.vue"),
33+
SelectScreen: () => import("../../components/SelectScreen.vue"),
34+
SelectStatus: () => import("../../components/SelectStatus.vue"),
35+
SelectUser: () => import("../../components/SelectUser.vue"),
36+
SelectUserGroup: () => import("../../components/SelectUserGroup.vue"),
37+
Session: () => import("../../components/Session.vue"),
38+
Sidebaricon: () => import("../../components/Sidebaricon.vue"),
39+
Timeline: () => import("../../components/Timeline.vue"),
40+
TimelineItem: () => import("../../components/TimelineItem.vue"),
41+
TreeView: () => import("../../components/TreeView.vue"),
42+
// Shared components folder
43+
AddToBundle: () => import("../../components/shared/AddToBundle"),
44+
AddToProjectModal: () => import("../../components/shared/AddToProjectModal"),
45+
AssetDependentTreeModal: () => import("../../components/shared/AssetDependentTreeModal.vue"),
46+
AssetTreeModal: () => import("../../components/shared/AssetTreeModal.vue"),
47+
BackendSelect: () => import("../../components/shared/BackendSelect.vue"),
48+
BasicSearch: () => import("../../components/shared/BasicSearch.vue"),
49+
CategorySelect: () => import("../../components/shared/CategorySelect.vue"),
50+
ChangeLog: () => import("../../components/shared/ChangeLog.vue"),
51+
ColorSchemeSelector: () => import("../../components/shared/ColorSchemeSelector.vue"),
52+
Column: () => import("../../components/shared/Column.vue"),
53+
ColumnChooser: () => import("../../components/shared/ColumnChooser.vue"),
54+
ColumnConfig: () => import("../../components/shared/ColumnConfig.vue"),
55+
DataCard: () => import("../../components/shared/DataCard.vue"),
56+
DataFormatSelector: () => import("../../components/shared/DataFormatSelector.vue"),
57+
DataMaskSelector: () => import("../../components/shared/DataMaskSelector.vue"),
58+
DataNode: () => import("../../components/shared/DataNode.vue"),
59+
DataTree: () => import("../../components/shared/DataTree.vue"),
60+
DownloadSvgButton: () => import("../../components/shared/DownloadSvgButton.vue"),
61+
DraggableFileUpload: () => import("../../components/shared/DraggableFileUpload.vue"),
62+
EllipsisMenu: () => import("../../components/shared/EllipsisMenu.vue"),
63+
FileUploadButton: () => import("../../components/shared/FileUploadButton.vue"),
64+
FilterTable: () => import("../../components/shared/FilterTable.vue"),
65+
IconDropdown: () => import("../../components/shared/IconDropdown.vue"),
66+
IconSelector: () => import("../../components/shared/IconSelector.vue"),
67+
InputImageCarousel: () => import("../../components/shared/InputImageCarousel.vue"),
68+
LaunchpadSettingsModal: () => import("../../components/shared/LaunchpadSettingsModal.vue"),
69+
Modal: () => import("../../components/shared/Modal.vue"),
70+
ModalSaveVersion: () => import("../../components/shared/ModalSaveVersion.vue"),
71+
MultiThumbnailFileUploader: () => import("../../components/shared/MultiThumbnailFileUploader.vue"),
72+
PaginationTable: () => import("../../components/shared/PaginationTable.vue"),
73+
PmqlInput: () => import("../../components/shared/PmqlInput.vue"),
74+
PmqlInputFilters: () => import("../../components/shared/PmqlInputFilters.vue"),
75+
ProjectSelect: () => import("../../components/shared/ProjectSelect.vue"),
76+
PTab: () => import("../../components/shared/PTab.vue"),
77+
PTabs: () => import("../../components/shared/PTabs.vue"),
78+
Required: () => import("../../components/shared/Required.vue"),
79+
SidebarButton: () => import("../../components/shared/SidebarButton.vue"),
80+
SidebarNav: () => import("../../components/shared/SidebarNav.vue"),
81+
SliderWithInput: () => import("../../components/shared/SliderWithInput.vue"),
82+
// Common components folder
83+
DataTreeToggle: () => import("../../components/common/data-tree-toggle.vue"),
84+
// Tasks components folder
85+
MobileTasks: () => import("../../tasks/components/MobileTasks.vue"),
86+
NavbarTaskMobile: () => import("../../tasks/components/NavbarTaskMobile.vue"),
87+
QuickFillPreview: () => import("../../tasks/components/QuickFillPreview.vue"),
88+
ReassignMobileModal: () => import("../../tasks/components/ReassignMobileModal.vue"),
89+
SplitpaneContainer: () => import("../../tasks/components/SplitpaneContainer.vue"),
90+
TaskDetailsMobile: () => import("../../tasks/components/TaskDetailsMobile.vue"),
91+
TaskListRowButtons: () => import("../../tasks/components/TaskListRowButtons.vue"),
92+
TaskLoading: () => import("../../tasks/components/TaskLoading.vue"),
93+
TaskSaveNotification: () => import("../../tasks/components/TaskSaveNotification.vue"),
94+
TaskSavePanel: () => import("../../tasks/components/TaskSavePanel.vue"),
95+
TasksHome: () => import("../../tasks/components/TasksHome.vue"),
96+
TasksList: () => import("../../tasks/components/TasksList.vue"),
97+
TasksListCounter: () => import("../../tasks/components/TasksListCounter.vue"),
98+
TasksPreview: () => import("../../tasks/components/TasksPreview.vue"),
99+
TaskTooltip: () => import("../../tasks/components/TaskTooltip.vue"),
100+
TaskView: () => import("../../tasks/components/TaskView.vue"),
101+
};
102+
103+
Object.entries(pmComponents).forEach(([key, component]) => {
104+
Vue.component(key, component);
105+
});
106+
107+
// Multiselect
108+
Vue.component("Multiselect", (resolve, reject) => {
109+
import("@processmaker/vue-multiselect").then((Multiselect) => {
110+
resolve(Multiselect.Multiselect);
111+
}).catch(reject);
112+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import AccessibilityMixin from "./components/common/mixins/accessibility";
2+
import { getGlobalVariable } from "../globalVariables";
3+
4+
const Vue = getGlobalVariable("Vue");
5+
6+
Vue.mixin(AccessibilityMixin);

resources/js/next/config/i18n.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import i18next from "i18next";
2+
import Backend from "i18next-chained-backend";
3+
import LocalStorageBackend from "i18next-localstorage-backend";
4+
import XHR from "i18next-xhr-backend";
5+
import VueI18Next from "@panter/vue-i18next";
6+
import { setGlobalPMVariable, getGlobalVariable } from "../globalVariables";
7+
8+
const Vue = getGlobalVariable("Vue");
9+
10+
const isProd = document.head.querySelector("meta[name=\"is-prod\"]")?.content === "true";
11+
let translationsLoaded = false;
12+
13+
const mdates = JSON.parse(
14+
document.head.querySelector("meta[name=\"i18n-mdate\"]")?.content,
15+
);
16+
17+
const missingTranslations = new Set();
18+
const missingTranslation = function (value) {
19+
if (missingTranslations.has(value)) { return; }
20+
missingTranslations.add(value);
21+
if (!isProd) {
22+
console.warn("Missing Translation:", value);
23+
}
24+
};
25+
26+
const i18nPromise = i18next.use(Backend).init({
27+
lng: document.documentElement.lang,
28+
fallbackLng: "en", // default language when no translations
29+
returnEmptyString: false, // When a translation is an empty string, return the default language, not empty
30+
nsSeparator: false,
31+
keySeparator: false,
32+
parseMissingKeyHandler(value) {
33+
if (!translationsLoaded) { return value; }
34+
// Report that a translation is missing
35+
missingTranslation(value);
36+
// Fallback to showing the english version
37+
return value;
38+
},
39+
backend: {
40+
backends: [
41+
LocalStorageBackend, // Try cache first
42+
XHR,
43+
],
44+
backendOptions: [
45+
{ versions: mdates },
46+
{ loadPath: "/i18next/fetch/{{lng}}/_default" },
47+
],
48+
},
49+
});
50+
51+
i18nPromise.then(() => { translationsLoaded = true; });
52+
53+
Vue.use(VueI18Next);
54+
Vue.mixin({ i18n: new VueI18Next(i18next) });
55+
56+
setGlobalPMVariable("i18n", i18next);
57+
setGlobalPMVariable("i18nPromise", i18nPromise);
58+
setGlobalPMVariable("missingTranslations", missingTranslations);
59+
setGlobalPMVariable("missingTranslation", missingTranslation);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { getGlobalPMVariable, setGlobalPMVariable } from "../globalVariables";
2+
3+
const apiClient = getGlobalPMVariable("apiClient");
4+
5+
const notifications = [];
6+
7+
const pushNotification = (notification) => {
8+
if (notifications.filter((x) => x.id === notification).length === 0) {
9+
notifications.push(notification);
10+
}
11+
};
12+
13+
const removeNotifications = (messageIds = [], urls = []) => apiClient.put("/read_notifications", { message_ids: messageIds, routes: urls }).then(() => {
14+
messageIds.forEach((messageId) => {
15+
notifications.splice(notifications.findIndex((x) => x.id === messageId), 1);
16+
});
17+
18+
urls.forEach((url) => {
19+
const messageIndex = notifications.findIndex((x) => x.url === url);
20+
if (messageIndex >= 0) {
21+
removeNotifications(notifications[messageIndex].id);
22+
}
23+
});
24+
});
25+
26+
const unreadNotifications = (messageIds = [], urls = []) => apiClient.put("/unread_notifications", { message_ids: messageIds, routes: urls });
27+
28+
const $notifications = {
29+
icons: {},
30+
};
31+
32+
setGlobalPMVariable("notifications", notifications);
33+
setGlobalPMVariable("pushNotification", pushNotification);
34+
setGlobalPMVariable("removeNotifications", removeNotifications);
35+
setGlobalPMVariable("unreadNotifications", unreadNotifications);
36+
setGlobalPMVariable("$notifications", $notifications);

resources/js/next/config/openAI.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { setGlobalPMVariable } from "../globalVariables";
2+
3+
const openAi = document.head.querySelector("meta[name=\"open-ai-nlq-to-pmql\"]");
4+
5+
setGlobalPMVariable("openAi", openAi ? {
6+
enabled: openAi.content,
7+
} : {
8+
enabled: false,
9+
});

0 commit comments

Comments
 (0)