From 345b7972b6187411f1367ddc563d14bfb31adcfb Mon Sep 17 00:00:00 2001 From: Jasti Sri Radhe Shyam Date: Thu, 26 Oct 2023 10:21:11 +0530 Subject: [PATCH] add version support Signed-off-by: Jasti Sri Radhe Shyam --- Makefile | 4 ++ crates/backend/src/main.rs | 5 ++ crates/backend/src/services/contract.rs | 1 + crates/backend/src/services/mod.rs | 1 + crates/backend/src/services/version.rs | 12 ++++ crates/generate-bindings/src/main.rs | 2 + crates/sandbox/src/lib.rs | 14 +++++ packages/ink-editor/src/api/version.ts | 44 ++++++++++++++ packages/playground/package.json | 1 + .../src/app/Header/VersionsSubmenu.tsx | 19 ++++++ packages/playground/src/app/Header/index.tsx | 14 +++++ packages/playground/src/app/index.tsx | 59 ++++++++++++------- .../playground/src/context/app/reducer.ts | 18 +++++- .../src/context/side-effects/version.ts | 36 +++++++++++ packages/playground/src/env.ts | 2 + packages/playground/webpack.config.js | 3 + yarn.lock | 32 ++++++++++ 17 files changed, 246 insertions(+), 21 deletions(-) create mode 100644 crates/backend/src/services/version.rs create mode 100644 packages/ink-editor/src/api/version.ts create mode 100644 packages/playground/src/app/Header/VersionsSubmenu.tsx create mode 100644 packages/playground/src/context/side-effects/version.ts diff --git a/Makefile b/Makefile index 894602463..ef1f6982a 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,8 @@ FORMATTING_URL ?= http://localhost:4000/format ANALYTICS_URL ?= https://api-sa.substrate.io +VERSION_LIST_URL ?= http://localhost:4000/version_list + DOCKER_USER_NAME ?= achimcc ################################################################################ @@ -63,6 +65,7 @@ playground-build: GIST_LOAD_URL=/gist/load \ GIST_CREATE_URL=/gist/create \ ANALYTICS_URL=$(ANALYTICS_URL) \ + VERSION_LIST_URL=/version_list \ yarn workspace playground run build playground-start: @@ -72,6 +75,7 @@ playground-start: GIST_LOAD_URL=$(GIST_LOAD_URL) \ GIST_CREATE_URL=$(GIST_CREATE_URL) \ ANALYTICS_URL=$(ANALYTICS_URL) \ + VERSION_LIST_URL=$(VERSION_LIST_URL) \ yarn workspace playground run start playground-clean: diff --git a/crates/backend/src/main.rs b/crates/backend/src/main.rs index b6df33e7c..af1ccb8ea 100644 --- a/crates/backend/src/main.rs +++ b/crates/backend/src/main.rs @@ -32,6 +32,7 @@ use crate::{ create::route_gist_create, load::route_gist_load, }, + version::route_version_list, }, }; use actix_cors::Cors; @@ -112,6 +113,10 @@ async fn main() -> std::io::Result<()> { .route( "/status", get().to(route_status), + ) + .route( + "/version_list", + get().to(route_version_list), ); match opts.github_token { diff --git a/crates/backend/src/services/contract.rs b/crates/backend/src/services/contract.rs index b57e2b9b8..a8ab4227f 100644 --- a/crates/backend/src/services/contract.rs +++ b/crates/backend/src/services/contract.rs @@ -148,6 +148,7 @@ pub async fn route_status() -> HttpResponse { HttpResponse::Ok().body("ink-compiler is live") } + // ------------------------------------------------------------------------------------------------- // TESTS // ------------------------------------------------------------------------------------------------- diff --git a/crates/backend/src/services/mod.rs b/crates/backend/src/services/mod.rs index ef0bac9a8..695a1c8be 100644 --- a/crates/backend/src/services/mod.rs +++ b/crates/backend/src/services/mod.rs @@ -20,3 +20,4 @@ pub mod contract; pub mod frontend; pub mod gist; +pub mod version; diff --git a/crates/backend/src/services/version.rs b/crates/backend/src/services/version.rs new file mode 100644 index 000000000..e1b02a77d --- /dev/null +++ b/crates/backend/src/services/version.rs @@ -0,0 +1,12 @@ +use actix_web::{ + body::BoxBody, + HttpResponse, +}; + +pub use sandbox::VersionListResult; + +pub async fn route_version_list() -> HttpResponse { + let formatting_result = "[\"1.0.0\"]".to_string(); + // let formatting_result = serde_json::to_string(&result).unwrap(); + HttpResponse::Ok().append_header(("Content-Type","application/json")).body(formatting_result) +} \ No newline at end of file diff --git a/crates/generate-bindings/src/main.rs b/crates/generate-bindings/src/main.rs index 4b572e9e5..531366522 100644 --- a/crates/generate-bindings/src/main.rs +++ b/crates/generate-bindings/src/main.rs @@ -18,6 +18,7 @@ mod cli; use crate::cli::Cli; use backend::services::{ + version::VersionListResult, contract::{ CompilationRequest, CompilationResult, @@ -64,6 +65,7 @@ fn main() -> std::io::Result<()> { GistLoadResponse, GistCreateRequest, GistCreateResponse, + VersionListResult ); let path = Path::new(&target); diff --git a/crates/sandbox/src/lib.rs b/crates/sandbox/src/lib.rs index 810723d41..6e31cd155 100644 --- a/crates/sandbox/src/lib.rs +++ b/crates/sandbox/src/lib.rs @@ -160,6 +160,20 @@ pub enum FormattingResult { Error { stdout: String, stderr: String }, } +#[derive(Deserialize, Serialize, TypeDef, PartialEq, Debug, Clone, Eq)] +#[serde(tag = "type", content = "payload", rename_all = "SCREAMING_SNAKE_CASE")] +pub enum VersionListResult { + Success { + versions: Vec, + stdout: String, + stderr: String, + }, + Error { + stdout: String, + stderr: String, + }, +} + // ------------------------------------------------------------------------------------------------- // CONSTANTS // ------------------------------------------------------------------------------------------------- diff --git a/packages/ink-editor/src/api/version.ts b/packages/ink-editor/src/api/version.ts new file mode 100644 index 000000000..65adbeecc --- /dev/null +++ b/packages/ink-editor/src/api/version.ts @@ -0,0 +1,44 @@ +import Common from '@paritytech/commontypes'; + +export type versionListApiResponse = + | { + type: 'OK'; + payload: Common.VersionListResult; + } + | { + type: 'NETWORK_ERROR'; + } + | { + type: 'SERVER_ERROR'; + payload: { status: number }; + }; + +export type Config = { + versionListUrl: string; +}; + +const mapResponse = async (response: Response): Promise => + response.status === 200 + ? { + type: 'OK', + payload: await response.json(), + } + : { + type: 'SERVER_ERROR', + payload: { status: response.status }, + }; + +export const versionListRequest = ( + config: Config, +): Promise => { + const opts: RequestInit = { + method: 'GET', + mode: 'cors', + credentials: 'same-origin', + headers: { 'Content-Type': 'application/json' }, + }; + + return fetch(config.versionListUrl || '', opts) + .then(mapResponse) + .catch(() => ({ type: 'NETWORK_ERROR' })); +}; diff --git a/packages/playground/package.json b/packages/playground/package.json index ec4a6babf..7d1d19de3 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,6 +11,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-monaco-editor": "^0.49.0", + "react-router-dom": "^6.17.0", "use-reducer-logger": "^1.0.2" }, "scripts": { diff --git a/packages/playground/src/app/Header/VersionsSubmenu.tsx b/packages/playground/src/app/Header/VersionsSubmenu.tsx new file mode 100644 index 000000000..d83095d67 --- /dev/null +++ b/packages/playground/src/app/Header/VersionsSubmenu.tsx @@ -0,0 +1,19 @@ +import { MenuElementWrapper } from '@paritytech/components/'; +import { ReactElement, useContext } from 'react'; +import { AppContext } from '~/context/app/'; +import { Dispatch, State } from '~/context/app/reducer'; + +export const VersionsSubmenu = (): ReactElement => { + const [state, dispatch]: [State, Dispatch] = useContext(AppContext); + + return ( +
+

