Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: GitHub download by URL #680

Closed
wants to merge 97 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
fcb0cfb
Rename github:open to github:gist for clarity
bergie Feb 20, 2017
0c56c82
Disambiguate by renaming example to gist
bergie Feb 20, 2017
0e33414
Add redirection support to URL router
bergie Feb 20, 2017
6296963
Typo fix
bergie Feb 20, 2017
bdd6507
Make 'download project' go to download URL
bergie Feb 20, 2017
47f3e73
After registering new repo, go to download URL
bergie Feb 20, 2017
214406f
Parse JSON response
bergie Feb 20, 2017
efe9976
Analytics support
bergie Feb 20, 2017
eef952c
Centralize handling of certain nav events
bergie Feb 20, 2017
dab128a
Adapt UrlMiddleware tests to new gist/example split
bergie Feb 20, 2017
f403eaf
Move runtime registry communications to graph
bergie Feb 20, 2017
abe0762
We don't need registry here any longer
bergie Feb 20, 2017
5a2c57a
Persist manually added runtimes, refs noflo/noflo-nodejs#105
bergie Feb 20, 2017
55179a9
More descriptive event name
bergie Feb 20, 2017
c17b35f
Bump noflo-indexeddb
bergie Feb 21, 2017
b23ce03
Make linter happy
bergie Feb 21, 2017
f273c22
Save runtime to registry when adding manually, refs noflo/noflo-nodej…
bergie Feb 21, 2017
a240e02
Centralize middleware test helpers
bergie Feb 21, 2017
7213cf8
Simplify middleware testing even further
bergie Feb 21, 2017
796750b
Debugging support
bergie Feb 21, 2017
29a5f37
Initial registry middleware tests
bergie Feb 21, 2017
c6d12e5
Provide an action for setting hash instead of UI doing it directly
bergie Feb 22, 2017
3ac4875
Use the hash event
bergie Feb 22, 2017
421c3fe
Send repo slug as parts
bergie Feb 22, 2017
8f35cad
Save branch info
bergie Feb 22, 2017
8751440
Don't send empty arrays
bergie Feb 22, 2017
7b79762
Remove redundant
bergie Feb 22, 2017
8fde246
Change gists so they download gist to a project, fixes #229 and fixes…
bergie Feb 22, 2017
6b84c04
Retain project gist ID until assigned to a repo
bergie Feb 22, 2017
aa09bbc
Don't list examples user has already downloaded locally
bergie Feb 22, 2017
d70d130
Hook in errors
bergie Feb 22, 2017
a22b859
Use correct component
bergie Feb 22, 2017
983c77a
More user-friendly error message
bergie Feb 22, 2017
774188f
Initial tests for gist fetching
bergie Feb 22, 2017
3dc1af8
Move state normalization from Polymer to NoFlo-land
bergie Feb 23, 2017
9b9400e
Normalize action payload
bergie Feb 23, 2017
5cfd9a2
Show main screen when not viewing project
bergie Feb 23, 2017
ecd931a
Option for logging the state object
bergie Feb 23, 2017
578f3da
Rewire search
bergie Feb 23, 2017
f0022f2
Hook compatible runtimes list back in
bergie Feb 23, 2017
fc64539
Hook remote projects listing back in
bergie Feb 23, 2017
14259e2
Send only action for new ones
bergie Feb 23, 2017
55951db
Rename StateMiddleware to Store to be closer to Redux conventions
bergie Feb 23, 2017
e6600c8
Rename action inport to 'action
bergie Feb 23, 2017
4e1664a
Some words about the overall architecture we're aiming for
bergie Feb 23, 2017
8ad8c49
Initial wildcard routing support
bergie Feb 23, 2017
31a7f23
Fix wildcards
bergie Feb 23, 2017
e9287ce
Don't capture noflo:ready
bergie Feb 23, 2017
24119a4
Send action also as property
bergie Feb 27, 2017
0d75608
Move DB initialization to middleware, let reducers update partial state
bergie Feb 27, 2017
113fb58
Move IndexedDB loading to middleware
bergie Feb 27, 2017
41edf10
Move example loading/filtering to reducer
bergie Feb 27, 2017
810761f
Define component
bergie Feb 27, 2017
52da0b7
Move runtime 'last seen' calc to reducer
bergie Feb 27, 2017
d8bfb08
Move remote project fetching to middleware
bergie Feb 27, 2017
0aaa52c
We can start cleaning up legacy context handling a bit
bergie Feb 27, 2017
d08332c
Move remote project fetching to registry middleware
bergie Feb 27, 2017
f866a81
Load local data once DB is ready
bergie Feb 27, 2017
15f6f72
Move saving to middleware
bergie Feb 27, 2017
3edddaa
Cleanup
bergie Feb 27, 2017
03a2e18
Move deletion to storage middleware
bergie Feb 28, 2017
0d56071
Update state on removal actions
bergie Feb 28, 2017
2cf0b94
Keep track of current runtimes vs. all
bergie Feb 28, 2017
50b1202
Better route-to-action mapping
bergie Feb 28, 2017
5e6435a
Populate workspace data as far as possible from local information
bergie Feb 28, 2017
24722ab
Remove debug
bergie Feb 28, 2017
5ae1962
Make the current graph live
bergie Feb 28, 2017
5b14d56
Don't instantiate at this stage
bergie Feb 28, 2017
d0994fd
Mention the types
bergie Feb 28, 2017
344ecb4
Remove as redundant
bergie Feb 28, 2017
fc54bf3
Handle gateway timeouts
bergie Feb 28, 2017
7658570
Only fetch runtimes when needed
bergie Feb 28, 2017
00d57fb
Only start routing hashes after we've loaded local data
bergie Feb 28, 2017
1282b07
Wait until all stores have been read before routing
bergie Feb 28, 2017
d5c5853
Use the S3 outage to implement better 'unavailable' handling
bergie Feb 28, 2017
5ea898c
Find and auto-connect a runtime when opening project
bergie Feb 28, 2017
9f95ebd
Add actions for successful/failed runtime connection
bergie Feb 28, 2017
fd050e4
Rewire searching and make it way faster
bergie Feb 28, 2017
d9c9fad
Send contents of workspace to runtime
bergie Mar 1, 2017
28790d9
Send Runtime commands as actions
bergie Mar 1, 2017
aaaa238
Send Runtime commands as actions
bergie Mar 1, 2017
387563c
Redirect to project if user already has it downloaded
bergie Mar 28, 2017
4bfe506
Make branch editable
bergie Mar 28, 2017
055f158
Bootstrap GitHub pull
bergie Mar 28, 2017
f75dca9
Add reducer for handling GitHub-related data
bergie Mar 28, 2017
ba463df
Refactor in/outports for better use in middleware
bergie Apr 11, 2017
b9bc46c
Wire GitHub sync into middleware
bergie Apr 11, 2017
e59fbe5
Use first graph as main is none is assigned
bergie Apr 11, 2017
58c2d21
Don't let project title overflow, fixes #287
bergie Apr 11, 2017
51e70ff
Wait for component ready
bergie Apr 12, 2017
7fbc651
Adapt to new action payloads from router
bergie Apr 12, 2017
4e9ab89
Add safety for empty gists
bergie Apr 12, 2017
2336b74
Skip until runtime actions are clear
bergie Apr 12, 2017
0ed58cc
Remove call to non-existing method
bergie Apr 12, 2017
92f7739
Use correct reducer
bergie Apr 12, 2017
f6ac4fe
Read correct array
bergie Apr 12, 2017
4ee9777
Open project after creation
bergie Apr 12, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/preview/components/*/
/spec/*.js
/spec/browser/*.js
/spec/utils/*.js
/spec/*.xml
/spec/tests.html
/dist/
Expand Down
16 changes: 13 additions & 3 deletions Gruntfile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ module.exports = ->
src: '*.coffee'
dest: 'spec'
ext: '.js'
spec_utils:
options:
bare: true
expand: true
cwd: 'spec/utils'
src: '*.coffee'
dest: 'spec/utils'
ext: '.js'
spec_browser:
options:
bare: true
Expand Down Expand Up @@ -348,11 +356,11 @@ module.exports = ->
max_line_length:
level: "ignore"
src: 'spec/*.coffee'
spec_browser:
spec_sub:
options:
max_line_length:
level: "ignore"
src: 'spec/browser/*.coffee'
src: 'spec/**/*.coffee'


