@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.js
CHANGED
|
@@ -837,22 +837,53 @@ function layout() {
|
|
|
837
837
|
// src/plugins/navigation.ts
|
|
838
838
|
import { eventBus as eventBus3 } from "@hai3/state";
|
|
839
839
|
import { i18nRegistry } from "@hai3/i18n";
|
|
840
|
+
|
|
841
|
+
// src/utils/basePath.ts
|
|
842
|
+
function normalizeBase(base) {
|
|
843
|
+
if (!base) {
|
|
844
|
+
return "/";
|
|
845
|
+
}
|
|
846
|
+
let normalized = base.startsWith("/") ? base : `/${base}`;
|
|
847
|
+
if (normalized !== "/" && normalized.endsWith("/")) {
|
|
848
|
+
normalized = normalized.slice(0, -1);
|
|
849
|
+
}
|
|
850
|
+
return normalized;
|
|
851
|
+
}
|
|
852
|
+
function stripBase(pathname, base) {
|
|
853
|
+
if (base === "/") {
|
|
854
|
+
return pathname;
|
|
855
|
+
}
|
|
856
|
+
if (!pathname.startsWith(base)) {
|
|
857
|
+
return null;
|
|
858
|
+
}
|
|
859
|
+
const nextChar = pathname.charAt(base.length);
|
|
860
|
+
if (nextChar && nextChar !== "/") {
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
return pathname.slice(base.length) || "/";
|
|
864
|
+
}
|
|
865
|
+
function prependBase(path, base) {
|
|
866
|
+
if (base === "/") {
|
|
867
|
+
return path;
|
|
868
|
+
}
|
|
869
|
+
const cleanPath = path.startsWith("/") ? path : `/${path}`;
|
|
870
|
+
return `${base}${cleanPath}`;
|
|
871
|
+
}
|
|
872
|
+
function resolveBase(pluginConfig, appConfig) {
|
|
873
|
+
const rawBase = pluginConfig?.base ?? appConfig?.base ?? "/";
|
|
874
|
+
return normalizeBase(rawBase);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// src/plugins/navigation.ts
|
|
840
878
|
var screenActions4 = screenActions;
|
|
841
879
|
var menuActions3 = menuActions;
|
|
842
|
-
function buildMenuItems(screenset) {
|
|
843
|
-
return screenset.menu.map((item) => ({
|
|
844
|
-
id: item.menuItem.screenId ?? item.menuItem.id,
|
|
845
|
-
label: item.menuItem.label,
|
|
846
|
-
icon: item.menuItem.icon
|
|
847
|
-
}));
|
|
848
|
-
}
|
|
849
880
|
function navigateToScreen2(payload) {
|
|
850
881
|
eventBus3.emit("navigation/screen/navigated", payload);
|
|
851
882
|
}
|
|
852
883
|
function navigateToScreenset(payload) {
|
|
853
884
|
eventBus3.emit("navigation/screenset/navigated", payload);
|
|
854
885
|
}
|
|
855
|
-
function navigation() {
|
|
886
|
+
function navigation(config) {
|
|
856
887
|
return {
|
|
857
888
|
name: "navigation",
|
|
858
889
|
dependencies: ["screensets"],
|
|
@@ -864,33 +895,66 @@ function navigation() {
|
|
|
864
895
|
},
|
|
865
896
|
onInit(app) {
|
|
866
897
|
const dispatch = app.store.dispatch;
|
|
898
|
+
const base = resolveBase(config, app.config);
|
|
867
899
|
let currentScreensetId = null;
|
|
868
|
-
async
|
|
869
|
-
await i18nRegistry.loadScreensetTranslations(
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
900
|
+
const loadScreensetTranslations = async (screensetId, language) => {
|
|
901
|
+
await i18nRegistry.loadScreensetTranslations(
|
|
902
|
+
screensetId,
|
|
903
|
+
language
|
|
904
|
+
);
|
|
905
|
+
};
|
|
906
|
+
const updateScreensetMenu = (screenset) => {
|
|
907
|
+
const menuItems = screenset.menu.map((item) => ({
|
|
908
|
+
id: item.menuItem.screenId ?? item.menuItem.id,
|
|
909
|
+
label: item.menuItem.label,
|
|
910
|
+
icon: item.menuItem.icon
|
|
911
|
+
}));
|
|
912
|
+
dispatch(menuActions3.setMenuItems(menuItems));
|
|
913
|
+
};
|
|
914
|
+
const activateScreenset = (screensetId) => {
|
|
915
|
+
if (screensetId === currentScreensetId) {
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
873
918
|
const screenset = app.screensetRegistry.get(screensetId);
|
|
874
|
-
if (!screenset)
|
|
919
|
+
if (!screenset) {
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
875
922
|
currentScreensetId = screensetId;
|
|
876
923
|
loadScreensetTranslations(screensetId).catch((err) => {
|
|
877
924
|
console.warn(`[HAI3] Failed to load translations for screenset ${screensetId}:`, err);
|
|
878
925
|
});
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
926
|
+
updateScreensetMenu(screenset);
|
|
927
|
+
};
|
|
928
|
+
const extractScreenId = () => {
|
|
929
|
+
const internalPath = stripBase(window.location.pathname, base);
|
|
930
|
+
if (!internalPath) {
|
|
931
|
+
return null;
|
|
932
|
+
}
|
|
933
|
+
const parts = internalPath.split("/").filter(Boolean);
|
|
934
|
+
return parts[0] || null;
|
|
935
|
+
};
|
|
936
|
+
const activateScreen = (screenId) => {
|
|
937
|
+
const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);
|
|
938
|
+
if (!screensetId) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
activateScreenset(screensetId);
|
|
942
|
+
dispatch(screenActions4.navigateTo(screenId));
|
|
943
|
+
};
|
|
882
944
|
eventBus3.on("navigation/screen/navigated", (payload) => {
|
|
883
|
-
if (
|
|
945
|
+
if (!app.routeRegistry?.hasScreen(payload.screensetId, payload.screenId)) {
|
|
884
946
|
console.warn(
|
|
885
947
|
`Screen "${payload.screenId}" in screenset "${payload.screensetId}" not found.`
|
|
886
948
|
);
|
|
887
949
|
return;
|
|
888
950
|
}
|
|
889
|
-
|
|
951
|
+
activateScreenset(payload.screensetId);
|
|
890
952
|
dispatch(screenActions4.navigateTo(payload.screenId));
|
|
891
953
|
if (typeof window !== "undefined") {
|
|
892
|
-
const url = `/${payload.screenId}
|
|
893
|
-
window.
|
|
954
|
+
const url = prependBase(`/${payload.screenId}`, base);
|
|
955
|
+
if (window.location.pathname !== url) {
|
|
956
|
+
window.history.pushState(null, "", url);
|
|
957
|
+
}
|
|
894
958
|
}
|
|
895
959
|
});
|
|
896
960
|
eventBus3.on("navigation/screenset/navigated", (payload) => {
|
|
@@ -907,15 +971,18 @@ function navigation() {
|
|
|
907
971
|
let lastLoadedLanguage = null;
|
|
908
972
|
i18nRegistry.subscribe(() => {
|
|
909
973
|
const currentLanguage = i18nRegistry.getLanguage();
|
|
910
|
-
if (!currentLanguage || currentLanguage === lastLoadedLanguage)
|
|
911
|
-
|
|
974
|
+
if (!currentLanguage || currentLanguage === lastLoadedLanguage) {
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
if (!currentScreensetId) {
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
912
980
|
const screenset = app.screensetRegistry.get(currentScreensetId);
|
|
913
|
-
if (!screenset)
|
|
981
|
+
if (!screenset) {
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
914
984
|
lastLoadedLanguage = currentLanguage;
|
|
915
|
-
loadScreensetTranslations(currentScreensetId, currentLanguage).then(() => {
|
|
916
|
-
const menuItems = buildMenuItems(screenset);
|
|
917
|
-
dispatch(menuActions3.setMenuItems(menuItems));
|
|
918
|
-
}).catch((err) => {
|
|
985
|
+
loadScreensetTranslations(currentScreensetId, currentLanguage).then(() => updateScreensetMenu(screenset)).catch((err) => {
|
|
919
986
|
console.warn(
|
|
920
987
|
`[HAI3] Failed to reload translations for screenset ${currentScreensetId}:`,
|
|
921
988
|
err
|
|
@@ -924,31 +991,15 @@ function navigation() {
|
|
|
924
991
|
});
|
|
925
992
|
if (typeof window !== "undefined") {
|
|
926
993
|
window.addEventListener("popstate", () => {
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
const screenId = parts2[0];
|
|
931
|
-
const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);
|
|
932
|
-
if (screensetId) {
|
|
933
|
-
updateMenuForScreenset(screensetId);
|
|
934
|
-
dispatch(screenActions4.navigateTo(screenId));
|
|
935
|
-
}
|
|
994
|
+
const screenId2 = extractScreenId();
|
|
995
|
+
if (screenId2) {
|
|
996
|
+
activateScreen(screenId2);
|
|
936
997
|
}
|
|
937
998
|
});
|
|
938
|
-
const
|
|
939
|
-
const parts = path.split("/").filter(Boolean);
|
|
999
|
+
const screenId = extractScreenId();
|
|
940
1000
|
const autoNavigate = app.config.autoNavigate !== false;
|
|
941
|
-
if (
|
|
942
|
-
|
|
943
|
-
const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);
|
|
944
|
-
if (screensetId) {
|
|
945
|
-
navigateToScreen2({ screensetId, screenId });
|
|
946
|
-
} else if (autoNavigate) {
|
|
947
|
-
const screensets2 = app.screensetRegistry.getAll();
|
|
948
|
-
if (screensets2.length > 0) {
|
|
949
|
-
navigateToScreenset({ screensetId: screensets2[0].id });
|
|
950
|
-
}
|
|
951
|
-
}
|
|
1001
|
+
if (screenId) {
|
|
1002
|
+
activateScreen(screenId);
|
|
952
1003
|
} else if (autoNavigate) {
|
|
953
1004
|
const screensets2 = app.screensetRegistry.getAll();
|
|
954
1005
|
if (screensets2.length > 0) {
|