Supported Versions

+ {state.versionList.map((version) => ( + + {version} + + ))} +
+ ); +}; diff --git a/packages/playground/src/app/Header/index.tsx b/packages/playground/src/app/Header/index.tsx index c1452431b..879b55656 100644 --- a/packages/playground/src/app/Header/index.tsx +++ b/packages/playground/src/app/Header/index.tsx @@ -13,6 +13,7 @@ import { } from '~/symbols'; import { OverlayPanel, ButtonWithIcon } from '@paritytech/components/'; import { SettingsSubmenu } from './SettingsSubmenu'; +import { VersionsSubmenu } from './VersionsSubmenu'; import { ShareSubmenu } from './ShareSubmenu'; import { AppContext } from '~/context/app/'; @@ -24,6 +25,7 @@ import { testing } from '~/context/side-effects/testing'; import { format } from '~/context/side-effects/format'; import * as constants from '~/constants'; import { Colors } from '@paritytech/components/ButtonWithIcon'; +import { useNavigate } from 'react-router-dom'; const openContractsUiUrl = (): void => { window.open(constants.CONTRACTS_UI_URL, '_blank'); @@ -54,6 +56,7 @@ export const Header = (): ReactElement => { const [, dispatchMessage]: [MessageState, MessageDispatch] = useContext(MessageContext); const settingsOverlay = useRef(null); + const versionsOverlay = useRef(null); const shareOverlay = useRef(null); const hasDownloadableResult = @@ -121,6 +124,14 @@ export const Header = (): ReactElement => { onClick={e => settingsOverlay.current && settingsOverlay.current.toggle(e, null)} /> + versionsOverlay.current && versionsOverlay.current.toggle(e, null)} + /> +
{ + + + diff --git a/packages/playground/src/app/index.tsx b/packages/playground/src/app/index.tsx index a6947dd59..fe7e0d099 100644 --- a/packages/playground/src/app/index.tsx +++ b/packages/playground/src/app/index.tsx @@ -8,11 +8,21 @@ import { ReactElement, useContext, useEffect } from 'react'; import { Dispatch, State } from '~/context/app/reducer'; import { MessageDispatch, MessageState } from '~/context/messages/reducer'; import { loadCode } from '~/context/side-effects/load-code'; +import { loadVersionList } from '~/context/side-effects/version'; import { monaco } from 'react-monaco-editor'; +import { + Routes, + Route, + useNavigate, + BrowserRouter, + useParams, +} from "react-router-dom"; const App = (): ReactElement => { const [state, dispatch]: [State, Dispatch] = useContext(AppContext); const [, messageDispatch]: [MessageState, MessageDispatch] = useContext(MessageContext); + const navigate = useNavigate(); + const { versionId } = useParams(); const { monacoUri: uri, formatting } = state; useEffect(() => { @@ -22,6 +32,7 @@ const App = (): ReactElement => { if (!model) return; model.setValue(code); }); + loadVersionList(state, { app: dispatch }).then() }, [uri]); useEffect(() => { @@ -54,31 +65,39 @@ const App = (): ReactElement => { }; return ( - } - editor={ - dispatch({ type: 'SET_URI', payload: uri })} - /> - } - console={} - /> + <> +

{versionId}

+ } + editor={ + dispatch({ type: 'SET_URI', payload: uri })} + /> + } + console={} + /> + ); }; const AppWithProvider = (): ReactElement => { return ( - - - - - + + + + + } /> + } /> + + + + ); }; diff --git a/packages/playground/src/context/app/reducer.ts b/packages/playground/src/context/app/reducer.ts index 01567faf3..90f191ec9 100644 --- a/packages/playground/src/context/app/reducer.ts +++ b/packages/playground/src/context/app/reducer.ts @@ -15,6 +15,8 @@ export const defaultState: State = { gist: { type: 'NOT_ASKED' }, contractSize: null, rustAnalyzer: false, + versionList: [], + version: '', }; export type State = { @@ -28,6 +30,8 @@ export type State = { gist: GistState; contractSize: number | null; rustAnalyzer: boolean; + versionList: string[]; + version: string; }; export type GistState = @@ -60,7 +64,9 @@ export type Action = | { type: 'SET_GIST_STATE'; payload: GistState } | { type: 'SET_URI'; payload: Uri } | { type: 'SET_CONTRACT_SIZE'; payload: number | null } - | { type: 'SET_RUST_ANALYZER_STATE'; payload: boolean }; + | { type: 'SET_RUST_ANALYZER_STATE'; payload: boolean } + | { type: 'SET_VERSIONS_STATE'; payload: string[] } + | { type: 'SET_VERSION_STATE'; payload: string }; export type Dispatch = (action: Action) => void; @@ -116,6 +122,16 @@ export const reducer = (state: State, action: Action): State => { ...state, contractSize: action.payload, }; + case 'SET_VERSIONS_STATE': + return { + ...state, + versionList: action.payload, + }; + case 'SET_VERSION_STATE': + return { + ...state, + version: action.payload, + }; default: return state; } diff --git a/packages/playground/src/context/side-effects/version.ts b/packages/playground/src/context/side-effects/version.ts new file mode 100644 index 000000000..4328c018b --- /dev/null +++ b/packages/playground/src/context/side-effects/version.ts @@ -0,0 +1,36 @@ +import { versionListRequest } from '@paritytech/ink-editor/api/version'; +import { State, Dispatch as AppDispatch } from '~/context/app/reducer'; +import { VERSION_LIST_URL } from '~/env'; + +type Dispatch = { + app: AppDispatch; +}; + +export async function loadVersionList(state: State, dispatch: Dispatch) { + // const { versionList: versions } = state; + const result = await versionListRequest({ versionListUrl: VERSION_LIST_URL || '' }); + + if (result.type === 'OK' && result.payload.type === 'SUCCESS') { + dispatch.app({ + type: 'SET_VERSIONS_STATE', + payload: result.payload.payload.versions, + }); + } else { + dispatch.app({ + type: 'SET_VERSIONS_STATE', + payload: [], + }); + } +} + +export async function setVersion(version: string, state: State, dispatch: Dispatch) { + const { versionList: versions } = state; + if (!version) { + version = versions.length > 0 && versions[0] ? versions[0] : ''; + } + + dispatch.app({ + type: 'SET_VERSION_STATE', + payload: version, + }); +} \ No newline at end of file diff --git a/packages/playground/src/env.ts b/packages/playground/src/env.ts index dd02f3007..841f38d45 100644 --- a/packages/playground/src/env.ts +++ b/packages/playground/src/env.ts @@ -8,4 +8,6 @@ export const GIST_CREATE_URL: string | undefined = process.env.GIST_CREATE_URL; export const GIST_LOAD_URL: string | undefined = process.env.GIST_LOAD_URL; +export const VERSION_LIST_URL: string | undefined = process.env.VERSION_LIST_URL; + export const NODE_ENV = process.env.NODE_ENV as 'production' | 'development'; diff --git a/packages/playground/webpack.config.js b/packages/playground/webpack.config.js index b71251340..2d70ffa5c 100644 --- a/packages/playground/webpack.config.js +++ b/packages/playground/webpack.config.js @@ -19,6 +19,7 @@ const localConfig = { output: { filename: 'bundle.[fullhash].js', path: path.resolve(__dirname, 'dist'), + publicPath: '/', }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx', '.wasm', '.css'], @@ -75,6 +76,7 @@ const localConfig = { FORMATTING_URL: '', GIST_CREATE_URL: '', GIST_LOAD_URL: '', + VERSION_LIST_URL: '', }), new webpack.ProvidePlugin({ process: 'process/browser', @@ -94,6 +96,7 @@ const localConfig = { warnings: false, }, }, + historyApiFallback: true, }, }; diff --git a/yarn.lock b/yarn.lock index e8417fecc..4642a580c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2725,6 +2725,13 @@ __metadata: languageName: node linkType: hard +"@remix-run/router@npm:1.10.0": + version: 1.10.0 + resolution: "@remix-run/router@npm:1.10.0" + checksum: f8f9fcd5f08465a7e0a05378398ff6df2c5c5ef5766df3490a134d64260b3b16f1bd490bb0c3f5925c2671a0c1d8d1fa01dfbdc7ecc3b2447dc6eafe6b73bcc2 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.24.1": version: 0.24.51 resolution: "@sinclair/typebox@npm:0.24.51" @@ -9672,6 +9679,7 @@ __metadata: react: ^18.2.0 react-dom: ^18.2.0 react-monaco-editor: ^0.49.0 + react-router-dom: ^6.17.0 remove: ^0.1.5 rimraf: ^3.0.2 tailwindcss: ^3.0.24 @@ -10603,6 +10611,30 @@ __metadata: languageName: node linkType: hard +"react-router-dom@npm:^6.17.0": + version: 6.17.0 + resolution: "react-router-dom@npm:6.17.0" + dependencies: + "@remix-run/router": 1.10.0 + react-router: 6.17.0 + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: e0ba4f4c507681e2ffdecdf2e67edf7ec0e2bf4be35222e29d013afdb03866a5e6ecacc8b452bd55797b9672785d02f81bd6dbf6b05ac93a59e48e774b0060de + languageName: node + linkType: hard + +"react-router@npm:6.17.0": + version: 6.17.0 + resolution: "react-router@npm:6.17.0" + dependencies: + "@remix-run/router": 1.10.0 + peerDependencies: + react: ">=16.8" + checksum: 99c30d94fbb34657e4c8c3ef1aaae33b143167d3869b442e06c83b4006f35200fde810029180e209654bef2f47f0b27a928f77cc2d859a358a2722cc9d494f03 + languageName: node + linkType: hard + "react-transition-group@npm:^4.4.1": version: 4.4.2 resolution: "react-transition-group@npm:4.4.2"