inlinelint:
Expand Down Expand Up @@ -389,6 +397,7 @@ module.exports = ->
options:
scripts: [
"../browser/<%=pkg.name%>.js"
"./utils/middleware.js"
'../node_modules/sinon/pkg/sinon-server.js'
]
files:
Expand Down Expand Up @@ -495,8 +504,9 @@ module.exports = ->
]
@registerTask 'spec', [
'coffeelint:spec'
'coffeelint:spec_browser'
'coffeelint:spec_sub'
'coffee:spec'
'coffee:spec_utils'
'coffee:spec_browser'
'connect:server'
'watch'
Expand Down
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,51 @@ Once it is built and the server is running you can access the UI at `http://loca

In addition to this project, the other repository of interest is the [the-graph](https://github.com/the-grid/the-graph) graph editor widget used for editing flows.


### Architecture

On high level, the noflo-ui architecture follows [Redux](http://redux.js.org/) conventions adapted to NoFlo. Here is how the main data flow looks like:

```fbp
Store OUT -> IN Middleware # Store sends actions together with application state to middleware
Middleware NEW -> ACTION Store # Middleware can trigger new actions
Middleware PASS -> IN Reduce # Actions go from middleware to reducers
Reduce OUT -> STATE Store # Reducers produce a new state object that gets sent to store
Reduce OUT -> STATE View # State also goes to the view
View ACTION -> ACTION Store # View can trigger actions
```

The actual flow is more detailed. You can view and edit it in `graphs/main.fbp`.

**Note:** the priciples outlined below are the architecture we're aiming towards. We're refactoring parts of the system to fit this architecture as we modify them. All new functionality should be implemented following this architecture.

#### Store

The Store component keeps track of the latest application state. When it receives new actions, it sends the out to the middleware and reducer chain together with the latest application state.

#### Middleware

noflo-ui middleware are components or graphs that can interact with particular actions. Each action passes through the chain of middlewares, and each middleware has two options on dealing with an action:

1. Pass the action along without modifying it
2. Capture the action and trigger new action(s)

Middleware are where side effects related to the application state are handled. This can include talking to external web services, FBP runtime communications, and loading or saving data to the local IndexedDB. Middleware do receive the current application state and can read from it, but they only manipulate state by the way of creating new actions.

Some middleware can also act as [generators](http://bergie.iki.fi/blog/noflo-process-api/#generator-components), creating new actions based on external input.

The middleware approach is explained further in [this blog post](http://bergie.iki.fi/blog/redux-middleware-noflo/).

#### Reducers

The job of the reducers is to receive actions and make changes to application state. The reducers must in effect be pure functions, where the same input state and action combination always produces the same new state.

#### View

The application's view layer is implemented as [Polymer](https://www.polymer-project.org/) elements. The application view receives the state object produced by the reducers.

User interactions in the application view must not make direct state changes. Instead, the application view can trigger new actions by firing Polymer events. These then get processed by the middleware and reducers, causing the state to change.

## Authentication and custom URLs

NoFlo UI is using GitHub for authentication. We have a default application configured to work at `http://localhost:9999`. If you want to serve your NoFlo UI from a different URL, you need to register your own [OAuth application](https://github.com/settings/applications/new) with them. Make sure to match GitHub's [redirect URL policy](https://developer.github.com/v3/oauth/#redirect-urls).
Expand Down
6 changes: 3 additions & 3 deletions components/BlobToEntry.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ handleGraph = (sha, content, entry, project, out) ->
graph.properties.changed = false
graph.properties.project = project.id

if entry.local
if entry.local and entry.local.startTransaction
entry.local.startTransaction sha
noflo.graph.mergeResolveTheirs entry.local, graph
entry.local.endTransaction sha
# Ensure the graph is marked as not changed since SHA
entry.local.properties.changed = false
out.send entry.local
out.send entry.local.toJSON()
return

graph.properties.name = entry.remote.name
Expand All @@ -31,7 +31,7 @@ handleGraph = (sha, content, entry, project, out) ->
graph.properties.environment = {} unless graph.properties.environment
graph.properties.environment.type = project.type unless graph.properties.environment.type
project.graphs.push graph
out.send graph
out.send graph.toJSON()

handleComponent = (sha, content, entry, project, out) ->
if entry.local
Expand Down
34 changes: 34 additions & 0 deletions components/CheckGistExists.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
noflo = require 'noflo'

exports.getComponent = ->
c = new noflo.Component
c.inPorts.add 'in',
datatype: 'object'
c.outPorts.add 'existing',
datatype: 'array'
c.outPorts.add 'new',
datatype: 'object'

noflo.helpers.WirePattern c,
out: ['existing', 'new']
async: true
, (data, groups, out, callback) ->
unless data.state?.projects?.local.length
# No local projects, pass
out.new.send data
do callback
return

existing = data.state.projects.local.filter (project) ->
project.gist is data.payload.gist
unless existing.length
out.new.send data
do callback
return

out.existing.send [
'project'
existing[0].id
existing[0].main
]
do callback
39 changes: 39 additions & 0 deletions components/CheckRepoExists.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
noflo = require 'noflo'

exports.getComponent = ->
c = new noflo.Component
c.inPorts.add 'in',
datatype: 'object'
c.outPorts.add 'existing',
datatype: 'array'
c.outPorts.add 'new',
datatype: 'object'

noflo.helpers.WirePattern c,
out: ['existing', 'new']
async: true
, (data, groups, out, callback) ->
unless data.state?.projects?.local.length
# No local projects, pass
out.new.send data
do callback
return

existing = data.state.projects.local.filter (project) ->
return false unless project.repo is data.payload.repo
if data.payload.branch is 'master' and not project.branch
# We didn't use to store branch info, assume master
return true
return project.branch is data.payload.branch
unless existing.length
out.new.send data
do callback
return

out.existing.send [
'project'
existing[0].id
existing[0].main
]
do callback

31 changes: 31 additions & 0 deletions components/ClearWorkspace.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
noflo = require 'noflo'

clearList = (list) ->
list.splice 0, list.length
clearWorkspace = (workspace) ->
workspace.project = null
workspace.graph = null
workspace.component = null
workspace.runtime.selected = null
clearList workspace.runtime.compatible
clearList workspace.graphs
clearList workspace.library
workspace.search.query = null
clearList workspace.search.components
clearList workspace.search.nodes
clearList workspace.selection.edges
clearList workspace.selection.nodes

exports.getComponent = ->
c = new noflo.Component
c.inPorts.add 'in',
datatype: 'object'
c.outPorts.add 'out',
datatype: 'object'

noflo.helpers.WirePattern c,
async: true
, (data, groups, out, callback) ->
clearWorkspace data.state.workspace
out.send data.state
do callback
125 changes: 0 additions & 125 deletions components/ContextToRuntime.coffee

This file was deleted.

Loading