├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── DEV_README.md ├── LICENSE ├── Prism logo 1.png ├── README.md ├── __tests__ ├── Login.test.tsx └── backend_tests │ ├── loginRoutes.ts │ ├── metricsRoutes.ts │ └── userController.ts ├── babel.config.cjs ├── babelrc.js ├── client ├── assets │ ├── In-Blue-96.png │ ├── In-Blue-96.png:Zone.Identifier │ ├── In-White-96.png │ ├── In-White-96.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214009.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214025.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214053.png │ ├── Screenshot 2023-08-08 214053.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214108.png │ ├── Screenshot 2023-08-08 214108.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214145.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214211.png:Zone.Identifier │ ├── Screenshot 2023-08-08 214238.png │ ├── Screenshot 2023-08-08 214238.png:Zone.Identifier │ ├── Screenshot 2023-08-08 223451.png:Zone.Identifier │ ├── Screenshot 2023-08-08 223511.png:Zone.Identifier │ ├── Screenshot 2023-08-08 223650.png:Zone.Identifier │ ├── Screenshot 2023-08-08 223707.png:Zone.Identifier │ ├── github-mark-white.png │ ├── github-mark-white.png:Zone.Identifier │ ├── github-mark.png │ ├── github-mark.png:Zone.Identifier │ ├── github-mark.svg │ ├── github-mark.svg:Zone.Identifier │ ├── icons8-twitter.svg │ ├── icons8-twitter.svg:Zone.Identifier │ ├── logo-twitter-png-40404.png │ ├── logo-twitter-png-40404.png:Zone.Identifier │ ├── prismlogo.png │ ├── prismlogodarkmode.png │ ├── selected_1_Dark.png │ ├── selected_1_Light.png │ ├── selected_2.png │ ├── selected_3.png │ ├── selected_4_dark.png │ ├── selected_4_light.png │ ├── selected_5_dark.png │ └── selected_5_light.png ├── components │ ├── App.tsx │ ├── ClusterView │ │ ├── ClusterViewHeader │ │ │ ├── ClusterViewHeader.tsx │ │ │ ├── LighDarkMode.tsx │ │ │ ├── Profile.tsx │ │ │ └── themeContext.tsx │ │ ├── Dashboard.tsx │ │ ├── Dashboard │ │ │ ├── ClusterMap.tsx │ │ │ ├── NodesView.tsx │ │ │ ├── Overview.tsx │ │ │ ├── PodsView.tsx │ │ │ └── mvp_dashboard.json │ │ └── SidePanel │ │ │ ├── Navigation.tsx │ │ │ └── SidePanel.tsx │ ├── LandingPage │ │ ├── LandingFooter.tsx │ │ ├── LandingHeader.tsx │ │ ├── LandingMain.tsx │ │ └── LandingPage.tsx │ ├── Login.tsx │ ├── Main │ │ ├── dashboard │ │ │ ├── clusterView.jsx │ │ │ ├── dashboard.jsx │ │ │ ├── nodesView.jsx │ │ │ ├── overview.jsx │ │ │ └── podsView.jsx │ │ ├── header │ │ │ ├── lighDarkMode.jsx │ │ │ ├── mainHeader.jsx │ │ │ └── profile.jsx │ │ ├── leftPanel.jsx │ │ └── main.jsx │ └── Signup.tsx ├── index.tsx ├── styles.css └── styles_output.css ├── coverage └── coverage-summary.json ├── custom-test-env.js ├── grafana ├── api_token.json ├── config_values.yaml └── dashboards │ └── mvp_dashboard.json ├── index.html ├── jest.config.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── prism_logo_square.png ├── readme-gifs ├── demo.gif ├── demo_darkmode.gif ├── demo_login.gif ├── demo_signup.gif └── demo_views.gif ├── server ├── controllers │ ├── metricsController.ts │ └── userController.ts ├── db │ ├── db.ts │ └── models │ │ └── userSchema.ts ├── routers │ ├── apiRouter.ts │ └── userRouter.ts └── server.ts ├── startup.zsh ├── tailwind.config.js ├── tsconfig.json ├── types ├── index.d.ts └── types.ts └── webpack.config.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended", 9 | "plugin:react/recommended" 10 | ], 11 | "overrides": [ 12 | { 13 | "env": { 14 | "node": true 15 | }, 16 | "files": [ 17 | ".eslintrc.{js,cjs}" 18 | ], 19 | "parserOptions": { 20 | "sourceType": "script" 21 | } 22 | } 23 | ], 24 | "parser": "@typescript-eslint/parser", 25 | "parserOptions": { 26 | "ecmaVersion": "latest", 27 | "sourceType": "module" 28 | }, 29 | "plugins": [ 30 | "@typescript-eslint", 31 | "react" 32 | ], 33 | "rules": { 34 | "react/prop-types": "off" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # if you need the .env file see our OSP slack! 2 | node_modules 3 | .env 4 | grafana/api_token.json 5 | build 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | client/components/app.jsx -------------------------------------------------------------------------------- /DEV_README.md: -------------------------------------------------------------------------------- 1 | # A Presumptive Thank You 2 | We're so excited that you're thinking about contributing to our application! We built this thinking of the many great directions in which it could go and are very grateful to those who would take it upon themselves to help. 3 | 4 | # Possible Directions for Future Work 5 | 6 | ## ⚛️ State management and Database Optimization 7 | Proper authentication and caching would increase security and enhance the user experience. This will require more comprehensive state management and a close look at what might be best to save in order to persist between reloads. 8 | 9 | Additionally, database caching of the dashboard panel URLs would also easily allow a mobile application to become feasible. 10 | 11 | ## Customizable dashboards 12 | It would make for an even better UX if users were able to freely resize and move dashboards in a way that would save in state (possibly persist through the database). 13 | 14 | ## 🃏 Test Coverage 15 | The current level of test coverage is very limited to route unit tests and a few key react components. 16 | Room for improvement includes: 17 | - [ ] Unit testing for middleware controllers 18 | - [ ] Route testing could be updated to include token authentication 19 | - [ ] State management integration testing 20 | 21 | ## 🚨 Health Alert Notifications 22 | In addition to allowing the user to view health, it would be useful for the application to be able to send notifications (could be on Slack or a mobile app notification) if something is wrong. This should be achievable using [Grafana's API](https://grafana.com/docs/grafana/latest/alerting/set-up/). 23 | 24 | ## 🛜 Inter-Cluster Network Views 25 | At a level above a single cluster, we think it would be of user benefit to be able to view relationships among more than one running cluster. 26 | This is perhaps the most ambitious stretch feature in its requirement to extend our application's understanding of the configuration of and access to one cluster to multiple, but it's also one of the most exciting! 27 | 28 | # File structure 29 | - [**client**](client) 30 | - [**assets**](client/assets) 31 | - [**components**](client/components) 32 | - [**ClusterView**](client/components/ClusterView) 33 | - [**ClusterViewHeader**](client/components/ClusterView/ClusterViewHeader) 34 | - [**Dashboard**](client/components/ClusterView/Dashboard) 35 | - [**SidePanel**](client/components/ClusterView/SidePanel) 36 | - [**LandingPage**](client/components/LandingPage) 37 | - [**Main**](client/components/Main) 38 | - [**dashboard**](client/components/Main/dashboard) 39 | - [**header**](client/components/Main/header) 40 | - [**coverage**](coverage) 41 | - [**grafana**](grafana) 42 | - [**dashboards**](grafana/dashboards) 43 | - [**server**](server) 44 | - [**controllers**](server/controllers) 45 | - [**db**](server/db) 46 | - [**models**](server/db/models) 47 | - [**routers**](server/routers) 48 | - [**types**](types) 49 | 50 | 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 OSLabs Beta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Prism logo 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/Prism logo 1.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![Kubernetes](https://img.shields.io/badge/Kubernetes-326ce5?style=for-the-badge&logo=kubernetes&logoColor=white) 4 | ![Docker](https://img.shields.io/badge/Docker-0db7ed?style=for-the-badge&logo=docker&logoColor=white) 5 | ![Prometheus](https://img.shields.io/badge/Prometheus-E7532D?style=for-the-badge&logo=prometheus&logoColor=white) 6 | ![Prometheus](https://img.shields.io/badge/Grafana-F69920?style=for-the-badge&logo=grafana&logoColor=white) 7 | ![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white) 8 | ![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E) 9 | ![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) 10 | ![ReactRouter](https://img.shields.io/badge/React_Router-CA4245?style=for-the-badge&logo=react-router&logoColor=white) 11 | ![Sass](https://img.shields.io/badge/Sass-CC6699?style=for-the-badge&logo=sass&logoColor=white) 12 | ![Node](https://img.shields.io/badge/-node-339933?style=for-the-badge&logo=node.js&logoColor=white) 13 | ![Express](https://img.shields.io/badge/express-%23404d59.svg?style=for-the-badge&logo=express&logoColor=%2361DAFB) 14 | ![Mongo](https://img.shields.io/badge/MongoDB-4EA94B?style=for-the-badge&logo=mongodb&logoColor=white) 15 | ![Tailwind](https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=white) 16 | ![Jest](https://img.shields.io/badge/Jest-323330?style=for-the-badge&logo=Jest&logoColor=white) 17 | ![Testing Library](https://img.shields.io/badge/testing%20library-323330?style=for-the-badge&logo=testing-library&logoColor=red) 18 | 19 |
20 | 21 | # Introducing Prism! 22 | 23 | Prism is a Kubernetes and Docker visualizer that helps users understand the status of and relationships between their nodes, pods, services, and containers. It will help developers quickly view their server status and identify problem areas with live metrics and pod health statistics. 24 | Our goal for this project was to provide the best possible user experience while minimizing the code a user has to write (everything launches with a single command). 25 | 26 | ## Get insights into your Kubernetes clusters and Docker containers 27 | 28 | Demo 29 | 30 | ## Secure, and built for you! 31 | 32 | Login to Prism to see your clusters, nodes, and pods automatically. And with a dark/light mode, you can enjoy it how you want. 33 | 34 | Demo 35 | 36 | ## Features 37 | 38 | | Feature | Status | 39 | | ----------------------------------------------------------------- | ------ | 40 | | Prometheus and Grafana Intergration | ✅ | 41 | | Custom Dashboard | ✅ | 42 | | an Overview, Pods view and Node view of metrics | ✅ | 43 | | SASS and Tailwind CSS | ✅ | 44 | | Typescript conversion | ✅ | 45 | | Testing (React Testing Library/Jest front-end, Supertest backend) | ⏳ | 46 | | Fully intergrated OAuth/User authentication | ⏳ | 47 | | Customizable Dashboards | 🙏🏻 | 48 | | Historcial Data and Trends | 🙏🏻 | 49 | 50 | Done = ✅ 51 |
52 | In Progress = ⏳ 53 |
54 | Looking for contributors = 🙏🏻 55 | 56 | ## Getting Started 57 | 58 | ### Requirements 59 | 60 | - [ ] Running cluster in Kubernetes/ Minikube 61 | - [ ] The following ports must be free: 62 | - [ ] 8080 ( where the application will be located) 63 | - [ ] 3333 (used by the backend of the application) 64 | - [ ] 3000 (used by Grafana) 65 | 66 | ### Steps : 67 | 68 | - [ ] Fork the repository and clone to your local machine 69 | - [ ] Set up authentication: Create a `.env` file in the root directory with the following: 70 | - [ ] (optional) Private auth database: Your MongoDB URI (key `MONGO_URI`) 71 | - [ ] (optional) GitHub OAuth: A client ID and secret key (keys `CLIENT_ID`, `CLIENT_SECRET`) 72 | - [Read more from GitHub about setting up oAuth in your settings](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) 73 | - [ ] A secret of your choice for json web tokens (key `JWT_SECRET`) 74 | - [ ] Execute the startup shell script (run `./startup.zsh`) - this will: 75 | 76 | - [ ] Install necessary dependencies for the web application 77 | - [ ] Install Prometheus 🔥 and Grafana 📊 onto your cluster with our custom configuration 78 | - [ ] Start up the web application 79 | 80 | - [ ] Go to `http://localhost:8080` and view metrics to your heart's desire 🤩 81 | 82 | ### Enjoy Prism! 83 | 84 | Once you've done the steps above you'll be able to quickly view live metrics and pod health statistics with ease. 85 | 86 | Demo 87 | 88 | ## Contribute to the project 89 | 90 | - View our [Contributor README](/DEV_README.md) 91 | 92 | ## Read More 93 | 94 | [Check out our article on Medium!](https://medium.com/@k8s.prism/prism-all-in-one-kubernetes-visualizer-7338b56f8de2) 95 | 96 | ## Authors 97 | 98 | - list of all people and our links 99 | - [Beserat Tafesse](https://github.com/BeseratT) 100 | - [Dawit Merid](https://github.com/dawitmerid) 101 | - [James Li](https://github.com/Jxmes-Li) 102 | - [Josh Hall](https://github.com/joshuarhall) 103 | - [Paul Glenn](https://github.com/paglenn) 104 | -------------------------------------------------------------------------------- /__tests__/Login.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import '@testing-library/jest-dom/extend-expect'; 4 | import Login from '../client/components/Login'; 5 | import { beforeEach, describe, expect, jest, test } from '@jest/globals'; 6 | import { useNavigate } from 'react-router'; 7 | // to import Jest and mocking useNavigate 8 | const mockUsedNavigate = jest.fn(); 9 | 10 | jest.mock('react-router-dom', () => ({ 11 | useNavigate: () => mockUsedNavigate, 12 | })); 13 | 14 | // const useNavigateMock = () => { 15 | // return mockUsedNavigate 16 | // } 17 | 18 | // jest.mock('react-router-dom', () => { 19 | // useNavigate: () => mockUsedNavigate 20 | // }) 21 | 22 | // Renders Login component before each test 23 | beforeEach(() => { 24 | render(); 25 | }); 26 | 27 | test('If it renders', () => { 28 | const ha = screen.getByText(/Login Form/); 29 | expect(ha).toBeInTheDocument(); 30 | }); 31 | 32 | test('If username and password input bars render', () => { 33 | const username = screen.getByRole('textbox', { 34 | name: 'username', 35 | }); 36 | const password = screen.getByLabelText(/password/); 37 | expect(username).toBeInTheDocument(); 38 | expect(password).toBeInTheDocument(); 39 | }); 40 | 41 | test('If clicking close goes to dashboard', () => {}); 42 | // function beforeEach(arg0: () => void) { 43 | // throw new Error("Function not implemented."); 44 | // } 45 | -------------------------------------------------------------------------------- /__tests__/backend_tests/loginRoutes.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | const userRoute: string = 'http://localhost:3333/user'; 3 | 4 | describe('Signup route tests', () => { 5 | const username: string = `Test ${Date.now()}`; 6 | it('should respond with username and a 201 status on successful creation', () => { 7 | return request(userRoute) 8 | .post('/signup') 9 | .send({ username: username, password: 'password' }) 10 | .expect(201) 11 | .then((response) => { 12 | expect(response.body.username).toBe(username); 13 | expect(response.body.created).toBe(true); 14 | }); 15 | }); 16 | 17 | it('should not create a duplicate user', () => { 18 | return request(userRoute) 19 | .post('/signup') 20 | .send({ username: username, password: 'password' }) 21 | .expect(202) 22 | .then((response) => { 23 | expect(response.body.created).toBe(false); 24 | }); 25 | }); 26 | }); 27 | 28 | // integration test for login route 29 | describe('login route tests', () => { 30 | it('should respond with a 200 status code for successful login', () => { 31 | return request(userRoute) 32 | .post('/login') 33 | .send({ username: 'Test', password: 'password' }) 34 | .expect(200) 35 | .then((response) => { 36 | expect(response.body.auth).toBe(true); 37 | }); 38 | }); 39 | 40 | it('should respond with a 401 status code for unsuccessful login', () => { 41 | return request(userRoute) 42 | .post('/login') 43 | .send({ username: 'Test', password: 'test' }) 44 | .expect(401) 45 | .then((response) => expect(response.body.auth).toBe(false)); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /__tests__/backend_tests/metricsRoutes.ts: -------------------------------------------------------------------------------- 1 | // Backend route integration tests 2 | import request from 'supertest'; 3 | const serverRoute: string = 'http://localhost:3333/api'; 4 | 5 | xdescribe('Dashboard creation route', () => { 6 | it('responds with dashboard url', () => { 7 | return request(serverRoute) 8 | .post('/') 9 | .then((response) => { 10 | console.log(response.body); 11 | expect(response.body.frameURL).toBeTruthy(); 12 | }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /__tests__/backend_tests/userController.ts: -------------------------------------------------------------------------------- 1 | //import userController from '../../server/controllers/userController'; 2 | import { Request, Response, NextFunction } from 'express'; 3 | 4 | // Typing: Request and response body are objects 5 | 6 | const next = jest.fn() as NextFunction; 7 | const request = { 8 | body: {}, 9 | } as Request; 10 | 11 | const response = { 12 | locals: {}, 13 | } as Response; 14 | 15 | // test createUser 16 | // xdescribe('user controller authentication', () => { 17 | // beforeEach(() => { 18 | // response.locals.user = {}; 19 | // (request.body.username = 'test'), (request.body.password = 'password'); 20 | // }); 21 | 22 | // test('Authentication sets properties correctly for true password ', async () => { 23 | // await userController.authUser(request, response, next); 24 | // expect(response.locals.user.username).toEqual(request.body.username); 25 | // expect(response.locals.user.auth).toBe(true); 26 | // }); 27 | // }); 28 | -------------------------------------------------------------------------------- /babel.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-react', 5 | { 6 | runtime: 'automatic', 7 | }, 8 | ], 9 | '@babel/preset-env', 10 | '@babel/preset-typescript', 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /babelrc.js: -------------------------------------------------------------------------------- 1 | export default { 2 | presets: [['@babel/preset-env', { modules: false }]], 3 | // The rest is the same ... 4 | }; 5 | -------------------------------------------------------------------------------- /client/assets/In-Blue-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/In-Blue-96.png -------------------------------------------------------------------------------- /client/assets/In-Blue-96.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=C:\Users\dawit\OneDrive\Desktop\BIBI\Logos\linkedin-logos.zip 4 | -------------------------------------------------------------------------------- /client/assets/In-White-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/In-White-96.png -------------------------------------------------------------------------------- /client/assets/In-White-96.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=C:\Users\dawit\OneDrive\Desktop\BIBI\Logos\linkedin-logos.zip 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214009.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214025.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214053.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/Screenshot 2023-08-08 214053.png -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214053.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/Screenshot 2023-08-08 214108.png -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214108.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214145.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214211.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214238.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/Screenshot 2023-08-08 214238.png -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 214238.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 223451.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 223511.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 223650.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/Screenshot 2023-08-08 223707.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe 3 | ZoneId=3 4 | -------------------------------------------------------------------------------- /client/assets/github-mark-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/github-mark-white.png -------------------------------------------------------------------------------- /client/assets/github-mark-white.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=C:\Users\dawit\OneDrive\Desktop\BIBI\Logos\github-mark (1).zip 4 | -------------------------------------------------------------------------------- /client/assets/github-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/github-mark.png -------------------------------------------------------------------------------- /client/assets/github-mark.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=C:\Users\dawit\OneDrive\Desktop\BIBI\Logos\github-mark (1).zip 4 | -------------------------------------------------------------------------------- /client/assets/github-mark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/assets/github-mark.svg:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=C:\Users\dawit\OneDrive\Desktop\BIBI\Logos\github-mark (1).zip 4 | -------------------------------------------------------------------------------- /client/assets/icons8-twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/assets/icons8-twitter.svg:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | HostUrl=about:internet 4 | -------------------------------------------------------------------------------- /client/assets/logo-twitter-png-40404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/logo-twitter-png-40404.png -------------------------------------------------------------------------------- /client/assets/logo-twitter-png-40404.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=https://www.freepnglogos.com/images/logo-twitter-png-40404.html 4 | HostUrl=https://www.freepnglogos.com/download/40404 5 | -------------------------------------------------------------------------------- /client/assets/prismlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/prismlogo.png -------------------------------------------------------------------------------- /client/assets/prismlogodarkmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/prismlogodarkmode.png -------------------------------------------------------------------------------- /client/assets/selected_1_Dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_1_Dark.png -------------------------------------------------------------------------------- /client/assets/selected_1_Light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_1_Light.png -------------------------------------------------------------------------------- /client/assets/selected_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_2.png -------------------------------------------------------------------------------- /client/assets/selected_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_3.png -------------------------------------------------------------------------------- /client/assets/selected_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_4_dark.png -------------------------------------------------------------------------------- /client/assets/selected_4_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_4_light.png -------------------------------------------------------------------------------- /client/assets/selected_5_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_5_dark.png -------------------------------------------------------------------------------- /client/assets/selected_5_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/Prism/ad41d215dc7a3c28aff7d8c3a811eee33c6f484c/client/assets/selected_5_light.png -------------------------------------------------------------------------------- /client/components/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, FC, useEffect } from 'react'; 2 | import { Route, Routes, useNavigate } from 'react-router-dom'; 3 | import Login from './Login'; 4 | import Signup from './Signup'; 5 | // import LandingPage from './LandingPage/LandingPage'; 6 | 7 | import { ThemeProvider } from './ClusterView/ClusterViewHeader/themeContext'; 8 | import Dashboard from './ClusterView/Dashboard'; 9 | 10 | interface Props {} 11 | 12 | const App: FC = () => { 13 | const [user, setUser] = useState({}); 14 | const [rerender, setRerender] = useState(false); 15 | const navigate = useNavigate(); 16 | 17 | // effect hook will get access token if 18 | useEffect(() => { 19 | const queryString = window.location.search; 20 | const urlParams = new URLSearchParams(queryString); 21 | const codeParam = urlParams.get('code'); 22 | console.log(codeParam); 23 | 24 | if (codeParam && localStorage.getItem('accessToken') === null) { 25 | async function getAccessToken() { 26 | await fetch('/user/getAccessToken?code=' + codeParam, { 27 | method: 'GET', 28 | }) 29 | .then((response) => { 30 | return response.json(); 31 | }) 32 | .then((data) => { 33 | console.log(data); 34 | 35 | if (data.access_token) { 36 | console.log('test from app.tx, then statement'); 37 | localStorage.setItem('accessToken', data.access_token); 38 | setRerender(!rerender); 39 | navigate('/dashboard'); 40 | } 41 | }); 42 | } 43 | getAccessToken(); 44 | } 45 | }, []); 46 | 47 | return ( 48 | <> 49 |
50 | 51 | 52 | } /> 53 | {/* } /> */} 54 | } /> 55 | } /> 56 | 57 | {/* }> 58 | }> 59 | }> 60 | }> 61 | }> 62 | } 65 | > 66 | 67 | }> */} 68 | {/* } /> */} 69 | {/* } /> 70 | } /> 71 | } /> */} 72 | {/* */} 73 | 74 | 75 |
76 | 77 | ); 78 | }; 79 | 80 | export default App; 81 | -------------------------------------------------------------------------------- /client/components/ClusterView/ClusterViewHeader/ClusterViewHeader.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import LightDarkMode from './LighDarkMode'; 3 | import Profile from './Profile'; 4 | import prismlogo from '../../../assets/prismlogo.png'; 5 | import prismlogodarkmode from '../../../assets/prismlogodarkmode.png'; 6 | 7 | interface Props {} 8 | 9 | const ClusterViewHeader: FC = () => { 10 | return ( 11 |
12 |
13 | LOGO 18 | LOGO 23 |

24 | Prism 25 |

26 |
27 | 28 |
29 | 30 | 31 |
32 |
33 | ); 34 | }; 35 | 36 | export default ClusterViewHeader; 37 | -------------------------------------------------------------------------------- /client/components/ClusterView/ClusterViewHeader/LighDarkMode.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, useContext } from 'react'; 2 | import { ThemeContext } from './themeContext'; 3 | import { MdLightMode, MdDarkMode } from 'react-icons/md'; 4 | 5 | interface Props {} 6 | 7 | const LightDarkMode: FC = () => { 8 | const { theme, setTheme } = useContext(ThemeContext); 9 | return ( 10 |
11 | {theme === 'dark' ? ( 12 | // Light mode button 13 |
14 |

Light

15 | 21 |
22 | ) : ( 23 | // Dark mode button 24 |
25 |

Dark

26 | 32 |
33 | )} 34 |
35 | ); 36 | }; 37 | 38 | export default LightDarkMode; 39 | -------------------------------------------------------------------------------- /client/components/ClusterView/ClusterViewHeader/Profile.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | 3 | interface Props { 4 | 5 | } 6 | 7 | const Profile: FC = () => { 8 | return ( 9 |
10 |

OSP-2

11 |

12 |
13 | ); 14 | }; 15 | 16 | export default Profile; 17 | -------------------------------------------------------------------------------- /client/components/ClusterView/ClusterViewHeader/themeContext.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from 'react'; 2 | import { ThemeProps } from 'types/types'; 3 | 4 | export const getInitialTheme = (): string => { 5 | if (typeof window !== 'undefined' && window.localStorage) { 6 | const storedPrefs = window.localStorage.getItem('current-theme'); 7 | if (typeof storedPrefs === 'string') { 8 | return storedPrefs; 9 | } 10 | if (window.matchMedia('(prefers-color-scheme: dark)').matches) { 11 | return 'dark'; 12 | } 13 | } 14 | return 'light'; 15 | }; 16 | 17 | export const ThemeContext = React.createContext(null); 18 | 19 | export const ThemeProvider = ({ initialTheme, children }: ThemeProps) => { 20 | const [theme, setTheme] = React.useState(getInitialTheme); 21 | 22 | const checkTheme = (existing: string): void => { 23 | const root = window.document.documentElement; 24 | const isDark = existing === 'dark'; 25 | 26 | root.classList.remove(isDark ? 'light' : 'dark'); 27 | root.classList.add(existing); 28 | 29 | localStorage.setItem('current-theme', existing); 30 | }; 31 | 32 | if (initialTheme) { 33 | checkTheme(initialTheme); 34 | } 35 | 36 | React.useEffect(() => { 37 | checkTheme(theme); 38 | }, [theme]); 39 | 40 | return ( 41 | 42 | {children} 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /client/components/ClusterView/Dashboard.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Outlet, NavLink } from 'react-router-dom'; 3 | import ClusterViewHeader from './ClusterViewHeader/ClusterViewHeader'; 4 | import SidePanel from './SidePanel/SidePanel'; 5 | import OverView from './Dashboard/Overview'; 6 | import Iframe from 'react-iframe'; 7 | import NodesView from './Dashboard/NodesView'; 8 | import PodsView from './Dashboard/PodsView'; 9 | import ClusterMap from './Dashboard/ClusterMap'; 10 | import { ComponentType } from 'react'; 11 | import type { ReactNode } from 'react'; 12 | 13 | interface SidePanelProps { 14 | setViewOverview: (value: boolean) => void; 15 | setViewNode: (value: boolean) => void; 16 | setViewPods: (value: boolean) => void; 17 | setViewClusterMap: (value: boolean) => void; 18 | } 19 | 20 | export default function Dashboard() { 21 | const [viewOverview, setViewOverview] = useState(true); 22 | const [viewNode, setViewNode] = useState(false); 23 | const [viewPods, setViewPods] = useState(false); 24 | const [viewClusterMap, setViewClusterMap] = useState(false); 25 | 26 | const [frames, updateFrames] = React.useState>([ 27 | null, 28 | ]); 29 | 30 | const getURL = async (): Promise => { 31 | const urlObj = await fetch('/api', { 32 | method: 'POST', 33 | headers: { 34 | 'Content-Type': 'application/json', 35 | }, 36 | }).then((response) => response.json()); 37 | // return url string from object 38 | return urlObj.frameURL; 39 | }; 40 | 41 | React.useEffect(() => { 42 | getURL() 43 | .then((urlString) => { 44 | const frameArray : Array = [] = []; 45 | const panelIdArray = [ 46 | '1', 47 | '3', 48 | '12', 49 | '4', 50 | '27', 51 | '25', 52 | '28', 53 | '10', 54 | '13', 55 | '26', 56 | '30', 57 | '18', 58 | '17', 59 | '19', 60 | '22', 61 | '20', 62 | '21', 63 | '23', 64 | '5', 65 | '29', 66 | ]; // the panels we want to access 67 | // console.log('effect hook running: ', urlString); 68 | if (urlString) { 69 | // iterate through panel ids that we want and edit the url for each one , pushing to panels array 70 | panelIdArray.forEach((id) => 71 | frameArray.push( 72 |