|
@@ -25,6 +25,8 @@ import DeploymentType from "./DeploymentType";
|
|
|
import IncidentsTab from "./incidents/IncidentsTab";
|
|
import IncidentsTab from "./incidents/IncidentsTab";
|
|
|
import BuildSettingsTab from "./BuildSettingsTab";
|
|
import BuildSettingsTab from "./BuildSettingsTab";
|
|
|
import { DisabledNamespacesForIncidents } from "./incidents/DisabledNamespaces";
|
|
import { DisabledNamespacesForIncidents } from "./incidents/DisabledNamespaces";
|
|
|
|
|
+import { Stack } from "../stacks/types";
|
|
|
|
|
+import { PopulatedEnvGroup } from "components/porter-form/types";
|
|
|
|
|
|
|
|
type Props = {
|
|
type Props = {
|
|
|
namespace: string;
|
|
namespace: string;
|
|
@@ -45,6 +47,74 @@ const getReadableDate = (s: string) => {
|
|
|
return `${time} on ${date}`;
|
|
return `${time} on ${date}`;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const useStackEnvGroups = (chart: ChartType) => {
|
|
|
|
|
+ const { currentProject, currentCluster, setCurrentError } = useContext(
|
|
|
|
|
+ Context
|
|
|
|
|
+ );
|
|
|
|
|
+ const [stackEnvGroups, setStackEnvGroups] = useState([]);
|
|
|
|
|
+ const [loading, setLoading] = useState(true);
|
|
|
|
|
+
|
|
|
|
|
+ const getEnvGroups = async (stack: Stack) => {
|
|
|
|
|
+ const envGroups = stack.latest_revision.env_groups;
|
|
|
|
|
+
|
|
|
|
|
+ const envGroupsWithValues = envGroups.map((envGroup) => {
|
|
|
|
|
+ return api
|
|
|
|
|
+ .getEnvGroup<PopulatedEnvGroup>(
|
|
|
|
|
+ "<token>",
|
|
|
|
|
+ {},
|
|
|
|
|
+ {
|
|
|
|
|
+ id: currentProject.id,
|
|
|
|
|
+ namespace: chart.namespace,
|
|
|
|
|
+ cluster_id: currentCluster.id,
|
|
|
|
|
+ name: envGroup.name,
|
|
|
|
|
+ version: envGroup.env_group_version,
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ .then((res) => res.data);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return Promise.all(envGroupsWithValues);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const getStack = (stack_id: string) =>
|
|
|
|
|
+ api
|
|
|
|
|
+ .getStack<Stack>(
|
|
|
|
|
+ "token",
|
|
|
|
|
+ {},
|
|
|
|
|
+ {
|
|
|
|
|
+ cluster_id: currentCluster.id,
|
|
|
|
|
+ project_id: currentProject.id,
|
|
|
|
|
+ stack_id,
|
|
|
|
|
+ namespace: chart.namespace,
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ .then((res) => res.data);
|
|
|
|
|
+
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ const stack_id = chart.stack_id;
|
|
|
|
|
+ if (!stack_id) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ getStack(stack_id)
|
|
|
|
|
+ .then((stack) => getEnvGroups(stack))
|
|
|
|
|
+ .then((populatedEnvGroups) => {
|
|
|
|
|
+ setStackEnvGroups(populatedEnvGroups);
|
|
|
|
|
+
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
|
+ setCurrentError(error);
|
|
|
|
|
+ });
|
|
|
|
|
+ }, [chart.stack_id]);
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ isStack: chart.stack_id?.length ? true : false,
|
|
|
|
|
+ stackEnvGroups,
|
|
|
|
|
+ isLoadingStackEnvGroups: loading,
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const ExpandedChart: React.FC<Props> = (props) => {
|
|
const ExpandedChart: React.FC<Props> = (props) => {
|
|
|
const [currentChart, setCurrentChart] = useState<ChartType>(
|
|
const [currentChart, setCurrentChart] = useState<ChartType>(
|
|
|
props.currentChart
|
|
props.currentChart
|
|
@@ -74,6 +144,12 @@ const ExpandedChart: React.FC<Props> = (props) => {
|
|
|
const [isAuthorized] = useAuth();
|
|
const [isAuthorized] = useAuth();
|
|
|
const [fullScreenLogs, setFullScreenLogs] = useState<boolean>(false);
|
|
const [fullScreenLogs, setFullScreenLogs] = useState<boolean>(false);
|
|
|
|
|
|
|
|
|
|
+ const {
|
|
|
|
|
+ isStack,
|
|
|
|
|
+ stackEnvGroups,
|
|
|
|
|
+ isLoadingStackEnvGroups,
|
|
|
|
|
+ } = useStackEnvGroups(currentChart);
|
|
|
|
|
+
|
|
|
const {
|
|
const {
|
|
|
newWebsocket,
|
|
newWebsocket,
|
|
|
openWebsocket,
|
|
openWebsocket,
|
|
@@ -528,7 +604,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (currentChart?.git_action_config?.git_repo && !currentChart.is_stack) {
|
|
|
|
|
|
|
+ if (currentChart?.git_action_config?.git_repo && !isStack) {
|
|
|
rightTabOptions.push({
|
|
rightTabOptions.push({
|
|
|
label: "Build Settings",
|
|
label: "Build Settings",
|
|
|
value: "build-settings",
|
|
value: "build-settings",
|
|
@@ -565,59 +641,6 @@ const ExpandedChart: React.FC<Props> = (props) => {
|
|
|
setDevOpsMode(!devOpsMode);
|
|
setDevOpsMode(!devOpsMode);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const renderIcon = () => {
|
|
|
|
|
- if (
|
|
|
|
|
- currentChart.chart.metadata.icon &&
|
|
|
|
|
- currentChart.chart.metadata.icon !== ""
|
|
|
|
|
- ) {
|
|
|
|
|
- return <Icon src={currentChart.chart.metadata.icon} />;
|
|
|
|
|
- } else {
|
|
|
|
|
- return <i className="material-icons">tonality</i>;
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- // const chartStatus = useMemo(() => {
|
|
|
|
|
- // const getAvailability = (kind: string, c: any) => {
|
|
|
|
|
- // switch (kind?.toLowerCase()) {
|
|
|
|
|
- // case "deployment":
|
|
|
|
|
- // case "replicaset":
|
|
|
|
|
- // return c.status.availableReplicas == c.status.replicas;
|
|
|
|
|
- // case "statefulset":
|
|
|
|
|
- // return c.status.readyReplicas == c.status.replicas;
|
|
|
|
|
- // case "daemonset":
|
|
|
|
|
- // return c.status.numberAvailable == c.status.desiredNumberScheduled;
|
|
|
|
|
- // }
|
|
|
|
|
- // };
|
|
|
|
|
-
|
|
|
|
|
- // const chartStatus = currentChart.info.status;
|
|
|
|
|
-
|
|
|
|
|
- // if (chartStatus === "deployed") {
|
|
|
|
|
- // for (var uid in controllers) {
|
|
|
|
|
- // let value = controllers[uid];
|
|
|
|
|
- // let available = getAvailability(value.metadata.kind, value);
|
|
|
|
|
- // let progressing = true;
|
|
|
|
|
-
|
|
|
|
|
- // controllers[uid]?.status?.conditions?.forEach((condition: any) => {
|
|
|
|
|
- // if (
|
|
|
|
|
- // condition.type == "Progressing" &&
|
|
|
|
|
- // condition.status == "False" &&
|
|
|
|
|
- // condition.reason == "ProgressDeadlineExceeded"
|
|
|
|
|
- // ) {
|
|
|
|
|
- // progressing = false;
|
|
|
|
|
- // }
|
|
|
|
|
- // });
|
|
|
|
|
-
|
|
|
|
|
- // if (!available && progressing) {
|
|
|
|
|
- // return "loading";
|
|
|
|
|
- // } else if (!available && !progressing) {
|
|
|
|
|
- // return "failed";
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
- // return "deployed";
|
|
|
|
|
- // }
|
|
|
|
|
- // return chartStatus;
|
|
|
|
|
- // }, [currentChart, controllers]);
|
|
|
|
|
-
|
|
|
|
|
const renderUrl = () => {
|
|
const renderUrl = () => {
|
|
|
if (url) {
|
|
if (url) {
|
|
|
return (
|
|
return (
|
|
@@ -840,37 +863,59 @@ const ExpandedChart: React.FC<Props> = (props) => {
|
|
|
latestVersion={currentChart.latest_version}
|
|
latestVersion={currentChart.latest_version}
|
|
|
upgradeVersion={handleUpgradeVersion}
|
|
upgradeVersion={handleUpgradeVersion}
|
|
|
/>
|
|
/>
|
|
|
- {(isPreview || leftTabOptions.length > 0) && (
|
|
|
|
|
- <BodyWrapper>
|
|
|
|
|
- <PorterFormWrapper
|
|
|
|
|
- formData={cloneDeep(currentChart.form)}
|
|
|
|
|
- valuesToOverride={{
|
|
|
|
|
- namespace: props.namespace,
|
|
|
|
|
- clusterId: currentCluster.id,
|
|
|
|
|
- }}
|
|
|
|
|
- renderTabContents={renderTabContents}
|
|
|
|
|
- isReadOnly={
|
|
|
|
|
- isPreview ||
|
|
|
|
|
- imageIsPlaceholder ||
|
|
|
|
|
- !isAuthorized("application", "", ["get", "update"])
|
|
|
|
|
- }
|
|
|
|
|
- onSubmit={onSubmit}
|
|
|
|
|
- includeMetadata
|
|
|
|
|
- rightTabOptions={rightTabOptions}
|
|
|
|
|
- leftTabOptions={leftTabOptions}
|
|
|
|
|
- color={isPreview ? "#f5cb42" : null}
|
|
|
|
|
- addendum={
|
|
|
|
|
- <TabButton
|
|
|
|
|
- onClick={toggleDevOpsMode}
|
|
|
|
|
- devOpsMode={devOpsMode}
|
|
|
|
|
- >
|
|
|
|
|
- <i className="material-icons">offline_bolt</i> DevOps
|
|
|
|
|
- Mode
|
|
|
|
|
- </TabButton>
|
|
|
|
|
- }
|
|
|
|
|
- saveValuesStatus={saveValuesStatus}
|
|
|
|
|
- />
|
|
|
|
|
- </BodyWrapper>
|
|
|
|
|
|
|
+ {isStack && isLoadingStackEnvGroups ? (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <LineBreak />
|
|
|
|
|
+ <Placeholder>
|
|
|
|
|
+ <TextWrap>
|
|
|
|
|
+ <Header>
|
|
|
|
|
+ <Spinner src={loadingSrc} />
|
|
|
|
|
+ </Header>
|
|
|
|
|
+ </TextWrap>
|
|
|
|
|
+ </Placeholder>
|
|
|
|
|
+ </>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <>
|
|
|
|
|
+ {(isPreview || leftTabOptions.length > 0) && (
|
|
|
|
|
+ <BodyWrapper>
|
|
|
|
|
+ <PorterFormWrapper
|
|
|
|
|
+ formData={cloneDeep(currentChart.form)}
|
|
|
|
|
+ valuesToOverride={{
|
|
|
|
|
+ namespace: props.namespace,
|
|
|
|
|
+ clusterId: currentCluster.id,
|
|
|
|
|
+ }}
|
|
|
|
|
+ renderTabContents={renderTabContents}
|
|
|
|
|
+ isReadOnly={
|
|
|
|
|
+ isPreview ||
|
|
|
|
|
+ imageIsPlaceholder ||
|
|
|
|
|
+ !isAuthorized("application", "", ["get", "update"])
|
|
|
|
|
+ }
|
|
|
|
|
+ onSubmit={onSubmit}
|
|
|
|
|
+ includeMetadata
|
|
|
|
|
+ rightTabOptions={rightTabOptions}
|
|
|
|
|
+ leftTabOptions={leftTabOptions}
|
|
|
|
|
+ color={isPreview ? "#f5cb42" : null}
|
|
|
|
|
+ addendum={
|
|
|
|
|
+ <TabButton
|
|
|
|
|
+ onClick={toggleDevOpsMode}
|
|
|
|
|
+ devOpsMode={devOpsMode}
|
|
|
|
|
+ >
|
|
|
|
|
+ <i className="material-icons">offline_bolt</i>{" "}
|
|
|
|
|
+ DevOps Mode
|
|
|
|
|
+ </TabButton>
|
|
|
|
|
+ }
|
|
|
|
|
+ saveValuesStatus={saveValuesStatus}
|
|
|
|
|
+ injectedProps={{
|
|
|
|
|
+ "key-value-array": {
|
|
|
|
|
+ availableSyncEnvGroups: isStack
|
|
|
|
|
+ ? stackEnvGroups
|
|
|
|
|
+ : undefined,
|
|
|
|
|
+ },
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ </BodyWrapper>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </>
|
|
|
)}
|
|
)}
|
|
|
</>
|
|
</>
|
|
|
)}
|
|
)}
|