mindmap 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +49 -45
- data/example/nodes/directory_node.html.erb +13 -0
- data/example/nodes/directory_node.rb +2 -8
- data/example/nodes/file_node.html.erb +9 -0
- data/example/nodes/file_node.rb +2 -4
- data/example/nodes/root_node.rb +7 -3
- data/lib/mindmap.rb +25 -7
- data/lib/mindmap/application.rb +8 -17
- data/lib/mindmap/cli.rb +2 -0
- data/lib/mindmap/config.rb +26 -0
- data/lib/mindmap/node.rb +11 -6
- data/lib/mindmap/renderer.rb +34 -24
- data/lib/mindmap/request.rb +52 -0
- data/lib/mindmap/version.rb +3 -1
- data/mindmap.gemspec +7 -3
- data/public/assets/{index.js → endless_scroll.js} +45 -31
- data/public/{index.html → endless_scroll.html} +2 -1
- metadata +10 -8
- data/example/views/.gitkeep +0 -0
- data/views/tag.html.erb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f9a87d885abe2676d51729bab2736a048eb05d8d6e263206438f559290a7544
|
4
|
+
data.tar.gz: f1ae3a3becb5c9427f6dbd6c73ecc52bf7f6e591f87896f1ca009a6b0a9a3081
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2320b9755f841d51c777981f73c0ed7abc67359341a95f7ea23759d151c912dcfaeeb59c881671f2d6961c05ae3940d7e9108e41b3f978994ed7b415145ac7c5
|
7
|
+
data.tar.gz: a357c59789fd329e2f299083fe8f31e86e9e10ddca9700223d7c2cf8d5fd34dbc08d99841690777cad986ca78782313ee2c45fba2311d998048753c6a2589e29
|
data/README.md
CHANGED
@@ -1,19 +1,26 @@
|
|
1
|
-
# Mindmap
|
1
|
+
# Mindmap (Work In Progress)
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/mindmap)
|
2
4
|
|
3
5
|
Mindmap is a tiny framework to render and browser a graph like structure,
|
4
6
|
assuming you have set of simple classes that are related to each other.
|
5
7
|
|
6
|
-
|
8
|
+
The following is the example project to browse file system, generated when issuing
|
9
|
+
"mindmap new" command, and contains 2 nodes (File, Directory)
|
10
|
+
|
11
|
+
[](https://imgur.com/a/tA7iCtp)
|
12
|
+
|
13
|
+
# Rationale
|
7
14
|
|
8
15
|
It started with another project I'm working on called
|
9
|
-
[rubrowser](https://github.com/emad-elsaid/rubrowser) it statically
|
16
|
+
[rubrowser](https://github.com/emad-elsaid/rubrowser) it statically analyze your
|
10
17
|
ruby code and visualize it in a graph, I thought that this kind of data
|
11
18
|
(tree/graph like) is everywhere, like my servers, that I can see files,
|
12
19
|
processes and other open sockets on it, through it I can open another server in
|
13
20
|
my network, browse through it, open a process there...and so on.
|
14
21
|
|
15
|
-
Or Imagine how many times you went to
|
16
|
-
and you can't remember what
|
22
|
+
Or Imagine how many times you went to Wikipedia and you found yourself on a page
|
23
|
+
and you can't remember what made you land here after couple hours of reading.
|
17
24
|
|
18
25
|
so I wanted a setup that does the following:
|
19
26
|
|
@@ -23,12 +30,12 @@ so I wanted a setup that does the following:
|
|
23
30
|
get back and take another path
|
24
31
|
* it should be as simple as possible to generate new graph project and put my
|
25
32
|
files in it.
|
26
|
-
* I wanted to have ready made
|
27
|
-
my own
|
33
|
+
* I wanted to have ready made layouts, and the ability to override them and define
|
34
|
+
my own layouts.
|
28
35
|
|
29
36
|
At first I thought of D3 and visualizing these nodes and make it interactive,
|
30
37
|
but I had to discard this idea as visualizing nodes in different forms will be
|
31
|
-
|
38
|
+
extremely hard for users, not to mention the graph will be very crowded.
|
32
39
|
|
33
40
|
So I settled on a page that renders the root node children first, then when you
|
34
41
|
try to open a node, I append children to the page and the path goes on
|
@@ -57,8 +64,7 @@ example/
|
|
57
64
|
│ ├── directory_node.rb
|
58
65
|
│ ├── file_node.rb
|
59
66
|
│ └── root_node.rb
|
60
|
-
|
61
|
-
└── views
|
67
|
+
└── public
|
62
68
|
|
63
69
|
3 directories, 5 files
|
64
70
|
```
|
@@ -71,22 +77,25 @@ the project contains an example nodes to browse the file system content, you can
|
|
71
77
|
start the server and open `http://localhost:9292` in your browser to see it in
|
72
78
|
action.
|
73
79
|
|
80
|
+
a tutorial could be found in the wiki [here](https://github.com/emad-elsaid/mindmap/wiki/Mindmap-tutorial-(file-system-browser))
|
81
|
+
|
74
82
|
## Project structure
|
75
83
|
|
76
84
|
* config.ru : a rack config file that starts mindmap application and serves
|
77
85
|
files from the public directory in both the gem and your project, with your
|
78
86
|
project public directory having precedence, so any file you put there will
|
79
87
|
override the library file.
|
80
|
-
* Gemfile : the project has only one direct
|
88
|
+
* Gemfile : the project has only one direct dependency `mindmap`
|
81
89
|
* nodes : a directory that has your classes that needs to be visualized, by
|
82
|
-
default it contains classes that visualize the file system
|
90
|
+
default it contains classes that visualize the file system, it also holds the
|
91
|
+
views for these classes in `class_name.html.erb` format or other formats
|
92
|
+
wanted like `class_name.json.erb` or similar
|
83
93
|
* public : the public directory, you can serve any files from there
|
84
|
-
|
85
|
-
library views then you don't need that directory
|
94
|
+
css framework in your views as they're loaded by default.
|
86
95
|
|
87
96
|
## How to write your Nodes
|
88
97
|
|
89
|
-
the `
|
98
|
+
the `nodes` directory holds your nodes, they're all loaded by default when
|
90
99
|
starting the mindmap server, the following is a commented example for a node class
|
91
100
|
|
92
101
|
```ruby
|
@@ -106,12 +115,6 @@ class DirectoryNode
|
|
106
115
|
File.basename(path)
|
107
116
|
end
|
108
117
|
|
109
|
-
# children_title is the title that will be displayed on this
|
110
|
-
# node children container when opened
|
111
|
-
def children_title
|
112
|
-
path
|
113
|
-
end
|
114
|
-
|
115
118
|
# it must return an array of other nodes that this node is related to
|
116
119
|
def children
|
117
120
|
Dir
|
@@ -121,15 +124,6 @@ class DirectoryNode
|
|
121
124
|
.map { |file| child(File.expand_path(file, path)) }
|
122
125
|
end
|
123
126
|
|
124
|
-
# returns the view ERB file name to render this node
|
125
|
-
# if you didn't define this method the default value will be
|
126
|
-
# the class name underscored, so a DirectoryNode class
|
127
|
-
# will be rendered using `directory_node.html.erb` template
|
128
|
-
# here we use a library view called tag
|
129
|
-
def view
|
130
|
-
:tag
|
131
|
-
end
|
132
|
-
|
133
127
|
private
|
134
128
|
|
135
129
|
def child(file_path)
|
@@ -140,7 +134,7 @@ class DirectoryNode
|
|
140
134
|
end
|
141
135
|
```
|
142
136
|
|
143
|
-
|
137
|
+
## How it works?
|
144
138
|
|
145
139
|
when you start the mindmap server, it loads all library code then loads the
|
146
140
|
project nodes, it serves files from library public and project public
|
@@ -152,14 +146,14 @@ an empty page that load jquery and bulma css framework and
|
|
152
146
|
|
153
147
|
`index.js` is what does the interaction part of the page, it request the `root`
|
154
148
|
node, so your `nodes` directory must contain that class, mindmap will handle the
|
155
|
-
request, creating `RootNode` object
|
149
|
+
request, creating `RootNode` object giving it all `parameters` sent with the
|
156
150
|
request as a hash, `Mindmap::Node#initializer` will assign any key value to the
|
157
151
|
object if the `key=` method is public, then mindmap will call the node children.
|
158
152
|
|
159
153
|
for every child we'll render it and return the result to the page, the page will
|
160
154
|
append the response, then wait until you click on any link that refer to a local
|
161
|
-
page,
|
162
|
-
|
155
|
+
page, when you do it'll handle the request, will request the link content with
|
156
|
+
Ajax sending the `data-params` of the link as parameters to the Ajax POST
|
163
157
|
request.
|
164
158
|
|
165
159
|
mindmap will know the node from the page, for example requesting `/file` will
|
@@ -167,37 +161,47 @@ signal mindmap to create a `FileNode` object with the passed arguments,
|
|
167
161
|
`/directory/specific_dir` will create a `Directory::SpecificDir` object...etc
|
168
162
|
|
169
163
|
|
170
|
-
|
164
|
+
## How rendering nodes works
|
171
165
|
|
172
166
|
the renderer will get the view name by calling `view` method, then search for a
|
173
|
-
file
|
167
|
+
file in the project nodes directory, when
|
174
168
|
found it'll be rendered as an ERB template with the node as a bounding context,
|
175
169
|
so any method called in the view will be executed from the node.
|
176
170
|
|
177
|
-
|
171
|
+
## How to form links in your views
|
178
172
|
|
179
|
-
any link that points to a URL that starts with '/' is
|
180
|
-
and mindmap
|
173
|
+
any link that points to a URL that starts with '/' is considered an AJAX link
|
174
|
+
and mindmap JavaScript will call the URL with a post request passing the
|
181
175
|
`data-params` attribute as parameters in the request, so it's a good idea that
|
182
176
|
you set some hash there that when gets assigned to the object it'll tell him
|
183
177
|
what to do, an ID in most cases, or for our example nodes the file path, for
|
184
178
|
others maybe UUID, by default the views will serialize the object as JSON and
|
185
179
|
put it in the attribute, you can be selective with your views implementation if
|
186
|
-
you wish, also `data-children-title` attribute is used by the mindmap
|
180
|
+
you wish, also `data-children-title` attribute is used by the mindmap JavaScript
|
187
181
|
to use it as a title for the response when appended to the page, it's a good
|
188
182
|
idea to print the node `children_title` in it.
|
189
183
|
|
190
|
-
|
191
|
-
how it works.
|
192
|
-
|
193
|
-
# Root Node
|
184
|
+
## Root Node
|
194
185
|
|
195
186
|
every graph must have an entry point, `RootNode` is our entry point, this nodes
|
196
187
|
doesn't have to have any views, an object is created from that class when the
|
197
188
|
page loads, and the children will be called an rendered, so the node itself
|
198
|
-
doesn't have to do anything but
|
189
|
+
doesn't have to do anything but implementing `children` method returning an array
|
199
190
|
of nodes to start with.
|
200
191
|
|
192
|
+
## Hot code reload
|
193
|
+
|
194
|
+
Mindmap doesn't have a hot reload feature, so if you want to change your code
|
195
|
+
then see the changes without restarting your server manually you can use
|
196
|
+
[reflex](https://github.com/cespare/reflex) or any other tool that executes a
|
197
|
+
command on files change, with reflex you can use this command
|
198
|
+
|
199
|
+
$ reflex -s rackup
|
200
|
+
|
201
|
+
or
|
202
|
+
|
203
|
+
$ reflex -s mindmap server
|
204
|
+
|
201
205
|
## Contributing
|
202
206
|
|
203
207
|
Bug reports and pull requests are welcome on GitHub at https://github.com/emad-elsaid/mindmap.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="content is-inline-block">
|
2
|
+
<div class="tags has-addons">
|
3
|
+
|
4
|
+
<span class="tag is-dark is-medium">
|
5
|
+
<%= name %>
|
6
|
+
</span>
|
7
|
+
|
8
|
+
<a href="<%= url %>" class="tag is-link is-medium" data-params="<%= html_escape(to_json) %>" data-children-title="<%= name %>">
|
9
|
+
<i class="fas fa-folder"></i>
|
10
|
+
</a>
|
11
|
+
|
12
|
+
</div>
|
13
|
+
</div>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class DirectoryNode
|
2
4
|
include Mindmap::Node
|
3
5
|
|
@@ -7,10 +9,6 @@ class DirectoryNode
|
|
7
9
|
File.basename(path)
|
8
10
|
end
|
9
11
|
|
10
|
-
def children_title
|
11
|
-
path
|
12
|
-
end
|
13
|
-
|
14
12
|
def children
|
15
13
|
Dir
|
16
14
|
.entries(path)
|
@@ -19,10 +17,6 @@ class DirectoryNode
|
|
19
17
|
.map { |file| child(File.expand_path(file, path)) }
|
20
18
|
end
|
21
19
|
|
22
|
-
def view
|
23
|
-
:tag
|
24
|
-
end
|
25
|
-
|
26
20
|
private
|
27
21
|
|
28
22
|
def child(file_path)
|
data/example/nodes/file_node.rb
CHANGED
data/example/nodes/root_node.rb
CHANGED
data/lib/mindmap.rb
CHANGED
@@ -1,20 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/all'
|
4
|
+
require 'rack'
|
2
5
|
|
3
6
|
Dir[File.expand_path('./mindmap/**/*.rb', __dir__)].each { |fl| require fl }
|
4
7
|
Dir[File.expand_path('./nodes/**/*.rb', Dir.pwd)].each { |fl| require fl }
|
5
8
|
|
6
9
|
module Mindmap
|
7
|
-
def self.application
|
10
|
+
def self.application(config = {})
|
8
11
|
apps = []
|
9
12
|
|
10
|
-
|
11
|
-
apps.unshift
|
12
|
-
|
13
|
+
app_config = Config.new(config)
|
14
|
+
apps.unshift Application.new(app_config)
|
15
|
+
lib_public = File.expand_path('../public', __dir__)
|
16
|
+
apps.unshift(
|
17
|
+
Rack::Static.new(
|
18
|
+
apps.first,
|
19
|
+
urls: [''],
|
20
|
+
root: lib_public,
|
21
|
+
index: app_config.index
|
22
|
+
)
|
23
|
+
)
|
13
24
|
|
14
|
-
|
25
|
+
local_public = File.expand_path('./public', Dir.pwd)
|
15
26
|
|
16
|
-
if File.exist?(
|
17
|
-
apps.unshift
|
27
|
+
if File.exist?(local_public)
|
28
|
+
apps.unshift(
|
29
|
+
Rack::Static.new(
|
30
|
+
apps.first,
|
31
|
+
urls: [''],
|
32
|
+
root: local_public,
|
33
|
+
index: app_config.index
|
34
|
+
)
|
35
|
+
)
|
18
36
|
end
|
19
37
|
|
20
38
|
Rack::Cascade.new(apps)
|
data/lib/mindmap/application.rb
CHANGED
@@ -1,28 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
|
3
5
|
module Mindmap
|
4
6
|
class Application
|
5
|
-
def
|
6
|
-
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
end
|
7
10
|
|
8
|
-
|
11
|
+
def call(env)
|
12
|
+
Request.new(env).response
|
9
13
|
end
|
10
14
|
|
11
15
|
private
|
12
16
|
|
13
|
-
|
14
|
-
node_name = request.path.camelize + 'Node'
|
15
|
-
node_klass = node_name.constantize
|
16
|
-
|
17
|
-
params = request.params.with_indifferent_access
|
18
|
-
node = node_klass.new(params)
|
19
|
-
node.children.map(&:render).join
|
20
|
-
end
|
21
|
-
|
22
|
-
def headers
|
23
|
-
{
|
24
|
-
'Content-Type' => 'text/html;charset=utf-8'
|
25
|
-
}
|
26
|
-
end
|
17
|
+
attr_accessor :config
|
27
18
|
end
|
28
19
|
end
|
data/lib/mindmap/cli.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mindmap
|
4
|
+
# hold the configuration for an application
|
5
|
+
class Config
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def index
|
11
|
+
layouts.first
|
12
|
+
end
|
13
|
+
|
14
|
+
def layouts
|
15
|
+
config.fetch(:layouts, default_layouts)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_accessor :config
|
21
|
+
|
22
|
+
def default_layouts
|
23
|
+
['endless_scroll.html']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/mindmap/node.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erb'
|
2
4
|
|
3
5
|
module Mindmap
|
4
|
-
# a module that must be
|
6
|
+
# a module that must be included to any graph node
|
5
7
|
# it has methods needed by the framework to render the node
|
6
8
|
module Node
|
7
9
|
include ERB::Util
|
@@ -10,25 +12,28 @@ module Mindmap
|
|
10
12
|
assign_params(params)
|
11
13
|
end
|
12
14
|
|
13
|
-
# assign a hash values to
|
15
|
+
# assign a hash values to attributes with the same name
|
14
16
|
def assign_params(params)
|
15
17
|
params.each do |key, value|
|
16
|
-
|
18
|
+
if self.class.public_method_defined?("#{key}=")
|
19
|
+
public_send("#{key}=", value)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
24
|
# renders the node ERB view file and returns the result
|
21
|
-
def render
|
22
|
-
Renderer.render(view, binding)
|
25
|
+
def render(format = :html)
|
26
|
+
Renderer.render("#{view}.#{format}", binding)
|
23
27
|
end
|
24
28
|
|
25
|
-
# The path to the view file relative to the "
|
29
|
+
# The path to the view file relative to the "nodes" directory
|
26
30
|
# by default the file is the class name underscored e.g
|
27
31
|
# if node class is `Graph::NodeName` it returns `graph/node_name`
|
28
32
|
def view
|
29
33
|
self.class.name.underscore
|
30
34
|
end
|
31
35
|
|
36
|
+
# returns the node url that could be used for a link
|
32
37
|
def url
|
33
38
|
'/' + self.class.name.underscore.gsub('_node', '')
|
34
39
|
end
|
data/lib/mindmap/renderer.rb
CHANGED
@@ -1,33 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erb'
|
2
4
|
|
3
5
|
module Mindmap
|
4
6
|
# Renders a view file from either the library views
|
5
7
|
# or the project views with a binding
|
6
8
|
class Renderer
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
9
|
+
def self.render(view, binding)
|
10
|
+
renderer_instance(view).render(binding)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.renderer_instance(view)
|
14
|
+
@renderers ||= {}
|
15
|
+
@renderers[view] ||= new(view)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(view)
|
19
|
+
@view = view
|
20
|
+
end
|
21
|
+
|
22
|
+
def render(binding)
|
23
|
+
erb.result(binding)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :view
|
29
|
+
|
30
|
+
def erb
|
31
|
+
@erb ||= ERB.new(view_content)
|
32
|
+
end
|
33
|
+
|
34
|
+
def view_content
|
35
|
+
raise(StandardError, "#{view} not found") unless File.exist?(view_path)
|
36
|
+
File.read(view_path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def view_path
|
40
|
+
@view_path ||= File.expand_path("./nodes/#{view}.erb", Dir.pwd)
|
31
41
|
end
|
32
42
|
end
|
33
43
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mindmap
|
4
|
+
class Request < Rack::Request
|
5
|
+
def response
|
6
|
+
[200, response_headers, response_body]
|
7
|
+
end
|
8
|
+
|
9
|
+
def params
|
10
|
+
super.with_indifferent_access
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def response_body
|
16
|
+
[node_children.map { |child| child.render(response_type) }.join]
|
17
|
+
end
|
18
|
+
|
19
|
+
def response_headers
|
20
|
+
{
|
21
|
+
'Content-Type' => "#{response_format};charset=utf-8"
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def response_type
|
26
|
+
case response_format
|
27
|
+
when 'text/html'
|
28
|
+
:html
|
29
|
+
when 'image/svg+xml'
|
30
|
+
:svg
|
31
|
+
else
|
32
|
+
:html
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def response_format
|
37
|
+
get_header('HTTP_ACCEPT') || 'text/html'
|
38
|
+
end
|
39
|
+
|
40
|
+
def node_children
|
41
|
+
@node_children ||= node.children
|
42
|
+
end
|
43
|
+
|
44
|
+
def node
|
45
|
+
@node ||= node_klass.new(params)
|
46
|
+
end
|
47
|
+
|
48
|
+
def node_klass
|
49
|
+
(path.camelize + 'Node').constantize
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/mindmap/version.rb
CHANGED
data/mindmap.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
lib = File.expand_path('
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
require 'mindmap/version'
|
4
4
|
|
@@ -8,8 +8,12 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['Emad Elsaid']
|
9
9
|
spec.email = ['emad.elsaid@blacklane.com']
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
|
11
|
+
spec.summary = <<-SUMMARY
|
12
|
+
A very specific and opinionated web framework to traverse a graph data structure
|
13
|
+
SUMMARY
|
14
|
+
spec.description = <<-DESC
|
15
|
+
A very specific and opinionated web framework to traverse a graph data structure
|
16
|
+
DESC
|
13
17
|
spec.homepage = 'https://github.com/emad-elsaid/mindmap'
|
14
18
|
spec.license = 'MIT'
|
15
19
|
|
@@ -1,25 +1,48 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
$.ajax({
|
2
|
+
type: "POST",
|
3
|
+
url: '/root',
|
4
|
+
headers: {
|
5
|
+
Accept: 'text/html'
|
6
|
+
},
|
7
|
+
success: function (data, text) {
|
8
|
+
$('#content').html(childrenContainer(null, data));
|
9
|
+
},
|
10
|
+
error: function (request, status, error) {
|
11
|
+
$('#content').html(childrenContainer(null, request.responseText));
|
6
12
|
}
|
13
|
+
});
|
7
14
|
|
8
|
-
|
15
|
+
$(document).on('click', 'a[href^="/"]', function(evt){
|
16
|
+
evt.preventDefault()
|
9
17
|
|
10
|
-
var
|
18
|
+
var element = $(this),
|
19
|
+
params = element.data('params'),
|
20
|
+
href = element.attr('href')
|
11
21
|
|
12
|
-
|
13
|
-
|
22
|
+
$.ajax({
|
23
|
+
type: "POST",
|
24
|
+
url: href,
|
25
|
+
data: params,
|
26
|
+
headers: {
|
27
|
+
Accept: 'text/html'
|
28
|
+
},
|
29
|
+
success: function (data, text) {
|
30
|
+
insertChildren(data, element)
|
31
|
+
},
|
32
|
+
error: function (request, status, error) {
|
33
|
+
insertChildren(request.responseText, element)
|
34
|
+
}
|
35
|
+
});
|
36
|
+
})
|
14
37
|
|
15
38
|
const insertChildren = function (content, element){
|
16
|
-
var parentContainer =
|
39
|
+
var parentContainer = element.parents(".children")
|
17
40
|
|
18
41
|
parentContainer
|
19
42
|
.nextAll()
|
20
43
|
.remove()
|
21
44
|
|
22
|
-
var title =
|
45
|
+
var title = element.data('children-title'),
|
23
46
|
children = childrenContainer(title, content)
|
24
47
|
|
25
48
|
children.insertAfter(parentContainer)
|
@@ -29,25 +52,16 @@ const insertChildren = function (content, element){
|
|
29
52
|
}, 500);
|
30
53
|
}
|
31
54
|
|
32
|
-
|
33
|
-
$('
|
34
|
-
})
|
55
|
+
const childrenContainer = function (title, content){
|
56
|
+
var contents = $('<div class="message is-info">')
|
35
57
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
evt.preventDefault()
|
40
|
-
evt.stopPropagation()
|
58
|
+
if( title ){
|
59
|
+
contents.append('<div class="message-header">'+ title +'</div>')
|
60
|
+
}
|
41
61
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
},
|
49
|
-
error: function (request, status, error) {
|
50
|
-
insertChildren(request.responseText, element)
|
51
|
-
}
|
52
|
-
});
|
53
|
-
})
|
62
|
+
contents.append('<div class="message-body">' + content + '</div>')
|
63
|
+
|
64
|
+
var children = $("<div>", {class: "children"}).html(contents)
|
65
|
+
|
66
|
+
return children
|
67
|
+
}
|
@@ -5,9 +5,10 @@
|
|
5
5
|
<title></title>
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
7
7
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
8
|
+
|
8
9
|
<script defer src="https://use.fontawesome.com/releases/v5.0.7/js/all.js"></script>
|
9
10
|
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
10
|
-
<script type="application/javascript" src="/assets/
|
11
|
+
<script type="application/javascript" src="/assets/endless_scroll.js"></script>
|
11
12
|
|
12
13
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.0/css/bulma.css" rel="stylesheet"/>
|
13
14
|
</head>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mindmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emad Elsaid
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,8 +80,8 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '10.0'
|
83
|
-
description: A very specific and opinionated web framework to traverse a graph
|
84
|
-
structure
|
83
|
+
description: " A very specific and opinionated web framework to traverse a graph
|
84
|
+
data structure\n"
|
85
85
|
email:
|
86
86
|
- emad.elsaid@blacklane.com
|
87
87
|
executables:
|
@@ -99,23 +99,25 @@ files:
|
|
99
99
|
- bin/setup
|
100
100
|
- example/Gemfile
|
101
101
|
- example/config.ru
|
102
|
+
- example/nodes/directory_node.html.erb
|
102
103
|
- example/nodes/directory_node.rb
|
104
|
+
- example/nodes/file_node.html.erb
|
103
105
|
- example/nodes/file_node.rb
|
104
106
|
- example/nodes/root_node.rb
|
105
107
|
- example/public/.gitkeep
|
106
|
-
- example/views/.gitkeep
|
107
108
|
- exe/mindmap
|
108
109
|
- lib/mindmap.rb
|
109
110
|
- lib/mindmap/application.rb
|
110
111
|
- lib/mindmap/cli.rb
|
112
|
+
- lib/mindmap/config.rb
|
111
113
|
- lib/mindmap/node.rb
|
112
114
|
- lib/mindmap/renderer.rb
|
115
|
+
- lib/mindmap/request.rb
|
113
116
|
- lib/mindmap/version.rb
|
114
117
|
- mindmap.gemspec
|
115
|
-
- public/assets/
|
118
|
+
- public/assets/endless_scroll.js
|
119
|
+
- public/endless_scroll.html
|
116
120
|
- public/favicon.ico
|
117
|
-
- public/index.html
|
118
|
-
- views/tag.html.erb
|
119
121
|
homepage: https://github.com/emad-elsaid/mindmap
|
120
122
|
licenses:
|
121
123
|
- MIT
|
data/example/views/.gitkeep
DELETED
File without changes
|
data/views/tag.html.erb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
<div class="content is-inline-block">
|
2
|
-
<div class="tags has-addons">
|
3
|
-
|
4
|
-
<span class="tag is-dark is-medium">
|
5
|
-
<%= name %>
|
6
|
-
</span>
|
7
|
-
|
8
|
-
<% if respond_to?(:children) %>
|
9
|
-
<a href="<%= url %>" class="tag is-link is-medium" data-params="<%= html_escape(to_json) %>" data-children-title="<%= children_title %>">
|
10
|
-
<i class="fas fa-folder"></i>
|
11
|
-
</a>
|
12
|
-
<% end %>
|
13
|
-
|
14
|
-
</div>
|
15
|
-
</div>
|