runid-lys 0.4.2 → 0.5.0

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 CHANGED
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-03-28
11
+
12
+ ### Added
13
+
14
+ - `useRestrictedLink` hook combining route permission checking with navigation via `useTransition`
15
+ - Export `useRestrictedLink` hook and `RestrictedLink` type from `runid-lys/providers`
16
+
17
+ ## [0.4.3] - 2026-03-16
18
+
19
+ ### Changed
20
+
21
+ - `ClientProvider` now determines public pages dynamically from route configuration (`route.type`) via `matchPath` instead of hardcoded pathname checks
22
+ - `ClientProvider` requires a new `routes` prop (`RouteInterface[]`)
23
+ - `PublicAppTemplate` uses `<Navigate>` component instead of `useNavigate` + `useEffect` for redirect
24
+
10
25
  ## [0.4.2] - 2026-03-14
11
26
 
12
27
  ### Fixed
@@ -1,29 +1,26 @@
1
1
  import { jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useEffect } from "react";
3
- import { useNavigate } from "react-router-dom";
3
+ import { Navigate } from "react-router-dom";
4
4
  import { a as useConnectedUserInfo, u as useChatbot } from "./hooks-CvhFUowR.js";
5
5
  const PublicAppTemplate = ({
6
6
  route,
7
7
  defaultPrivateRoute,
8
8
  children
9
9
  }) => {
10
- const navigate = useNavigate();
10
+ var _a;
11
11
  const { user } = useConnectedUserInfo();
12
12
  const { setIsChatbotEnabled } = useChatbot();
13
13
  useEffect(() => {
14
14
  setIsChatbotEnabled(false);
15
15
  return () => setIsChatbotEnabled(true);
16
16
  }, [setIsChatbotEnabled]);
17
- useEffect(() => {
18
- var _a;
19
- const isOpened = ((_a = route.options) == null ? void 0 : _a.opened) === true;
20
- if (user && !isOpened) {
21
- navigate(defaultPrivateRoute.path);
22
- }
23
- }, [user, route.options, defaultPrivateRoute.path, navigate]);
17
+ const isOpened = ((_a = route.options) == null ? void 0 : _a.opened) === true;
18
+ if (user && !isOpened) {
19
+ return /* @__PURE__ */ jsx(Navigate, { to: defaultPrivateRoute.path, replace: true });
20
+ }
24
21
  return /* @__PURE__ */ jsx(Fragment, { children });
25
22
  };
26
23
  export {
27
24
  PublicAppTemplate as P
28
25
  };
29
- //# sourceMappingURL=PublicAppTemplate-SRJ1HtD0.js.map
26
+ //# sourceMappingURL=PublicAppTemplate-B93G2Smc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublicAppTemplate-B93G2Smc.js","sources":["../src/templates/PublicAppTemplate.tsx"],"sourcesContent":["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":";;;;AAmBA,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;"}
@@ -3,14 +3,14 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
5
  import * as React from "react";
6
- import React__default, { createContext, useContext, useMemo, useState, useCallback, useRef, useEffect, useReducer, forwardRef, Suspense, useImperativeHandle } from "react";
6
+ import React__default, { createContext, useContext, useMemo, useState, useCallback, useRef, useEffect, useReducer, forwardRef, Suspense, useImperativeHandle, useTransition } from "react";
7
7
  import { C as ChatbotContext, b as ConnectedUserContext, a as useConnectedUserInfo } from "./hooks-CvhFUowR.js";
8
- import { useSearchParams, useLocation } from "react-router-dom";
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";
11
11
  import { c as clearRelayCache } from "./RelayEnvironment-D880U9SM.js";
12
12
  import { i as isErrorKey, e as errorTranslations } from "./errors-BOacmKM0.js";
