Skip to content

Commit

Permalink
Fix get sub router base get sub router routes (#122)
Browse files Browse the repository at this point in the history
* Start to fix getSubRouterBase-getSubRouterRoutes

* Update method and doc

* Update tests
  • Loading branch information
Willy Brauner authored Oct 18, 2022
1 parent 84ab6b1 commit af9f08c
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 69 deletions.
18 changes: 7 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,20 +256,16 @@ import {
} from "@cher-ami/router";

const FooPage = forwardRef((props, handleRef) => {
// Get parent router context
const { base, routes } = useRouter();

// Parsed routes list and get path by route name
const path = getPathByRouteName(routesList, "FooPage"); // "/foo"
// ...
// Parsed routes list and get path by route name -> "/foo"
const path = getPathByRouteName(router.routes, "FooPage");
// (if last param is false, '/:lang' will be not added) -> "/base/:lang/foo"
const subBase = getSubRouterBase(path, router.base, true);
// get subRoutes
const subRoutes = getSubRouterRoutes(path, router.routes);
return (
<div>
<Router
// -> "/base/:lang/foo" (if last param is false, ':lang' will be not added)
base={getSubRouterBase(path, base, true)}
// children routes array of FooPage
routes={getSubRouterRoutes(path, routes)}
>
<Router base={subBase} routes={subRoutes}>
<Stack />
</Router>
</div>
Expand Down
3 changes: 1 addition & 2 deletions examples/example-client/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type TLang = "en" | "fr" | "de";

const langService = new LangService<TLang>({
languages: [{ key: "en" }, { key: "fr" }, { key: "de" }],
showDefaultLangInUrl: true,
showDefaultLangInUrl: false,
base,
});

Expand All @@ -23,7 +23,6 @@ const root = createRoot(document.getElementById("root"));
root.render(
<Router
history={createBrowserHistory()}
//staticLocation="/base/en/about"
langService={langService}
routes={routesList}
base={base}
Expand Down
18 changes: 6 additions & 12 deletions examples/example-client/src/pages/BarPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {
} from "@cher-ami/router";
import { transitionsHelper } from "../helper/transitionsHelper";
import { routesList } from "../routes";
import debug from "@wbe/debug";

const componentName: string = "BarPage";
const log = debug(`router:${componentName}`);

interface IProps {}

Expand All @@ -28,22 +30,14 @@ export const BarPage = forwardRef((props: IProps, handleRef: ForwardedRef<any>)
});

const router = useRouter();
const path = getPathByRouteName(routesList, "BarPage");
console.log("getPathByRouteName", path);

console.log(
"getSubRouterRoutes(path, router.routes)",
getSubRouterRoutes(path, router.routes)
);
const path = getPathByRouteName(router.routes, "BarPage");
const subBase = getSubRouterBase(path, router.base);
const subRoutes = getSubRouterRoutes(path, router.routes);

return (
<div className={componentName} ref={rootRef}>
{componentName}
<Router
id={3}
base={getSubRouterBase(path, router.base, true)}
routes={getSubRouterRoutes(path, router.routes)}
>
<Router id={3} base={subBase} routes={subRoutes}>
<div className={componentName}>
<nav>
<ul>
Expand Down
11 changes: 4 additions & 7 deletions examples/example-client/src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from "@cher-ami/router";
import { transitionsHelper } from "../helper/transitionsHelper";
import debug from "@wbe/debug";
import { routesList } from "../routes";

const componentName: string = "HomePage";
const log = debug(`router:${componentName}`);
Expand All @@ -34,16 +33,14 @@ const HomePage = forwardRef((props: IProps, handleRef: ForwardedRef<any>) => {
});

const router = useRouter();
const path = getPathByRouteName(routesList, "HomePage");
const path = getPathByRouteName(router.routes, "HomePage");
const subBase = getSubRouterBase(path, router.base);
const subRoutes = getSubRouterRoutes(path, router.routes);

return (
<div className={componentName} ref={rootRef}>
{componentName}
<Router
id={2}
base={getSubRouterBase(path, router.base)}
routes={getSubRouterRoutes(path, router.routes)}
>
<Router id={2} base={subBase} routes={subRoutes}>
<div className={componentName}>
<nav>
<ul>
Expand Down
3 changes: 1 addition & 2 deletions examples/example-client/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ export const routesList: TRoute[] = [
component: HomePage,
children: [
{
path: "/foo",
//path: { en: "/foo", fr: "/foo-fr", de: "/foo-de" },
path: { en: "/foo", fr: "/foo-fr", de: "/foo-de" },
component: FooPage,
},
{
Expand Down
24 changes: 9 additions & 15 deletions src/core/LangService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ export type TLanguage<T = any> = {
};

class LangService<TLang = any> {
/**
* Check if singleton is init
*/
public isInit: boolean = false;

/**
* contains available languages
*/
Expand Down Expand Up @@ -76,7 +71,6 @@ class LangService<TLang = any> {
this.defaultLang = this.getDefaultLang(languages);
this.currentLang = this.getLangFromString() || this.defaultLang;
this.showDefaultLangInUrl = showDefaultLangInUrl;
this.isInit = true;
}

/**
Expand Down Expand Up @@ -140,7 +134,7 @@ class LangService<TLang = any> {
chooseForcePageReload = true;
}

// 3. if curent lang is default lang, add /currentLang.key after base
// 3. if current lang is default lang, add /currentLang.key after base
else if (this.isDefaultLangKey(this.currentLang.key)) {
const newUrlWithoutBase = preparedNewUrl.substr(
this.base.length,
Expand All @@ -158,7 +152,7 @@ class LangService<TLang = any> {
log("newUrl is no set, do not reload or refresh, return.", newUrl);
return;
}
// register current langage (not usefull if we reload the app.)
// register current language (not useful if we reload the app.)
this.currentLang = toLang;
// remove last / if exist and if he is not alone
newUrl = removeLastCharFromString(newUrl, "/", true);
Expand All @@ -171,10 +165,6 @@ class LangService<TLang = any> {
* @param forcePageReload
*/
public redirect(forcePageReload: boolean = true): void {
if (!this.isInit) {
console.warn("redirect: LangService is not init, exit.");
return;
}
if (!this.showDefaultLangInUrl) {
log("redirect: URLs have a lang param or language is valid, don't redirect.");
return;
Expand Down Expand Up @@ -211,10 +201,13 @@ class LangService<TLang = any> {
* Determine when we need to show current lang in URL
*/
public showLangInUrl(): boolean {
// if option is true, always display lang in URL
if (this.showDefaultLangInUrl) {
return this.isInit;
return true;
// if this option is false
} else {
return this.isInit && !this.isDefaultLangKey();
// show in URL only if whe are not on the default lang
return !this.isDefaultLangKey(this.currentLang.key);
}
}

Expand Down Expand Up @@ -319,7 +312,8 @@ class LangService<TLang = any> {
*/
protected getLangPathByLang(
route: TRoute,
lang = this.getLangFromString(this.staticLocation || window.location.pathname)?.key || this.defaultLang.key
lang = this.getLangFromString(this.staticLocation || window.location.pathname)?.key ||
this.defaultLang.key
): string {
let selectedPath: string;
if (typeof route.path === "string") {
Expand Down
28 changes: 18 additions & 10 deletions src/core/core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe("public", () => {
});

describe("getSubRouterBase", () => {
it("should return subrouter base URL", () => {
it("should return subRouter base URL", () => {
expect(getSubRouterBase("/foo", "")).toBe("/foo");
expect(getSubRouterBase("/foo", "/")).toBe("/foo");
expect(getSubRouterBase("/foo", "/hello/")).toBe("/hello/foo");
Expand All @@ -54,18 +54,26 @@ describe("public", () => {
expect(getSubRouterBase(langPathTest, "/base/", false)).toBe("/base/foo-en");
Routers.langService = undefined;
});

it("should return subRouter base URL with 'showDefaultLangInUrl: false' option", () => {
Routers.langService = new LangService({
languages: [{ key: "en" }, { key: "fr" }],
showDefaultLangInUrl: false,
});
["/", "/foo", "/foo/bar/biz"].forEach((e) => {
expect(getSubRouterBase(e, "/base/", true)).toBe(`/base${e}`);
expect(getSubRouterBase(e, "/base/", false)).toBe(`/base${e}`);
});
Routers.langService = undefined;
});
});

describe("getSubRouterRoutes", () => {
it("should return subrouter route list", () => {
getSubRouterRoutes("/", routeList.find((e) => e.name === "HomePage").children);
getSubRouterRoutes("/:testParam?", [
{
path: "/foo4",
props: { color: "red" },
name: "Foo4Page",
},
]);
it("should return subRouter route list", () => {
const homeChildren = getSubRouterRoutes("/", routeList);
expect(homeChildren).toEqual(routeList.find((e) => e.name === "HomePage").children);
const aboutChildren = getSubRouterRoutes("/about", routeList);
expect(aboutChildren).toEqual(routeList.find((e) => e.name === "AboutPage").children);
});
});

Expand Down
25 changes: 15 additions & 10 deletions src/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,21 @@ export function createUrl(
* Get sub router base URL
* @param path
* @param base
* @param addLangToUrl
* @param showLangInUrl
* @param addLangToUrl:
* if true, base will be /base/:lang/path/subPath
* if false, base will be /base/path/subPath
* @returns
*/
export function getSubRouterBase(
path: string | { [x: string]: string },
base: string,
addLangToUrl: boolean = true,
showLangInUrl: boolean = Routers.langService?.showLangInUrl()
addLangToUrl: boolean = true
): string {
return joinPaths([
base,
showLangInUrl && addLangToUrl ? "/:lang" : "",
getLangPath(path),
]);
// case langService is init, and we don't want to show default lang in URL, and we are on default lang.
// /:lang is return as path, but we want to get no lang in returned base string
const addLang = Routers.langService?.showLangInUrl() && addLangToUrl ? "/:lang" : "";
const pathAfterLang = path === "/:lang" ? getLangPath("/") : getLangPath(path);
return joinPaths([base, addLang, pathAfterLang]);
}

/**
Expand All @@ -114,8 +114,13 @@ export function getSubRouterRoutes(
path: string | { [x: string]: string },
routes: TRoute[]
): TRoute[] {
// case langService is init, and we don't want to show default lang in URL, and we are on default lang.
// /:lang is return as path, but we want to search path with "/" instead
const formattedPath =
!Routers.langService?.showLangInUrl() && path === "/:lang" ? "/" : path;

return routes.find((route) => {
return getLangPath(route.path) === getLangPath(path);
return getLangPath(route.path) === getLangPath(formattedPath);
})?.children;
}

Expand Down

0 comments on commit af9f08c

Please sign in to comment.