Skip to content

Environments Refactor + New Plugin Updates #1684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
create 3 contexts
  • Loading branch information
iamfaran committed May 8, 2025
commit badf60f31fadd829e07f0a4dc08f281a8854131c
Original file line number Diff line number Diff line change
@@ -1,156 +1,91 @@
import React, {
createContext,
useContext,
useEffect,
useState,
useCallback,
ReactNode,
} from "react";
import { message } from "antd";
import {
getEnvironmentById,
getEnvironments,
updateEnvironment,
} from "../services/environments.service";
import { Environment } from "../types/environment.types";

interface EnvironmentContextState {
// Environment data
environment: Environment | null;
environments: Environment[];

// Loading states
isLoadingEnvironment: boolean;
isLoadingEnvironments: boolean;

// Error state
error: string | null;

// Functions
refreshEnvironment: (envId?: string) => Promise<void>;
refreshEnvironments: () => Promise<void>;
updateEnvironmentData: (envId: string, data: Partial<Environment>) => Promise<Environment>;
}

const EnvironmentContext = createContext<EnvironmentContextState | undefined>(undefined);

export const useEnvironmentContext = () => {
const context = useContext(EnvironmentContext);
if (!context) {
throw new Error(
"useEnvironmentContext must be used within an EnvironmentProvider"
);
}
return context;
};

interface ProviderProps {
children: ReactNode;
}

