|
| 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 | +} |
0 commit comments