matestack-ui-vuejs 3.0.0.rc1

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 (77) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +492 -0
  4. data/Rakefile +64 -0
  5. data/lib/matestack/ui/component.rb +1 -0
  6. data/lib/matestack/ui/isolated_component.rb +1 -0
  7. data/lib/matestack/ui/vue_js/components/action.js +70 -0
  8. data/lib/matestack/ui/vue_js/components/action.rb +46 -0
  9. data/lib/matestack/ui/vue_js/components/app.js +122 -0
  10. data/lib/matestack/ui/vue_js/components/app.rb +46 -0
  11. data/lib/matestack/ui/vue_js/components/async.js +104 -0
  12. data/lib/matestack/ui/vue_js/components/async.rb +84 -0
  13. data/lib/matestack/ui/vue_js/components/cable.js +96 -0
  14. data/lib/matestack/ui/vue_js/components/cable.rb +69 -0
  15. data/lib/matestack/ui/vue_js/components/collection/content.js +96 -0
  16. data/lib/matestack/ui/vue_js/components/collection/content.rb +32 -0
  17. data/lib/matestack/ui/vue_js/components/collection/filter.js +45 -0
  18. data/lib/matestack/ui/vue_js/components/collection/filter.rb +29 -0
  19. data/lib/matestack/ui/vue_js/components/collection/filter_reset.rb +19 -0
  20. data/lib/matestack/ui/vue_js/components/collection/helper.rb +128 -0
  21. data/lib/matestack/ui/vue_js/components/collection/next.rb +19 -0
  22. data/lib/matestack/ui/vue_js/components/collection/order.js +45 -0
  23. data/lib/matestack/ui/vue_js/components/collection/order.rb +28 -0
  24. data/lib/matestack/ui/vue_js/components/collection/order_toggle.rb +21 -0
  25. data/lib/matestack/ui/vue_js/components/collection/order_toggle_indicator.rb +30 -0
  26. data/lib/matestack/ui/vue_js/components/collection/page.rb +21 -0
  27. data/lib/matestack/ui/vue_js/components/collection/previous.rb +19 -0
  28. data/lib/matestack/ui/vue_js/components/form/base.rb +179 -0
  29. data/lib/matestack/ui/vue_js/components/form/checkbox.js +13 -0
  30. data/lib/matestack/ui/vue_js/components/form/checkbox.rb +109 -0
  31. data/lib/matestack/ui/vue_js/components/form/checkbox_mixin.js +90 -0
  32. data/lib/matestack/ui/vue_js/components/form/context.rb +15 -0
  33. data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.js +50 -0
  34. data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.rb +35 -0
  35. data/lib/matestack/ui/vue_js/components/form/fields_for_remove_item.rb +19 -0
  36. data/lib/matestack/ui/vue_js/components/form/form.js +276 -0
  37. data/lib/matestack/ui/vue_js/components/form/form.rb +77 -0
  38. data/lib/matestack/ui/vue_js/components/form/input.js +13 -0
  39. data/lib/matestack/ui/vue_js/components/form/input.rb +54 -0
  40. data/lib/matestack/ui/vue_js/components/form/input_mixin.js +79 -0
  41. data/lib/matestack/ui/vue_js/components/form/nested_form.js +153 -0
  42. data/lib/matestack/ui/vue_js/components/form/nested_form.rb +57 -0
  43. data/lib/matestack/ui/vue_js/components/form/radio.js +13 -0
  44. data/lib/matestack/ui/vue_js/components/form/radio.rb +85 -0
  45. data/lib/matestack/ui/vue_js/components/form/radio_mixin.js +75 -0
  46. data/lib/matestack/ui/vue_js/components/form/select.js +13 -0
  47. data/lib/matestack/ui/vue_js/components/form/select.rb +96 -0
  48. data/lib/matestack/ui/vue_js/components/form/select_mixin.js +76 -0
  49. data/lib/matestack/ui/vue_js/components/form/textarea.js +13 -0
  50. data/lib/matestack/ui/vue_js/components/form/textarea.rb +37 -0
  51. data/lib/matestack/ui/vue_js/components/form/textarea_mixin.js +54 -0
  52. data/lib/matestack/ui/vue_js/components/helpers.js +5 -0
  53. data/lib/matestack/ui/vue_js/components/isolated.js +105 -0
  54. data/lib/matestack/ui/vue_js/components/isolated.rb +86 -0
  55. data/lib/matestack/ui/vue_js/components/mixin.js +66 -0
  56. data/lib/matestack/ui/vue_js/components/onclick.js +18 -0
  57. data/lib/matestack/ui/vue_js/components/onclick.rb +37 -0
  58. data/lib/matestack/ui/vue_js/components/page_switch.js +24 -0
  59. data/lib/matestack/ui/vue_js/components/page_switch.rb +35 -0
  60. data/lib/matestack/ui/vue_js/components/runtime_render.js +17 -0
  61. data/lib/matestack/ui/vue_js/components/toggle.js +70 -0
  62. data/lib/matestack/ui/vue_js/components/toggle.rb +38 -0
  63. data/lib/matestack/ui/vue_js/components/transition.js +44 -0
  64. data/lib/matestack/ui/vue_js/components/transition.rb +40 -0
  65. data/lib/matestack/ui/vue_js/components/transition_handling_mixin.js +100 -0
  66. data/lib/matestack/ui/vue_js/components.rb +118 -0
  67. data/lib/matestack/ui/vue_js/event_hub.js +12 -0
  68. data/lib/matestack/ui/vue_js/helpers/query_params_helper.js +56 -0
  69. data/lib/matestack/ui/vue_js/index.js +94 -0
  70. data/lib/matestack/ui/vue_js/initialize.rb +10 -0
  71. data/lib/matestack/ui/vue_js/utils.rb +67 -0
  72. data/lib/matestack/ui/vue_js/version.rb +7 -0
  73. data/lib/matestack/ui/vue_js/vue.rb +75 -0
  74. data/lib/matestack/ui/vue_js/vue_attributes.rb +13 -0
  75. data/lib/matestack/ui/vue_js.rb +52 -0
  76. data/lib/matestack/ui/vue_js_component.rb +1 -0
  77. metadata +150 -0
