Fix Building timeout and macbook shortcuts (#1964)

* Fixed shortcuts not working on mac

* fixed top level vertices and added timeout

* revert flowStore changes

* chore: Update worker timeout setting

* feat: Add endpoint to retrieve config settings

The commit adds a new endpoint `/config` to retrieve the configuration settings. This endpoint returns the `ConfigResponse` model, which includes the `timeout` value. The implementation handles any exceptions and logs them appropriately.

* feat: Add fetchConfig function to retrieve configuration settings

This commit adds a new function fetchConfig to the API utils module. The function makes an HTTP GET request to the /config endpoint and returns the configuration data. Any errors that occur during the request are logged and rethrown. This function will be used to initialize the application with the fetched configuration.

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>

* revert changes

* feat: Add setupAxiosDefaults function to initialize Axios configurations

This commit adds a new function setupAxiosDefaults to the API utils module. The function fetches the configuration data using the fetchConfig function and sets up default configurations for Axios. It sets the base URL and timeout for Axios requests based on the fetched configuration. This function will be used to initialize Axios with the correct configurations.

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>

* fix(langflow): rename 'timeout' setting to 'worker_timeout' for clarity and consistency
feat(langflow): add 'frontend_timeout' setting to control frontend API call timeout
chore(langflow): reorganize imports and constants in settings module for better readability

* Set frontend_timeout to 0

---------

Co-authored-by: ogabrielluiz <gabriel@langflow.org>
This commit is contained in:
Lucas Oliveira 2024-05-28 17:18:36 +02:00 • committed by GitHub
commit 7d67f36000
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 95 additions and 20 deletions

View file

@ -1,3 +1,4 @@
import axios from "axios";
import { useContext, useEffect, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { useNavigate } from "react-router-dom";
@ -15,6 +16,7 @@ import {
} from "./constants/constants";
import { AuthContext } from "./contexts/authContext";
import { autoLogin, getGlobalVariables, getHealth } from "./controllers/API";
import { setupAxiosDefaults } from "./controllers/API/utils";
import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path";
import Router from "./routes";
import useAlertStore from "./stores/alertStore";
@ -28,10 +30,10 @@ export default function App() {
useTrackLastVisitedPath();
const removeFromTempNotificationList = useAlertStore(
(state) => state.removeFromTempNotificationList,
(state) => state.removeFromTempNotificationList
);
const tempNotificationList = useAlertStore(
(state) => state.tempNotificationList,
(state) => state.tempNotificationList
);
const [fetchError, setFetchError] = useState(false);
const isLoading = useFlowsManagerStore((state) => state.isLoading);
@ -49,7 +51,7 @@ export default function App() {
const refreshVersion = useDarkStore((state) => state.refreshVersion);
const refreshStars = useDarkStore((state) => state.refreshStars);
const setGlobalVariables = useGlobalVariablesStore(
(state) => state.setGlobalVariables,
(state) => state.setGlobalVariables
);
const checkHasStore = useStoreStore((state) => state.checkHasStore);
const navigate = useNavigate();
@ -114,9 +116,11 @@ export default function App() {
return new Promise<void>(async (resolve, reject) => {
if (isAuthenticated) {
try {
await setupAxiosDefaults();
await getFoldersApi();
await getTypes();
await refreshFlows();
console.log(axios.defaults);
const res = await getGlobalVariables();
setGlobalVariables(res);
checkHasStore();

View file

@ -48,7 +48,7 @@ function ApiInterceptor() {
}
await clearBuildVerticesState(error);
return Promise.reject(error);
},
}
);
const isAuthorizedURL = (url) => {
@ -65,10 +65,10 @@ function ApiInterceptor() {
const parsedURL = new URL(url);
const isDomainAllowed = authorizedDomains.some(
(domain) => parsedURL.origin === new URL(domain).origin,
(domain) => parsedURL.origin === new URL(domain).origin
);
const isEndpointAllowed = authorizedEndpoints.some((endpoint) =>
parsedURL.pathname.includes(endpoint),
parsedURL.pathname.includes(endpoint)
);
return isDomainAllowed || isEndpointAllowed;
@ -112,7 +112,7 @@ function ApiInterceptor() {
},
(error) => {
return Promise.reject(error);
},
}
);
return () => {
@ -144,7 +144,7 @@ function ApiInterceptor() {
if (error?.config?.headers) {
delete error.config.headers["Authorization"];
error.config.headers["Authorization"] = `Bearer ${cookies.get(
"access_token_lf",
"access_token_lf"
)}`;
const response = await axios.request(error.config);
return response;

View file

@ -0,0 +1,32 @@
import axios from "axios";
import { BASE_URL_API } from "../../constants/constants";
/**
* Fetches the configuration data from the API.
* @returns {Promise<any>} A promise that resolves to the configuration data.
* @throws {Error} If there was an error fetching the configuration data.
*/
export async function fetchConfig() {
try {
const response = await axios.get(`${BASE_URL_API}config`);
return response.data;
} catch (error) {
console.error("Failed to fetch configuration:", error);
throw error;
}
}
/**
* Sets up default configurations for Axios.
* Fetches the timeout configuration and sets it as the default timeout for Axios requests.
*/
export async function setupAxiosDefaults() {
const config = await fetchConfig();
// Create Axios instance with the fetched timeout configuration
const timeoutInMilliseconds = config.frontend_timeout
? config.frontend_timeout * 1000
: 30000;
axios.defaults.baseURL = "";
axios.defaults.timeout = timeoutInMilliseconds;
}

View file

@ -271,7 +271,7 @@ export default function NodeToolbarComponent({
selected &&
(hasApiKey || hasStore) &&
(event.ctrlKey || event.metaKey) &&
event.key === "u"
event.key.toUpperCase() === "U"
) {
event.preventDefault();
handleSelectChange("update");
@ -280,7 +280,7 @@ export default function NodeToolbarComponent({
selected &&
isGroup &&
(event.ctrlKey || event.metaKey) &&
event.key === "g"
event.key.toUpperCase() === "G"
) {
event.preventDefault();
handleSelectChange("ungroup");
@ -290,7 +290,7 @@ export default function NodeToolbarComponent({
(hasApiKey || hasStore) &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
event.key === "S"
event.key.toUpperCase() === "S"
) {
event.preventDefault();
setShowconfirmShare((state) => !state);
@ -300,7 +300,7 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
event.key === "Q"
event.key.toUpperCase() === "Q"
) {
event.preventDefault();
if (isMinimal) {
@ -317,7 +317,7 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
event.key === "U"
event.key.toUpperCase() === "U"
) {
event.preventDefault();
if (hasCode) return setOpenModal((state) => !state);
@ -327,12 +327,16 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
event.key === "A"
event.key.toUpperCase() === "A"
) {
event.preventDefault();
setShowModalAdvanced((state) => !state);
}
if (selected && (event.ctrlKey || event.metaKey) && event.key === "s") {
if (
selected &&
(event.ctrlKey || event.metaKey) &&
event.key.toUpperCase() === "S"
) {
if (isSaved) {
event.preventDefault();
return setShowOverrideModal((state) => !state);
@ -347,7 +351,7 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
event.key === "D"
event.key.toUpperCase() === "D"
) {
event.preventDefault();
if (data.node?.documentation) {
@ -357,7 +361,11 @@ export default function NodeToolbarComponent({
title: `${data.id} docs is not available at the moment.`,
});
}
if (selected && (event.ctrlKey || event.metaKey) && event.key === "j") {
if (
selected &&
(event.ctrlKey || event.metaKey) &&
event.key.toUpperCase() === "J"
) {
event.preventDefault();
downloadNode(flowComponent!);
}