Skip to content
Snippets Groups Projects
Commit 1b3a74f6 authored by Nitish Kumar's avatar Nitish Kumar
Browse files

first raw iteration of bitia-cli frontend

parent 3ee9da42
No related branches found
No related tags found
1 merge request!22Draft: first raw iteration of bitia-cli frontend
Pipeline #6162 failed with stages
in 1 minute and 8 seconds
Showing with 2634 additions and 9 deletions
......@@ -9,8 +9,12 @@ import typing as T
import os
import functools
from enum import Enum
import subprocess
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from rich.progress import track
from pathlib import Path
import bitia.helper as bhelper
from bitia.logger import logger, cprint, set_logger_level, console
......@@ -25,6 +29,19 @@ import typer
app = typer.Typer()
app_cli = FastAPI()
origins = [
"http://localhost:3000",
"http://localhost:8000",
]
app_cli.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class VerbosityLevel(str, Enum):
debug = "debug"
......@@ -50,7 +67,7 @@ def session(func):
return wrapper
@app_cli.get("/create-container")
@app.command("create-container")
@session
def create_remote_container(
......@@ -84,7 +101,7 @@ def create_remote_container(
logger.info(output_lines[-1])
return res
@app_cli.get("/list-container")
@app.command("list-container")
@session
def list_containers(user_input):
......@@ -92,6 +109,7 @@ def list_containers(user_input):
if not _list_remote_container(user_input):
for container in _list_remote_container(user_input):
cprint(container)
return container
def _list_remote_container(user_input) -> T.List[str]:
......@@ -109,16 +127,16 @@ def _list_remote_container(user_input) -> T.List[str]:
return []
return res.json()["containers"].split(",")
@app_cli.get("/artifacts")
@app.command("artifacts")
@session
def get_generated_artifacts(user_input):
# check if the containers for the corresponding pipeline exists
if not _list_remote_container(user_input):
cprint(
"Artifacts for this pipeline doesn't exist, please run the pipeline using `bitia run` first..."
f"Artifacts for this pipeline: {user_input} doesn't exist, please run the pipeline using `bitia run` first..."
)
return
return "Artifacts for this pipeline doesn't exist, please run the pipeline using `bitia run` first..."
pipeline = bpipeline.user_input_to_pipeline(user_input)
res = bhelper.get(
endpoint="artifacts",
......@@ -132,8 +150,9 @@ def get_generated_artifacts(user_input):
server = bconfig.get_server().rstrip("/")
cprint("Directory is being served at: ")
cprint(f"{server}/{path}")
return f"Directory is being served at: {server}/{path}"
@app_cli.get("/logs")
@app.command("logs")
@session
def stream_log(user_input):
......@@ -152,7 +171,7 @@ def stream_log(user_input):
for line in res.iter_lines():
cprint(line.decode().rstrip())
@app_cli.get("/submit")
@app.command("submit")
@session
def submit_pipeline(user_input, *, rerun: bool = False, output_lines: T.List[str]):
......@@ -167,7 +186,7 @@ def submit_pipeline(user_input, *, rerun: bool = False, output_lines: T.List[str
cprint(f"{containers}")
return containers
@app_cli.get("/run")
@app.command("run")
@session
def run_user_input(user_input, *, rerun: bool = False, output_lines: T.List[str] = []):
......@@ -178,11 +197,12 @@ def run_user_input(user_input, *, rerun: bool = False, output_lines: T.List[str]
for _bl in bhelper.log_container(container, server=bconfig.get_server()):
print(_bl.decode().rstrip())
@app_cli.get("/checksum")
@app.command("checksum")
def checksum(user_input):
pipeline = bpipeline.user_input_to_pipeline(user_input)
cprint(pipeline.checksum)
return pipeline.checksum
@app.callback()
......@@ -210,11 +230,19 @@ def main(
cprint(f"Using server {bconfig.get_server()}")
@app_cli.get("/version")
@app.command()
def version():
"""version information"""
cprint(bversion())
return bversion()
@app.command()
def ui():
"""spin up a frontend server for the cli"""
parent_dir = Path(__file__).parent.parent
ui_path = parent_dir / 'new-ui'
subprocess.run(['npm', 'run', 'dev'], cwd=ui_path)
if __name__ == "__main__":
app()
{
"name": "bitia-cli",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"axios": "^1.3.2"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz",
"integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
}
}
}
{
"dependencies": {
"axios": "^1.3.2"
}
}
> 1%
last 2 versions
not dead
not ie 11
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
],
}
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# default
## Project setup
```
# yarn
yarn
# npm
npm install
# pnpm
pnpm install
```
### Compiles and hot-reloads for development
```
# yarn
yarn dev
# npm
npm run dev
# pnpm
pnpm dev
```
### Compiles and minifies for production
```
# yarn
yarn build
# npm
npm run build
# pnpm
pnpm build
```
### Customize configuration
See [Configuration Reference](https://vitejs.dev/config/).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BiTiA</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
This diff is collapsed.
{
"name": "new-ui",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --fix --ignore-path .gitignore"
},
"dependencies": {
"@mdi/font": "7.0.96",
"roboto-fontface": "*",
"vue": "^3.2.38",
"vue-router": "^4.0.0",
"vuetify": "^3.0.0",
"webfontloader": "^1.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.3",
"eslint": "^8.22.0",
"eslint-plugin-vue": "^9.3.0",
"vite": "^3.1.9",
"vite-plugin-vuetify": "^1.0.0-alpha.12"
}
}
ui/public/favicon.ico

15 KiB

<template>
<router-view />
</template>
<script setup>
//
</script>
ui/src/assets/logo.png

432 KiB

<template>
<v-footer class="pa-3 fixed-bottom bottom:0 width:100% left:0 right:0">
<v-container class="footer">
<v-row align="center">
<v-col class="text-center" cols="12">
<span class="subtitle-2 font-weight-light">Copyright © {{ new Date().getFullYear() }} <a class="text-white"
href="https://www.subcom.tech/">SubCom</a></span>
</v-col>
</v-row>
</v-container>
</v-footer>
</template>
<style>
.footer {
background-color: #03A9F4;
color: whitesmoke;
text-align: center;
}
</style>
\ No newline at end of file
<template>
<v-form>
<v-text-field label="Commands" v-model="sha256_sum" />
<v-text-field v-if="selectedOption === 'create-container'" label="Container Name" v-model="containerName" />
<v-text-field v-if="selectedOption === 'run'" label="Command" v-model="command" />
<v-text-field v-if="selectedOption === 'artifacts'" label="Artifact Path" v-model="artifactPath" />
<v-text-field v-if="selectedOption === 'submit'" label="Path" v-model="path" />
<v-text-field v-if="selectedOption === 'version'" label="Version" v-model="version" />
<v-btn color="primary" @click="submitForm">Submit</v-btn>
</v-form>
</template>
<script>
export default {
data() {
return {
sha256_sum: '',
containerName: '',
command: '',
artifactPath: '',
path: '',
version: '',
selectedOption: ''
}
},
methods: {
submitForm() {
if (this.selectedOption === 'create-container') {
console.log("Creating container with name: " + this.containerName);
} else if (this.selectedOption === 'run') {
console.log("Running command: " + this.command);
} else if (this.selectedOption === 'artifacts') {
console.log("Retrieving artifacts from path: " + this.artifactPath);
} else if (this.selectedOption === 'submit') {
console.log("Submitting path: " + this.path);
} else if (this.selectedOption === 'version') {
console.log("Checking version: " + this.version);
} else {
console.log("SHA256_SUM: " + this.sha256_sum);
}
}
}
}
</script>
\ No newline at end of file
<template>
<div>
<div v-if="showResult">
<br /> <br />
<p> Version: {{ version }}</p>
</div>
</div>
</template>
<script>
export default {
name: "OutputSection",
props: {
version: String,
showResult: Boolean
}
};
</script>
<template>
<v-toolbar app color="light-blue">
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-btn to="/" exact>
<v-icon>
<img src="../assets/logo.png" alt="BiTiA Logo" height="50" width="50" contain>
</v-icon>
</v-btn>
<v-toolbar-title class="subtitle-2 font-weight-medium">BiTiA</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn text>Home</v-btn>
<v-btn text>Commands</v-btn>
<v-btn text>Documentation</v-btn>
<v-btn text>Support</v-btn>
</v-toolbar>
</template>
<template>
<v-app>
<default-view />
</v-app>
</template>
<script setup>
import DefaultView from './View.vue'
</script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment