basemate-ui-core 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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +495 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/basemate_ui_core_manifest.js +2 -0
  6. data/app/assets/javascripts/basemate/ui/core/application.js +15 -0
  7. data/app/assets/stylesheets/basemate/ui/core/application.css +15 -0
  8. data/app/concepts/app/cell/app.rb +75 -0
  9. data/app/concepts/app/js/app.js +27 -0
  10. data/app/concepts/app/js/store.js +66 -0
  11. data/app/concepts/app/utils/app_node.rb +53 -0
  12. data/app/concepts/app/view/app.haml +4 -0
  13. data/app/concepts/component/cell/dynamic.rb +110 -0
  14. data/app/concepts/component/cell/static.rb +14 -0
  15. data/app/concepts/component/js/component.js +38 -0
  16. data/app/concepts/component/view/children.haml +2 -0
  17. data/app/concepts/component/view/dynamic.haml +6 -0
  18. data/app/concepts/component/view/static.haml +1 -0
  19. data/app/concepts/core/js/core.js +20 -0
  20. data/app/concepts/div/cell/div.rb +5 -0
  21. data/app/concepts/div/view/div.haml +3 -0
  22. data/app/concepts/header/cell/header.rb +5 -0
  23. data/app/concepts/header/view/header.haml +3 -0
  24. data/app/concepts/heading/cell/heading.rb +5 -0
  25. data/app/concepts/heading/view/heading.haml +50 -0
  26. data/app/concepts/html/cell/html.rb +17 -0
  27. data/app/concepts/html/js/html.js +10 -0
  28. data/app/concepts/html/view/html.haml +3 -0
  29. data/app/concepts/img/cell/img.rb +5 -0
  30. data/app/concepts/img/view/img.haml +1 -0
  31. data/app/concepts/link/cell/link.rb +14 -0
  32. data/app/concepts/link/view/link.haml +6 -0
  33. data/app/concepts/main/cell/main.rb +5 -0
  34. data/app/concepts/main/view/main.haml +3 -0
  35. data/app/concepts/nav/cell/nav.rb +5 -0
  36. data/app/concepts/nav/view/nav.haml +3 -0
  37. data/app/concepts/navigation/cell/button.rb +5 -0
  38. data/app/concepts/navigation/view/button.haml +3 -0
  39. data/app/concepts/page/cell/content.rb +5 -0
  40. data/app/concepts/page/cell/page.rb +110 -0
  41. data/app/concepts/page/utils/page_node.rb +51 -0
  42. data/app/concepts/page/view/content.haml +7 -0
  43. data/app/concepts/page/view/page.haml +3 -0
  44. data/app/concepts/partial/cell/partial.rb +5 -0
  45. data/app/concepts/partial/view/partial.haml +3 -0
  46. data/app/concepts/plain/cell/plain.rb +10 -0
  47. data/app/concepts/section/cell/section.rb +5 -0
  48. data/app/concepts/section/view/section.haml +3 -0
  49. data/app/concepts/shared/utils/to_cell.rb +27 -0
  50. data/app/concepts/span/cell/span.rb +5 -0
  51. data/app/concepts/span/view/span.haml +3 -0
  52. data/app/concepts/transition/cell/transition.rb +18 -0
  53. data/app/concepts/transition/js/transition.js +26 -0
  54. data/app/concepts/transition/view/transition.haml +6 -0
  55. data/app/controllers/basemate/ui/core/application_controller.rb +9 -0
  56. data/app/helpers/basemate/ui/core/application_helper.rb +35 -0
  57. data/config/routes.rb +2 -0
  58. data/lib/basemate/ui/core.rb +14 -0
  59. data/lib/basemate/ui/core/engine.rb +19 -0
  60. data/lib/basemate/ui/core/version.rb +7 -0
  61. data/lib/tasks/basemate/ui/core_tasks.rake +4 -0
  62. metadata +190 -0
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Basemate::Ui::Core'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/basemate/ui/core .js
2
+ //= link_directory ../stylesheets/basemate/ui/core .css
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,75 @@
1
+ module App::Cell
2
+ class App < Trailblazer::Cell
3
+ include ActionView::Helpers::ActiveModelHelper
4
+ include ActionView::Helpers::ActiveModelInstanceTag
5
+ include ActionView::Helpers::AssetTagHelper
6
+ include ActionView::Helpers::AssetUrlHelper
7
+ include ActionView::Helpers::AtomFeedHelper
8
+ include ActionView::Helpers::CacheHelper
9
+ include ActionView::Helpers::CaptureHelper
10
+ include ActionView::Helpers::CspHelper
11
+ include ActionView::Helpers::CsrfHelper
12
+ include ActionView::Helpers::DateHelper
13
+ include ActionView::Helpers::DebugHelper
14
+ include ActionView::Helpers::FormHelper
15
+ include ActionView::Helpers::FormOptionsHelper
16
+ include ActionView::Helpers::FormTagHelper
17
+ include ActionView::Helpers::JavaScriptHelper
18
+ include ActionView::Helpers::NumberHelper
19
+ include ActionView::Helpers::OutputSafetyHelper
20
+ include ActionView::Helpers::RecordTagHelper
21
+ # include ActionView::Helpers::RenderingHelper
22
+ include ActionView::Helpers::SanitizeHelper
23
+ include ActionView::Helpers::TagHelper
24
+ include ActionView::Helpers::TextHelper
25
+ include ActionView::Helpers::TranslationHelper
26
+ include ActionView::Helpers::UrlHelper
27
+ include ::Cell::Haml
28
+ include ::Basemate::Ui::Core::ApplicationHelper
29
+ include Shared::Utils::ToCell
30
+ # include ::Rails.application.routes.url_helpers
31
+
32
+ view_paths << "#{Basemate::Ui::Core::Engine.root}/app/concepts"
33
+
34
+ def initialize(model=nil, options={})
35
+ super
36
+ @nodes = {}
37
+ @cells = {}
38
+ @page_block = nil
39
+ setup
40
+ end
41
+
42
+ def setup
43
+ true
44
+ end
45
+
46
+ def prepare
47
+ true
48
+ end
49
+
50
+
51
+ def show(page_nodes, &block)
52
+ @page_nodes = page_nodes
53
+ prepare
54
+ response
55
+ render(view: :app, &block)
56
+ end
57
+
58
+ def page_nodes
59
+ @page_nodes
60
+ end
61
+
62
+ def components(&block)
63
+ @nodes = ::App::Utils::AppNode.build(self, &block)
64
+
65
+ @nodes.each do |key, node|
66
+ @cells[key] = to_cell(key, node["component_name"], node["config"], node["argument"], node["components"])
67
+ end
68
+ end
69
+
70
+ def partial(&block)
71
+ ::App::Utils::AppNode.build(self, &block)
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ import Vue from 'vue/dist/vue.esm'
2
+ import axios from 'axios'
3
+ import VRuntimeTemplate from "v-runtime-template"
4
+ import Vuex from 'vuex'
5
+
6
+ const componentDef = {
7
+ props: ['appConfig', 'params'],
8
+ data: function(){
9
+ return {}
10
+ },
11
+ computed: Vuex.mapState({
12
+ asyncTemplate: state => state.pageTemplate,
13
+ }),
14
+ mounted: function(){
15
+ const self = this;
16
+ window.onpopstate = function(event) {
17
+ self.$store.dispatch("navigateTo", {url: document.location.pathname, backwards: true} );
18
+ }
19
+ },
20
+ components: {
21
+ VRuntimeTemplate: VRuntimeTemplate
22
+ }
23
+ }
24
+
25
+ let component = Vue.component('app', componentDef)
26
+
27
+ export default componentDef
@@ -0,0 +1,66 @@
1
+ import Vue from 'vue/dist/vue.esm'
2
+ import Vuex from 'vuex'
3
+ import axios from 'axios'
4
+
5
+ Vue.use(Vuex)
6
+
7
+ const store = new Vuex.Store({
8
+ state: {
9
+ pageTemplate: null,
10
+ currentPath: document.location.pathname
11
+ },
12
+ mutations: {
13
+ setPageTemplate (state, serverResponse){
14
+ state.pageTemplate = serverResponse
15
+ },
16
+ setCurrentPath (state, path){
17
+ state.currentPath = path
18
+ }
19
+ },
20
+ actions: {
21
+ navigateTo ({ commit, state }, { url, backwards }) {
22
+ if (typeof basemateUiCoreTransitionStart !== 'undefined') {
23
+ basemateUiCoreTransitionStart(url);
24
+ }
25
+ if (!window.history.pushState) {
26
+ document.location.href = url;
27
+ return;
28
+ }
29
+ return new Promise((resolve, reject) => {
30
+ axios({
31
+ method: "get",
32
+ url: url,
33
+ headers: {
34
+ 'X-CSRF-Token': document.getElementsByName("csrf-token")[0].getAttribute('content')
35
+ },
36
+ params: {"only_page": true}
37
+ })
38
+ .then(function(response){
39
+ if (backwards){
40
+ window.history.replaceState({basemateApp: true, url: url}, null, url);
41
+ } else {
42
+ window.history.pushState({basemateApp: true, url: url}, null, url);
43
+ }
44
+ setTimeout(function () {
45
+ resolve(response["data"])
46
+ commit('setPageTemplate', response["data"])
47
+ commit('setCurrentPath', url)
48
+ if (typeof basemateUiCoreTransitionSuccess !== 'undefined') {
49
+ basemateUiCoreTransitionSuccess(url);
50
+ }
51
+ }, 300);
52
+ })
53
+ .catch(function(response){
54
+ setTimeout(function () {
55
+ resolve(response["data"])
56
+ if (typeof basemateUiCoreTransitionError !== 'undefined') {
57
+ basemateUiCoreTransitionError(url);
58
+ }
59
+ }, 300);
60
+ })
61
+ })
62
+ }
63
+ }
64
+ })
65
+
66
+ export default store
@@ -0,0 +1,53 @@
1
+ module App::Utils
2
+ class AppNode
3
+
4
+ def self.build(app_instance, &block)
5
+ node = AppNode.new(app_instance)
6
+ node.instance_eval(&block)
7
+ node.hash
8
+ end
9
+
10
+ attr_reader :hash
11
+
12
+ def initialize(app_instance)
13
+ @hash = {}
14
+ @node_start_id = 0
15
+ @app_instance = app_instance
16
+ app_instance.instance_variables.each do |app_instance_var_key|
17
+ self.instance_variable_set(app_instance_var_key, app_instance.instance_variable_get(app_instance_var_key))
18
+ end
19
+ end
20
+
21
+ def method_missing meth, *args, &block
22
+ begin
23
+ @app_instance.send(meth, *args, &block)
24
+ rescue
25
+ node_id = @node_start_id + 1
26
+ @node_start_id = node_id
27
+ current_node = "#{meth}_#{@node_start_id}"
28
+ @hash[current_node] = {}
29
+ @hash[current_node]["component_name"] = meth.to_s
30
+ @hash[current_node]["config"] = {}
31
+ @hash[current_node]["argument"] = nil
32
+
33
+ if meth == :page_content
34
+ @hash[current_node]["components"] = @app_instance.send(:page_nodes)
35
+ elsif meth == :partial
36
+ @hash[current_node]["components"] = @app_instance.send(args.first, *args.drop(1))
37
+ else
38
+ if args.first.is_a?(Hash)
39
+ @hash[current_node]["config"] = args.first
40
+ else
41
+ @hash[current_node]["argument"] = args.first
42
+ end
43
+
44
+ if block_given?
45
+ @hash[current_node]["components"] = AppNode.build(@app_instance, &block)
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,4 @@
1
+ %component{"is": "app", "inline-template": true}
2
+ %div
3
+ - @cells.each do |key, cell|
4
+ = cell.call(:show)
@@ -0,0 +1,110 @@
1
+ module Component::Cell
2
+ class Dynamic < Trailblazer::Cell
3
+ include ActionView::Helpers::ActiveModelHelper
4
+ include ActionView::Helpers::ActiveModelInstanceTag
5
+ include ActionView::Helpers::AssetTagHelper
6
+ include ActionView::Helpers::AssetUrlHelper
7
+ include ActionView::Helpers::AtomFeedHelper
8
+ include ActionView::Helpers::CacheHelper
9
+ include ActionView::Helpers::CaptureHelper
10
+ include ActionView::Helpers::CspHelper
11
+ include ActionView::Helpers::CsrfHelper
12
+ include ActionView::Helpers::DateHelper
13
+ include ActionView::Helpers::DebugHelper
14
+ include ActionView::Helpers::FormHelper
15
+ include ActionView::Helpers::FormOptionsHelper
16
+ include ActionView::Helpers::FormTagHelper
17
+ include ActionView::Helpers::JavaScriptHelper
18
+ include ActionView::Helpers::NumberHelper
19
+ include ActionView::Helpers::OutputSafetyHelper
20
+ include ActionView::Helpers::RecordTagHelper
21
+ # include ActionView::Helpers::RenderingHelper
22
+ include ActionView::Helpers::SanitizeHelper
23
+ include ActionView::Helpers::TagHelper
24
+ include ActionView::Helpers::TextHelper
25
+ include ActionView::Helpers::TranslationHelper
26
+ include ActionView::Helpers::UrlHelper
27
+ # include ActionView::Helpers::UrlHelper
28
+ # include ActionView::Helpers::TranslationHelper
29
+ include ::Cell::Haml
30
+ include ::Basemate::Ui::Core::ApplicationHelper
31
+ include Shared::Utils::ToCell
32
+
33
+ view_paths << "#{Basemate::Ui::Core::Engine.root}/app/concepts"
34
+ view_paths << "#{::Rails.root}/app/basemate"
35
+
36
+ def initialize(model=nil, options={})
37
+ super
38
+ @component_config = options.except(:context, :children, :url_params)
39
+ @url_params = options[:url_params].except(:action, :controller, :component_key)
40
+ @component_key = options[:component_key]
41
+ @children_cells = {}
42
+ @controller_context = context[:controller_context]
43
+ @argument = model
44
+ @static = false
45
+ generate_component_name
46
+ generate_children_cells
47
+ setup
48
+ end
49
+
50
+ def self.static
51
+ @static = true
52
+ end
53
+
54
+ def setup
55
+ true
56
+ end
57
+
58
+ def show(&block)
59
+ render(view: :dynamic, &block)
60
+ end
61
+
62
+ def render_children
63
+ render(view: :children)
64
+ end
65
+
66
+ def render_content(&block)
67
+ render do
68
+ render_children
69
+ end
70
+ end
71
+
72
+ def component_id
73
+ options[:id] ||= @component_key
74
+ end
75
+
76
+ def js_action name, arguments
77
+ argumentString = arguments.join('", "')
78
+ argumentString = '"' + argumentString + '"'
79
+ [name, '(', argumentString, ')'].join("")
80
+ end
81
+
82
+ def navigate_to path
83
+ js_action("navigateTo", [path])
84
+ end
85
+
86
+ private
87
+
88
+ def generate_children_cells
89
+ unless options[:children].nil?
90
+ options[:children].each do |key, node|
91
+ @children_cells[key] = to_cell("#{@component_key}__#{key}", node["component_name"], node["config"], node["argument"], node["components"])
92
+ end
93
+ end
94
+ end
95
+
96
+ def generate_component_name
97
+ name_parts = self.class.name.split("::")
98
+ name = name_parts[0] + name_parts[1]
99
+ if name_parts[0] == name_parts[2]
100
+ name = name_parts[0] + name_parts[1]
101
+ @component_class = name.underscore.gsub("_", "-")
102
+ else
103
+ name = name_parts[0] + name_parts[2] + name_parts[1]
104
+ @component_class = name.underscore.gsub("_", "-")
105
+ end
106
+ @component_name = @component_class.gsub("-cell", "")
107
+ end
108
+
109
+ end
110
+ end
@@ -0,0 +1,14 @@
1
+ module Component::Cell
2
+ class Static < Component::Cell::Dynamic
3
+
4
+ def initialize(model=nil, options={})
5
+ super
6
+ @static = true
7
+ end
8
+
9
+ def show(&block)
10
+ render(view: :static, &block)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ import Vue from 'vue/dist/vue.esm'
2
+ import axios from 'axios'
3
+ import VRuntimeTemplate from "v-runtime-template"
4
+
5
+ const componentMixin = {
6
+ props: ['componentConfig', 'params'],
7
+ data: function(){
8
+ return {
9
+ asyncTemplate: null
10
+ }
11
+ },
12
+ methods: {
13
+ rerender: function(){
14
+ var self = this;
15
+ self.params["component_key"] = self.componentConfig["component_key"]
16
+ axios({
17
+ method: "get",
18
+ url: self.componentConfig["origin_url"],
19
+ headers: {
20
+ 'X-CSRF-Token': document.getElementsByName("csrf-token")[0].getAttribute('content')
21
+ },
22
+ params: self.params
23
+ })
24
+ .then(function(response){
25
+ self.asyncTemplate = response["data"];
26
+ })
27
+ },
28
+ rerenderWith: function(newParams){
29
+ Object.assign(this.params, newParams);
30
+ this.rerender()
31
+ }
32
+ },
33
+ components: {
34
+ VRuntimeTemplate: VRuntimeTemplate
35
+ }
36
+ }
37
+
38
+ export default componentMixin