export const EnvironmentProvider: React.FC<ProviderProps> = ({
children,
}) => {
// State for environment data
const [environment, setEnvironment] = useState<Environment | null>(null);
const [environments, setEnvironments] = useState<Environment[]>([]);

// Loading states
const [isLoadingEnvironment, setIsLoadingEnvironment] = useState<boolean>(false);
const [isLoadingEnvironments, setIsLoadingEnvironments] = useState<boolean>(true);

// Error state
const [error, setError] = useState<string | null>(null);

// Function to fetch a specific environment by ID
const fetchEnvironment = useCallback(async (environmentId?: string) => {
// Only fetch if we have an environment ID
if (!environmentId) {
setEnvironment(null);
return;
}

setIsLoadingEnvironment(true);
setError(null);

try {
const data = await getEnvironmentById(environmentId);
console.log("Environment data:", data);
setEnvironment(data);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : "Environment not found or failed to load";
setError(errorMessage);
} finally {
setIsLoadingEnvironment(false);
}
}, []);

// Function to fetch all environments
const fetchEnvironments = useCallback(async () => {
setIsLoadingEnvironments(true);
setError(null);

try {
const data = await getEnvironments();
console.log("Environments data:", data);
setEnvironments(data);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : "Failed to load environments list";
setError(errorMessage);
} finally {
setIsLoadingEnvironments(false);
}
}, []);

// Function to update an environment
// Function to update an environment
const updateEnvironmentData = useCallback(async (
environmentId: string,
data: Partial<Environment>
): Promise<Environment> => {
try {
const updatedEnv = await updateEnvironment(environmentId, data);

// Show success message
message.success("Environment updated successfully");

// Refresh the environments list
fetchEnvironments();

// If we're viewing a single environment and it's the one we updated,
// refresh that environment data as well
if (environment && environment.environmentId === environmentId) {
fetchEnvironment(environmentId);
}

return updatedEnv;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : "Failed to update environment";
message.error(errorMessage);
throw err;
}
}, [environment, fetchEnvironment, fetchEnvironments]);

// Initial data loading - just fetch environments list
useEffect(() => {
fetchEnvironments();
}, [fetchEnvironments]);

// Create the context value
const value: EnvironmentContextState = {
environment,
environments,
isLoadingEnvironment,
isLoadingEnvironments,
error,
refreshEnvironment: fetchEnvironment,
refreshEnvironments: fetchEnvironments,
updateEnvironmentData,
};

return (
<EnvironmentContext.Provider value={value}>
{children}
</EnvironmentContext.Provider>
);
// client/packages/lowcoder/src/pages/setting/environments/context/EnvironmentContext.tsx
import React, {
createContext,
useContext,
useEffect,
useState,
useCallback,
ReactNode,
} from "react";
import { message } from "antd";
import { getEnvironments } from "../services/environments.service";
import { Environment } from "../types/environment.types";

interface EnvironmentContextState {
// Environments list data
environments: Environment[];

// Loading state
isLoading: boolean;

// Error state
error: string | null;

// Functions
refreshEnvironments: () => Promise<void>;
}

const EnvironmentContext = createContext<EnvironmentContextState | undefined>(undefined);

export const useEnvironmentContext = () => {
const context = useContext(EnvironmentContext);
if (!context) {
throw new Error(
"useEnvironmentContext must be used within an EnvironmentProvider"
);
}
return context;
};

interface ProviderProps {
children: ReactNode;
}

export const EnvironmentProvider: React.FC<ProviderProps> = ({
children,
}) => {
// State for environments list
const [environments, setEnvironments] = useState<Environment[]>([]);

// Loading state
const [isLoading, setIsLoading] = useState<boolean>(true);

// Error state
const [error, setError] = useState<string | null>(null);

// Function to fetch all environments
const fetchEnvironments = useCallback(async () => {
setIsLoading(true);
setError(null);

try {
const data = await getEnvironments();
setEnvironments(data);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : "Failed to load environments list";
setError(errorMessage);
message.error(errorMessage);
} finally {
setIsLoading(false);
}
}, []);

// Initial data loading
useEffect(() => {
fetchEnvironments();
}, [fetchEnvironments]);

// Create the context value
const value: EnvironmentContextState = {
environments,
isLoading,
error,
refreshEnvironments: fetchEnvironments,
};

return (
<EnvironmentContext.Provider value={value}>
{children}
</EnvironmentContext.Provider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// client/packages/lowcoder/src/pages/setting/environments/context/SingleEnvironmentContext.tsx
import React, {
createContext,
useContext,
useEffect,
useState,
useCallback,
ReactNode,
} from "react";
import { message } from "antd";
import { useParams } from "react-router-dom";
import { getEnvironmentById, updateEnvironment } from "../services/environments.service";
import { Environment } from "../types/environment.types";

interface SingleEnvironmentContextState {
// Environment data
environment: Environment | null;

// Loading states
isLoading: boolean;

// Error state
error: string | null;

// Functions
refreshEnvironment: () => Promise<void>;
updateEnvironmentData: (data: Partial<Environment>) => Promise<Environment>;
}

const SingleEnvironmentContext = createContext<SingleEnvironmentContextState | undefined>(undefined);

export const useSingleEnvironmentContext = () => {
const context = useContext(SingleEnvironmentContext);
if (!context) {
throw new Error(
"useSingleEnvironmentContext must be used within a SingleEnvironmentProvider"
);
}
return context;
};

interface ProviderProps {
children: ReactNode;
environmentId?: string; // Optional prop-based ID
}

export const SingleEnvironmentProvider: React.FC<ProviderProps> = ({
children,
environmentId: propEnvironmentId,
}) => {
// Get environmentId from URL params if not provided as prop
const { envId } = useParams<{ envId: string }>();
const environmentId = propEnvironmentId || envId;

// State for environment data
const [environment, setEnvironment] = useState<Environment | null>(null);

// Loading states
const [isLoading, setIsLoading] = useState<boolean>(true);

// Error state
const [error, setError] = useState<string | null>(null);

// Function to fetch environment by ID
const fetchEnvironment = useCallback(async () => {
// Only fetch if we have an environment ID
if (!environmentId) {
setEnvironment(null);
setIsLoading(false);
return;
}

setIsLoading(true);
setError(null);

try {
const data = await getEnvironmentById(environmentId);
setEnvironment(data);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : "Environment not found or failed to load";
setError(errorMessage);
} finally {
setIsLoading(false);
}
}, [environmentId]);

// Function to update the environment
const updateEnvironmentData = useCallback(async (
data: Partial<Environment>
): Promise<Environment> => {
if (!environmentId || !environment) {
throw new Error("No environment selected");
}

try {
const updatedEnv = await updateEnvironment(environmentId, data);

// Show success message
message.success("Environment updated successfully");

// Update local state
setEnvironment(updatedEnv);

return updatedEnv;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : "Failed to update environment";
message.error(errorMessage);
throw err;
}
}, [environment, environmentId]);

// Load environment data when the component mounts or environmentId changes
useEffect(() => {
fetchEnvironment();
}, [fetchEnvironment]);

// Create the context value
const value: SingleEnvironmentContextState = {
environment,
isLoading,
error,
refreshEnvironment: fetchEnvironment,
updateEnvironmentData,
};

return (
<SingleEnvironmentContext.Provider value={value}>
{children}
</SingleEnvironmentContext.Provider>
);
};
Loading