merge fix
This commit is contained in:
commit
f1512ab015
22 changed files with 237 additions and 129 deletions
51
.github/workflows/lint-js.yml
vendored
Normal file
51
.github/workflows/lint-js.yml
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
name: Lint Frontend
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "src/frontend/**"
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_VERSION: "21"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-linters:
|
||||||
|
name: Run linters
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
id: setup-node
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
|
||||||
|
- name: Cache Node.js dependencies
|
||||||
|
uses: actions/cache@v4
|
||||||
|
id: npm-cache
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
|
||||||
|
- name: Install Node.js dependencies
|
||||||
|
run: |
|
||||||
|
cd src/frontend
|
||||||
|
npm ci
|
||||||
|
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
|
||||||
|
|
||||||
|
- name: Run linters
|
||||||
|
uses: wearerequired/lint-action@v1
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.github_token }}
|
||||||
|
auto_fix: true
|
||||||
|
git_email: "gabriel@langflow.org"
|
||||||
|
# Enable linters
|
||||||
|
eslint: true
|
||||||
|
prettier: true
|
||||||
|
prettier_args: '--write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore'
|
||||||
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
name: lint
|
name: Lint Python
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- "poetry.lock"
|
|
||||||
- "pyproject.toml"
|
|
||||||
- "src/backend/**"
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "poetry.lock"
|
- "poetry.lock"
|
||||||
- "pyproject.toml"
|
- "pyproject.toml"
|
||||||
- "src/backend/**"
|
- "src/backend/**"
|
||||||
|
- "tests/**"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POETRY_VERSION: "1.8.2"
|
POETRY_VERSION: "1.8.2"
|
||||||
|
|
@ -45,6 +40,13 @@ jobs:
|
||||||
path: |
|
path: |
|
||||||
./.mypy_cache
|
./.mypy_cache
|
||||||
key: ${{ runner.os }}-mypy-${{ hashFiles('**/pyproject.toml') }}
|
key: ${{ runner.os }}-mypy-${{ hashFiles('**/pyproject.toml') }}
|
||||||
- name: Lint check
|
- name: Run linters
|
||||||
run: |
|
uses: wearerequired/lint-action@v1
|
||||||
make lint
|
with:
|
||||||
|
github_token: ${{ secrets.github_token }}
|
||||||
|
# Enable linters
|
||||||
|
git_email: "gabriel@langflow.org"
|
||||||
|
mypy: true
|
||||||
|
mypy_args: '--namespace-packages -p "langflow"'
|
||||||
|
mypy_command_prefix: "poetry run"
|
||||||
|
|
||||||
14
.github/workflows/matchers/ruff.json
vendored
Normal file
14
.github/workflows/matchers/ruff.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"problemMatcher": [
|
||||||
|
{
|
||||||
|
"owner": "ruff",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "^(Would reformat): (.+)$",
|
||||||
|
"message": 1,
|
||||||
|
"file": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
39
.github/workflows/style-check-py.yml
vendored
Normal file
39
.github/workflows/style-check-py.yml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
name: Ruff Style Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "poetry.lock"
|
||||||
|
- "pyproject.toml"
|
||||||
|
- "src/backend/**"
|
||||||
|
- "tests/**"
|
||||||
|
|
||||||
|
env:
|
||||||
|
POETRY_VERSION: "1.8.2"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
python-version:
|
||||||
|
- "3.12"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
|
||||||
|
uses: "./.github/actions/poetry_caching"
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
poetry-version: ${{ env.POETRY_VERSION }}
|
||||||
|
cache-key: ${{ runner.os }}-poetry-${{ env.POETRY_VERSION }}-${{ hashFiles('**/poetry.lock') }}
|
||||||
|
- name: Install Python dependencies
|
||||||
|
run: |
|
||||||
|
poetry env use ${{ matrix.python-version }}
|
||||||
|
poetry install
|
||||||
|
- name: Register problem matcher
|
||||||
|
run: echo "::add-matcher::.github/workflows/matchers/ruff.json"
|
||||||
|
- name: Run Ruff
|
||||||
|
run: poetry run ruff check --output-format=github .
|
||||||
|
- name: Run Ruff format
|
||||||
|
run: poetry run ruff format --check .
|
||||||
|
|
||||||
|
|
@ -1,18 +1,5 @@
|
||||||
fail_fast: true
|
fail_fast: true
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
|
||||||
rev: "v9.1.1"
|
|
||||||
hooks:
|
|
||||||
- id: eslint
|
|
||||||
files: \.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
|
|
||||||
types: [file]
|
|
||||||
args: ["--fix", "--no-warn-ignored"]
|
|
||||||
additional_dependencies:
|
|
||||||
- eslint@9.1.1
|
|
||||||
- eslint-plugin-prettier
|
|
||||||
- eslint-config-prettier
|
|
||||||
- prettier
|
|
||||||
- eslint-plugin-react@latest
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.1.0
|
rev: v4.1.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|
@ -25,16 +12,3 @@ repos:
|
||||||
args:
|
args:
|
||||||
- --fix=lf
|
- --fix=lf
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
||||||
# Ruff version.
|
|
||||||
rev: v0.4.2
|
|
||||||
hooks:
|
|
||||||
# Run the linter.
|
|
||||||
- id: ruff
|
|
||||||
# Python
|
|
||||||
files: \.py$
|
|
||||||
types: [file]
|
|
||||||
# Run the formatter.
|
|
||||||
- id: ruff-format
|
|
||||||
files: \.py$
|
|
||||||
types: [file]
|
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ import { autoLogin, getGlobalVariables, getHealth } from "./controllers/API";
|
||||||
import { setupAxiosDefaults } from "./controllers/API/utils";
|
import { setupAxiosDefaults } from "./controllers/API/utils";
|
||||||
import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path";
|
import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path";
|
||||||
import Router from "./routes";
|
import Router from "./routes";
|
||||||
|
import { Case } from "./shared/components/caseComponent";
|
||||||
import useAlertStore from "./stores/alertStore";
|
import useAlertStore from "./stores/alertStore";
|
||||||
import { useDarkStore } from "./stores/darkStore";
|
import { useDarkStore } from "./stores/darkStore";
|
||||||
import useFlowsManagerStore from "./stores/flowsManagerStore";
|
import useFlowsManagerStore from "./stores/flowsManagerStore";
|
||||||
import { useFolderStore } from "./stores/foldersStore";
|
import { useFolderStore } from "./stores/foldersStore";
|
||||||
import { useGlobalVariablesStore } from "./stores/globalVariablesStore/globalVariables";
|
import { useGlobalVariablesStore } from "./stores/globalVariablesStore/globalVariables";
|
||||||
import { useStoreStore } from "./stores/storeStore";
|
import { useStoreStore } from "./stores/storeStore";
|
||||||
import { useTypesStore } from "./stores/typesStore";
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
useTrackLastVisitedPath();
|
useTrackLastVisitedPath();
|
||||||
|
|
||||||
|
|
@ -43,10 +43,8 @@ export default function App() {
|
||||||
|
|
||||||
const { isAuthenticated, login, setUserData, setAutoLogin, getUser } =
|
const { isAuthenticated, login, setUserData, setAutoLogin, getUser } =
|
||||||
useContext(AuthContext);
|
useContext(AuthContext);
|
||||||
const refreshFlows = useFlowsManagerStore((state) => state.refreshFlows);
|
|
||||||
const setLoading = useAlertStore((state) => state.setLoading);
|
const setLoading = useAlertStore((state) => state.setLoading);
|
||||||
const fetchApiData = useStoreStore((state) => state.fetchApiData);
|
const fetchApiData = useStoreStore((state) => state.fetchApiData);
|
||||||
const getTypes = useTypesStore((state) => state.getTypes);
|
|
||||||
const refreshVersion = useDarkStore((state) => state.refreshVersion);
|
const refreshVersion = useDarkStore((state) => state.refreshVersion);
|
||||||
const refreshStars = useDarkStore((state) => state.refreshStars);
|
const refreshStars = useDarkStore((state) => state.refreshStars);
|
||||||
const setGlobalVariables = useGlobalVariablesStore(
|
const setGlobalVariables = useGlobalVariablesStore(
|
||||||
|
|
@ -56,8 +54,7 @@ export default function App() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dark = useDarkStore((state) => state.dark);
|
const dark = useDarkStore((state) => state.dark);
|
||||||
|
|
||||||
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
const isLoadingFolders = useFolderStore((state) => state.isLoadingFolders);
|
||||||
const loadingFolders = useFolderStore((state) => state.loading);
|
|
||||||
|
|
||||||
const [isLoadingHealth, setIsLoadingHealth] = useState(false);
|
const [isLoadingHealth, setIsLoadingHealth] = useState(false);
|
||||||
|
|
||||||
|
|
@ -115,13 +112,13 @@ export default function App() {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
try {
|
try {
|
||||||
await setupAxiosDefaults();
|
await setupAxiosDefaults();
|
||||||
await getFoldersApi();
|
|
||||||
await getTypes();
|
|
||||||
await refreshFlows();
|
|
||||||
const res = await getGlobalVariables();
|
const res = await getGlobalVariables();
|
||||||
setGlobalVariables(res);
|
setGlobalVariables(res);
|
||||||
|
|
||||||
checkHasStore();
|
checkHasStore();
|
||||||
fetchApiData();
|
fetchApiData();
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch data:", error);
|
console.error("Failed to fetch data:", error);
|
||||||
|
|
@ -174,6 +171,8 @@ export default function App() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isLoadingApplication = isLoading || isLoadingFolders;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
//need parent component with width and height
|
//need parent component with width and height
|
||||||
<div className="flex h-full flex-col">
|
<div className="flex h-full flex-col">
|
||||||
|
|
@ -196,15 +195,15 @@ export default function App() {
|
||||||
></FetchErrorComponent>
|
></FetchErrorComponent>
|
||||||
}
|
}
|
||||||
|
|
||||||
{isLoading || loadingFolders ? (
|
<Case condition={isLoadingApplication}>
|
||||||
<div className="loading-page-panel">
|
<div className="loading-page-panel">
|
||||||
<LoadingComponent remSize={50} />
|
<LoadingComponent remSize={50} />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
</Case>
|
||||||
<>
|
|
||||||
<Router />
|
<Case condition={!isLoadingApplication}>
|
||||||
</>
|
<Router />
|
||||||
)}
|
</Case>
|
||||||
</>
|
</>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
<div></div>
|
<div></div>
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
const currentFolder = pathname.split("/");
|
const currentFolder = pathname.split("/");
|
||||||
const urlWithoutPath = pathname.split("/").length < 4;
|
const urlWithoutPath = pathname.split("/").length < 4;
|
||||||
const myCollectionId = useFolderStore((state) => state.myCollectionId);
|
const myCollectionId = useFolderStore((state) => state.myCollectionId);
|
||||||
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
|
||||||
const folderIdDragging = useFolderStore((state) => state.folderIdDragging);
|
const folderIdDragging = useFolderStore((state) => state.folderIdDragging);
|
||||||
|
const refreshFolders = useFolderStore((state) => state.refreshFolders);
|
||||||
|
|
||||||
const checkPathName = (itemId: string) => {
|
const checkPathName = (itemId: string) => {
|
||||||
if (urlWithoutPath && itemId === myCollectionId) {
|
if (urlWithoutPath && itemId === myCollectionId) {
|
||||||
|
|
@ -85,7 +85,7 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
function addNewFolder() {
|
function addNewFolder() {
|
||||||
addFolder({ name: "New Folder", parent_id: null, description: "" }).then(
|
addFolder({ name: "New Folder", parent_id: null, description: "" }).then(
|
||||||
(res) => {
|
(res) => {
|
||||||
getFoldersApi(true);
|
refreshFolders();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
const refreshFolders = useFolderStore((state) => state.refreshFolders);
|
||||||
const flows = useFlowsManagerStore((state) => state.flows);
|
const flows = useFlowsManagerStore((state) => state.flows);
|
||||||
|
|
||||||
const triggerFolderChange = (folderId) => {
|
const triggerFolderChange = (folderId) => {
|
||||||
|
|
@ -118,7 +118,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
setFolderIdDragging("");
|
setFolderIdDragging("");
|
||||||
|
|
||||||
updateFlowInDatabase(updatedFlow).then(() => {
|
updateFlowInDatabase(updatedFlow).then(() => {
|
||||||
getFoldersApi(true);
|
refreshFolders();
|
||||||
triggerFolderChange(folderId);
|
triggerFolderChange(folderId);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -129,7 +129,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
setFolderDragging(false);
|
setFolderDragging(false);
|
||||||
setFolderIdDragging("");
|
setFolderIdDragging("");
|
||||||
uploadFlowsFromFolders(formData).then(() => {
|
uploadFlowsFromFolders(formData).then(() => {
|
||||||
getFoldersApi(true);
|
refreshFolders();
|
||||||
triggerFolderChange(folderId);
|
triggerFolderChange(folderId);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export default function SidebarNav({
|
||||||
}: SidebarNavProps) {
|
}: SidebarNavProps) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const pathname = location.pathname;
|
const pathname = location.pathname;
|
||||||
const loadingFolders = useFolderStore((state) => state.loading);
|
const loadingFolders = useFolderStore((state) => state.isLoadingFolders);
|
||||||
const folders = useFolderStore((state) => state.folders);
|
const folders = useFolderStore((state) => state.folders);
|
||||||
|
|
||||||
const pathValues = ["folder", "components", "flows", "all"];
|
const pathValues = ["folder", "components", "flows", "all"];
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ const TableComponent = forwardRef<
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
realRef.current.api.hideOverlay();
|
realRef?.current?.api?.hideOverlay();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
if (props.onGridReady) props.onGridReady(params);
|
if (props.onGridReady) props.onGridReady(params);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
|
||||||
import Cookies from "universal-cookie";
|
import Cookies from "universal-cookie";
|
||||||
import { getLoggedUser, requestLogout } from "../controllers/API";
|
import { getLoggedUser, requestLogout } from "../controllers/API";
|
||||||
import useAlertStore from "../stores/alertStore";
|
import useAlertStore from "../stores/alertStore";
|
||||||
|
import { useFolderStore } from "../stores/foldersStore";
|
||||||
import { Users } from "../types/api";
|
import { Users } from "../types/api";
|
||||||
import { AuthContextType } from "../types/contexts/auth";
|
import { AuthContextType } from "../types/contexts/auth";
|
||||||
|
|
||||||
|
|
@ -42,7 +43,8 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
const [apiKey, setApiKey] = useState<string | null>(
|
const [apiKey, setApiKey] = useState<string | null>(
|
||||||
cookies.get("apikey_tkn_lflw")
|
cookies.get("apikey_tkn_lflw")
|
||||||
);
|
);
|
||||||
// const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
|
||||||
|
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedAccessToken = cookies.get("access_token_lf");
|
const storedAccessToken = cookies.get("access_token_lf");
|
||||||
|
|
@ -64,7 +66,8 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
setUserData(user);
|
setUserData(user);
|
||||||
const isSuperUser = user!.is_superuser;
|
const isSuperUser = user!.is_superuser;
|
||||||
setIsAdmin(isSuperUser);
|
setIsAdmin(isSuperUser);
|
||||||
// await getFoldersApi(true);
|
|
||||||
|
getFoldersApi(true, true);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ function ApiInterceptor() {
|
||||||
|
|
||||||
if (!checkRequest) {
|
if (!checkRequest) {
|
||||||
controller.abort("Duplicate Request");
|
controller.abort("Duplicate Request");
|
||||||
|
console.error("Duplicate Request");
|
||||||
}
|
}
|
||||||
|
|
||||||
const accessToken = cookies.get("access_token_lf");
|
const accessToken = cookies.get("access_token_lf");
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@ export function checkDuplicateRequestAndStoreRequest(config) {
|
||||||
const lastUrl = localStorage.getItem("lastUrlCalled");
|
const lastUrl = localStorage.getItem("lastUrlCalled");
|
||||||
const lastMethodCalled = localStorage.getItem("lastMethodCalled");
|
const lastMethodCalled = localStorage.getItem("lastMethodCalled");
|
||||||
const lastRequestTime = localStorage.getItem("lastRequestTime");
|
const lastRequestTime = localStorage.getItem("lastRequestTime");
|
||||||
|
const lastCurrentUrl = localStorage.getItem("lastCurrentUrl");
|
||||||
|
|
||||||
|
const currentUrl = window.location.pathname;
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
|
|
||||||
const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) =>
|
const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) =>
|
||||||
config?.url!.includes(request)
|
config?.url!.includes(request)
|
||||||
);
|
);
|
||||||
|
|
@ -17,7 +18,8 @@ export function checkDuplicateRequestAndStoreRequest(config) {
|
||||||
lastMethodCalled === config.method &&
|
lastMethodCalled === config.method &&
|
||||||
lastMethodCalled === "get" && // Assuming you want to check only for GET requests
|
lastMethodCalled === "get" && // Assuming you want to check only for GET requests
|
||||||
lastRequestTime &&
|
lastRequestTime &&
|
||||||
currentTime - parseInt(lastRequestTime, 10) < 800
|
currentTime - parseInt(lastRequestTime, 10) < 300 &&
|
||||||
|
lastCurrentUrl === currentUrl
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +27,7 @@ export function checkDuplicateRequestAndStoreRequest(config) {
|
||||||
localStorage.setItem("lastUrlCalled", config.url ?? "");
|
localStorage.setItem("lastUrlCalled", config.url ?? "");
|
||||||
localStorage.setItem("lastMethodCalled", config.method ?? "");
|
localStorage.setItem("lastMethodCalled", config.method ?? "");
|
||||||
localStorage.setItem("lastRequestTime", currentTime.toString());
|
localStorage.setItem("lastRequestTime", currentTime.toString());
|
||||||
|
localStorage.setItem("lastCurrentUrl", currentUrl);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1094,8 +1094,6 @@ export async function getMessagesTable(
|
||||||
|
|
||||||
const rowsOrganized = rows.data;
|
const rowsOrganized = rows.data;
|
||||||
|
|
||||||
console.log(rowsOrganized);
|
|
||||||
|
|
||||||
const columns = extractColumnsFromRows(rowsOrganized, mode, excludedFields);
|
const columns = extractColumnsFromRows(rowsOrganized, mode, excludedFields);
|
||||||
const sessions = new Set<string>();
|
const sessions = new Set<string>();
|
||||||
rowsOrganized.forEach((row) => {
|
rowsOrganized.forEach((row) => {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export default function LoginAdminPage() {
|
||||||
const [inputState, setInputState] =
|
const [inputState, setInputState] =
|
||||||
useState<loginInputStateType>(CONTROL_LOGIN_STATE);
|
useState<loginInputStateType>(CONTROL_LOGIN_STATE);
|
||||||
const { login, isAuthenticated, setUserData } = useContext(AuthContext);
|
const { login, isAuthenticated, setUserData } = useContext(AuthContext);
|
||||||
|
const setLoading = useAlertStore((state) => state.setLoading);
|
||||||
|
|
||||||
const { password, username } = inputState;
|
const { password, username } = inputState;
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
|
|
@ -35,6 +36,10 @@ export default function LoginAdminPage() {
|
||||||
};
|
};
|
||||||
onLogin(user)
|
onLogin(user)
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
|
console.log("admin page");
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
login(user.access_token);
|
login(user.access_token);
|
||||||
navigate("/admin/");
|
navigate("/admin/");
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { CONTROL_LOGIN_STATE } from "../../constants/constants";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
import { onLogin } from "../../controllers/API";
|
import { onLogin } from "../../controllers/API";
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
import { LoginType } from "../../types/api";
|
import { LoginType } from "../../types/api";
|
||||||
import {
|
import {
|
||||||
inputHandlerEventType,
|
inputHandlerEventType,
|
||||||
|
|
@ -23,6 +24,7 @@ export default function LoginPage(): JSX.Element {
|
||||||
const { login } = useContext(AuthContext);
|
const { login } = useContext(AuthContext);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
|
const setLoading = useFlowsManagerStore((state) => state.setIsLoading);
|
||||||
|
|
||||||
function handleInput({
|
function handleInput({
|
||||||
target: { name, value },
|
target: { name, value },
|
||||||
|
|
@ -37,6 +39,9 @@ export default function LoginPage(): JSX.Element {
|
||||||
};
|
};
|
||||||
onLogin(user)
|
onLogin(user)
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
|
console.log("login page");
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
login(user.access_token);
|
login(user.access_token);
|
||||||
navigate("/");
|
navigate("/");
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,19 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
import useAlertStore from "../../../../../../stores/alertStore";
|
|
||||||
import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore";
|
||||||
import { useFolderStore } from "../../../../../../stores/foldersStore";
|
|
||||||
import { handleDownloadFolderFn } from "../../../../utils/handle-download-folder";
|
|
||||||
import InputSearchComponent from "../inputSearchComponent";
|
import InputSearchComponent from "../inputSearchComponent";
|
||||||
import TabsSearchComponent from "../tabsComponent";
|
import TabsSearchComponent from "../tabsComponent";
|
||||||
|
|
||||||
type HeaderTabsSearchComponentProps = {};
|
type HeaderTabsSearchComponentProps = {};
|
||||||
|
|
||||||
const HeaderTabsSearchComponent = ({}: HeaderTabsSearchComponentProps) => {
|
const HeaderTabsSearchComponent = ({}: HeaderTabsSearchComponentProps) => {
|
||||||
const location = useLocation();
|
|
||||||
const myCollectionId = useFolderStore((state) => state.myCollectionId);
|
|
||||||
const folderId = location?.state?.folderId || myCollectionId;
|
|
||||||
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
||||||
const [tabActive, setTabActive] = useState("Flows");
|
const [tabActive, setTabActive] = useState("Flows");
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
|
||||||
const allFlows = useFlowsManagerStore((state) => state.allFlows);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [inputValue, setInputValue] = useState("");
|
||||||
|
|
||||||
const setSearchFlowsComponents = useFlowsManagerStore(
|
const setSearchFlowsComponents = useFlowsManagerStore(
|
||||||
(state) => state.setSearchFlowsComponents
|
(state) => state.setSearchFlowsComponents
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDownloadFolder = () => {
|
|
||||||
if (allFlows.length === 0) {
|
|
||||||
setErrorData({
|
|
||||||
title: "Folder is empty",
|
|
||||||
list: [],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleDownloadFolderFn(folderId);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="relative flex items-end gap-4">
|
<div className="relative flex items-end gap-4">
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,12 @@ import useAlertStore from "../../../stores/alertStore";
|
||||||
import { useFolderStore } from "../../../stores/foldersStore";
|
import { useFolderStore } from "../../../stores/foldersStore";
|
||||||
import { deleteFolder, getFolderById } from "../services";
|
import { deleteFolder, getFolderById } from "../services";
|
||||||
|
|
||||||
const useDeleteFolder = ({ navigate, getFoldersApi }) => {
|
const useDeleteFolder = ({ navigate }) => {
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const folderToEdit = useFolderStore((state) => state.folderToEdit);
|
const folderToEdit = useFolderStore((state) => state.folderToEdit);
|
||||||
const myCollectionId = useFolderStore((state) => state.myCollectionId);
|
const myCollectionId = useFolderStore((state) => state.myCollectionId);
|
||||||
|
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
||||||
|
|
||||||
const handleDeleteFolder = () => {
|
const handleDeleteFolder = () => {
|
||||||
deleteFolder(folderToEdit?.id!)
|
deleteFolder(folderToEdit?.id!)
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,9 @@ export default function HomePage(): JSX.Element {
|
||||||
const [openFolderModal, setOpenFolderModal] = useState(false);
|
const [openFolderModal, setOpenFolderModal] = useState(false);
|
||||||
const [openDeleteFolderModal, setOpenDeleteFolderModal] = useState(false);
|
const [openDeleteFolderModal, setOpenDeleteFolderModal] = useState(false);
|
||||||
const is_component = pathname === "/components";
|
const is_component = pathname === "/components";
|
||||||
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
|
||||||
const setFolderToEdit = useFolderStore((state) => state.setFolderToEdit);
|
const setFolderToEdit = useFolderStore((state) => state.setFolderToEdit);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
getFoldersApi();
|
|
||||||
}, 300);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentFlowId("");
|
setCurrentFlowId("");
|
||||||
}, [pathname]);
|
}, [pathname]);
|
||||||
|
|
@ -45,7 +38,7 @@ export default function HomePage(): JSX.Element {
|
||||||
is_component,
|
is_component,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleDeleteFolder } = useDeleteFolder({ navigate, getFoldersApi });
|
const { handleDeleteFolder } = useDeleteFolder({ navigate });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -7,64 +7,100 @@ import {
|
||||||
} from "../pages/MainPage/services";
|
} from "../pages/MainPage/services";
|
||||||
import { FoldersStoreType } from "../types/zustand/folders";
|
import { FoldersStoreType } from "../types/zustand/folders";
|
||||||
import useFlowsManagerStore from "./flowsManagerStore";
|
import useFlowsManagerStore from "./flowsManagerStore";
|
||||||
|
import { useTypesStore } from "./typesStore";
|
||||||
|
|
||||||
export const useFolderStore = create<FoldersStoreType>((set, get) => ({
|
export const useFolderStore = create<FoldersStoreType>((set, get) => ({
|
||||||
folders: [],
|
folders: [],
|
||||||
getFoldersApi: (refetch = false) => {
|
getFoldersApi: (refetch = false, startupApplication: boolean = false) => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
if (get()?.folders.length === 0 || refetch === true) {
|
if (get()?.folders.length === 0 || refetch === true) {
|
||||||
get().setLoading(true);
|
get().setIsLoadingFolders(true);
|
||||||
getFolders().then(
|
getFolders().then(
|
||||||
(res) => {
|
async (res) => {
|
||||||
const foldersWithoutStarterProjects = res?.filter(
|
const foldersWithoutStarterProjects = res?.filter(
|
||||||
(folder) => folder.name !== STARTER_FOLDER_NAME,
|
(folder) => folder.name !== STARTER_FOLDER_NAME
|
||||||
);
|
);
|
||||||
|
|
||||||
const starterProjects = res?.find(
|
const starterProjects = res?.find(
|
||||||
(folder) => folder.name === STARTER_FOLDER_NAME,
|
(folder) => folder.name === STARTER_FOLDER_NAME
|
||||||
);
|
);
|
||||||
|
|
||||||
set({ starterProjectId: starterProjects!.id ?? "" });
|
set({ starterProjectId: starterProjects!.id ?? "" });
|
||||||
set({ folders: foldersWithoutStarterProjects });
|
set({ folders: foldersWithoutStarterProjects });
|
||||||
|
|
||||||
const myCollectionId = res?.find(
|
const myCollectionId = res?.find(
|
||||||
(f) => f.name === DEFAULT_FOLDER,
|
(f) => f.name === DEFAULT_FOLDER
|
||||||
)?.id;
|
)?.id;
|
||||||
|
|
||||||
set({ myCollectionId });
|
set({ myCollectionId });
|
||||||
|
|
||||||
if (refetch === true) {
|
const { refreshFlows } = useFlowsManagerStore.getState();
|
||||||
useFlowsManagerStore.getState().refreshFlows();
|
const { getTypes } = useTypesStore.getState();
|
||||||
useFlowsManagerStore.getState().setAllFlows;
|
const { setIsLoadingFolders } = get();
|
||||||
}
|
|
||||||
|
if (refetch) {
|
||||||
|
if (startupApplication) {
|
||||||
|
await refreshFlows();
|
||||||
|
await getTypes();
|
||||||
|
} else {
|
||||||
|
refreshFlows();
|
||||||
|
getTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setIsLoadingFolders(false);
|
||||||
|
|
||||||
get().setLoading(false);
|
|
||||||
resolve();
|
resolve();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
set({ folders: [] });
|
set({ folders: [] });
|
||||||
get().setLoading(false);
|
get().setIsLoadingFolders(false);
|
||||||
reject(error);
|
reject(error);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
refreshFolders: () => {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
getFolders().then(
|
||||||
|
async (res) => {
|
||||||
|
const foldersWithoutStarterProjects = res?.filter(
|
||||||
|
(folder) => folder.name !== STARTER_FOLDER_NAME
|
||||||
|
);
|
||||||
|
|
||||||
|
const starterProjects = res?.find(
|
||||||
|
(folder) => folder.name === STARTER_FOLDER_NAME
|
||||||
|
);
|
||||||
|
|
||||||
|
set({ starterProjectId: starterProjects!.id ?? "" });
|
||||||
|
set({ folders: foldersWithoutStarterProjects });
|
||||||
|
|
||||||
|
const myCollectionId = res?.find(
|
||||||
|
(f) => f.name === DEFAULT_FOLDER
|
||||||
|
)?.id;
|
||||||
|
|
||||||
|
set({ myCollectionId });
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
set({ folders: [] });
|
||||||
|
get().setIsLoadingFolders(false);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
setFolders: (folders) => set(() => ({ folders: folders })),
|
setFolders: (folders) => set(() => ({ folders: folders })),
|
||||||
loading: false,
|
isLoadingFolders: false,
|
||||||
setLoading: (loading) => set(() => ({ loading: loading })),
|
setIsLoadingFolders: (isLoadingFolders) => set(() => ({ isLoadingFolders })),
|
||||||
getFolderById: (id) => {
|
getFolderById: (id) => {
|
||||||
if (id) {
|
if (id) {
|
||||||
getFolderById(id).then(
|
getFolderById(id).then((res) => {
|
||||||
(res) => {
|
const setAllFlows = useFlowsManagerStore.getState().setAllFlows;
|
||||||
const setAllFlows = useFlowsManagerStore.getState().setAllFlows;
|
setAllFlows(res.flows);
|
||||||
setAllFlows(res.flows);
|
set({ selectedFolder: res });
|
||||||
set({ selectedFolder: res });
|
});
|
||||||
},
|
|
||||||
() => {
|
|
||||||
get().getFoldersApi(true);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectedFolder: null,
|
selectedFolder: null,
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,13 @@ import { FolderType } from "../../../pages/MainPage/entities";
|
||||||
|
|
||||||
export type FoldersStoreType = {
|
export type FoldersStoreType = {
|
||||||
folders: FolderType[];
|
folders: FolderType[];
|
||||||
getFoldersApi: (refetch?: boolean) => Promise<void>;
|
getFoldersApi: (
|
||||||
|
refetch?: boolean,
|
||||||
|
startupApplication?: boolean
|
||||||
|
) => Promise<void>;
|
||||||
setFolders: (folders: FolderType[]) => void;
|
setFolders: (folders: FolderType[]) => void;
|
||||||
loading: boolean;
|
isLoadingFolders: boolean;
|
||||||
setLoading: (loading: boolean) => void;
|
setIsLoadingFolders: (isLoadingFolders: boolean) => void;
|
||||||
selectedFolder: FolderType | null;
|
selectedFolder: FolderType | null;
|
||||||
getFolderById: (id: string) => void;
|
getFolderById: (id: string) => void;
|
||||||
getMyCollectionFolder: () => void;
|
getMyCollectionFolder: () => void;
|
||||||
|
|
@ -23,4 +26,5 @@ export type FoldersStoreType = {
|
||||||
setFolderIdDragging: (id: string) => void;
|
setFolderIdDragging: (id: string) => void;
|
||||||
starterProjectId: string;
|
starterProjectId: string;
|
||||||
setStarterProjectId: (id: string) => void;
|
setStarterProjectId: (id: string) => void;
|
||||||
|
refreshFolders: () => void;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export function normalCaseToSnakeCase(str: string): string {
|
||||||
|
|
||||||
export function toTitleCase(
|
export function toTitleCase(
|
||||||
str: string | undefined,
|
str: string | undefined,
|
||||||
isNodeField?: boolean,
|
isNodeField?: boolean
|
||||||
): string {
|
): string {
|
||||||
if (!str) return "";
|
if (!str) return "";
|
||||||
let result = str
|
let result = str
|
||||||
|
|
@ -65,7 +65,7 @@ export function toTitleCase(
|
||||||
if (isNodeField) return word;
|
if (isNodeField) return word;
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
return checkUpperWords(
|
return checkUpperWords(
|
||||||
word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return checkUpperWords(word.toLowerCase());
|
return checkUpperWords(word.toLowerCase());
|
||||||
|
|
@ -78,7 +78,7 @@ export function toTitleCase(
|
||||||
if (isNodeField) return word;
|
if (isNodeField) return word;
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
return checkUpperWords(
|
return checkUpperWords(
|
||||||
word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
word[0].toUpperCase() + word.slice(1).toLowerCase()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return checkUpperWords(word.toLowerCase());
|
return checkUpperWords(word.toLowerCase());
|
||||||
|
|
@ -182,7 +182,7 @@ export function checkLocalStorageKey(key: string): boolean {
|
||||||
|
|
||||||
export function IncrementObjectKey(
|
export function IncrementObjectKey(
|
||||||
object: object,
|
object: object,
|
||||||
key: string,
|
key: string
|
||||||
): { newKey: string; increment: number } {
|
): { newKey: string; increment: number } {
|
||||||
let count = 1;
|
let count = 1;
|
||||||
const type = removeCountFromString(key);
|
const type = removeCountFromString(key);
|
||||||
|
|
@ -217,7 +217,7 @@ export function groupByFamily(
|
||||||
data: APIDataType,
|
data: APIDataType,
|
||||||
baseClasses: string,
|
baseClasses: string,
|
||||||
left: boolean,
|
left: boolean,
|
||||||
flow?: NodeType[],
|
flow?: NodeType[]
|
||||||
): groupedObjType[] {
|
): groupedObjType[] {
|
||||||
const baseClassesSet = new Set(baseClasses.split("\n"));
|
const baseClassesSet = new Set(baseClasses.split("\n"));
|
||||||
let arrOfPossibleInputs: Array<{
|
let arrOfPossibleInputs: Array<{
|
||||||
|
|
@ -263,7 +263,7 @@ export function groupByFamily(
|
||||||
hasBaseClassInBaseClasses:
|
hasBaseClassInBaseClasses:
|
||||||
foundNode?.hasBaseClassInBaseClasses ||
|
foundNode?.hasBaseClassInBaseClasses ||
|
||||||
nodeData.node!.base_classes?.some((baseClass) =>
|
nodeData.node!.base_classes?.some((baseClass) =>
|
||||||
baseClassesSet.has(baseClass),
|
baseClassesSet.has(baseClass)
|
||||||
), //seta como anterior ou verifica se o node tem base class
|
), //seta como anterior ou verifica se o node tem base class
|
||||||
displayName: nodeData.node?.display_name,
|
displayName: nodeData.node?.display_name,
|
||||||
});
|
});
|
||||||
|
|
@ -280,10 +280,10 @@ export function groupByFamily(
|
||||||
if (!foundNode) {
|
if (!foundNode) {
|
||||||
foundNode = {
|
foundNode = {
|
||||||
hasBaseClassInTemplate: Object.values(node!.template).some(
|
hasBaseClassInTemplate: Object.values(node!.template).some(
|
||||||
checkBaseClass,
|
checkBaseClass
|
||||||
),
|
),
|
||||||
hasBaseClassInBaseClasses: node!.base_classes?.some((baseClass) =>
|
hasBaseClassInBaseClasses: node!.base_classes?.some((baseClass) =>
|
||||||
baseClassesSet.has(baseClass),
|
baseClassesSet.has(baseClass)
|
||||||
),
|
),
|
||||||
displayName: node?.display_name,
|
displayName: node?.display_name,
|
||||||
};
|
};
|
||||||
|
|
@ -355,7 +355,7 @@ export function isTimeStampString(str: string): boolean {
|
||||||
export function extractColumnsFromRows(
|
export function extractColumnsFromRows(
|
||||||
rows: object[],
|
rows: object[],
|
||||||
mode: "intersection" | "union",
|
mode: "intersection" | "union",
|
||||||
excludeColumns?: Array<string>,
|
excludeColumns?: Array<string>
|
||||||
): (ColDef<any> | ColGroupDef<any>)[] {
|
): (ColDef<any> | ColGroupDef<any>)[] {
|
||||||
let columnsKeys: { [key: string]: ColDef<any> | ColGroupDef<any> } = {};
|
let columnsKeys: { [key: string]: ColDef<any> | ColGroupDef<any> } = {};
|
||||||
if (rows.length === 0) {
|
if (rows.length === 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue