Skip to content

Commit

Permalink
v0.2 - release (#67)
Browse files Browse the repository at this point in the history
* init strapi

* implemented initial content types

* Organizing readme (#1)

* updated readme

* added git flow chart

* fixed spelling err

* Updated README and added yarn workspaces

* Created React App and added lib functions

* WIP: Ardulib not loading object from DOM

* Fixed Blockly.Inject being called before component renders

* Hotfix: Fixes getJS button crashing app

* removed old topic and types

* added complexity type, reassigned relationships, and edited field settings

* init server readme

* update er digram link

* migrated from sqlite3 to mysql running in docker

* init Dockerfile for production api image

* wrapped project in docker compose, defined container for api, db, and compile

* mv .dockerignore to server folder

* scaffolding: server -> cms

* updated main readme scaffolding and development sections

* rm <br/>

* update cms package

* init compile

* cleanup

* un-md Dockerfile

* Removed yarn workspace functionality and documentation

* gitignore packages

* run the compile service on port 8080

* build compile image in compose

* set dev db host via env

* updated project readme

* added scripts for running compile and cms independently

* fixed development link in cms and compile readmes

* actually fixed the links

* testing heroku deploy

* yml vs yaml

* service type for heroku is web

* must be a string too!

* WIP: Client not yet accessible from localhost

* added entrypoint to client dockerfile and remapped volume/ports

* added client development config for cms and compile host names

* added client to main readme development section

* Update README.md

* Setup basic page routing

* Passing activities to workspaces based on selection

* WIP: Weird css bug

* remove react from docker-compose

* fixed react import issue

* renamed containers created with compose

* updated to latest beta of strapi and removed sqlite3 dependency

* use mysql for all database environments

* host helper for getting cms and compile hosts

* add client homepage for build

* root docker file builds client and cms and packages them together

* host helper just saves consts

* use postgres for production

* Basic dynamic block rendering

* database connection settings

* don't use localhost

* Added example model

* Final cleanup

* renmae host hellper

* fix hosts import

* dep update cms

* Rename Hosts.js to hosts.js

* use postgres

* updated documentation

* + documentation improvements

* init app.json

* added postgresql addon

* as and options for app.json

* use relative path for cms api calls

* use localhost for development

* Cleaned up warning messages, renamed app in manifest

* Solves issue #18 - React builds but is not usable

#18

* Updated client README

* Cleaning up documentation

* Changed client to use hosts.js in place of deployment config files

* Updated git flow documentation

* dakota made me do this :(

* Setting correct paths for blockly libs

* Added button hover information

* created a middleware to serve the frontend w/ react router

* updated documentation

* public/frontend

* fixed json parsing err on cms readme

* update read me

* dep

* added public url to build process for cleaner client dev

* fixed host resolution for cms @home view

* git ignore public/frontend

* include frontend folder

* fix prod app bundling

* Changed root routing from /Home to /

* topics now has activities

* Changed dependency use to imported script

* Fixed CORS issue with strapi query during development

* Cleaning up console.log statements for dev merge


Fixing Merge conflict

* Changed path to "/workspace" and fixed warnings

* fixed build-frontend script err

* added the .env file to the client setup documentation

* updated root documentation to follow client setup

* add localhost:1337 to development cors

* removed client .env and added cross-env for build-frontend script

* block category belongs to many blocks

* updated admin build

* activities are only related to their blocks now and return a custom toolbox

* remove block category definition

* blocks now have descriptions not definitions

* enable dev db to build from an sql file

* remove .cache

* cross-env is not good

* display nested activity details

* Refactored activities to pull from updated API

* Moved some js functionality to helper file

* added type to topic find

* restored activities find controller and created seperate route/hander for activities toolbox

* created dataaccess layer to simplify api calls

* implemented new api in client and added dataaccess calls

* condensed dataaccess files

* moved hosts to dataaccess

* fix compile preflight err

* bump

* fixed missing toolbox on re-render

* Update README.md

* Update README.md

* Formatting dump

* clean up, clean up

* update workspace useEffect for render err and sensitivety

* added alert for arduino code

* Abstraction is trash and so are you

* wrote an init script that uses pg_restore rather than importing a .sql

* updated documentation for adding the dump to scripts

* script formating

* All .sh files now keep LF line endings when pulled to windows

* Updated documentation for /admin not beuilding

* fixed comment in .gitattributes

* migrated to strapi 3.0.1

* added custom ssl config

* added template field to activity and removed topic from activity

* review apps as containers

* import staging db in review app

* updated documentation links to latest strapi docs

* get xml from workspace and load workspace w/ activity xml

* Removed unnecessary function

* Workspace now saves on page refresh

* Removed alert for compile request

Co-authored-by: Dakota <[email protected]>
Co-authored-by: nionata <[email protected]>
  • Loading branch information
3 people authored Jun 25, 2020
1 parent 8da2757 commit 65c5a7b
Show file tree
Hide file tree
Showing 15 changed files with 384 additions and 308 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#### `cms/`

[Cms](/cms#cms) is the REST API and admin portal that powers the backend. It is powered by [Node](https://nodejs.org/en/) and [Strapi]().
[Cms](/cms#cms) is the REST API and admin portal that powers the backend. It is powered by [Node](https://nodejs.org/en/) and [Strapi](https://strapi.io/documentation/v3.x/getting-started/introduction.html).

#### `compile/`

Expand Down
8 changes: 5 additions & 3 deletions app.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{
"name": "STEM-C",
"description": "Web Blockly IDE for Arduino",
"repository": "https://github.com/STEM-C/STEM-C",
"stack": "container",
"addons": [
{
"plan": "heroku-postgresql",
"as": "DATABASE"
}
]
],
"scripts": {
"postdeploy": "pg_dump $STAGING_DATABASE_URL | psql $DATABASE_URL && bundle exec rake db:migrate"
}
}
6 changes: 1 addition & 5 deletions client/src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import React, { useState } from 'react'
import { Route, Switch } from 'react-router-dom'
import Workspace from "./views/Workspace/Workspace"
import Home from "./views/Home/Home"
Expand All @@ -7,10 +7,6 @@ import NotFound from "./views/NotFound"
const App = () => {
const [selectedActivity, setSelectedActivity] = useState()

useEffect(() => {
console.log("Selected activity has changed to: ", selectedActivity)
}, [selectedActivity])

return (
<div>
<Switch>
Expand Down
1 change: 1 addition & 0 deletions client/src/views/Home/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function Home(props) {
const [activities, setActivities] = useState([]) // temporary - eventually topics should render their activities

useEffect(() => {
localStorage.clear()

getTopics().then(topics => {

Expand Down
40 changes: 27 additions & 13 deletions client/src/views/Workspace/Workspace.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import React, { useEffect, useRef, useState } from "react"
import { Link } from "react-router-dom"
import { compileArduinoCode, getArduino, getJS } from './helpers.js'
import { compileArduinoCode, getArduino, getJS, getXml, setLocalActivity } from './helpers.js'
import "./Workspace.css"
import { getActivityToolbox } from "../../dataaccess/requests.js"
import { useHistory } from "react-router-dom"

function App(props) {

const [activity, setActivity] = useState({})
const [activity, setActivity] = useState({} )
const [hoverXml, setHoverXml] = useState(false)
const [hoverJS, setHoverJS] = useState(false)
const [hoverArduino, setHoverArduino] = useState(false)
const [hoverCompile, setHoverCompile] = useState(false)

let history = useHistory()
let workspaceRef = useRef(null)
const setWorkspace = () => workspaceRef.current = window.Blockly.inject('blockly-canvas', {toolbox: document.getElementById('toolbox')})

const setWorkspace = () => workspaceRef.current = window.Blockly.inject('blockly-canvas', { toolbox: document.getElementById('toolbox') })

useEffect(() => {
const localActivity = localStorage.getItem("my-activity")
const {selectedActivity} = props

if (localActivity && !selectedActivity) {

let loadedActivity = JSON.parse(localActivity)
setActivity(loadedActivity)

} else if (selectedActivity) {

getActivityToolbox(selectedActivity.id).then(response => {

let loadedActivity = {...selectedActivity, toolbox: response.toolbox}

localStorage.setItem("my-activity", JSON.stringify(loadedActivity))
Expand All @@ -36,16 +37,25 @@ function App(props) {
window.location = '/' // this should probably use the react router dom to add to history stack
}

// clean up - removes blockly div from DOM
// clean up - removes blockly div from DOM
return () => {
workspaceRef.current.dispose()
if (workspaceRef.current) {
workspaceRef.current.dispose()
}
}
}, [props])
}, [props, history])

useEffect(() => {

// once the activity state is set, set the workspace
if (Object.keys(activity).length && !workspaceRef.current) setWorkspace()
if (Object.keys(activity).length && !workspaceRef.current) {
setWorkspace()
workspaceRef.current.addChangeListener(() => setLocalActivity(workspaceRef.current))

if (activity.template) {
let xml = window.Blockly.Xml.textToDom(activity.template)
window.Blockly.Xml.domToWorkspace(xml, workspaceRef.current)
}
}
}, [activity])

return (
Expand All @@ -54,6 +64,10 @@ function App(props) {
<div id="nav-container" className="flex vertical-container space-between">
<h1 id="title"><Link to={"/"}>STEM+C</Link></h1>
<div id="action-btn-container" className="flex space-between">
<i onClick={() => getXml(workspaceRef.current)} className="fas fa-code hvr-info"
onMouseEnter={() => setHoverXml(true)}
onMouseLeave={() => setHoverXml(false)}/>
{hoverXml && <div className="popup JS">Shows Xml Code</div>}
<i onClick={() => getJS(workspaceRef.current)} className="fab fa-js hvr-info"
onMouseEnter={() => setHoverJS(true)}
onMouseLeave={() => setHoverJS(false)}/>
Expand All @@ -76,12 +90,12 @@ function App(props) {
</div>
</div>
<div id="bottom-container" className="flex vertical-container">
<div id="blockly-canvas" style={{"height": "800px", "width": "100%"}}/>
<div id="blockly-canvas" style={{ "height": "800px", "width": "100%" }} onChange={() => setLocalActivity(workspaceRef.current)}/>
</div>
</div>

{/* This xml is for the blocks' menu we will provide. Here are examples on how to include categories and subcategories */}
<xml id="toolbox" style={{"display": "none"}} is="Blockly workspace">
<xml id="toolbox" style={{ "display": "none" }} is="Blockly workspace">
{
// Maps out block categories
activity.toolbox && activity.toolbox.map(([category, blocks]) => (
Expand Down
26 changes: 23 additions & 3 deletions client/src/views/Workspace/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@ import { compileCode } from "../../dataaccess/requests";

const AvrboyArduino = window.AvrgirlArduino;

export const setLocalActivity = (workspaceRef) => {
let workspaceDom = window.Blockly.Xml.workspaceToDom(workspaceRef)
let workspaceText = window.Blockly.Xml.domToText(workspaceDom)
const localActivity = JSON.parse(localStorage.getItem("my-activity"))

let lastActivity = {...localActivity, template: workspaceText}
localStorage.setItem("my-activity", JSON.stringify(lastActivity))
}

// Generates xml from blockly canvas
export const getXml = (workspaceRef) => {

const { Blockly } = window

let xml = Blockly.Xml.workspaceToDom(workspaceRef)
let xml_text = Blockly.Xml.domToText(xml)
alert(xml_text);
return (xml_text);
};

// Generates javascript code from blockly canvas
export const getJS = (workspaceRef) => {
window.Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
Expand All @@ -11,18 +31,18 @@ export const getJS = (workspaceRef) => {
};

// Generates Arduino code from blockly canvas
export const getArduino = (workspaceRef) => {
export const getArduino = (workspaceRef, alert = true) => {
window.Blockly.Arduino.INFINITE_LOOP_TRAP = null;
let code = window.Blockly.Arduino.workspaceToCode(workspaceRef);
alert(code);
if(alert) alert(code);
return (code);
};

// Sends compiled arduino code to server and returns hex to flash board with
export const compileArduinoCode = async (workspaceRef) => {
let body = {
"board": "arduino:avr:uno",
"sketch": getArduino(workspaceRef)
"sketch": getArduino(workspaceRef, false)
};

// gets compiled hex from server
Expand Down
4 changes: 2 additions & 2 deletions cms/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Cms

> REST API and admin portal that comprise the backend. It is powered by [Node](https://nodejs.org/en/), [Strapi](https://strapi.io/documentation/3.0.0-beta.x/getting-started/introduction.html), and [PostgreSQL](https://www.postgresql.org/). The file structure is defined by Strapi and is documented [here](https://strapi.io/documentation/3.0.0-beta.x/concepts/file-structure.html#files-structure).
> REST API and admin portal that comprise the backend. It is powered by [Node](https://nodejs.org/en/), [Strapi](https://strapi.io/documentation/v3.x/getting-started/introduction.html), and [PostgreSQL](https://www.postgresql.org/). The file structure is defined by Strapi and is documented [here](https://strapi.io/documentation/3.0.0-beta.x/concepts/file-structure.html#files-structure).
<br/>

Expand Down Expand Up @@ -102,5 +102,5 @@ Built with [React](https://reactjs.org/) and served by [Node](https://nodejs.org

> In some cases /admin may be blank, in this case `yarn build` needs to be run from the docker container
Read the full [documentation](https://strapi.io/documentation/3.0.0-beta.x/admin-panel/customization.html) on the admin panel.
Read the full [documentation](https://strapi.io/documentation/v3.x/admin-panel/customization.html) on the admin panel.

6 changes: 3 additions & 3 deletions cms/api/activity/models/activity.settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
"learning_category": {
"model": "learning-category"
},
"topic": {
"model": "topic"
},
"blocks": {
"collection": "block"
},
"template": {
"type": "text"
}
}
}
3 changes: 1 addition & 2 deletions cms/api/topic/models/topic.settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
"model": "type"
},
"activities": {
"collection": "activity",
"via": "topic"
"collection": "activity"
}
}
}
2 changes: 1 addition & 1 deletion cms/build/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
<!-- The app hooks into this div -->
<div id="app"></div>
<!-- A lot of magic happens in this file. HtmlWebpackPlugin automatically includes all assets (e.g. bundle.js, main.css) with the correct HTML tags, which is why they are missing in this HTML file. Don't add any assets here! (Check out webpackconfig.js if you want to know more) -->
<script type="text/javascript" src="/admin/runtime~main.a30f2f79.js"></script><script type="text/javascript" src="/admin/main.0bcd5ec7.chunk.js"></script></body>
<script type="text/javascript" src="/admin/runtime~main.4605f481.js"></script><script type="text/javascript" src="/admin/main.c2683de7.chunk.js"></script></body>
</html>
48 changes: 48 additions & 0 deletions cms/config/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* parses a PostgreSQL DB connection URL into the parts needed
* by Strapi. Without this, heroku may throw ECONNREFUSED 127.0.0.1:xxxx.
*/

const url = require('url')

if (process.env.DATABASE_URL) {
const parsed = url.parse(process.env.DATABASE_URL, true)
const [username, password] = parsed.auth.split(':')

process.env.DATABASE_HOST = parsed.hostname
process.env.DATABASE_PORT = Number(parsed.port)
process.env.DATABASE_NAME = parsed.pathname.substr(1)
process.env.DATABASE_USERNAME = username
process.env.DATABASE_PASSWORD = password
}

module.exports = ({ env }) => ({
defaultConnection: 'default',
connections: {
default: {
connector: 'bookshelf',
settings: {
client: 'postgres',
host: env('DATABASE_HOST', 'localhost'),
port: env.int('DATABASE_PORT', 5432),
database: env('DATABASE_NAME', 'strapi'),
username: env('DATABASE_USERNAME', 'postgres'),
password: env('DATABASE_PASSWORD', 'postgres'),
schema: 'public',
ssl: env('DATABASE_SSL', false)
},
options: {
// ssl: {
// 'rejectUnauthorized': false
// }
'pool': {
'min': 0,
'max': 15,
'idleTimeoutMillis': 30000,
'createTimeoutMillis': 30000,
'acquireTimeoutMillis': 30000
}
}
},
},
})
27 changes: 27 additions & 0 deletions cms/config/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
timeout: 100,
load: {
before: ['responseTime', 'logger', 'cors', 'responses', 'gzip'],
order: [
'Define the middlewares\' load order by putting their name in this array is the right order',
],
after: ['parser', 'router'],
},
settings: {
public: {
path: './public',
maxAge: 60000,
},
// logger: {
// // dev + prod
// level: debug + info,
// requests: true + false
// }

// dev
// cors: {
// enabled: true,
// origin: ['http://localhost:3000', 'http://localhost:1337']
// },
},
}
7 changes: 7 additions & 0 deletions cms/config/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
admin: {
url: env('URL', '/admin')
}
})
18 changes: 9 additions & 9 deletions cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
"dependencies": {
"knex": "<0.20.0",
"pg": "^8.1.0",
"strapi": "3.0.0-beta.20.3",
"strapi-admin": "3.0.0-beta.20.3",
"strapi-connector-bookshelf": "3.0.0-beta.20.3",
"strapi-plugin-content-manager": "3.0.0-beta.20.3",
"strapi-plugin-content-type-builder": "3.0.0-beta.20.3",
"strapi-plugin-email": "3.0.0-beta.20.3",
"strapi-plugin-upload": "3.0.0-beta.20.3",
"strapi-plugin-users-permissions": "3.0.0-beta.20.3",
"strapi-utils": "3.0.0-beta.20.3"
"strapi": "3.0.1",
"strapi-admin": "3.0.1",
"strapi-connector-bookshelf": "3.0.1",
"strapi-plugin-content-manager": "3.0.1",
"strapi-plugin-content-type-builder": "3.0.1",
"strapi-plugin-email": "3.0.1",
"strapi-plugin-upload": "3.0.1",
"strapi-plugin-users-permissions": "3.0.1",
"strapi-utils": "3.0.1"
},
"author": {
"name": "Nicholas Ionata"
Expand Down
Loading

0 comments on commit 65c5a7b

Please sign in to comment.