Skip to content

Commit 282c0d1

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 91330aa + d2c5635 commit 282c0d1

23 files changed

+445
-392
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Signum Framework doesn't use any numeric versioning, since is distributed as sou
4646

4747
Whenever there are big changes worth to mention, we typicaly write it in the related commit. Here is the list of the relevant changes:
4848

49+
* [2020.05.14 Slimming Signum.React](https://github.com/signumsoftware/framework/commit/31c91dad34f251f0c728cad426d5f5db9e496261#comments)
4950
* [2020.02.27 Updates package.json](https://github.com/signumsoftware/framework/commit/08f78128326fad5eaf80f184d67f76863f5aa8a9#comments)
5051
* [2020.02.25 Typescript 3.8 and other changes](https://github.com/signumsoftware/framework/commit/8cdc9ab0ec5488dcfa65b2539bc7e784f0607f47#comments)
5152
* [2020.02.14 Southwind inside of a Docker Container and running in Azure](https://github.com/signumsoftware/framework/commit/f9cc544a09cf1d80ae52ac659b57af06d8e730c5#comments)
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import * as React from "react";
2+
import { Route, Switch } from "react-router"
3+
import * as H from "history"
4+
import * as AppRelativeRoutes from "./AppRelativeRoutes";
5+
import { IUserEntity, TypeEntity } from "./Signum.Entities.Basics";
6+
import { Dic, classes, } from './Globals';
7+
import { ImportRoute } from "./AsyncImport";
8+
import { clearContextHeaders, ajaxGet, ajaxPost } from "./Services";
9+
import { PseudoType, Type, getTypeName } from "./Reflection";
10+
import { Entity, EntityPack, Lite, ModifiableEntity } from "./Signum.Entities";
11+
12+
Dic.skipClasses.push(React.Component);
13+
14+
export let currentUser: IUserEntity | undefined;
15+
export function setCurrentUser(user: IUserEntity | undefined) {
16+
currentUser = user;
17+
}
18+
19+
export let history: H.History;
20+
export function setCurrentHistory(h: H.History) {
21+
history = h;
22+
}
23+
24+
export let setTitle: (pageTitle?: string) => void;
25+
export function setTitleFunction(titleFunction: (pageTitle?: string) => void) {
26+
setTitle = titleFunction;
27+
}
28+
29+
export function useTitle(title: string, deps?: readonly any[]) {
30+
React.useEffect(() => {
31+
setTitle(title);
32+
return () => setTitle();
33+
}, deps);
34+
}
35+
36+
export function createAppRelativeHistory(): H.History {
37+
var h = H.createBrowserHistory({});
38+
AppRelativeRoutes.useAppRelativeBasename(h);
39+
AppRelativeRoutes.useAppRelativeComputeMatch(Route);
40+
AppRelativeRoutes.useAppRelativeComputeMatch(ImportRoute as any);
41+
AppRelativeRoutes.useAppRelativeSwitch(Switch);
42+
setCurrentHistory(h);
43+
return h;
44+
}
45+
46+
47+
export const clearSettingsActions: Array<() => void> = [
48+
clearContextHeaders,
49+
];
50+
51+
export function clearAllSettings() {
52+
clearSettingsActions.forEach(a => a());
53+
}
54+
55+
export let resetUI: () => void = () => { };
56+
export function setResetUI(reset: () => void) {
57+
resetUI = reset;
58+
}
59+
60+
export namespace Expander {
61+
export let onGetExpanded: () => boolean;
62+
export let onSetExpanded: (isExpanded: boolean) => void;
63+
64+
export function setExpanded(expanded: boolean): boolean {
65+
let wasExpanded = onGetExpanded != null && onGetExpanded();;
66+
if (onSetExpanded)
67+
onSetExpanded(expanded);
68+
69+
return wasExpanded;
70+
}
71+
}
72+
73+
export function useExpand() {
74+
React.useEffect(() => {
75+
const wasExpanded = Expander.setExpanded(true);
76+
return () => { Expander.setExpanded(wasExpanded); }
77+
}, []);
78+
79+
}
80+
81+
export function pushOrOpenInTab(path: string, e: React.MouseEvent<any> | React.KeyboardEvent<any>) {
82+
if ((e as React.MouseEvent<any>).button == 2)
83+
return;
84+
85+
e.preventDefault();
86+
if (e.ctrlKey || (e as React.MouseEvent<any>).button == 1)
87+
window.open(toAbsoluteUrl(path));
88+
else if (path.startsWith("http"))
89+
window.location.href = path;
90+
else
91+
history.push(path);
92+
}
93+
94+
export function toAbsoluteUrl(appRelativeUrl: string): string {
95+
if (appRelativeUrl?.startsWith("~/"))
96+
return window.__baseUrl + appRelativeUrl.after("~/");
97+
98+
var relativeCrappyUrl = history.location.pathname.beforeLast("/") + "/~/"; //In Link render ~/ is considered a relative url
99+
if (appRelativeUrl?.startsWith(relativeCrappyUrl))
100+
return window.__baseUrl + appRelativeUrl.after(relativeCrappyUrl);
101+
102+
if (appRelativeUrl.startsWith(window.__baseUrl) || appRelativeUrl.startsWith("http"))
103+
return appRelativeUrl;
104+
105+
return appRelativeUrl;
106+
}
107+
108+
109+
declare global {
110+
interface String {
111+
formatHtml(...parameters: any[]): React.ReactElement<any>;
112+
}
113+
114+
interface Array<T> {
115+
joinCommaHtml(this: Array<T>, lastSeparator: string): React.ReactElement<any>;
116+
}
117+
}
118+
119+
String.prototype.formatHtml = function (this: string) {
120+
const regex = /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g;
121+
122+
const args = arguments;
123+
124+
const parts = this.split(regex);
125+
126+
const result: (string | React.ReactElement<any>)[] = [];
127+
for (let i = 0; i < parts.length - 4; i += 4) {
128+
result.push(parts[i]);
129+
result.push(args[parseInt(parts[i + 1])]);
130+
}
131+
result.push(parts[parts.length - 1]);
132+
133+
return React.createElement("span", undefined, ...result);
134+
};
135+
136+
Array.prototype.joinCommaHtml = function (this: any[], lastSeparator: string) {
137+
const args = arguments;
138+
139+
const result: (string | React.ReactElement<any>)[] = [];
140+
for (let i = 0; i < this.length - 2; i++) {
141+
result.push(this[i]);
142+
result.push(", ");
143+
}
144+
145+
if (this.length >= 2) {
146+
result.push(this[this.length - 2]);
147+
result.push(lastSeparator)
148+
}
149+
150+
if (this.length >= 1) {
151+
result.push(this[this.length - 1]);
152+
}
153+
154+
return React.createElement("span", undefined, ...result);
155+
}

Signum.React/Scripts/AppRelativeRoutes.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import * as React from "react";
22
import { match, Route, RouterChildContext, matchPath, RouteProps, Switch, __RouterContext } from "react-router";
33
import * as H from "history";
4+
import * as AppContext from './AppContext'
45
import * as Navigator from "./Navigator";
56

67
//monkey-patching prototypes to make use of this is implemented: https://github.com/ReactTraining/react-router/issues/5000
78

89
function fixBaseName<T>(baseFunction: (location: H.LocationDescriptorObject | string, state?: any) => T): (location: H.LocationDescriptorObject | string, state?: any) => T {
910
return (location, state) => {
1011
if (typeof location === "string") {
11-
return baseFunction(Navigator.toAbsoluteUrl(location), state);
12+
return baseFunction(AppContext.toAbsoluteUrl(location), state);
1213
} else {
13-
location!.pathname = Navigator.toAbsoluteUrl(location!.pathname!);
14+
location!.pathname = AppContext.toAbsoluteUrl(location!.pathname!);
1415
return baseFunction(location, state);
1516
}
1617
};
@@ -28,7 +29,7 @@ export function useAppRelativeComputeMatch(RouteClass: typeof Route) {
2829
(RouteClass.prototype as any).computeMatch = function computeMatch(this: Route, props: RouteProps, context: RouterChildContext<any>) {
2930
let { path, ...p } = props;
3031

31-
const newPath = path && Navigator.toAbsoluteUrl(path as string);
32+
const newPath = path && AppContext.toAbsoluteUrl(path as string);
3233

3334
return baseMatch.call(this, { path: newPath, ...p }, context);
3435
};
@@ -60,7 +61,7 @@ export function useAppRelativeSwitch(SwitchClass: typeof Switch) {
6061
const path = child.props.path ?? child.props.from;
6162

6263
match = path
63-
? matchPath(location.pathname, { ...child.props, path: Navigator.toAbsoluteUrl(path as string) })
64+
? matchPath(location.pathname, { ...child.props, path: AppContext.toAbsoluteUrl(path as string) })
6465
: context.match;
6566
}
6667
});

Signum.React/Scripts/AsyncImport.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ export function ImportComponent({ onImportModule, componentProps }: ImportCompon
2424
}
2525

2626
interface ImportRouteProps {
27-
path?: string | string[];
28-
exact?: boolean;
29-
sensitive?: boolean;
27+
path?: string | string[];
28+
exact?: boolean;
29+
sensitive?: boolean;
3030
strict?: boolean;
31-
location?: H.Location;
31+
location?: H.Location;
3232

3333
onImportModule: () => Promise<ComponentModule>;
3434

@@ -41,5 +41,5 @@ export function ImportRoute({ onImportModule, ...rest }: ImportRouteProps) {
4141
{(props: RouteChildrenProps<any>) => <ImportComponent onImportModule={onImportModule} componentProps={props} />}
4242
</Route>
4343
);
44-
}
44+
}
4545

0 commit comments

Comments
 (0)