@@ -0,0 +1,76 @@
1
+ const formSelectMixin = {
2
+ inject: [
3
+ 'parentFormUid',
4
+ 'parentFormData',
5
+ 'parentFormErrors',
6
+ 'parentFormLoading',
7
+ 'parentFormIsNestedForm',
8
+ 'parentFormResetErrors',
9
+ 'parentNestedFormRuntimeId'
10
+ ],
11
+ methods: {
12
+ initialize: function(){
13
+ const self = this
14
+ let data = {};
15
+
16
+ for (let key in self.getRefs()) {
17
+
18
+ let initValue;
19
+ let valueType;
20
+
21
+ if (key.startsWith("select.")) {
22
+ initValue = self.getRefs()[key]["attributes"]["init-value"];
23
+ valueType = self.getRefs()[key]["attributes"]["value-type"];
24
+ }
25
+
26
+ if (key.startsWith("select.")) {
27
+ if (key.startsWith("select.multiple.")) {
28
+ self.parentFormData[key.replace("select.multiple.", "")] = null
29
+ if (initValue) {
30
+ self.setValue(JSON.parse(initValue["value"]));
31
+ self.afterInitialize(JSON.parse(initValue["value"]))
32
+ } else {
33
+ self.setValue([]);
34
+ self.afterInitialize([]);
35
+ }
36
+ } else {
37
+ self.parentFormData[key.replace("select.", "")] = null
38
+ if (initValue) {
39
+ if (valueType && valueType["value"] == "Integer") {
40
+ self.setValue(parseInt(initValue["value"]));
41
+ self.afterInitialize(parseInt(initValue["value"]))
42
+ } else {
43
+ self.setValue(initValue["value"]);
44
+ self.afterInitialize(initValue["value"])
45
+ }
46
+ } else {
47
+ self.setValue(null);
48
+ self.afterInitialize(null)
49
+ }
50
+ }
51
+ }
52
+ }
53
+ },
54
+ inputChanged: function (key) {
55
+ if (this.parentFormIsNestedForm){
56
+ this.parentFormData["_destroy"] = false;
57
+ }
58
+ this.parentFormResetErrors(key);
59
+ },
60
+ afterInitialize: function(value){
61
+ // can be used in the main component for further initialization steps
62
+ },
63
+ setValue: function (value){
64
+ this.parentFormData[this.props["key"]] = value
65
+ }
66
+ },
67
+ mounted: function(){
68
+ this.registerScopedEvent("init", this.initialize, this.parentFormUid)
69
+ },
70
+ beforeUnmount: function(){
71
+ this.removeScopedEvent("init", this.initialize, this.parentFormUid)
72
+ }
73
+
74
+ }
75
+
76
+ export default formSelectMixin
@@ -0,0 +1,13 @@
1
+ import formTextareaMixin from "./textarea_mixin";
2
+ import componentMixin from "../mixin";
3
+ import componentHelpers from "../helpers";
4
+
5
+ const componentDef = {
6
+ mixins: [componentMixin, formTextareaMixin],
7
+ template: componentHelpers.inlineTemplate,
8
+ data() {
9
+ return {};
10
+ }
11
+ }
12
+
13
+ export default componentDef;
@@ -0,0 +1,37 @@
1
+ module Matestack
2
+ module Ui
3
+ module VueJs
4
+ module Components
5
+ module Form
6
+ class Textarea < Matestack::Ui::VueJs::Components::Form::Base
7
+ vue_name 'matestack-ui-core-form-textarea'
8
+
9
+ def response
10
+ div class: 'matestack-ui-core-form-textarea' do
11
+ label input_label, ":for": id if input_label
12
+ textarea textarea_attributes
13
+ render_errors
14
+ end
15
+ end
16
+
17
+ def textarea_attributes
18
+ attributes
19
+ end
20
+
21
+ def component_id
22
+ "textarea-component-for-#{key}"
23
+ end
24
+
25
+ def vue_props
26
+ {
27
+ init_value: init_value,
28
+ key: key
29
+ }
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,54 @@
1
+ const formTextareaMixin = {
2
+ inject: [
3
+ 'parentFormUid',
4
+ 'parentFormData',
5
+ 'parentFormErrors',
6
+ 'parentFormLoading',
7
+ 'parentFormIsNestedForm',
8
+ 'parentFormResetErrors',
9
+ 'parentNestedFormRuntimeId'
10
+ ],
11
+ methods: {
12
+ initialize: function(){
13
+ const self = this
14
+ let data = {};
15
+
16
+ for (let key in this.getRefs()) {
17
+ if (key.startsWith("input.")) {
18
+ let initValue = self.getRefs()[key]["attributes"]["init-value"];
19
+
20
+ self.parentFormData[key.replace("input.", "")] = null
21
+
22
+ if (initValue) {
23
+ self.setValue(initValue["value"])
24
+ self.afterInitialize(initValue["value"])
25
+ } else {
26
+ self.setValue(null)
27
+ self.afterInitialize(null)
28
+ }
29
+ }
30
+ }
31
+ },
32
+ inputChanged: function (key) {
33
+ if (this.parentFormIsNestedForm){
34
+ this.parentFormData["_destroy"] = false;
35
+ }
36
+ this.parentFormResetErrors(key);
37
+ },
38
+ afterInitialize: function(value){
39
+ // can be used in the main component for further initialization steps
40
+ },
41
+ setValue: function (value){
42
+ this.parentFormData[this.props["key"]] = value
43
+ }
44
+ },
45
+ mounted: function(){
46
+ this.registerScopedEvent("init", this.initialize, this.parentFormUid)
47
+ },
48
+ beforeUnmount: function(){
49
+ this.removeScopedEvent("init", this.initialize, this.parentFormUid)
50
+ }
51
+
52
+ }
53
+
54
+ export default formTextareaMixin
@@ -0,0 +1,5 @@
1
+ const componentHelpers = {
2
+ inlineTemplate: '<slot :vc="vc"></slot>' // can not be mixed in
3
+ }
4
+
5
+ export default componentHelpers
@@ -0,0 +1,105 @@
1
+ import axios from 'axios'
2
+ import matestackEventHub from '../event_hub'
3
+ import componentMixin from './mixin'
4
+ import componentHelpers from './helpers'
5
+
6
+ const componentDef = {
7
+ mixins: [componentMixin],
8
+ props: ['props', 'params'],
9
+ template: componentHelpers.inlineTemplate,
10
+ data: function(){
11
+ return {
12
+ isolatedTemplate: null,
13
+ loading: false,
14
+ loadingError: false
15
+ }
16
+ },
17
+ methods: {
18
+ rerender: function(){
19
+ var self = this;
20
+ self.loading = true;
21
+ self.loadingError = false;
22
+ if(self.props["rerender_delay"] != undefined){
23
+ setTimeout(function () {
24
+ self.renderIsolatedContent();
25
+ }, parseInt(this.props["rerender_delay"]));
26
+ } else {
27
+ self.renderIsolatedContent();
28
+ }
29
+ },
30
+ renderIsolatedContent: function(){
31
+ var self = this;
32
+ self.loading = true;
33
+ self.loadingError = false;
34
+ axios({
35
+ method: "get",
36
+ url: location.pathname + location.search,
37
+ headers: {
38
+ 'X-CSRF-Token': self.getXcsrfToken()
39
+ },
40
+ params: {
41
+ "component_class": self.props["component_class"],
42
+ "public_options": self.props["public_options"]
43
+ }
44
+ })
45
+ .then(function(response){
46
+ self.loading = false;
47
+ self.loadingStart = false;
48
+ self.loadingEnd = true;
49
+ self.isolatedTemplate = response['data'];
50
+ })
51
+ .catch(function(error){
52
+ self.loadingError = true;
53
+ matestackEventHub.$emit('isolate_rerender_error', { class: self.props["component_class"] })
54
+ })
55
+ },
56
+ startDefer: function(){
57
+ const self = this
58
+ self.loading = true;
59
+ setTimeout(function () {
60
+ self.renderIsolatedContent()
61
+ }, parseInt(this.props["defer"]));
62
+ }
63
+ },
64
+ created: function () {
65
+ const self = this
66
+ },
67
+ beforeUnmount: function() {
68
+ const self = this
69
+ if(this.props["rerender_on"] != undefined){
70
+ var rerender_events = this.props["rerender_on"].split(",")
71
+ rerender_events.forEach(rerender_event => matestackEventHub.$off(rerender_event.trim(), self.renderIsolatedContent));
72
+ }
73
+ },
74
+ mounted: function (){
75
+ const self = this
76
+ if(this.props["init_on"] === undefined || this.props["init_on"] === null){
77
+ if(self.props["defer"] == true || Number.isInteger(self.props["defer"])){
78
+ if(!isNaN(self.props["defer"])){
79
+ self.startDefer()
80
+ }
81
+ else{
82
+ self.renderIsolatedContent();
83
+ }
84
+ }
85
+ }else{
86
+ if(self.props["defer"] != undefined){
87
+ if(!isNaN(self.props["defer"])){
88
+ var init_on_events = this.props["init_on"].split(",")
89
+ init_on_events.forEach(init_on_event => matestackEventHub.$on(init_on_event.trim(), self.startDefer));
90
+ }
91
+ }else{
92
+ var init_on_events = this.props["init_on"].split(",")
93
+ init_on_events.forEach(init_on_event => matestackEventHub.$on(init_on_event.trim(), self.renderIsolatedContent));
94
+ }
95
+ }
96
+
97
+ if(this.props["rerender_on"] != undefined){
98
+ var rerender_events = this.props["rerender_on"].split(",")
99
+ rerender_events.forEach(rerender_event => matestackEventHub.$on(rerender_event.trim(), self.rerender));
100
+ }
101
+
102
+ }
103
+ }
104
+
105
+ export default componentDef
@@ -0,0 +1,86 @@
1
+ module Matestack
2
+ module Ui
3
+ module VueJs
4
+ module Components
5
+ class Isolated < Matestack::Ui::VueJs::Vue
6
+ vue_name 'matestack-ui-core-isolate'
7
+
8
+ optional :defer, :init_on, :public_options, :rerender_on, :rerender_delay
9
+
10
+ def initialize(html_tag = nil, text = nil, options = {}, &block)
11
+ extract_options(text, options)
12
+ only_public_options!
13
+ isolated_parent = Matestack::Ui::Core::Context.isolated_parent
14
+ Matestack::Ui::Core::Context.isolated_parent = self
15
+ super(html_tag, text, options, &block)
16
+ Matestack::Ui::Core::Context.isolated_parent = isolated_parent
17
+ end
18
+
19
+ def create_children
20
+ # content only should be rendered if param :component_class is present
21
+ warn "[WARNING] '#{self.class}' was accessed but not authorized" unless authorized?
22
+ if params[:component_class].present?
23
+ self.response if authorized?
24
+ else
25
+ self.isolated do
26
+ self.response if authorized?
27
+ end
28
+ end
29
+ end
30
+
31
+ def isolated
32
+ vue_component do
33
+ div class: 'matestack-isolated-component-container', 'v-bind:class': '{ loading: vc.loading === true }' do
34
+ if self.respond_to? :loading_state_element
35
+ div class: 'loading-state-element-wrapper', 'v-bind:class': '{ loading: vc.loading === true }' do
36
+ loading_state_element
37
+ end
38
+ end
39
+ unless ctx.defer || ctx.init_on
40
+ div class: 'matestack-isolated-component-wrapper', 'v-if': 'vc.isolatedTemplate == null', 'v-bind:class': '{ loading: vc.loading === true }' do
41
+ div class: 'matestack-isolated-component-root' do
42
+ yield
43
+ end
44
+ end
45
+ end
46
+ div class: 'matestack-isolated-component-wrapper', 'v-if': 'vc.isolatedTemplate != null', 'v-bind:class': '{ loading: vc.loading === true }' do
47
+ div class: 'matestack-isolated-component-root' do
48
+ Matestack::Ui::Core::Base.new('matestack-ui-core-runtime-render', ':template': 'vc.isolatedTemplate', ':vc': 'vc')
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def vue_props
56
+ {
57
+ component_class: self.class.name,
58
+ public_options: ctx.public_options,
59
+ defer: ctx.defer,
60
+ rerender_on: ctx.rerender_on,
61
+ rerender_delay: ctx.rerender_delay,
62
+ init_on: ctx.init_on,
63
+ }
64
+ end
65
+
66
+ def public_options
67
+ ctx.public_options || {}
68
+ end
69
+
70
+ def authorized?
71
+ raise "'authorized?' needs to be implemented by '#{self.class}'"
72
+ end
73
+
74
+ def only_public_options!
75
+ if self.options.except(:defer, :init_on, :public_options, :rerender_on, :rerender_delay).keys.any?
76
+ error_message = "isolated components can only take params in a public_options hash, which will be exposed to the client side in order to perform an async request with these params."
77
+ error_message << " Check your usages of '#{self.class}' components"
78
+ raise error_message
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,66 @@
1
+ import matestackEventHub from '../event_hub'
2
+
3
+ const componentMixin = {
4
+ props: ['props', 'params', 'matestack-ui-core-ref'],
5
+ computed: {
6
+ vc: function(){
7
+ return this;
8
+ }
9
+ },
10
+ methods: {
11
+ getRefs: function(){
12
+ // while working with vue.js 2.x, we used inline templates. $refs was working fine
13
+ // from vue.js 3.x on, we cannot use inline tempates anymore but must use default slot instead
14
+ // $refs is empty due to this migration
15
+ // that's the reason for the following workaround
16
+ var componentScopedRefs = {};
17
+ var scopeId = this.props['component_uid'];
18
+ var componentRelativeRefs = this.getElement().querySelectorAll("[matestack-ui-core-ref]")
19
+ // var defaultSlot = this.$slots.default({ vc: this.vc })[0]
20
+ // var globalRefs = defaultSlot.context.$refs
21
+ for (let i in componentRelativeRefs) {
22
+ let node = componentRelativeRefs[i]
23
+ if (node.getAttribute){
24
+ let nodeRef = node.getAttribute("matestack-ui-core-ref")
25
+ if(nodeRef.startsWith(scopeId)){
26
+ componentScopedRefs[nodeRef.replace(scopeId+"-", "")] = node
27
+ }
28
+ }
29
+
30
+ }
31
+ return componentScopedRefs;
32
+ },
33
+ getElement: function(){
34
+ return document.getElementById("uid-"+this.props['component_uid']);
35
+ },
36
+ registerEvents: function(events, callback){
37
+ if(events != undefined){
38
+ var event_names = events.split(",")
39
+ event_names.forEach(event_name => matestackEventHub.$on(event_name.trim(), callback));
40
+ }
41
+ },
42
+ removeEvents: function(events, callback){
43
+ if(events != undefined){
44
+ var event_names = events.split(",")
45
+ event_names.forEach(event_name => matestackEventHub.$off(event_name.trim(), callback));
46
+ }
47
+ },
48
+ emitScopedEvent: function(name, data={}){
49
+ matestackEventHub.$emit(this.props['component_uid']+"_"+name, data)
50
+ },
51
+ registerScopedEvent: function(name, callback, scopeId=this.props['component_uid']){
52
+ matestackEventHub.$on(scopeId+"_"+name, callback)
53
+ },
54
+ removeScopedEvent: function(name, callback, scopeId=this.props['component_uid']){
55
+ matestackEventHub.$off(scopeId+"_"+name, callback)
56
+ },
57
+ getXcsrfToken: function(){
58
+ if(document.getElementsByName("csrf-token")[0]){
59
+ return document.getElementsByName("csrf-token")[0].getAttribute("content")
60
+ }
61
+ }
62
+ }
63
+
64
+ }
65
+
66
+ export default componentMixin
@@ -0,0 +1,18 @@
1
+ import matestackEventHub from '../event_hub'
2
+ import componentMixin from './mixin'
3
+ import componentHelpers from './helpers'
4
+
5
+ const componentDef = {
6
+ mixins: [componentMixin],
7
+ template: componentHelpers.inlineTemplate,
8
+ data: function(){
9
+ return { }
10
+ },
11
+ methods: {
12
+ perform: function(){
13
+ matestackEventHub.$emit(this.props["emit"], this.props["data"])
14
+ }
15
+ }
16
+ }
17
+
18
+ export default componentDef
@@ -0,0 +1,37 @@
1
+ module Matestack
2
+ module Ui
3
+ module VueJs
4
+ module Components
5
+ class Onclick < Matestack::Ui::VueJs::Vue
6
+ vue_name 'matestack-ui-core-onclick'
7
+
8
+ optional :emit, :data
9
+
10
+ def response
11
+ a onclick_attributes do
12
+ yield
13
+ end
14
+ end
15
+
16
+ def onclick_attributes
17
+ options.merge({
18
+ class: "matestack-onclick-component-root",
19
+ 'v-on:click.prevent': 'vc.perform',
20
+ href: "#"
21
+ })
22
+ end
23
+
24
+ protected
25
+
26
+ def vue_props
27
+ {
28
+ emit: ctx.emit,
29
+ data: ctx.data,
30
+ }
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ import componentMixin from './mixin'
2
+ import componentHelpers from './helpers'
3
+
4
+ const componentDef = {
5
+ mixins: [componentMixin],
6
+ template: componentHelpers.inlineTemplate,
7
+ data: function(){
8
+ return {}
9
+ },
10
+ inject: [
11
+ 'pageTemplate',
12
+ 'pageLoading'
13
+ ],
14
+ computed: {
15
+ asyncPageTemplate: function(){
16
+ return this.pageTemplate
17
+ },
18
+ loading: function(){
19
+ return this.pageLoading
20
+ }
21
+ }
22
+ }
23
+
24
+ export default componentDef
@@ -0,0 +1,35 @@
1
+ module Matestack
2
+ module Ui
3
+ module VueJs
4
+ module Components
5
+ class PageSwitch < Matestack::Ui::VueJs::Vue
6
+
7
+ vue_name "matestack-ui-core-page-switch"
8
+
9
+ def response
10
+ div class: 'matestack-page-container', 'v-bind:class': '{ "loading": vc.loading === true }' do
11
+ if Matestack::Ui::Core::Context.layout.respond_to? :loading_state_element
12
+ div class: 'loading-state-element-wrapper', 'v-bind:class': '{ "loading": vc.loading === true }' do
13
+ Matestack::Ui::Core::Context.layout.loading_state_element
14
+ end
15
+ end
16
+ div class: 'matestack-page-wrapper', 'v-bind:class': '{ "loading": vc.loading === true }' do
17
+ div 'v-if': 'vc.asyncPageTemplate == null' do
18
+ div class: 'matestack-page-root' do
19
+ yield
20
+ end
21
+ end
22
+ div 'v-if': 'vc.asyncPageTemplate != null' do
23
+ div class: 'matestack-page-root' do
24
+ Matestack::Ui::Core::Base.new('matestack-ui-core-runtime-render', ':template': 'vc.asyncPageTemplate', ':vc': 'vc')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ // import componentMixin from './mixin'
2
+
3
+ const componentDef = {
4
+ template: `<component :is="dynamicComponent" :vc="vc" :template="template" />`,
5
+ props: ['vc', 'template'],
6
+ computed: {
7
+ dynamicComponent: function() {
8
+ return {
9
+ // mixins: [componentMixin],
10
+ props: ['vc', 'template'],
11
+ template: `${this.template || '<div></div>'}`,
12
+ }
13
+ }
14
+ }
15
+ }
16
+
17
+ export default componentDef
@@ -0,0 +1,70 @@
1
+ import matestackEventHub from '../event_hub'
2
+ import componentMixin from './mixin'
3
+ import componentHelpers from './helpers'
4
+
5
+ const componentDef = {
6
+ mixins: [componentMixin],
7
+ template: componentHelpers.inlineTemplate,
8
+ data: function(){
9
+ return {
10
+ showing: true,
11
+ hide_after_timeout: null,
12
+ event: {
13
+ data: {}
14
+ }
15
+ }
16
+ },
17
+ methods: {
18
+ show: function(event_data){
19
+ const self = this
20
+ if (this.showing === true){
21
+ return
22
+ }
23
+ this.showing = true
24
+ this.event.data = event_data
25
+ if(this.props["hide_after"] != undefined){
26
+ self.hide_after_timeout = setTimeout(function () {
27
+ self.hide()
28
+ }, parseInt(this.props["hide_after"]));
29
+ }
30
+ },
31
+ hide: function(){
32
+ this.showing = false
33
+ this.event.data = {}
34
+ }
35
+ },
36
+ created: function () {
37
+ const self = this
38
+ if(this.props["show_on"] != undefined){
39
+ this.showing = false
40
+ var show_events = this.props["show_on"].split(",")
41
+ show_events.forEach(show_event => matestackEventHub.$on(show_event.trim(), self.show));
42
+ }
43
+ if(this.props["hide_on"] != undefined){
44
+ var hide_events = this.props["hide_on"].split(",")
45
+ hide_events.forEach(hide_event => matestackEventHub.$on(hide_event.trim(), self.hide));
46
+ }
47
+ if(this.props["show_on"] != undefined){
48
+ this.showing = false
49
+ }
50
+ if(this.props["init_show"] == true){
51
+ this.showing = true
52
+ }
53
+ },
54
+ beforeUnmount: function() {
55
+ const self = this
56
+ clearTimeout(self.hide_after_timeout)
57
+ matestackEventHub.$off(this.props["show_on"], self.show);
58
+ matestackEventHub.$off(this.props["hide_on"], self.hide);
59
+ if(this.props["show_on"] != undefined){
60
+ var shown_events = this.props["show_on"].split(",")
61
+ shown_events.forEach(show_event => matestackEventHub.$off(show_event.trim(), self.show));
62
+ }
63
+ if(this.props["hide_on"] != undefined){
64
+ var hiden_events = this.props["hide_on"].split(",")
65
+ hiden_events.forEach(hide_event => matestackEventHub.$off(hide_event.trim(), self.hide));
66
+ }
67
+ },
68
+ }
69
+
70
+ export default componentDef