runid-lys 0.6.0 → 0.7.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/CHANGELOG.md +16 -0
- package/dist/{hooks-CvhFUowR.js → PublicAppTemplate-DLKcJZVR.js} +23 -2
- package/dist/PublicAppTemplate-DLKcJZVR.js.map +1 -0
- package/dist/{constants-BMsk7KvD.js → constants-mSRd0a6-.js} +134 -26
- package/dist/constants-mSRd0a6-.js.map +1 -0
- package/dist/index.js +23 -21
- package/dist/index.js.map +1 -1
- package/dist/providers/ChatbotProvider/index.d.ts +8 -2
- package/dist/providers/RouteProvider/hooks.d.ts +22 -0
- package/dist/providers/RouteProvider/index.d.ts +45 -0
- package/dist/providers/hooks/useRestrictedLink.d.ts +3 -2
- package/dist/providers/hooks/useRouteAccess.d.ts +25 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +23 -20
- package/dist/templates/index.js +1 -1
- package/dist/types/descriptionTypes.d.ts +7 -1
- package/dist/types/routeTypes.d.ts +7 -1
- package/package.json +1 -1
- package/dist/PublicAppTemplate-B93G2Smc.js +0 -26
- package/dist/PublicAppTemplate-B93G2Smc.js.map +0 -1
- package/dist/constants-BMsk7KvD.js.map +0 -1
- package/dist/hooks-CvhFUowR.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `RouteProvider` exposing the active route, the route map and helpers via `useRouteInfo`, wiring page context and chatbot auto-open, and rendering project-supplied private/public templates
|
|
13
|
+
- `useRouteAccess` hook centralizing route permission checks (supports `string` and `string[]` any-of semantics for `mainWebserviceName`)
|
|
14
|
+
- Export `RouteProvider`, `useRouteInfo`, `useRouteAccess`, and related types (`RouteContextValue`, `RouteProviderProps`, `RouteTemplateProps`) from `runid-lys/providers`
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `RouteInterface.mainWebserviceName` and `PageDescriptionType.mainWebserviceName` accept `string | string[]` (any-of) in addition to `string`
|
|
19
|
+
- `useRestrictedLink` delegates permission checking to `useRouteAccess` so single/array semantics stay in one place
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Empty-string URL query params are no longer coerced to `0` when forwarded to the chatbot page context
|
|
24
|
+
- `ChatbotProvider` resets its state (messages, conversation id, mode, streaming, refresh signal) when the connected user changes (login, logout, account switch) to prevent conversation leaks between accounts in the same browser session — implemented by keying the inner provider on `user?.id` so React unmounts the subtree atomically. Requires `ChatbotProvider` to be mounted inside `ConnectedUserProvider`.
|
|
25
|
+
|
|
10
26
|
## [0.6.0] - 2026-05-14
|
|
11
27
|
|
|
12
28
|
### Added
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect } from "react";
|
|
3
|
+
import { Navigate } from "react-router-dom";
|
|
2
4
|
const ChatbotContext = createContext(null);
|
|
3
5
|
const useChatbot = () => {
|
|
4
6
|
const context = useContext(ChatbotContext);
|
|
@@ -28,10 +30,29 @@ const ConnectedUserContext = createContext({
|
|
|
28
30
|
function useConnectedUserInfo() {
|
|
29
31
|
return useContext(ConnectedUserContext);
|
|
30
32
|
}
|
|
33
|
+
const PublicAppTemplate = ({
|
|
34
|
+
route,
|
|
35
|
+
defaultPrivateRoute,
|
|
36
|
+
children
|
|
37
|
+
}) => {
|
|
38
|
+
var _a;
|
|
39
|
+
const { user } = useConnectedUserInfo();
|
|
40
|
+
const { setIsChatbotEnabled } = useChatbot();
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
setIsChatbotEnabled(false);
|
|
43
|
+
return () => setIsChatbotEnabled(true);
|
|
44
|
+
}, [setIsChatbotEnabled]);
|
|
45
|
+
const isOpened = ((_a = route.options) == null ? void 0 : _a.opened) === true;
|
|
46
|
+
if (user && !isOpened) {
|
|
47
|
+
return /* @__PURE__ */ jsx(Navigate, { to: defaultPrivateRoute.path, replace: true });
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
50
|
+
};
|
|
31
51
|
export {
|
|
32
52
|
ChatbotContext as C,
|
|
53
|
+
PublicAppTemplate as P,
|
|
33
54
|
useConnectedUserInfo as a,
|
|
34
55
|
ConnectedUserContext as b,
|
|
35
56
|
useChatbot as u
|
|
36
57
|
};
|
|
37
|
-
//# sourceMappingURL=
|
|
58
|
+
//# sourceMappingURL=PublicAppTemplate-DLKcJZVR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicAppTemplate-DLKcJZVR.js","sources":["../src/providers/ChatbotProvider/hooks.ts","../src/providers/ConnectedUserProvider/hooks.ts","../src/templates/PublicAppTemplate.tsx"],"sourcesContent":["import {createContext, useContext} from \"react\";\nimport {ChatbotContextValue} from \"./types\";\n\nexport const ChatbotContext = createContext<ChatbotContextValue | null>(null);\n\nexport const useChatbot = (): ChatbotContextValue => {\n const context = useContext(ChatbotContext);\n if (!context) {\n throw new Error(\"useChatbot must be used within a ChatbotProvider\");\n }\n return context;\n};\n","import {createContext, useContext} from \"react\";\nimport {ConnectedUserInterface} from \"./types\";\n\n/**\n * Connected user context\n */\nconst ConnectedUserContext = createContext<{\n user: ConnectedUserInterface | undefined\n push(webservice: () => void): void\n login: [(login: string, password: string) => void, boolean],\n logout: [() => void, boolean],\n refresh: [() => void, boolean],\n handleSessionExpired: (onRefreshSuccess?: () => void) => void\n}>({\n user: undefined,\n push: () => {\n console.warn(\"ConnectedUserProvider not initialized: push\")\n },\n login: [() => {\n console.warn(\"ConnectedUserProvider not initialized: login\")\n }, false],\n logout: [() => {\n console.warn(\"ConnectedUserProvider not initialized: logout\")\n }, false],\n refresh: [() => {\n console.warn(\"ConnectedUserProvider not initialized: refresh\")\n }, false],\n handleSessionExpired: () => {\n console.warn(\"ConnectedUserProvider not initialized: handleSessionExpired\")\n }\n});\n\n/**\n * Hook to access connected user info\n */\nfunction useConnectedUserInfo() {\n return useContext(ConnectedUserContext)\n}\n\nexport {\n ConnectedUserContext,\n useConnectedUserInfo\n}\n","import * as React from \"react\";\nimport {useEffect} from \"react\";\nimport {Navigate} from \"react-router-dom\";\nimport {useConnectedUserInfo} from \"../providers/ConnectedUserProvider/hooks\";\nimport {useChatbot} from \"../providers/ChatbotProvider/hooks\";\nimport {RouteInterface} from \"../types/routeTypes\";\n\ninterface PublicAppTemplateProps {\n route: RouteInterface\n defaultPrivateRoute: RouteInterface\n defaultPublicRoute: RouteInterface\n children: React.ReactNode\n}\n\n/**\n * Public app template\n * Wraps public pages and redirects authenticated users to private area\n * Unless route.options?.opened is true (public pages accessible when connected)\n */\nconst PublicAppTemplate: React.ComponentType<PublicAppTemplateProps> = (\n {\n route,\n defaultPrivateRoute,\n children\n }) => {\n\n /*******************************************************************************************************************\n * HOOKS\n ******************************************************************************************************************/\n\n const {user} = useConnectedUserInfo();\n const {setIsChatbotEnabled} = useChatbot();\n\n /*******************************************************************************************************************\n * EFFECTS\n ******************************************************************************************************************/\n\n // Disable chatbot on public pages\n useEffect(() => {\n setIsChatbotEnabled(false);\n return () => setIsChatbotEnabled(true);\n }, [setIsChatbotEnabled]);\n\n /*******************************************************************************************************************\n * RENDER\n ******************************************************************************************************************/\n\n // Redirect authenticated users to private area (unless page is opened)\n const isOpened = route.options?.opened === true;\n if (user && !isOpened) {\n return <Navigate to={defaultPrivateRoute.path} replace />;\n }\n\n return (\n <>\n {children}\n </>\n );\n};\n\nexport default PublicAppTemplate;\n"],"names":[],"mappings":";;;AAGO,MAAM,iBAAiB,cAA0C,IAAI;AAErE,MAAM,aAAa,MAA2B;AACjD,QAAM,UAAU,WAAW,cAAc;AACzC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACtE;AACA,SAAO;AACX;ACLA,MAAM,uBAAuB,cAO1B;AAAA,EACC,MAAM;AAAA,EACN,MAAM,MAAM;AACR,YAAQ,KAAK,6CAA6C;AAAA,EAC9D;AAAA,EACA,OAAO,CAAC,MAAM;AACV,YAAQ,KAAK,8CAA8C;AAAA,EAC/D,GAAG,KAAK;AAAA,EACR,QAAQ,CAAC,MAAM;AACX,YAAQ,KAAK,+CAA+C;AAAA,EAChE,GAAG,KAAK;AAAA,EACR,SAAS,CAAC,MAAM;AACZ,YAAQ,KAAK,gDAAgD;AAAA,EACjE,GAAG,KAAK;AAAA,EACR,sBAAsB,MAAM;AACxB,YAAQ,KAAK,6DAA6D;AAAA,EAC9E;AACJ,CAAC;AAKD,SAAS,uBAAuB;AAC5B,SAAO,WAAW,oBAAoB;AAC1C;AClBA,MAAM,oBAAiE,CACnE;AAAA,EACI;AAAA,EACA;AAAA,EACA;AACJ,MAAM;;AAMN,QAAM,EAAC,KAAA,IAAQ,qBAAA;AACf,QAAM,EAAC,oBAAA,IAAuB,WAAA;AAO9B,YAAU,MAAM;AACZ,wBAAoB,KAAK;AACzB,WAAO,MAAM,oBAAoB,IAAI;AAAA,EACzC,GAAG,CAAC,mBAAmB,CAAC;AAOxB,QAAM,aAAW,WAAM,YAAN,mBAAe,YAAW;AAC3C,MAAI,QAAQ,CAAC,UAAU;AACnB,+BAAQ,UAAA,EAAS,IAAI,oBAAoB,MAAM,SAAO,MAAC;AAAA,EAC3D;AAEA,yCAES,UACL;AAER;"}
|
|
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4
4
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import React__default, { createContext, useContext, useMemo, useState, useCallback, useRef, useEffect, useReducer, forwardRef, Suspense, useImperativeHandle, useTransition } from "react";
|
|
7
|
-
import { C as ChatbotContext, b as ConnectedUserContext,
|
|
7
|
+
import { a as useConnectedUserInfo, C as ChatbotContext, b as ConnectedUserContext, u as useChatbot, P as PublicAppTemplate } from "./PublicAppTemplate-DLKcJZVR.js";
|
|
8
8
|
import { useSearchParams, useLocation, matchPath, useNavigate } from "react-router-dom";
|
|
9
9
|
import { usePreloadedQuery, useFragment, useMutation, useQueryLoader } from "react-relay";
|
|
10
10
|
import { IntlProvider, useIntl } from "react-intl";
|
|
@@ -124,6 +124,10 @@ const useRefreshSignal = () => {
|
|
|
124
124
|
return useContext(RefreshSignalContext);
|
|
125
125
|
};
|
|
126
126
|
const ChatbotProvider = ({ children }) => {
|
|
127
|
+
const { user } = useConnectedUserInfo();
|
|
128
|
+
return /* @__PURE__ */ jsx(ChatbotProviderInner, { children }, (user == null ? void 0 : user.id) ?? "anonymous");
|
|
129
|
+
};
|
|
130
|
+
const ChatbotProviderInner = ({ children }) => {
|
|
127
131
|
const [messages, setMessages] = useState([]);
|
|
128
132
|
const [conversationId, setConversationId] = useState(null);
|
|
129
133
|
const [isChatbotMode, setIsChatbotMode] = useState(false);
|
|
@@ -2155,16 +2159,117 @@ const ClientProvider = ({ children, routes }) => {
|
|
|
2155
2159
|
return /* @__PURE__ */ jsx(ClientContext.Provider, { value, children });
|
|
2156
2160
|
};
|
|
2157
2161
|
ClientProvider.displayName = "ClientProvider";
|
|
2162
|
+
const RouteContext = createContext({
|
|
2163
|
+
route: null,
|
|
2164
|
+
defaultPrivateRoute: null,
|
|
2165
|
+
defaultPublicRoute: null,
|
|
2166
|
+
allRoutes: {},
|
|
2167
|
+
getRouteByName: () => void 0
|
|
2168
|
+
});
|
|
2169
|
+
const useRouteInfo = () => useContext(RouteContext);
|
|
2170
|
+
const RouteProvider = ({
|
|
2171
|
+
route,
|
|
2172
|
+
routes,
|
|
2173
|
+
defaultPrivateRoute,
|
|
2174
|
+
defaultPublicRoute,
|
|
2175
|
+
privateTemplate: PrivateTemplate,
|
|
2176
|
+
publicTemplate: PublicTemplate = PublicAppTemplate,
|
|
2177
|
+
children
|
|
2178
|
+
}) => {
|
|
2179
|
+
const { setPageContext } = usePageContext();
|
|
2180
|
+
const { appliedParams } = useUrlQueries();
|
|
2181
|
+
const { setIsChatbotMode } = useChatbot();
|
|
2182
|
+
useEffect(() => {
|
|
2183
|
+
const params = {};
|
|
2184
|
+
let orderByField = null;
|
|
2185
|
+
let orderDir = null;
|
|
2186
|
+
appliedParams.forEach((value, key) => {
|
|
2187
|
+
if (key === "orderBy") {
|
|
2188
|
+
orderByField = value;
|
|
2189
|
+
return;
|
|
2190
|
+
}
|
|
2191
|
+
if (key === "orderDir") {
|
|
2192
|
+
orderDir = value;
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
if (value !== "" && !isNaN(Number(value))) {
|
|
2196
|
+
params[key] = Number(value);
|
|
2197
|
+
} else {
|
|
2198
|
+
params[key] = value;
|
|
2199
|
+
}
|
|
2200
|
+
});
|
|
2201
|
+
if (orderByField) {
|
|
2202
|
+
const isAscending = orderDir !== "DESC";
|
|
2203
|
+
params.orderBy = { [orderByField]: isAscending };
|
|
2204
|
+
}
|
|
2205
|
+
setPageContext(route.name, params);
|
|
2206
|
+
}, [route.name, appliedParams, setPageContext]);
|
|
2207
|
+
useEffect(() => {
|
|
2208
|
+
if (route.autoOpenChatbot) {
|
|
2209
|
+
setIsChatbotMode(true);
|
|
2210
|
+
}
|
|
2211
|
+
}, [route.name, route.autoOpenChatbot, setIsChatbotMode]);
|
|
2212
|
+
const allRoutes = useMemo(() => {
|
|
2213
|
+
const routesMap = {};
|
|
2214
|
+
routes.forEach((r) => {
|
|
2215
|
+
routesMap[r.name] = r;
|
|
2216
|
+
});
|
|
2217
|
+
return routesMap;
|
|
2218
|
+
}, [routes]);
|
|
2219
|
+
const getRouteByName = useCallback(
|
|
2220
|
+
(name) => allRoutes[name],
|
|
2221
|
+
[allRoutes]
|
|
2222
|
+
);
|
|
2223
|
+
return /* @__PURE__ */ jsxs(RouteContext.Provider, { value: {
|
|
2224
|
+
route,
|
|
2225
|
+
defaultPrivateRoute,
|
|
2226
|
+
defaultPublicRoute,
|
|
2227
|
+
allRoutes,
|
|
2228
|
+
getRouteByName
|
|
2229
|
+
}, children: [
|
|
2230
|
+
route.type === "public" && /* @__PURE__ */ jsx(
|
|
2231
|
+
PublicTemplate,
|
|
2232
|
+
{
|
|
2233
|
+
route,
|
|
2234
|
+
defaultPublicRoute,
|
|
2235
|
+
defaultPrivateRoute,
|
|
2236
|
+
children
|
|
2237
|
+
}
|
|
2238
|
+
),
|
|
2239
|
+
route.type === "private" && /* @__PURE__ */ jsx(
|
|
2240
|
+
PrivateTemplate,
|
|
2241
|
+
{
|
|
2242
|
+
route,
|
|
2243
|
+
defaultPublicRoute,
|
|
2244
|
+
defaultPrivateRoute,
|
|
2245
|
+
children
|
|
2246
|
+
}
|
|
2247
|
+
)
|
|
2248
|
+
] });
|
|
2249
|
+
};
|
|
2250
|
+
const useRouteAccess = () => {
|
|
2251
|
+
const { checkWebserviceAccess } = useWebserviceAccess();
|
|
2252
|
+
const { getRouteByName } = useRouteInfo();
|
|
2253
|
+
return useCallback(
|
|
2254
|
+
(routeOrName) => {
|
|
2255
|
+
if (!routeOrName) return false;
|
|
2256
|
+
const route = typeof routeOrName === "string" ? getRouteByName(routeOrName) : routeOrName;
|
|
2257
|
+
if (!route) return false;
|
|
2258
|
+
if (!route.mainWebserviceName) return true;
|
|
2259
|
+
if (Array.isArray(route.mainWebserviceName)) {
|
|
2260
|
+
return route.mainWebserviceName.some(checkWebserviceAccess);
|
|
2261
|
+
}
|
|
2262
|
+
return checkWebserviceAccess(route.mainWebserviceName);
|
|
2263
|
+
},
|
|
2264
|
+
[checkWebserviceAccess, getRouteByName]
|
|
2265
|
+
);
|
|
2266
|
+
};
|
|
2158
2267
|
const EMPTY_PARAMS = {};
|
|
2159
2268
|
function useRestrictedLink(route, parameters = EMPTY_PARAMS, queryParameters = EMPTY_PARAMS) {
|
|
2160
|
-
const
|
|
2269
|
+
const hasAccess = useRouteAccess();
|
|
2161
2270
|
const routerNavigate = useNavigate();
|
|
2162
2271
|
const [, startTransition] = useTransition();
|
|
2163
|
-
const hasPermission = useMemo(() =>
|
|
2164
|
-
if (!route) return false;
|
|
2165
|
-
if (!route.mainWebserviceName) return true;
|
|
2166
|
-
return checkWebserviceAccess(route.mainWebserviceName);
|
|
2167
|
-
}, [route, checkWebserviceAccess]);
|
|
2272
|
+
const hasPermission = useMemo(() => hasAccess(route), [hasAccess, route]);
|
|
2168
2273
|
const navigate = useCallback(() => {
|
|
2169
2274
|
if (!route) return;
|
|
2170
2275
|
startTransition(() => {
|
|
@@ -2179,10 +2284,13 @@ function useRestrictedLink(route, parameters = EMPTY_PARAMS, queryParameters = E
|
|
|
2179
2284
|
const GRAPHQL_ERROR = "GraphQL Error";
|
|
2180
2285
|
export {
|
|
2181
2286
|
AlertMessageProvider as A,
|
|
2287
|
+
useUrlQueries as B,
|
|
2182
2288
|
ChatbotProvider as C,
|
|
2289
|
+
useWebserviceAccess as D,
|
|
2183
2290
|
ErrorBoundaryProvider as E,
|
|
2184
2291
|
FilterLabelsProvider as F,
|
|
2185
2292
|
GRAPHQL_ERROR as G,
|
|
2293
|
+
webserviceAccessProviderConfig as H,
|
|
2186
2294
|
LocaleProvider as L,
|
|
2187
2295
|
PageContextProvider as P,
|
|
2188
2296
|
RefreshSignalContext as R,
|
|
@@ -2196,24 +2304,24 @@ export {
|
|
|
2196
2304
|
LysLoadingContext as e,
|
|
2197
2305
|
LysMutationProvider as f,
|
|
2198
2306
|
LysQueryProvider as g,
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2307
|
+
RouteProvider as h,
|
|
2308
|
+
useClientId as i,
|
|
2309
|
+
useDialogWithUpdates as j,
|
|
2310
|
+
useFilterLabels as k,
|
|
2311
|
+
useLocale as l,
|
|
2312
|
+
useLysDialog as m,
|
|
2313
|
+
useLysLoadingFallback as n,
|
|
2314
|
+
useLysMutation as o,
|
|
2315
|
+
useLysQuery as p,
|
|
2316
|
+
usePageContext as q,
|
|
2317
|
+
usePermissionCheck as r,
|
|
2318
|
+
useRefreshSignal as s,
|
|
2319
|
+
useRestrictedLink as t,
|
|
2212
2320
|
useAlertMessages as u,
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2321
|
+
useRouteAccess as v,
|
|
2322
|
+
useRouteInfo as w,
|
|
2323
|
+
useSignal as x,
|
|
2324
|
+
useSignalRefresh as y,
|
|
2325
|
+
useSignalSubscription as z
|
|
2218
2326
|
};
|
|
2219
|
-
//# sourceMappingURL=constants-
|
|
2327
|
+
//# sourceMappingURL=constants-mSRd0a6-.js.map
|