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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +492 -0
- data/Rakefile +64 -0
- data/lib/matestack/ui/component.rb +1 -0
- data/lib/matestack/ui/isolated_component.rb +1 -0
- data/lib/matestack/ui/vue_js/components/action.js +70 -0
- data/lib/matestack/ui/vue_js/components/action.rb +46 -0
- data/lib/matestack/ui/vue_js/components/app.js +122 -0
- data/lib/matestack/ui/vue_js/components/app.rb +46 -0
- data/lib/matestack/ui/vue_js/components/async.js +104 -0
- data/lib/matestack/ui/vue_js/components/async.rb +84 -0
- data/lib/matestack/ui/vue_js/components/cable.js +96 -0
- data/lib/matestack/ui/vue_js/components/cable.rb +69 -0
- data/lib/matestack/ui/vue_js/components/collection/content.js +96 -0
- data/lib/matestack/ui/vue_js/components/collection/content.rb +32 -0
- data/lib/matestack/ui/vue_js/components/collection/filter.js +45 -0
- data/lib/matestack/ui/vue_js/components/collection/filter.rb +29 -0
- data/lib/matestack/ui/vue_js/components/collection/filter_reset.rb +19 -0
- data/lib/matestack/ui/vue_js/components/collection/helper.rb +128 -0
- data/lib/matestack/ui/vue_js/components/collection/next.rb +19 -0
- data/lib/matestack/ui/vue_js/components/collection/order.js +45 -0
- data/lib/matestack/ui/vue_js/components/collection/order.rb +28 -0
- data/lib/matestack/ui/vue_js/components/collection/order_toggle.rb +21 -0
- data/lib/matestack/ui/vue_js/components/collection/order_toggle_indicator.rb +30 -0
- data/lib/matestack/ui/vue_js/components/collection/page.rb +21 -0
- data/lib/matestack/ui/vue_js/components/collection/previous.rb +19 -0
- data/lib/matestack/ui/vue_js/components/form/base.rb +179 -0
- data/lib/matestack/ui/vue_js/components/form/checkbox.js +13 -0
- data/lib/matestack/ui/vue_js/components/form/checkbox.rb +109 -0
- data/lib/matestack/ui/vue_js/components/form/checkbox_mixin.js +90 -0
- data/lib/matestack/ui/vue_js/components/form/context.rb +15 -0
- data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.js +50 -0
- data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.rb +35 -0
- data/lib/matestack/ui/vue_js/components/form/fields_for_remove_item.rb +19 -0
- data/lib/matestack/ui/vue_js/components/form/form.js +276 -0
- data/lib/matestack/ui/vue_js/components/form/form.rb +77 -0
- data/lib/matestack/ui/vue_js/components/form/input.js +13 -0
- data/lib/matestack/ui/vue_js/components/form/input.rb +54 -0
- data/lib/matestack/ui/vue_js/components/form/input_mixin.js +79 -0
- data/lib/matestack/ui/vue_js/components/form/nested_form.js +153 -0
- data/lib/matestack/ui/vue_js/components/form/nested_form.rb +57 -0
- data/lib/matestack/ui/vue_js/components/form/radio.js +13 -0
- data/lib/matestack/ui/vue_js/components/form/radio.rb +85 -0
- data/lib/matestack/ui/vue_js/components/form/radio_mixin.js +75 -0
- data/lib/matestack/ui/vue_js/components/form/select.js +13 -0
- data/lib/matestack/ui/vue_js/components/form/select.rb +96 -0
- data/lib/matestack/ui/vue_js/components/form/select_mixin.js +76 -0
- data/lib/matestack/ui/vue_js/components/form/textarea.js +13 -0
- data/lib/matestack/ui/vue_js/components/form/textarea.rb +37 -0
- data/lib/matestack/ui/vue_js/components/form/textarea_mixin.js +54 -0
- data/lib/matestack/ui/vue_js/components/helpers.js +5 -0
- data/lib/matestack/ui/vue_js/components/isolated.js +105 -0
- data/lib/matestack/ui/vue_js/components/isolated.rb +86 -0
- data/lib/matestack/ui/vue_js/components/mixin.js +66 -0
- data/lib/matestack/ui/vue_js/components/onclick.js +18 -0
- data/lib/matestack/ui/vue_js/components/onclick.rb +37 -0
- data/lib/matestack/ui/vue_js/components/page_switch.js +24 -0
- data/lib/matestack/ui/vue_js/components/page_switch.rb +35 -0
- data/lib/matestack/ui/vue_js/components/runtime_render.js +17 -0
- data/lib/matestack/ui/vue_js/components/toggle.js +70 -0
- data/lib/matestack/ui/vue_js/components/toggle.rb +38 -0
- data/lib/matestack/ui/vue_js/components/transition.js +44 -0
- data/lib/matestack/ui/vue_js/components/transition.rb +40 -0
- data/lib/matestack/ui/vue_js/components/transition_handling_mixin.js +100 -0
- data/lib/matestack/ui/vue_js/components.rb +118 -0
- data/lib/matestack/ui/vue_js/event_hub.js +12 -0
- data/lib/matestack/ui/vue_js/helpers/query_params_helper.js +56 -0
- data/lib/matestack/ui/vue_js/index.js +94 -0
- data/lib/matestack/ui/vue_js/initialize.rb +10 -0
- data/lib/matestack/ui/vue_js/utils.rb +67 -0
- data/lib/matestack/ui/vue_js/version.rb +7 -0
- data/lib/matestack/ui/vue_js/vue.rb +75 -0
- data/lib/matestack/ui/vue_js/vue_attributes.rb +13 -0
- data/lib/matestack/ui/vue_js.rb +52 -0
- data/lib/matestack/ui/vue_js_component.rb +1 -0
- 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,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
|