Skip to content

Commit

Permalink
Show app-level notifications on dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexTugarev authored and roboquat committed Jul 22, 2022
1 parent 568d9e7 commit 9399771
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
2 changes: 2 additions & 0 deletions components/dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import SelectIDEModal from "./settings/SelectIDEModal";
import { StartPage, StartPhase } from "./start/StartPage";
import { isGitpodIo } from "./utils";
import { BlockedRepositories } from "./admin/BlockedRepositories";
import { AppNotifications } from "./AppNotifications";

const Setup = React.lazy(() => import(/* webpackPrefetch: true */ "./Setup"));
const Workspaces = React.lazy(() => import(/* webpackPrefetch: true */ "./workspaces/Workspaces"));
Expand Down Expand Up @@ -346,6 +347,7 @@ function App() {
<Route>
<div className="container">
<Menu />
<AppNotifications />
<Switch>
<Route path={projectsPathNew} exact component={NewProject} />
<Route path="/open" exact component={Open} />
Expand Down
76 changes: 76 additions & 0 deletions components/dashboard/src/AppNotifications.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License-AGPL.txt in the project root for license information.
*/

import { useEffect, useState } from "react";
import Alert from "./components/Alert";
import { getGitpodService } from "./service/service";

const KEY_APP_NOTIFICATIONS = "KEY_APP_NOTIFICATIONS";

export function AppNotifications() {
const [notifications, setNotifications] = useState<string[]>([]);

useEffect(() => {
let localState = getLocalStorageObject(KEY_APP_NOTIFICATIONS);
if (Array.isArray(localState)) {
setNotifications(localState);
return;
}
(async () => {
const serverState = await getGitpodService().server.getNotifications();
setNotifications(serverState);
setLocalStorageObject(KEY_APP_NOTIFICATIONS, serverState);
})();
}, []);

const topNotification = notifications[0];
if (topNotification === undefined) {
return null;
}

const dismissNotification = () => {
removeLocalStorageObject(KEY_APP_NOTIFICATIONS);
setNotifications([]);
};

return (
<div className="app-container pt-2">
<Alert
type={"warning"}
closable={true}
onClose={() => dismissNotification()}
showIcon={true}
className="flex rounded mb-2 w-full"
>
<span>{topNotification}</span>
</Alert>
</div>
);
}

function getLocalStorageObject(key: string): any {
try {
const string = window.localStorage.getItem(key);
if (!string) {
return;
}
return JSON.parse(string);
} catch (error) {
return;
}
}

function removeLocalStorageObject(key: string): void {
window.localStorage.removeItem(key);
}

function setLocalStorageObject(key: string, object: Object): void {
try {
window.localStorage.setItem(key, JSON.stringify(object));
} catch (error) {
console.error("Setting localstorage item failed", key, object, error);
}
}
11 changes: 10 additions & 1 deletion components/dashboard/src/components/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface AlertProps {
// Without background color, default false
light?: boolean;
closable?: boolean;
onClose?: () => void;
showIcon?: boolean;
icon?: React.ReactNode;
children?: React.ReactNode;
Expand Down Expand Up @@ -80,7 +81,15 @@ export default function Alert(props: AlertProps) {
<span className="flex-1 text-left">{props.children}</span>
{props.closable && (
<span className={`mt-1 ml-4 h-4 w-4`}>
<XSvg onClick={() => setVisible(false)} className="w-3 h-4 cursor-pointer"></XSvg>
<XSvg
onClick={() => {
setVisible(false);
if (props.onClose) {
props.onClose();
}
}}
className="w-3 h-4 cursor-pointer"
></XSvg>
</span>
)}
</div>
Expand Down

0 comments on commit 9399771

Please sign in to comment.