mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
fix: resolve file conflicts
This commit is contained in:
@@ -24,11 +24,13 @@ export const GenericFormDialog = <T,>({
|
||||
Form,
|
||||
rowKey,
|
||||
payload: data,
|
||||
editText,
|
||||
addText,
|
||||
...rest
|
||||
}: GenericFormDialogProps<T>) => {
|
||||
const { t } = useTranslate();
|
||||
const hasRow = rowKey ? data?.[rowKey] : data;
|
||||
const translationKey = hasRow ? rest.editText : rest.addText;
|
||||
const translationKey = hasRow ? editText : addText;
|
||||
|
||||
return (
|
||||
<Form
|
||||
|
||||
@@ -392,6 +392,7 @@ export default function NlpSample() {
|
||||
`nlpsample/export${type ? `?type=${type}` : ""}`,
|
||||
)}
|
||||
startIcon={<DownloadIcon />}
|
||||
disabled={dataGridProps?.rows?.length === 0}
|
||||
>
|
||||
{t("button.export")}
|
||||
</Button>
|
||||
|
||||
@@ -55,10 +55,10 @@ export const NlpValues = ({ entityId }: { entityId: string }) => {
|
||||
const canHaveSynonyms = nlpEntity?.lookups?.[0] === NlpLookups.keywords;
|
||||
const { onSearch, searchPayload } = useSearch<INlpValue>({
|
||||
$eq: [{ entity: entityId }],
|
||||
$or: ["doc", "value"]
|
||||
$or: ["doc", "value"],
|
||||
});
|
||||
const { dataGridProps } = useFind(
|
||||
{ entity: EntityType.NLP_VALUE },
|
||||
{ entity: EntityType.NLP_VALUE, format: Format.FULL },
|
||||
{
|
||||
params: searchPayload,
|
||||
},
|
||||
@@ -103,7 +103,7 @@ export const NlpValues = ({ entityId }: { entityId: string }) => {
|
||||
],
|
||||
t("label.operations"),
|
||||
);
|
||||
const synonymsColumn = {
|
||||
const synonymsColumn = {
|
||||
flex: 3,
|
||||
field: "synonyms",
|
||||
headerName: t("label.synonyms"),
|
||||
@@ -125,6 +125,24 @@ export const NlpValues = ({ entityId }: { entityId: string }) => {
|
||||
disableColumnMenu: true,
|
||||
renderHeader,
|
||||
},
|
||||
{
|
||||
flex: 2,
|
||||
field: "nlpSamplesCount",
|
||||
align: "center",
|
||||
headerName: t("label.nlp_samples_count"),
|
||||
sortable: true,
|
||||
disableColumnMenu: true,
|
||||
headerAlign: "center",
|
||||
renderHeader,
|
||||
renderCell: ({ row }) => (
|
||||
<Chip
|
||||
sx={{ alignContent: "center" }}
|
||||
id={row.id}
|
||||
label={row.nlpSamplesCount}
|
||||
variant="inbox"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
flex: 3,
|
||||
field: "doc",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import { Grid } from "@mui/material";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import PluginIcon from "@/app-components/svg/toolbar/PluginIcon";
|
||||
import { useFind } from "@/hooks/crud/useFind";
|
||||
@@ -17,18 +18,22 @@ import { Block, StyledTitle } from "./Aside";
|
||||
|
||||
export const CustomBlocks = () => {
|
||||
const { t } = useTranslate();
|
||||
const { data: customBlocks } = useFind(
|
||||
const { data: customBlocks = [] } = useFind(
|
||||
{ entity: EntityType.CUSTOM_BLOCK },
|
||||
{ hasCount: false },
|
||||
);
|
||||
const memoizedCustomBlocks = useMemo(
|
||||
() => customBlocks.sort((a, b) => a.id.localeCompare(b.id)),
|
||||
[customBlocks],
|
||||
);
|
||||
|
||||
return customBlocks?.length ? (
|
||||
return memoizedCustomBlocks.length ? (
|
||||
<>
|
||||
<Grid mb="2">
|
||||
<StyledTitle>{t("title.custom_blocks")}</StyledTitle>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
{customBlocks?.map((customBlock) => (
|
||||
{memoizedCustomBlocks.map((customBlock) => (
|
||||
<Block
|
||||
key={customBlock.id}
|
||||
title={t(`title.${customBlock.namespace}`, {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@@ -9,13 +9,21 @@
|
||||
import { createContext, ReactNode, useContext } from "react";
|
||||
import { FormProvider, UseFormReturn } from "react-hook-form";
|
||||
|
||||
import { IBlockAttributes, IBlock } from "@/types/block.types";
|
||||
import { IBlock, IBlockAttributes } from "@/types/block.types";
|
||||
|
||||
// Create a custom context for the block value
|
||||
const BlockContext = createContext<IBlock | undefined>(undefined);
|
||||
|
||||
// Custom hook to use block context
|
||||
export const useBlock = () => useContext(BlockContext);
|
||||
export const useBlock = () => {
|
||||
const context = useContext(BlockContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useBlock must be used within an BlockContext");
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
// This component wraps FormProvider and adds block to its context
|
||||
function BlockFormProvider({
|
||||
@@ -23,7 +31,7 @@ function BlockFormProvider({
|
||||
methods,
|
||||
block,
|
||||
}: {
|
||||
methods: UseFormReturn<IBlockAttributes, any, undefined>;
|
||||
methods: UseFormReturn<IBlockAttributes>;
|
||||
block: IBlock | undefined;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
|
||||
@@ -11,15 +11,190 @@ import styled from "@emotion/styled";
|
||||
import {
|
||||
DefaultLinkFactory,
|
||||
DefaultLinkWidget,
|
||||
NodeModel,
|
||||
PortModel
|
||||
} from "@projectstorm/react-diagrams";
|
||||
|
||||
import { AdvancedLinkModel } from "./AdvancedLinkModel";
|
||||
|
||||
const PROXIMITY_THRESHOLD = 500;
|
||||
const MIN_DISTANCE = 0.1;
|
||||
const MAX_DISTANCE = 2000;
|
||||
const CONTROL_POINT_PADDING = 10;
|
||||
const BACKWARD_LINK_THRESHOLD = 12; // pixels
|
||||
const MIN_SCALE_FACTOR = 1.5;
|
||||
const MAX_SCALE_FACTOR = 2.0;
|
||||
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
interface Boundaries {
|
||||
left: number,
|
||||
right: number,
|
||||
top: number,
|
||||
bottom: number,
|
||||
}
|
||||
|
||||
interface Dimensions {
|
||||
width: number,
|
||||
height: number,
|
||||
}
|
||||
// Helper function to get port dimensions
|
||||
const getPortDimensions = (port: PortModel): Dimensions => {
|
||||
return {
|
||||
width: port.width || CONTROL_POINT_PADDING,
|
||||
height: port.height || CONTROL_POINT_PADDING,
|
||||
};
|
||||
};
|
||||
// Helper function to calculate port center point
|
||||
const getPortCenterPoint = (port: PortModel): Point => {
|
||||
const portSize = getPortDimensions(port);
|
||||
|
||||
return {
|
||||
x: port.getPosition().x + portSize.width / 2,
|
||||
y: port.getPosition().y + portSize.height / 2,
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Logarithmic scaling function that adjusts between 1.5 and 2 based on distance,
|
||||
* minimum distance, and maximum distance.
|
||||
* @param distance - The distance to scale.
|
||||
* @param minDistance - A small value to prevent division by zero or too small values.
|
||||
* @param maxDistance - The maximum expected distance.
|
||||
*/
|
||||
const logFactor = (
|
||||
distance: number,
|
||||
minDistance: number,
|
||||
maxDistance: number
|
||||
): number => {
|
||||
const scale = Math.log(distance + minDistance) / Math.log(maxDistance + minDistance);
|
||||
|
||||
return MIN_SCALE_FACTOR + scale * (MAX_SCALE_FACTOR - MIN_SCALE_FACTOR); // Scaled to range between 1.5 and 2
|
||||
};
|
||||
/**
|
||||
* Calculates the horizontal (X-axis) overlap in pixels between two node boundaries.
|
||||
* Returns 0 if there is no overlap.
|
||||
*/
|
||||
const calculateXOverlap = (
|
||||
sourceBounds: Boundaries,
|
||||
targetBounds: Boundaries
|
||||
): number => {
|
||||
return Math.max(
|
||||
0,
|
||||
Math.min(sourceBounds.right, targetBounds.right) -
|
||||
Math.max(sourceBounds.left, targetBounds.left)
|
||||
);
|
||||
};
|
||||
/**
|
||||
* Calculates the vertical (Y-axis) overlap in pixels between two node boundaries.
|
||||
* Returns 0 if there is no overlap.
|
||||
*/
|
||||
const calculateYOverlap = (
|
||||
sourceBounds: Boundaries,
|
||||
targetBounds: Boundaries
|
||||
): number => {
|
||||
return Math.max(
|
||||
0,
|
||||
Math.min(sourceBounds.bottom, targetBounds.bottom) -
|
||||
Math.max(sourceBounds.top, targetBounds.top)
|
||||
);
|
||||
};
|
||||
/**
|
||||
* Converts an overlap amount into a ratio (0 to 1) based on the larger of the two node dimensions.
|
||||
* Useful for dynamically adjusting offsets based on how much nodes visually intersect.
|
||||
*/
|
||||
const calculateOverlapRatio = (
|
||||
overlapAmount: number,
|
||||
sourceDimension: number,
|
||||
targetDimension: number
|
||||
): number => {
|
||||
const maxRange = Math.max(sourceDimension, targetDimension);
|
||||
|
||||
return overlapAmount / maxRange;
|
||||
};
|
||||
/**
|
||||
* Computes the Euclidean distance between two points.
|
||||
* Used to scale offsets and curve control points based on how far apart nodes are.
|
||||
*/
|
||||
const calculateDistance = (startPoint: Point, endPoint: Point): number => {
|
||||
return Math.sqrt(
|
||||
Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)
|
||||
);
|
||||
};
|
||||
/**
|
||||
* Calculates the bounding box of a node based on its position and size.
|
||||
* Returns an object with `left`, `right`, `top`, and `bottom` properties representing the node's edges.
|
||||
*/
|
||||
const calculateNodeBoundaries = (node: NodeModel): Boundaries => {
|
||||
return {
|
||||
left: node.getPosition().x,
|
||||
right: node.getPosition().x + node.width,
|
||||
top: node.getPosition().y,
|
||||
bottom: node.getPosition().y + node.height,
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Calculates the width and height of a node based on the position of one of its ports.
|
||||
*
|
||||
* This approach avoids relying on the node's width and height properties,
|
||||
* which may not be accurate or available at render time due to asynchronous rendering behavior.
|
||||
*
|
||||
* Instead, it uses the relative position of the port to infer the size of the node.
|
||||
* Assumes that the port's position reflects the visual layout and placement on the node.
|
||||
*
|
||||
* @param port - A PortModel instance attached to the node
|
||||
* @returns An object containing the inferred width and height of the node
|
||||
*/
|
||||
const calculateNodeDimension = (port: PortModel): Dimensions => {
|
||||
// Get the top-left position of the node
|
||||
const nodePos = port.getNode().getPosition();
|
||||
// Get the top-left position of the port
|
||||
const portPos = port.getPosition();
|
||||
// Width is the horizontal distance from the node's left to the port's right edge
|
||||
const width = (portPos.x - nodePos.x) + port.width;
|
||||
// Height is estimated by doubling the vertical offset from the node to the port
|
||||
// (port is vertically centered), then adding the port's height
|
||||
const height = Math.abs(portPos.y - nodePos.y) * 2 + port.height;
|
||||
|
||||
return { width, height };
|
||||
};
|
||||
/**
|
||||
* Calculates a single control point for a cubic Bézier curve.
|
||||
* Adjusts based on direction, dynamic offset, and node boundaries.
|
||||
*/
|
||||
const calculateControlPoint = (
|
||||
anchor: Point,
|
||||
horizontalOffset: number,
|
||||
verticalOffset: number,
|
||||
verticalDirection: number,
|
||||
nodeBounds: Boundaries,
|
||||
isStart: boolean,
|
||||
controlPointPadding: number
|
||||
): Point => {
|
||||
let x =
|
||||
anchor.x + (isStart ? horizontalOffset : -horizontalOffset);
|
||||
let y =
|
||||
anchor.y + (isStart ? verticalDirection * verticalOffset : -verticalDirection * verticalOffset);
|
||||
|
||||
// Apply minimum horizontal constraint
|
||||
x = isStart
|
||||
? Math.max(x, nodeBounds.right + controlPointPadding)
|
||||
: Math.min(x, nodeBounds.left - controlPointPadding);
|
||||
|
||||
// Apply vertical constraint based on direction
|
||||
y =
|
||||
verticalDirection > 0
|
||||
? isStart
|
||||
? Math.max(y, nodeBounds.bottom + controlPointPadding)
|
||||
: Math.min(y, nodeBounds.top - controlPointPadding)
|
||||
: isStart
|
||||
? Math.min(y, nodeBounds.top - controlPointPadding)
|
||||
: Math.max(y, nodeBounds.bottom + controlPointPadding);
|
||||
|
||||
return { x, y };
|
||||
};
|
||||
const createCurvedPath = (start: Point, end: Point, nodeHeight: number) => {
|
||||
const controlPoint1X = start.x + nodeHeight - 20;
|
||||
const controlPoint1Y = start.y - nodeHeight;
|
||||
@@ -28,6 +203,74 @@ const createCurvedPath = (start: Point, end: Point, nodeHeight: number) => {
|
||||
|
||||
return `M ${start.x},${start.y} C ${controlPoint1X},${controlPoint1Y} ${controlPoint2X},${controlPoint2Y} ${end.x},${end.y}`;
|
||||
};
|
||||
const createBackwardCurvedPath = (
|
||||
sourcePort: PortModel,
|
||||
targetPort: PortModel,
|
||||
) => {
|
||||
// Set a threshold for node proximity, below which dynamic adjustments to offsets are applied
|
||||
// This helps in reducing abrupt curve steepness when nodes are close to each other
|
||||
const proximityThreshold = PROXIMITY_THRESHOLD;
|
||||
const minDistance = MIN_DISTANCE;
|
||||
const maxDistance = MAX_DISTANCE;
|
||||
const sourceNode = sourcePort.getNode();
|
||||
const targetNode = targetPort.getNode();
|
||||
// Get node dimensions
|
||||
const { width: sourceNodeWidth, height: sourceNodeHeight } = calculateNodeDimension(sourcePort);
|
||||
const { width: targetNodeWidth, height: targetNodeHeight } = calculateNodeDimension(targetPort);
|
||||
// Get node boundaries
|
||||
const sourceNodeBounds: Boundaries = calculateNodeBoundaries(sourceNode);
|
||||
const targetNodeBounds: Boundaries = calculateNodeBoundaries(targetNode);
|
||||
// **NEW:** Adjust `start` and `end` to match the exact center of ports
|
||||
const adjustedStart: Point = getPortCenterPoint(sourcePort);
|
||||
const adjustedEnd: Point = getPortCenterPoint(targetPort);
|
||||
// Calculate the distance between nodes
|
||||
const nodeDistance: number = calculateDistance(adjustedStart, adjustedEnd);
|
||||
// Use node dimensions and distance to calculate dynamic offsets
|
||||
const horizontalOffset: number = Math.max(sourceNodeWidth, targetNodeWidth);
|
||||
const verticalOffset: number = Math.max(sourceNodeHeight, targetNodeHeight);
|
||||
|
||||
// Dynamic factor, adjusting horizontal and vertical offsets based on the distance
|
||||
let adjustedHorizontalOffset: number = horizontalOffset * logFactor(nodeDistance, minDistance, maxDistance);
|
||||
let adjustedVerticalOffset: number = verticalOffset * logFactor(nodeDistance, minDistance, maxDistance);
|
||||
|
||||
// Horizontal overlap ratio (0 = no overlap, 1 = fully overlapping horizontally)
|
||||
const xOverlapAmount: number = calculateXOverlap(sourceNodeBounds, targetNodeBounds);
|
||||
const xOverlapRatio: number = calculateOverlapRatio(xOverlapAmount, sourceNodeWidth, targetNodeWidth);
|
||||
// Vertical overlap ratio (0 = no overlap, 1 = fully overlapping vertically)
|
||||
const yOverlapAmount: number = calculateYOverlap(sourceNodeBounds, targetNodeBounds);
|
||||
const yOverlapRatio: number = calculateOverlapRatio(yOverlapAmount, sourceNodeHeight, targetNodeHeight);
|
||||
// Determine vertical direction for Y alignment
|
||||
const verticalDirection: number = adjustedEnd.y >= adjustedStart.y ? 1 : -1;
|
||||
|
||||
// If Node Distance is small, multiply offsets by overlap ratios
|
||||
// to avoid abrupt curve steepness
|
||||
if (nodeDistance < proximityThreshold) {
|
||||
adjustedHorizontalOffset *= xOverlapRatio;
|
||||
adjustedVerticalOffset *= yOverlapRatio;
|
||||
}
|
||||
// Compute control points with dynamic offset
|
||||
const controlPoint1 = calculateControlPoint(
|
||||
adjustedStart,
|
||||
adjustedHorizontalOffset,
|
||||
adjustedVerticalOffset,
|
||||
verticalDirection,
|
||||
sourceNodeBounds,
|
||||
true,
|
||||
CONTROL_POINT_PADDING
|
||||
);
|
||||
const controlPoint2 = calculateControlPoint(
|
||||
adjustedEnd,
|
||||
adjustedHorizontalOffset,
|
||||
adjustedVerticalOffset,
|
||||
verticalDirection,
|
||||
targetNodeBounds,
|
||||
false,
|
||||
CONTROL_POINT_PADDING
|
||||
);
|
||||
|
||||
// Return the cubic Bezier curve
|
||||
return `M ${adjustedStart.x},${adjustedStart.y} C ${controlPoint1.x},${controlPoint1.y} ${controlPoint2.x},${controlPoint2.y} ${adjustedEnd.x},${adjustedEnd.y}`;
|
||||
};
|
||||
|
||||
namespace S {
|
||||
export const Keyframes = keyframes`
|
||||
@@ -68,41 +311,52 @@ export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
model: AdvancedLinkModel,
|
||||
selected: boolean,
|
||||
path: string,
|
||||
) {
|
||||
const isSelfLoop =
|
||||
model.getSourcePort().getNode() === model.getTargetPort().getNode();
|
||||
) {
|
||||
const backwardLinkThreshold = BACKWARD_LINK_THRESHOLD;
|
||||
const sourcePort = model.getSourcePort();
|
||||
const targetPort = model.getTargetPort();
|
||||
const isSelfLoop = sourcePort.getNode() === targetPort.getNode();
|
||||
const sourcePortPosition = sourcePort.getPosition();
|
||||
const targetPortPosition = targetPort.getPosition();
|
||||
const startPoint: Point = {
|
||||
x: sourcePortPosition.x + 20,
|
||||
y: sourcePortPosition.y + 20,
|
||||
};
|
||||
const endPoint: Point = {
|
||||
x: targetPortPosition.x + 20,
|
||||
y: targetPortPosition.y + 20,
|
||||
};
|
||||
// Check if it's a backward link (moving left)
|
||||
const isBackward = startPoint.x - endPoint.x > backwardLinkThreshold;
|
||||
|
||||
if (isSelfLoop) {
|
||||
// Adjust the path to create a curve
|
||||
const sourcePortPosition = model.getSourcePort().getPosition();
|
||||
const targetPortPosition = model.getTargetPort().getPosition();
|
||||
const startPoint: Point = {
|
||||
x: sourcePortPosition.x + 20,
|
||||
y: sourcePortPosition.y + 20,
|
||||
};
|
||||
const endPoint: Point = {
|
||||
x: targetPortPosition.x + 20,
|
||||
y: targetPortPosition.y + 20,
|
||||
};
|
||||
const targetPortHeight = model.getTargetPort().height;
|
||||
const targetNdeHeight =
|
||||
(model.getTargetPort().getPosition().y -
|
||||
model.getTargetPort().getNode().getPosition().y) *
|
||||
// Adjust start Point to match the exact source port's centre
|
||||
const adjustedStartPoint: Point = getPortCenterPoint(sourcePort);
|
||||
// Handle self-loop (curved) links
|
||||
const targetPortHeight = targetPort.height;
|
||||
const targetNodeHeight =
|
||||
(targetPort.getPosition().y -
|
||||
targetPort.getNode().getPosition().y) *
|
||||
2 +
|
||||
targetPortHeight;
|
||||
|
||||
path = createCurvedPath(startPoint, endPoint, targetNdeHeight);
|
||||
}
|
||||
|
||||
return (
|
||||
path = createCurvedPath(adjustedStartPoint, endPoint, targetNodeHeight);
|
||||
} else if (isBackward) {
|
||||
// Handle backward (leftward) link with refined function
|
||||
path = createBackwardCurvedPath(sourcePort, targetPort);
|
||||
}
|
||||
|
||||
return (
|
||||
<S.Path
|
||||
selected={selected}
|
||||
stroke={
|
||||
selected ? model.getOptions().selectedColor : model.getOptions().color
|
||||
selected
|
||||
? model.getOptions().selectedColor
|
||||
: model.getOptions().color
|
||||
}
|
||||
strokeWidth={model.getOptions().width}
|
||||
d={path}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import getConfig from "next/config";
|
||||
import { useRouter } from "next/router";
|
||||
import { createContext, ReactNode, useEffect, useState } from "react";
|
||||
import { createContext, ReactNode } from "react";
|
||||
import {
|
||||
QueryObserverResult,
|
||||
RefetchOptions,
|
||||
@@ -25,7 +25,6 @@ import { useSubscribeBroadcastChannel } from "@/hooks/useSubscribeBroadcastChann
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { RouterType } from "@/services/types";
|
||||
import { IUser } from "@/types/user.types";
|
||||
import { getFromQuery } from "@/utils/URL";
|
||||
|
||||
export interface AuthContextValue {
|
||||
user: IUser | undefined;
|
||||
@@ -51,10 +50,8 @@ const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
export const AuthProvider = ({ children }: AuthProviderProps): JSX.Element => {
|
||||
const router = useRouter();
|
||||
const [search, setSearch] = useState("");
|
||||
const hasPublicPath = PUBLIC_PATHS.includes(router.pathname);
|
||||
const { i18n } = useTranslate();
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const queryClient = useQueryClient();
|
||||
const updateLanguage = (lang: string) => {
|
||||
i18n.changeLanguage(lang);
|
||||
@@ -66,11 +63,11 @@ export const AuthProvider = ({ children }: AuthProviderProps): JSX.Element => {
|
||||
};
|
||||
const authRedirection = async (isAuthenticated: boolean) => {
|
||||
if (isAuthenticated) {
|
||||
const redirect = getFromQuery({ search, key: "redirect" });
|
||||
const nextPage = redirect && decodeURIComponent(redirect);
|
||||
|
||||
if (nextPage?.startsWith("/")) {
|
||||
await router.push(nextPage);
|
||||
if (
|
||||
router.query.redirect &&
|
||||
router.query.redirect.toString().startsWith("/")
|
||||
) {
|
||||
await router.push(router.query.redirect.toString());
|
||||
} else if (hasPublicPath) {
|
||||
await router.push(RouterType.HOME);
|
||||
}
|
||||
@@ -109,14 +106,9 @@ export const AuthProvider = ({ children }: AuthProviderProps): JSX.Element => {
|
||||
router.reload();
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const search = location.search;
|
||||
|
||||
setSearch(search);
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
|
||||
if (!isReady || isLoading) return <Progress />;
|
||||
if (isLoading) {
|
||||
return <Progress />;
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface INlpValueAttributes {
|
||||
expressions?: string[];
|
||||
metadata?: Record<string, any>;
|
||||
builtin?: boolean;
|
||||
nlpSamplesCount?: number;
|
||||
}
|
||||
|
||||
export interface INlpValueStub extends IBaseSchema, INlpValueAttributes {}
|
||||
|
||||
@@ -8,26 +8,6 @@
|
||||
|
||||
import qs from "qs";
|
||||
|
||||
export const getFromQuery = ({
|
||||
key,
|
||||
search,
|
||||
defaultValue = "",
|
||||
}: {
|
||||
key: string;
|
||||
search?: string;
|
||||
defaultValue?: string;
|
||||
}) => {
|
||||
try {
|
||||
const paramsString = search || window.location.search;
|
||||
const searchParams = new URLSearchParams(paramsString);
|
||||
const loadCampaign = searchParams.get(key) || defaultValue;
|
||||
|
||||
return loadCampaign;
|
||||
} catch (e) {
|
||||
return defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
export const buildURL = (baseUrl: string, relativePath: string): string => {
|
||||
try {
|
||||
return new URL(relativePath).toString();
|
||||
|
||||
Reference in New Issue
Block a user