Skip to content
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

Adding toaster, dynamically checking pewpewVersion #201

Merged
merged 12 commits into from
Mar 18, 2024
5 changes: 5 additions & 0 deletions controller/components/PewPewVersions/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Danger } from "../Alert";
import Div from "../Div";
import React from "react";
import Toaster from "../Toaster";
import styled from "styled-components";

const VersionDiv = styled(Div)`
Expand All @@ -24,6 +25,7 @@ const VersionDivSelect = styled(Div)`
export interface VersionInitalProps {
pewpewVersion: string;
pewpewVersions: string[];
latestPewPewVersion: string;
loading: boolean;
error: boolean;
}
Expand All @@ -38,12 +40,14 @@ export const PewPewVersions = ({
name,
pewpewVersion,
onChange,
latestPewPewVersion: latestPewPewTag,
pewpewVersions = [],
loading,
error
}: VersionProps) => {
// console.log("PewPewVersions state", { pewpewVersions, loading, error });
let optionItems: JSX.Element[] | undefined;
const toasterMessage: string = "IMPORTANT: Please configure your YAML properly!!! The latest version of Pewpew is set to: " + latestPewPewTag;
if (pewpewVersions && pewpewVersions.length > 0) {
optionItems = pewpewVersions.map((version: string) => (<option value={version} key={version}>{version}</option>));
}
Expand All @@ -53,6 +57,7 @@ export const PewPewVersions = ({
{loading && <VersionDivSelect>Loading...</VersionDivSelect>}
{!loading && !error && <VersionDivSelect><select name={name} value={pewpewVersion} onChange={onChange}>{optionItems} </select></VersionDivSelect>}
{error && <VersionDivSelect><Danger>Could not load the current PewPew Versions</Danger></VersionDivSelect>}
<Toaster id="toaster" message={toasterMessage}/>
</VersionDiv>
);
};
Expand Down
5 changes: 4 additions & 1 deletion controller/components/PewPewVersions/initialProps.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { LogLevel, log } from "@fs/ppaas-common";
import { getCurrentPewPewLatestVersion, getPewPewVersionsInS3 } from "../../pages/api/util/pewpew";
import { API_PEWPEW } from "../../types";
import { VersionInitalProps } from ".";
import { getPewPewVersionsInS3 } from "../../pages/api/util/pewpew";
import { latestPewPewVersion } from "../../pages/api/util/clientutil";

export const getServerSideProps = async (): Promise<VersionInitalProps> => {
try {
const pewpewVersions: string[] = await getPewPewVersionsInS3();
const currentPewPewLatestVersion: string | undefined = await getCurrentPewPewLatestVersion();
log("getPewPewVersionsInS3", LogLevel.DEBUG, pewpewVersions);
// Grab the response
// console.log("PewPewVersions pewpewVersions: " + JSON.stringify(pewpewVersions), pewpewVersions);
Expand All @@ -16,6 +17,7 @@ export const getServerSideProps = async (): Promise<VersionInitalProps> => {
return {
pewpewVersion: latestPewPewVersion, // We always want to default to latest
pewpewVersions,
latestPewPewVersion: currentPewPewLatestVersion || "unknown",
loading: false,
error: false
};
Expand All @@ -25,6 +27,7 @@ export const getServerSideProps = async (): Promise<VersionInitalProps> => {
return {
pewpewVersion: "",
pewpewVersions: [],
latestPewPewVersion: "unknown",
loading: false,
error: true
};
Expand Down
1 change: 1 addition & 0 deletions controller/components/PewPewVersions/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const props: VersionProps = {
console.log("newVal: ", newVal);
},
pewpewVersions: ["0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", latestPewPewVersion, "0.1.6"],
latestPewPewVersion : "latestVersion",
loading: false,
error: false
};
Expand Down
2 changes: 2 additions & 0 deletions controller/components/StartTestForm/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const versionInitalPropsEmpty: VersionInitalProps = {
pewpewVersion: "",
loading: false,
pewpewVersions: [],
latestPewPewVersion: "",
error: true
};
const queueInitialProps: QueueInitialProps = {
Expand All @@ -50,6 +51,7 @@ const versionInitalProps: VersionInitalProps = {
pewpewVersion: "",
loading: false,
pewpewVersions: [latestPewPewVersion, "0.5.10", "0.5.11", "0.5.12"],
latestPewPewVersion: "latest",
error: false
};
let ppaasTestId: PpaasTestId;
Expand Down
49 changes: 49 additions & 0 deletions controller/components/Toaster/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useEffect } from "react";
import styled, { keyframes } from "styled-components";
import { Info } from "../Alert";

interface ToasterProps {
message: string; // Ensure message prop is of type string
duration?: number;
id: string; // Unique ID for the toaster
}

// Fade-in animation
const fadeIn = keyframes`
from { opacity: 0; }
to { opacity: 1; }
`;

// Fade-out animation
const fadeOut = keyframes`
from { opacity: 1; }
to { opacity: 0; }
`;

const Container = styled(Info)`
position: fixed;
bottom: 20px;
right: 20px;
width: 30%;
font-size: 17px;

animation: ${fadeIn} 0.3s ease-in-out forwards;
&.fade-out { animation: ${fadeOut} 0.3s ease-in-out forwards; }
`;

const Toaster: React.FC<ToasterProps> = ({ id, message, duration = 7000 }) => {
useEffect(() => {
setTimeout(() => {
const toasterElement = document.getElementById(id);
if (toasterElement) {
toasterElement.classList.add("fade-out");
setTimeout(() => {
toasterElement.remove();
}, 300); // Wait for fade-out animation to complete before removing element
}
}, duration);
}, [id, duration]);
return <Container id={id}>{message}</Container>;
};

export default Toaster;
16 changes: 16 additions & 0 deletions controller/components/Toaster/story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Meta, StoryFn } from "@storybook/react";
import { GlobalStyle } from "../Layout";
import React from "react";
import Toaster from "./index";

export default {
title: "Toaster",
component: Toaster
} as Meta<typeof Toaster>;

export const Default: StoryFn = () => (
<React.Fragment>
<GlobalStyle />
<Toaster id="toaster" message={"Type your message here: "}/>
</React.Fragment>
);
2 changes: 1 addition & 1 deletion controller/pages/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ const Admin = ({ authPermission, versionInitalProps, error: propsError }: AdminP

export const getServerSideProps: GetServerSideProps =
async (ctx: GetServerSidePropsContext): Promise<GetServerSidePropsResult<AdminProps>> => {
let versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], error: true };
let versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], latestPewPewVersion: "", error: true };
try {
// Authenticate
const authPermissions: AuthPermissions | string = await authPage(ctx, AuthPermission.Admin);
Expand Down
40 changes: 38 additions & 2 deletions controller/pages/api/util/pewpew.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
const deleteS3 = s3.deleteObject;
export const PEWPEW_EXECUTABLE_NAME: string = "pewpew";
const PEWPEW_EXECUTABLE_NAME_WINDOWS: string = "pewpew.exe";
const VERSION_TAG_NAME: string = "version";

/**
* Queries S3 for all objects in the pewpew/ folder that end with pewpew (not pewpew.exe).
Expand All @@ -46,6 +47,8 @@
localDirectory: LOCAL_FILE_LOCATION,
extension: PEWPEW_EXECUTABLE_NAME
});
console.log("PEWPEW FILES FROM S3")

Check warning on line 50 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Unexpected console statement

Check warning on line 50 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Missing semicolon

Check warning on line 50 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Unexpected console statement

Check warning on line 50 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Missing semicolon
console.log(pewpewFiles)

Check warning on line 51 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Unexpected console statement

Check warning on line 51 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Missing semicolon

Check warning on line 51 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Unexpected console statement

Check warning on line 51 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Missing semicolon
if (pewpewFiles.length === 0) {
throw new Error("No pewpew binaries found in s3");
}
Expand Down Expand Up @@ -74,6 +77,16 @@
}
}

// Store these as maps for fast lookup oldest can be found by lastRequested, lastUpdated, and lastChecked
// We can't use static variables since the memory spaces aren't shared between api and getServerSideProps
// https://stackoverflow.com/questions/70260701/how-to-share-data-between-api-route-and-getserversideprops
declare global {
// https://stackoverflow.com/questions/68481686/type-typeof-globalthis-has-no-index-signature
// eslint-disable-next-line no-var
tkmcmaster marked this conversation as resolved.
Show resolved Hide resolved
/** The pewpew version that 'latest' is currently set to */
var currentLatestVersion: string | undefined;

Check failure on line 87 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Unexpected var, use let or const instead

Check failure on line 87 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Unexpected var, use let or const instead
}

/**
* defines the POST /api/pewpew route which posts new versions of pewpew to s3
* @param parsedForm ParsedForm with the data
Expand Down Expand Up @@ -134,13 +147,12 @@
if (version === null) {
return { json: { message: `${match[1]} is not a valid semver version: ${version}` }, status: 400 };
}

const uploadPromises: Promise<PpaasS3File>[] = [];
const versionLogDisplay = latest ? `${version} as latest` : version;
const versionFolder = latest ? latestPewPewVersion : version;
log(PEWPEW_EXECUTABLE_NAME + " only upload, version: " + versionLogDisplay, LogLevel.DEBUG, files);
// Pass in an override Map to override the default tags and not set a "test" tag
const tags = new Map<string, string>([["pewpew", "true"]]);
const tags = new Map<string, string>([[PEWPEW_BINARY_FOLDER, "true"], [VERSION_TAG_NAME, version]]);
if (Array.isArray(files.additionalFiles)) {
for (const file of files.additionalFiles) {
uploadPromises.push(uploadFile(file, `${PEWPEW_BINARY_FOLDER}/${versionFolder}`, tags));
Expand All @@ -149,6 +161,16 @@
uploadPromises.push(uploadFile(files.additionalFiles, `${PEWPEW_BINARY_FOLDER}/${versionFolder}`, tags));
}
await Promise.all(uploadPromises);
// If latest version is being updated:
if(latest){

Check warning on line 165 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Expected space(s) after "if"

Check warning on line 165 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Missing space before opening brace

Check warning on line 165 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Expected space(s) after "if"

Check warning on line 165 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Missing space before opening brace
global.currentLatestVersion = version;
try {

Check warning on line 168 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Trailing spaces not allowed

Check warning on line 168 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Trailing spaces not allowed
log("Sucessfully saved PewPew's latest version to file. ", LogLevel.INFO);
} catch (error) {
log("Writing latest PewPew's latest version to file failed: ", LogLevel.ERROR, error);
}
}
log(PEWPEW_EXECUTABLE_NAME + " only uploaded, version: " + versionLogDisplay, LogLevel.INFO, { files, authPermissions: getLogAuthPermissions(authPermissions) });
return { json: { message: "PewPew uploaded, version: " + versionLogDisplay }, status: 200 };
} else {
Expand Down Expand Up @@ -215,3 +237,17 @@
throw error;
}
}

export async function getCurrentPewPewLatestVersion (): Promise<string | undefined>{

Check warning on line 241 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Missing space before opening brace

Check warning on line 241 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Missing space before opening brace
if(global.currentLatestVersion){

Check warning on line 242 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Expected space(s) after "if"

Check warning on line 242 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (18.x)

Missing space before opening brace

Check warning on line 242 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Expected space(s) after "if"

Check warning on line 242 in controller/pages/api/util/pewpew.ts

View workflow job for this annotation

GitHub Actions / Build project (20.x)

Missing space before opening brace
return global.currentLatestVersion;
}
try {
const pewpewTags = await s3.getTags({s3Folder: `${PEWPEW_BINARY_FOLDER}/${latestPewPewVersion}`, filename: PEWPEW_EXECUTABLE_NAME});
global.currentLatestVersion = pewpewTags && pewpewTags.get(VERSION_TAG_NAME); // <- change to get the tag here
return global.currentLatestVersion;
} catch (error) {
log("Could not load latest pewpew in file", LogLevel.ERROR, error);
throw error;
}
}
3 changes: 1 addition & 2 deletions controller/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,5 @@
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
]
"**/*.tsx"]
tkmcmaster marked this conversation as resolved.
Show resolved Hide resolved
}
Loading