@hai3/framework 0.2.0-alpha.0 → 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +101 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +101 -50
- package/dist/index.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +16 -1
- package/dist/types.d.ts +16 -1
- package/package.json +13 -5
package/dist/index.cjs
CHANGED
|
@@ -972,22 +972,53 @@ function layout() {
|
|
|
972
972
|
// src/plugins/navigation.ts
|
|
973
973
|
var import_state13 = require("@hai3/state");
|
|
974
974
|
var import_i18n = require("@hai3/i18n");
|
|
975
|
+
|
|
976
|
+
// src/utils/basePath.ts
|
|
977
|
+
function normalizeBase(base) {
|
|
978
|
+
if (!base) {
|
|
979
|
+
return "/";
|
|
980
|
+
}
|
|
981
|
+
let normalized = base.startsWith("/") ? base : `/${base}`;
|
|
982
|
+
if (normalized !== "/" && normalized.endsWith("/")) {
|
|
983
|
+
normalized = normalized.slice(0, -1);
|
|
984
|
+
}
|
|
985
|
+
return normalized;
|
|
986
|
+
}
|
|
987
|
+
function stripBase(pathname, base) {
|
|
988
|
+
if (base === "/") {
|
|
989
|
+
return pathname;
|
|
990
|
+
}
|
|
991
|
+
if (!pathname.startsWith(base)) {
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
const nextChar = pathname.charAt(base.length);
|
|
995
|
+
if (nextChar && nextChar !== "/") {
|
|
996
|
+
return null;
|
|
997
|
+
}
|
|
998
|
+
return pathname.slice(base.length) || "/";
|
|
999
|
+
}
|
|
1000
|
+
function prependBase(path, base) {
|
|
1001
|
+
if (base === "/") {
|
|
1002
|
+
return path;
|
|
1003
|
+
}
|
|
1004
|
+
const cleanPath = path.startsWith("/") ? path : `/${path}`;
|
|
1005
|
+
return `${base}${cleanPath}`;
|
|
1006
|
+
}
|
|
1007
|
+
function resolveBase(pluginConfig, appConfig) {
|
|
1008
|
+
const rawBase = pluginConfig?.base ?? appConfig?.base ?? "/";
|
|
1009
|
+
return normalizeBase(rawBase);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// src/plugins/navigation.ts
|
|
975
1013
|
var screenActions4 = screenActions;
|
|
976
1014
|
var menuActions3 = menuActions;
|
|
977
|
-
function buildMenuItems(screenset) {
|
|
978
|
-
return screenset.menu.map((item) => ({
|
|
979
|
-
id: item.menuItem.screenId ?? item.menuItem.id,
|
|
980
|
-
label: item.menuItem.label,
|
|
981
|
-
icon: item.menuItem.icon
|
|
982
|
-
}));
|
|
983
|
-
}
|
|
984
1015
|
function navigateToScreen2(payload) {
|
|
985
1016
|
import_state13.eventBus.emit("navigation/screen/navigated", payload);
|
|
986
1017
|
}
|
|
987
1018
|
function navigateToScreenset(payload) {
|
|
988
1019
|
import_state13.eventBus.emit("navigation/screenset/navigated", payload);
|
|
989
1020
|
}
|
|
990
|
-
function navigation() {
|
|
1021
|
+
function navigation(config) {
|
|
991
1022
|
return {
|
|
992
1023
|
name: "navigation",
|
|
993
1024
|
dependencies: ["screensets"],
|
|
@@ -999,33 +1030,66 @@ function navigation() {
|
|
|
999
1030
|
},
|
|
1000
1031
|
onInit(app) {
|
|
1001
1032
|
const dispatch = app.store.dispatch;
|
|
1033
|
+
const base = resolveBase(config, app.config);
|
|
1002
1034
|
let currentScreensetId = null;
|
|
1003
|
-
async
|
|
1004
|
-
await import_i18n.i18nRegistry.loadScreensetTranslations(
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1035
|
+
const loadScreensetTranslations = async (screensetId, language) => {
|
|
1036
|
+
await import_i18n.i18nRegistry.loadScreensetTranslations(
|
|
1037
|
+
screensetId,
|
|
1038
|
+
language
|
|
1039
|
+
);
|
|
1040
|
+
};
|
|
1041
|
+
const updateScreensetMenu = (screenset) => {
|
|
1042
|
+
const menuItems = screenset.menu.map((item) => ({
|
|
1043
|
+
id: item.menuItem.screenId ?? item.menuItem.id,
|
|
1044
|
+
label: item.menuItem.label,
|
|
1045
|
+
icon: item.menuItem.icon
|
|
1046
|
+
}));
|
|
1047
|
+
dispatch(menuActions3.setMenuItems(menuItems));
|
|
1048
|
+
};
|
|
1049
|
+
const activateScreenset = (screensetId) => {
|
|
1050
|
+
if (screensetId === currentScreensetId) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1008
1053
|
const screenset = app.screensetRegistry.get(screensetId);
|
|
1009
|
-
if (!screenset)
|
|
1054
|
+
if (!screenset) {
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1010
1057
|
currentScreensetId = screensetId;
|
|
1011
1058
|
loadScreensetTranslations(screensetId).catch((err) => {
|
|
1012
1059
|
console.warn(`[HAI3] Failed to load translations for screenset ${screensetId}:`, err);
|
|
1013
1060
|
});
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1061
|
+
updateScreensetMenu(screenset);
|
|
1062
|
+
};
|
|
1063
|
+
const extractScreenId = () => {
|
|
1064
|
+
const internalPath = stripBase(window.location.pathname, base);
|
|
1065
|
+
if (!internalPath) {
|
|
1066
|
+
return null;
|
|
1067
|
+
}
|
|
1068
|
+
const parts = internalPath.split("/").filter(Boolean);
|
|
1069
|
+
return parts[0] || null;
|
|
1070
|
+
};
|
|
1071
|
+
const activateScreen = (screenId) => {
|
|
1072
|
+
const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);
|
|
1073
|
+
if (!screensetId) {
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
activateScreenset(screensetId);
|
|
1077
|
+
dispatch(screenActions4.navigateTo(screenId));
|
|
1078
|
+
};
|
|
1017
1079
|
import_state13.eventBus.on("navigation/screen/navigated", (payload) => {
|
|
1018
|
-
if (
|
|
1080
|
+
if (!app.routeRegistry?.hasScreen(payload.screensetId, payload.screenId)) {
|
|
1019
1081
|
console.warn(
|
|
1020
1082
|
`Screen "${payload.screenId}" in screenset "${payload.screensetId}" not found.`
|
|
1021
1083
|
);
|
|
1022
1084
|
return;
|
|
1023
1085
|
}
|
|
1024
|
-
|
|
1086
|
+
activateScreenset(payload.screensetId);
|
|
1025
1087
|
dispatch(screenActions4.navigateTo(payload.screenId));
|
|
1026
1088
|
if (typeof window !== "undefined") {
|
|
1027
|
-
const url = `/${payload.screenId}
|
|
1028
|
-
window.
|
|
1089
|
+
const url = prependBase(`/${payload.screenId}`, base);
|
|
1090
|
+
if (window.location.pathname !== url) {
|
|
1091
|
+
window.history.pushState(null, "", url);
|
|
1092
|
+
}
|
|
1029
1093
|
}
|
|
1030
1094
|
});
|
|
1031
1095
|
import_state13.eventBus.on("navigation/screenset/navigated", (payload) => {
|
|
@@ -1042,15 +1106,18 @@ function navigation() {
|
|
|
1042
1106
|
let lastLoadedLanguage = null;
|
|
1043
1107
|
import_i18n.i18nRegistry.subscribe(() => {
|
|
1044
1108
|
const currentLanguage = import_i18n.i18nRegistry.getLanguage();
|
|
1045
|
-
if (!currentLanguage || currentLanguage === lastLoadedLanguage)
|
|
1046
|
-
|
|
1109
|
+
if (!currentLanguage || currentLanguage === lastLoadedLanguage) {
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
if (!currentScreensetId) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1047
1115
|
const screenset = app.screensetRegistry.get(currentScreensetId);
|
|
1048
|
-
if (!screenset)
|
|
1116
|
+
if (!screenset) {
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1049
1119
|
lastLoadedLanguage = currentLanguage;
|
|
1050
|
-
loadScreensetTranslations(currentScreensetId, currentLanguage).then(() => {
|
|
1051
|
-
const menuItems = buildMenuItems(screenset);
|
|
1052
|
-
dispatch(menuActions3.setMenuItems(menuItems));
|
|
1053
|
-
}).catch((err) => {
|
|
1120
|
+
loadScreensetTranslations(currentScreensetId, currentLanguage).then(() => updateScreensetMenu(screenset)).catch((err) => {
|
|
1054
1121
|
console.warn(
|
|
1055
1122
|
`[HAI3] Failed to reload translations for screenset ${currentScreensetId}:`,
|
|
1056
1123
|
err
|
|
@@ -1059,31 +1126,15 @@ function navigation() {
|
|
|
1059
1126
|
});
|
|
1060
1127
|
if (typeof window !== "undefined") {
|
|
1061
1128
|
window.addEventListener("popstate", () => {
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
const screenId = parts2[0];
|
|
1066
|
-
const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);
|
|
1067
|
-
if (screensetId) {
|
|
1068
|
-
updateMenuForScreenset(screensetId);
|
|
1069
|
-
dispatch(screenActions4.navigateTo(screenId));
|
|
1070
|
-
}
|
|
1129
|
+
const screenId2 = extractScreenId();
|
|
1130
|
+
if (screenId2) {
|
|
1131
|
+
activateScreen(screenId2);
|
|
1071
1132
|
}
|
|
1072
1133
|
});
|
|
1073
|
-
const
|
|
1074
|
-
const parts = path.split("/").filter(Boolean);
|
|
1134
|
+
const screenId = extractScreenId();
|
|
1075
1135
|
const autoNavigate = app.config.autoNavigate !== false;
|
|
1076
|
-
if (
|
|
1077
|
-
|
|
1078
|
-
const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);
|
|
1079
|
-
if (screensetId) {
|
|
1080
|
-
navigateToScreen2({ screensetId, screenId });
|
|
1081
|
-
} else if (autoNavigate) {
|
|
1082
|
-
const screensets2 = app.screensetRegistry.getAll();
|
|
1083
|
-
if (screensets2.length > 0) {
|
|
1084
|
-
navigateToScreenset({ screensetId: screensets2[0].id });
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1136
|
+
if (screenId) {
|
|
1137
|
+
activateScreen(screenId);
|
|
1087
1138
|
} else if (autoNavigate) {
|
|
1088
1139
|
const screensets2 = app.screensetRegistry.getAll();
|
|
1089
1140
|
if (screensets2.length > 0) {
|