13
- import { e as extractOperationNames, c as checkOperationsPermission, b as createComponentTranslations, t as toSnakeCase } from "./translationTools-CSKULpZZ.js";
13
+ import { f as extractOperationNames, c as checkOperationsPermission, d as createComponentTranslations, t as toSnakeCase, j as generateUrlByRoute } from "./translationTools-RWoOzX2m.js";
14
14
  class ErrorBoundaryProvider extends React__default.Component {
15
15
  constructor() {
16
16
  super(...arguments);
@@ -2099,7 +2099,7 @@ function useClientId() {
2099
2099
  }
2100
2100
  const SESSION_KEY = "lys_clientId";
2101
2101
  const URL_PARAM_KEY = "clientId";
2102
- const ClientProvider = ({ children }) => {
2102
+ const ClientProvider = ({ children, routes }) => {
2103
2103
  const { user } = useConnectedUserInfo();
2104
2104
  const { update: updateUrl, appliedParams } = useUrlQueries();
2105
2105
  const location = useLocation();
@@ -2118,15 +2118,20 @@ const ClientProvider = ({ children }) => {
2118
2118
  updateUrl({ [URL_PARAM_KEY]: null });
2119
2119
  }
2120
2120
  }, [user, updateUrl]);
2121
+ const isPublicPage = useMemo(() => {
2122
+ const matchedRoute = routes.find((route) => matchPath(route.path, location.pathname));
2123
+ return (matchedRoute == null ? void 0 : matchedRoute.type) === "public";
2124
+ }, [routes, location.pathname]);
2121
2125
  useEffect(() => {
2122
2126
  if (!user) return;
2127
+ if (isPublicPage) return;
2123
2128
  const resolvedClientId = isLocked ? user.clientId : selectedClientId;
2124
2129
  if (resolvedClientId) {
2125
2130
  updateUrl({ [URL_PARAM_KEY]: resolvedClientId });
2126
2131
  } else {
2127
2132
  updateUrl({ [URL_PARAM_KEY]: null });
2128
2133
  }
2129
- }, [selectedClientId, location.pathname, isLocked, user, updateUrl]);
2134
+ }, [selectedClientId, location.pathname, isLocked, user, updateUrl, isPublicPage]);
2130
2135
  const clientId = useMemo(() => {
2131
2136
  if (user == null ? void 0 : user.clientId) {
2132
2137
  return user.clientId;
@@ -2150,6 +2155,27 @@ const ClientProvider = ({ children }) => {
2150
2155
  return /* @__PURE__ */ jsx(ClientContext.Provider, { value, children });
2151
2156
  };
2152
2157
  ClientProvider.displayName = "ClientProvider";
2158
+ const EMPTY_PARAMS = {};
2159
+ function useRestrictedLink(route, parameters = EMPTY_PARAMS, queryParameters = EMPTY_PARAMS) {
2160
+ const { checkWebserviceAccess } = useWebserviceAccess();
2161
+ const routerNavigate = useNavigate();
2162
+ 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]);
2168
+ const navigate = useCallback(() => {
2169
+ if (!route) return;
2170
+ startTransition(() => {
2171
+ routerNavigate(generateUrlByRoute(route, parameters, queryParameters));
2172
+ });
2173
+ }, [route, routerNavigate, startTransition, parameters, queryParameters]);
2174
+ return {
2175
+ hasPermission,
2176
+ navigate: hasPermission ? navigate : void 0
2177
+ };
2178
+ }
2153
2179
  const GRAPHQL_ERROR = "GraphQL Error";
2154
2180
  export {
2155
2181
  AlertMessageProvider as A,
@@ -2181,12 +2207,13 @@ export {
2181
2207
  usePageContext as p,
2182
2208
  usePermissionCheck as q,
2183
2209
  useRefreshSignal as r,
2184
- useSignal as s,
2185
- useSignalRefresh as t,
2210
+ useRestrictedLink as s,
2211
+ useSignal as t,
2186
2212
  useAlertMessages as u,
2187
- useSignalSubscription as v,
2188
- useUrlQueries as w,
2189
- useWebserviceAccess as x,
2190
- webserviceAccessProviderConfig as y
2213
+ useSignalRefresh as v,
2214
+ useSignalSubscription as w,
2215
+ useUrlQueries as x,
2216
+ useWebserviceAccess as y,
2217
+ webserviceAccessProviderConfig as z
2191
2218
  };
2192
- //# sourceMappingURL=constants-CgExWMDS.js.map
2219
+ //# sourceMappingURL=constants-BLmcEnm4.js.map