aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/src/views/center/TimelineBoard.tsx26
-rw-r--r--FrontEnd/src/views/common/Spinner.css13
-rw-r--r--FrontEnd/src/views/common/Spinner.tsx30
-rw-r--r--FrontEnd/vite.config.js2
4 files changed, 56 insertions, 15 deletions
diff --git a/FrontEnd/src/views/center/TimelineBoard.tsx b/FrontEnd/src/views/center/TimelineBoard.tsx
index d7aa39ab..3961a7bc 100644
--- a/FrontEnd/src/views/center/TimelineBoard.tsx
+++ b/FrontEnd/src/views/center/TimelineBoard.tsx
@@ -208,7 +208,8 @@ const TimelineBoardItemContainer: React.FC<TimelineBoardItemContainerProps> = ({
interface TimelineBoardUIProps {
title?: string;
- timelines: HttpTimelineInfo[] | "offline" | "loading";
+ state: "offline" | "loading" | "loaded";
+ timelines: HttpTimelineInfo[];
onReload: () => void;
className?: string;
editHandler?: {
@@ -218,7 +219,7 @@ interface TimelineBoardUIProps {
}
const TimelineBoardUI: React.FC<TimelineBoardUIProps> = (props) => {
- const { title, timelines, className, editHandler } = props;
+ const { title, state, timelines, className, editHandler } = props;
const editable = editHandler != null;
@@ -246,13 +247,13 @@ const TimelineBoardUI: React.FC<TimelineBoardUIProps> = (props) => {
))}
</div>
{(() => {
- if (timelines === "loading") {
+ if (state === "loading") {
return (
<div className="d-flex flex-grow-1 justify-content-center align-items-center">
<Spinner />
</div>
);
- } else if (timelines === "offline") {
+ } else if (state === "offline") {
return (
<div className="d-flex flex-grow-1 justify-content-center align-items-center">
<LoadFailReload onReload={props.onReload} />
@@ -301,36 +302,39 @@ const TimelineBoard: React.FC<TimelineBoardProps> = ({
load,
editHandler,
}) => {
- const [timelines, setTimelines] = React.useState<
- HttpTimelineInfo[] | "offline" | "loading"
- >("loading");
+ const [state, setState] = React.useState<"offline" | "loading" | "loaded">(
+ "loading"
+ );
+ const [timelines, setTimelines] = React.useState<HttpTimelineInfo[]>([]);
React.useEffect(() => {
let subscribe = true;
- if (timelines === "loading") {
+ if (state === "loading") {
void load().then(
(timelines) => {
if (subscribe) {
+ setState("loaded");
setTimelines(timelines);
}
},
() => {
- setTimelines("offline");
+ setState("offline");
}
);
}
return () => {
subscribe = false;
};
- }, [load, timelines]);
+ }, [load, state]);
return (
<TimelineBoardUI
title={title}
className={className}
+ state={state}
timelines={timelines}
onReload={() => {
- setTimelines("loading");
+ setState("loaded");
}}
editHandler={
typeof timelines === "object" && editHandler != null
diff --git a/FrontEnd/src/views/common/Spinner.css b/FrontEnd/src/views/common/Spinner.css
new file mode 100644
index 00000000..a1de68d2
--- /dev/null
+++ b/FrontEnd/src/views/common/Spinner.css
@@ -0,0 +1,13 @@
+@keyframes cru-spinner-animation {
+ from {
+ transform: scale(0,0);
+ }
+}
+
+.cru-spinner {
+ display: inline-block;
+ animation: cru-spinner-animation 0.5s infinite alternate;
+ background-color: currentColor;
+ border-radius: 50%;
+ transform-origin: center;
+}
diff --git a/FrontEnd/src/views/common/Spinner.tsx b/FrontEnd/src/views/common/Spinner.tsx
index 783c9be2..b591d8ab 100644
--- a/FrontEnd/src/views/common/Spinner.tsx
+++ b/FrontEnd/src/views/common/Spinner.tsx
@@ -1,13 +1,37 @@
-import { PaletteColorType } from "@/palette";
import React from "react";
+import classnames from "classnames";
+
+import { PaletteColorType } from "@/palette";
+
+import "./Spinner.css";
export interface SpinnerProps {
- size?: "sm" | "md" | "lg" | number;
+ size?: "sm" | "md" | "lg" | number | string;
color?: PaletteColorType;
}
export default function Spinner(
props: SpinnerProps
): React.ReactElement | null {
- return <span />;
+ const { size, color } = props;
+ const calculatedSize =
+ size === "sm"
+ ? "18px"
+ : size === "md"
+ ? "30px"
+ : size === "lg"
+ ? "42px"
+ : typeof size === "number"
+ ? size
+ : size == null
+ ? "20px"
+ : size;
+ const calculatedColor = color ?? "primary";
+
+ return (
+ <span
+ className={classnames("cru-spinner", `cru-color-${calculatedColor}`)}
+ style={{ width: calculatedSize, height: calculatedSize }}
+ />
+ );
}
diff --git a/FrontEnd/vite.config.js b/FrontEnd/vite.config.js
index 88529a33..64e0457f 100644
--- a/FrontEnd/vite.config.js
+++ b/FrontEnd/vite.config.js
@@ -22,7 +22,7 @@ export default defineConfig({
alias: [{ find: "@", replacement: "/src" }],
},
server: {
- port: 13000,
+ port: 10030,
proxy: {
"/api": {
target: "http://localhost:5000",