Skip to content

Commit

Permalink
Embedded Cluster: Show available updates in the UI (#4680)
Browse files Browse the repository at this point in the history
  • Loading branch information
miaawong authored Jun 13, 2024
1 parent b38a8f1 commit 91e6a9c
Showing 1 changed file with 183 additions and 115 deletions.
298 changes: 183 additions & 115 deletions web/src/components/apps/AppVersionHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Props = {
app: App;
displayErrorModal: boolean;
isBundleUploading: boolean;
isEmbeddedCluster: boolean;
makeCurrentVersion: (
slug: string,
version: Version | null,
Expand All @@ -84,6 +85,7 @@ type Props = {
type State = {
airgapUploader: AirgapUploader | null;
airgapUploadError: string;
availableUpdates: Version[] | null;
appUpdateChecker: Repeater;
checkedReleasesToDiff: Version[];
checkingForUpdateError: boolean;
Expand Down Expand Up @@ -155,6 +157,7 @@ class AppVersionHistory extends Component<Props, State> {
this.state = {
airgapUploader: null,
airgapUploadError: "",
availableUpdates: null,
appUpdateChecker: new Repeater(),
checkedReleasesToDiff: [],
checkingForUpdateError: false,
Expand Down Expand Up @@ -254,36 +257,7 @@ class AppVersionHistory extends Component<Props, State> {
}
}

// TODO NOW: remove this
const appSlug = this.props.params.slug;
fetch(`${process.env.API_ENDPOINT}/app/${appSlug}/start-upgrade-service`, {
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
kotsVersion: "v1.109.3",
versionLabel: "0.0.268",
updateCursor: "895",
}),
credentials: "include",
method: "POST",
})
.then(async (res) => {
if (res.ok) {
this.setState({
shouldShowUpgradeServiceModal: true,
});
return;
}
const text = await res.text();
console.log("failed to init upgrade service", text);
})
.catch((err) => {
console.log(err);
});

this._mounted = true;
this.fetchAvailableUpdates();
}

componentDidUpdate = async (lastProps: Props) => {
Expand Down Expand Up @@ -316,6 +290,27 @@ class AppVersionHistory extends Component<Props, State> {
this._mounted = false;
}

fetchAvailableUpdates = async () => {
const appSlug = this.props.params.slug;
const res = await fetch(
`${process.env.API_ENDPOINT}/app/${appSlug}/updates`,
{
headers: {
"Content-Type": "application/json",
},
credentials: "include",
method: "GET",
}
);
if (!res.ok) {
return;
}
const response = await res.json();

this.setState({ availableUpdates: response.updates });
return response;
};

fetchKotsDownstreamHistory = async () => {
const appSlug = this.props.params.slug;

Expand Down Expand Up @@ -1399,6 +1394,68 @@ class AppVersionHistory extends Component<Props, State> {
}
};

startUpgraderService = (version: Version) => {
const appSlug = this.props.params.slug;
fetch(`${process.env.API_ENDPOINT}/app/${appSlug}/start-upgrade-service`, {
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
// not used// doesn't matter right now
kotsVersion: "v1.109.3",
versionLabel: version.versionLabel,
// channel sequence
updateCursor: version.updateCursor,
}),
credentials: "include",
method: "POST",
})
.then(async (res) => {
if (res.ok) {
this.setState({
shouldShowUpgradeServiceModal: true,
});
return;
}
const text = await res.text();
console.log("failed to init upgrade service", text);
})
.catch((err) => {
console.log(err);
});

this._mounted = true;
};

renderAvailableECUpdatesRow = (versions: Version[]) => {
return (
<div className="tw-max-h-[275px] tw-overflow-auto">
<p className="u-fontSize--normal u-fontWeight--medium tw-color-gray-800 tw-mb-2">
Available Updates
</p>
<div className="tw-flex tw-flex-col tw-gap-2">
{versions.map((version, index) => (
<div
key={index}
className="tw-h-10 tw-bg-white tw-p-4 tw-flex tw-justify-between tw-items-center tw-rounded"
>
<p className="u-fontSize--header2 u-fontWeight--bold u-lineHeight--medium card-item-title ">
{version.versionLabel}
</p>
<button
className={"btn tw-ml-2 primary blue"}
onClick={() => this.startUpgraderService(version)}
>
Deploy
</button>
</div>
))}
</div>
</div>
);
};

renderAppVersionHistoryRow = (version: Version, index?: number) => {
if (
!version ||
Expand Down Expand Up @@ -1783,7 +1840,7 @@ class AppVersionHistory extends Component<Props, State> {
{(versionHistory.length === 0 && gitopsIsConnected) ||
versionHistory?.length > 0 ? (
<>
{gitopsIsConnected ? (
{gitopsIsConnected && (
<div
style={{ maxWidth: "1030px" }}
className="u-width--full u-marginBottom--30"
Expand All @@ -1807,96 +1864,107 @@ class AppVersionHistory extends Component<Props, State> {
}
/>
</div>
) : (
)}
{!gitopsIsConnected && (
<div className="TableDiff--Wrapper card-bg u-marginBottom--30">
<div className="flex justifyContent--spaceBetween alignItems--center u-marginBottom--15">
<p className="u-fontSize--normal u-fontWeight--medium u-textColor--info">
{this.state.updatesAvailable
? "New version available"
: ""}
</p>
<div className="flex alignItems--center">
{!this.props.outletContext.isEmbeddedCluster && (
<div className="flex justifyContent--spaceBetween alignItems--center u-marginBottom--15">
<p className="u-fontSize--normal u-fontWeight--medium u-textColor--info">
{this.state.updatesAvailable
? "New version available"
: ""}
</p>
<div className="flex alignItems--center">
{app?.isAirgap && airgapUploader ? (
<MountAware
onMount={(el: Element) =>
airgapUploader?.assignElement(el)
}
>
<div className="flex alignItems--center">
<span className="icon clickable dashboard-card-upload-version-icon u-marginRight--5" />
<span className="link u-fontSize--small u-lineHeight--default">
Upload new version
</span>
</div>
</MountAware>
) : (
<div className="flex alignItems--center">
{checkingForUpdates &&
!this.props.outletContext
.isBundleUploading ? (
<div className="flex alignItems--center u-marginRight--20">
<Loader
className="u-marginRight--5"
size="15"
/>
<span className="u-textColor--bodyCopy u-fontWeight--medium u-fontSize--small u-lineHeight--default">
{checkingUpdateMessage === ""
? "Checking for updates"
: checkingUpdateTextShort}
<div className="flex alignItems--center">
{app?.isAirgap && airgapUploader ? (
<MountAware
onMount={(el: Element) =>
airgapUploader?.assignElement(el)
}
>
<div className="flex alignItems--center">
<span className="icon clickable dashboard-card-upload-version-icon u-marginRight--5" />
<span className="link u-fontSize--small u-lineHeight--default">
Upload new version
</span>
</div>
) : (
<div className="flex alignItems--center u-marginRight--20">
<span
className="flex-auto flex alignItems--center link u-fontSize--small"
onClick={this.onCheckForUpdates}
>
<Icon
icon="check-update"
size={16}
className="clickable u-marginRight--5"
color={""}
style={{}}
disableFill={false}
removeInlineStyle={false}
</MountAware>
) : (
<div className="flex alignItems--center">
{checkingForUpdates &&
!this.props.outletContext
.isBundleUploading ? (
<div className="flex alignItems--center u-marginRight--20">
<Loader
className="u-marginRight--5"
size="15"
/>
Check for update
</span>
</div>
)}
<span
className="flex-auto flex alignItems--center link u-fontSize--small"
onClick={this.toggleAutomaticUpdatesModal}
>
<Icon
icon="schedule-sync"
size={16}
className="clickable u-marginRight--5"
color={""}
style={{}}
disableFill={false}
removeInlineStyle={false}
/>
Configure automatic updates
</span>
</div>
)}
<span className="u-textColor--bodyCopy u-fontWeight--medium u-fontSize--small u-lineHeight--default">
{checkingUpdateMessage === ""
? "Checking for updates"
: checkingUpdateTextShort}
</span>
</div>
) : (
<div className="flex alignItems--center u-marginRight--20">
<span
className="flex-auto flex alignItems--center link u-fontSize--small"
onClick={this.onCheckForUpdates}
>
<Icon
icon="check-update"
size={16}
className="clickable u-marginRight--5"
color={""}
style={{}}
disableFill={false}
removeInlineStyle={false}
/>
Check for update
</span>
</div>
)}
<span
className="flex-auto flex alignItems--center link u-fontSize--small"
onClick={
this.toggleAutomaticUpdatesModal
}
>
<Icon
icon="schedule-sync"
size={16}
className="clickable u-marginRight--5"
color={""}
style={{}}
disableFill={false}
removeInlineStyle={false}
/>
Configure automatic updates
</span>
</div>
)}
</div>
{versionHistory.length > 1 && !gitopsIsConnected
? this.renderDiffBtn()
: null}
</div>
{versionHistory.length > 1 && !gitopsIsConnected
? this.renderDiffBtn()
: null}
</div>
</div>
{pendingVersion ? (
this.renderAppVersionHistoryRow(pendingVersion)
) : (
<div className="card-item flex-column flex1 u-marginTop--20 u-marginBottom--10 alignItems--center justifyContent--center">
<p className="u-fontSize--normal u-fontWeight--medium u-textColor--bodyCopy u-padding--10">
Application up to date.
</p>
</div>
)}
{this.state.availableUpdates &&
this.props.outletContext.isEmbeddedCluster &&
this.renderAvailableECUpdatesRow(
this.state.availableUpdates
)}
{!this.props.outletContext.isEmbeddedCluster &&
(pendingVersion ? (
this.renderAppVersionHistoryRow(pendingVersion)
) : (
<div className="card-item flex-column flex1 u-marginTop--20 u-marginBottom--10 alignItems--center justifyContent--center">
<p className="u-fontSize--normal u-fontWeight--medium u-textColor--bodyCopy u-padding--10">
Application up to date.
</p>
</div>
))}
{(this.state.numOfSkippedVersions > 0 ||
this.state.numOfRemainingVersions > 0) && (
<p className="u-fontSize--small u-fontWeight--medium u-lineHeight--more u-textColor--info u-marginTop--10">
Expand All @@ -1916,12 +1984,12 @@ class AppVersionHistory extends Component<Props, State> {
)}
</div>
)}
{versionHistory?.length > 0 ? (
{versionHistory?.length > 0 && (
<>
{this.renderUpdateProgress()}
{this.renderAllVersions()}
</>
) : null}
)}
</>
) : (
<div className="flex-column flex1 alignItems--center justifyContent--center">
Expand Down

0 comments on commit 91e6a9c

Please sign in to comment.