vue_crud 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7a3968959d978911425d23ccc57bad7a6e520b1d
4
+ data.tar.gz: e22d398e429375cb72eb45068d691f8e8db1201d
5
+ SHA512:
6
+ metadata.gz: 68fcb6ff3f771628a6d82db744af6e76d87b9e143dea98ab6736a9412d0cd59a82ecc938279c0098fe1e73d6bf43dffea411d7dba191dc6f6e2f0ca1fe478fe2
7
+ data.tar.gz: b57aad62dbf33091b101f4128cabb298a8e73952fa28570a9b7504dbe174c8cd67cd6a19b7020b28d4104ca0cea5a9ce1a5934d6c32f0f6a08e9975a39e3868a
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.13.4
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vue_crud.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # VueCrud
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/vue_crud`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'vue_crud'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install vue_crud
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/vue_crud.
36
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "vue_crud"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,11 @@
1
+ #lib/generators/gemname/install_generator.rb
2
+ require 'rails/generators'
3
+ module VueCrud
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("../templates", __FILE__)
6
+
7
+ def copy_template_file
8
+ copy_file "vue_crud.html", "public/vue_crud.html"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,221 @@
1
+ <script type="text/javascript">
2
+ $(document).ready(function() {
3
+ $('.vue_form_for_new').html($('#vue_form').html());
4
+ var model_row = $($('#model-row').html());
5
+ model_row.find('.custom_model_row').html(
6
+ $('#custom_model_row').html()
7
+ );
8
+ model_row.find('.custom_action').html(
9
+ $('#custom_action').html()
10
+ );
11
+ model_row.find('.vue_form_for_edit').html(
12
+ $('#vue_form').html()
13
+ );
14
+ model_row.find('.custom_modal_body').html(
15
+ $('#custom_modal_body').html()
16
+ );
17
+ model_row.find('.custom_modal_action').html(
18
+ $('#custom_modal_action').html()
19
+ );
20
+
21
+ $('#model-row').html(model_row);
22
+ vue_init();
23
+ $('.filter .ui.dropdown').dropdown();
24
+ });
25
+ </script>
26
+
27
+
28
+ <div id="models">
29
+ <input type="text" name="progress" id="form-progress">
30
+ <h1 class="ui header">
31
+ {{ info.titles.title }}
32
+ <div class="sub header"><small>{{ info.titles.subtitle }}</small></div>
33
+ </h1>
34
+ <div class="ui blue button" data-modal="#modelModal">Add</div>
35
+ <div class="ui divider"></div>
36
+ <!-- NOTE: Filter -->
37
+ <div class="ui left action right icon labeled input filter" :class="{loading: is_calculating}">
38
+ <a :href="info.url_prefix" class="ui button red" v-show="selected_attribute">Reset</a>
39
+ <div class="ui basic floating dropdown button">
40
+ <div class="text">{{ selected_attribute || 'Attribute' }}</div>
41
+ <i class="dropdown icon"></i>
42
+ <div class="menu attribute_select">
43
+ <div class="item attribute_option" v-for="attribute in info.model_attributes" :model_prefix="attribute.model_prefix || ''" :target="attribute.name" :class="{selected: selected_attribute == attribute.name,active: selected_attribute == attribute.name}">{{ attribute.display_name }}</div>
44
+ </div>
45
+ </div>
46
+ <input type="text" id="searchQuery" :placeholder="searchStatus" v-model="searchQuery">
47
+ <i class="icon search"></i>
48
+ </div>
49
+ <div class="ui divider"></div>
50
+ <!-- NOTE: Pagination -->
51
+ <div class="ui pagination menu">
52
+ <a class="item" @click.prevent="setPage(currentPage-1)" :class="{'disabled': (currentPage == '1')}">
53
+
54
+ </a>
55
+ <a v-for="n in totalPage" @click.prevent="setPage(n)" :class="{'active': (currentPage == (n))}" class="item">
56
+ {{n}}
57
+ </a>
58
+ <a class="item" @click.prevent="setPage(currentPage+1)" :class="{'disabled': (currentPage == totalPage)}">
59
+
60
+ </a>
61
+ </div>
62
+ <div class="ui divider"></div>
63
+ <!-- NOTE: model-row -->
64
+ <div class="row ui cards">
65
+ <model-row is="model-row" v-for="model in filteredModels" :model="model" :info="info" :selected_attribute="model_prefix + '.' + selected_attribute"></model-row>
66
+ </div>
67
+
68
+ <!-- NOTE: modal for new action -->
69
+ <div class="ui modal new_modal" id="modelModal">
70
+ <div class="header">Create {{ info.titles.title }}</div>
71
+ <!-- NOTE: Vue form -->
72
+ <div class="content vue_form_for_new"></div>
73
+ <div class="actions">
74
+ <div class="ui basic gray cancel button">Cancel</div>
75
+ <div @click="createModel" class="ui primary button">Create</div>
76
+ </div>
77
+ <div class="ui blue bottom attached progress">
78
+ <div class="bar" :style="{width: progress + '%'}"></div>
79
+ </div>
80
+ </div>
81
+ </div>
82
+
83
+ <!-- NOTE: Templates -->
84
+ <script type="text/x-template" id="model-row">
85
+ <div class="col-md-4">
86
+ <div class="card">
87
+ <div class="content">
88
+ <div class="header" v-if="info.titles.title_attribute_model_prefix">{{ model[info.titles.title_attribute_model_prefix][info.titles.title_attribute] }}</div>
89
+ <div class="header" v-else>{{ model[info.titles.title_attribute] }}</div>
90
+ <div class="meta">{{ info.titles.model_name }}</div>
91
+ <div class="ui divider"></div>
92
+ <div class="description">
93
+ <div class="ui small feed" v-for="attribute in info.model_attributes" v-if="attribute.visible">
94
+ <div class="event">
95
+ <div class="content">
96
+ <div class="summary" :class="{highlight: attribute.model_prefix + '.' + attribute.name == selected_attribute}" v-if="attribute.model_prefix">
97
+ {{ attribute.display_name }}: {{ model[attribute.model_prefix][attribute.name] }}
98
+ </div>
99
+ <div class="summary" :class="{highlight: attribute.model_prefix + '.' + attribute.name == selected_attribute}" v-else>
100
+ {{ attribute.display_name }}: {{ model[attribute.name] }}
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ <!-- NOTE: Custom model row -->
106
+ <div class="custom_model_row"></div>
107
+ </div>
108
+ </div>
109
+ <div class="extra content">
110
+ <div class="ui orange right ribbon label" v-show="modified">您有尚未儲存的變更,<a href="#" @click="updateModel(false)" onclick="return false" class="save_now">立即儲存</a></div>
111
+ <div class="ui teal right ribbon label" v-show="is_success">儲存成功</div>
112
+ <div class="ui divider"></div>
113
+ <!-- NOTE: Custom action -->
114
+ <div class="inline-block custom_action"></div>
115
+ <div class="ui blue button" :data-modal="'#editModal_' + model.id">Edit</div>
116
+ <div @click="deleteModel" class="ui basic red right floated button" v-show="!deleteMode">Delete</div>
117
+ </div>
118
+ <div class="ui modal" :id="'editModal_' + model.id">
119
+ <div class="ui inverted dimmer">
120
+ <div class="ui indeterminate text loader">Progressing</div>
121
+ </div>
122
+ <div class="header">Update {{ info.titles.title }}</div>
123
+ <div class="content">
124
+ <!-- NOTE: Not customMode -->
125
+ <div v-show="!customMode" class="vue_form_for_edit"></div>
126
+ <!-- NOTE: Is customMode -->
127
+ <!-- NOTE: Custom modal body -->
128
+ <div v-show="customMode"><div class="custom_modal_body"></div></div>
129
+ </div>
130
+ <div class="actions">
131
+ <button class="ui basic gray cancel button">Cancel</button>
132
+ <button @click="updateModel" class="ui button blue" v-show="!customMode">Update</button>
133
+ <!-- NOTE: Custom modal action -->
134
+ <div class="inline-block custom_modal_action"></div>
135
+ </div>
136
+ </div>
137
+ <div class="ui blue bottom attached progress">
138
+ <div class="bar" :style="{width: progress + '%'}"></div>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </script>
143
+
144
+ <script type="text/x-template" id="vue_form">
145
+ <form class="ui form">
146
+ <div v-for="attribute in info.model_attributes" v-if="attribute.editable">
147
+ <div class="field" v-if="attribute.type == 'select'">
148
+ <label :for="'model_' + attribute.display_name">{{ attribute.display_name }}</label>
149
+ <select :id="'model_' + attribute.display_name" v-if="attribute.model_prefix" v-model="model[attribute.model_prefix][attribute.name]" class="ui fluid dropdown">
150
+ <option v-for="option in attribute.options" :value="option.value" v-text="option.text"></option>
151
+ </select>
152
+ <select :id="'model_' + attribute.display_name" v-else v-model="model[attribute.name]" class="ui fluid dropdown">
153
+ <option v-for="option in attribute.options" :value="option.value" v-text="option.text"></option>
154
+ </select>
155
+ <div class="ui pointing red basic label" v-show="errors[attribute.name]">
156
+ <span style="color: red" v-for="(error, index) in errors[attribute.name]">
157
+ <span v-if="index > 0">,</span> {{ error }}
158
+ </span>
159
+ </div>
160
+ </div>
161
+ <div class="field" v-if="attribute.type == 'multiSelect'">
162
+ <label :for="'model_' + attribute.display_name">{{ attribute.display_name }}</label>
163
+ <select :id="'model_' + attribute.display_name" multiple v-if="attribute.model_prefix" v-model="model[attribute.model_prefix][attribute.name]" class="ui fluid dropdown">
164
+ <option v-for="option in attribute.options" :value="option.value" v-text="option.text"></option>
165
+ </select>
166
+ <select :id="'model_' + attribute.display_name" multiple v-else v-model="model[attribute.name]" class="ui fluid dropdown">
167
+ <option v-for="option in attribute.options" :value="option.value" v-text="option.text"></option>
168
+ </select>
169
+ <div class="ui pointing red basic label" v-show="errors[attribute.name]">
170
+ <span style="color: red" v-for="(error, index) in errors[attribute.name]">
171
+ <span v-if="index > 0">,</span> {{ error }}
172
+ </span>
173
+ </div>
174
+ </div>
175
+ <div class="field" v-if="attribute.type == 'textarea'">
176
+ <label :for="'model_' + attribute.display_name">{{ attribute.display_name }}</label>
177
+ <textarea :id="'model_' + attribute.display_name" v-if="attribute.model_prefix" v-model="model[attribute.model_prefix][attribute.name]"></textarea>
178
+ <textarea :id="'model_' + attribute.display_name" v-else v-model="model[attribute.name]"></textarea>
179
+ <div class="ui pointing red basic label" v-show="errors[attribute.name]">
180
+ <span style="color: red" v-for="(error, index) in errors[attribute.name]">
181
+ <span v-if="index > 0">,</span> {{ error }}
182
+ </span>
183
+ </div>
184
+ </div>
185
+ <div class="field" v-if="attribute.type == 'checkbox'">
186
+ <div class="ui slider checkbox">
187
+ <input type="checkbox" :id="'model_' + attribute.display_name" v-if="attribute.model_prefix" v-model="model[attribute.model_prefix][attribute.name]">
188
+ <input type="checkbox" :id="'model_' + attribute.display_name" v-else v-model="model[attribute.name]">
189
+ <label :for="'model_' + attribute.display_name">{{ attribute.display_name }}</label>
190
+ </div>
191
+ <div class="ui pointing red basic label" v-show="errors[attribute.name]">
192
+ <span style="color: red" v-for="(error, index) in errors[attribute.name]">
193
+ <span v-if="index > 0">,</span> {{ error }}
194
+ </span>
195
+ </div>
196
+ </div>
197
+ <div class="field" v-if="attribute.type != 'select' && attribute.type != 'multiSelect' && attribute.type != 'textarea' && attribute.type != 'checkbox'">
198
+ <label :for="'model_' + attribute.display_name">{{ attribute.display_name }}</label>
199
+ <input :type="attribute.type" :id="'model_' + attribute.display_name" v-if="attribute.model_prefix" v-model="model[attribute.model_prefix][attribute.name]">
200
+ <input :type="attribute.type" :id="'model_' + attribute.display_name" v-else v-model="model[attribute.name]">
201
+ <div class="ui pointing red basic label" v-show="errors[attribute.name]">
202
+ <span style="color: red" v-for="(error, index) in errors[attribute.name]">
203
+ <span v-if="index > 0">,</span> {{ error }}
204
+ </span>
205
+ </div>
206
+ </div>
207
+ </div>
208
+ </form>
209
+ </script>
210
+ <!-- NOTE: memo-->
211
+ <!-- <div class="row well well-sm">
212
+ <model-row is="model-row" v-for="model in models" :model="model"></model-row>
213
+ </div> -->
214
+ <!-- ┌───────────────────────────────────────┐ -->
215
+ <!-- │ ↓ -->
216
+ <!-- v-for model in models 這個 model 會透過 :model="model" 傳值到 template,無法直接使用 v-for 迴圈出來的 model -->
217
+ <!-- │
218
+ In model-row component props: { ↓
219
+ model: Object
220
+ }
221
+ -->
@@ -0,0 +1,4 @@
1
+ module VueCrud
2
+ class Engine < Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module VueCrud
2
+ VERSION = "0.1.0"
3
+ end
data/lib/vue_crud.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "vue_crud/version"
2
+ require "vue_crud/engine"
3
+ require "generators/vue_crud/install_generator"
4
+ module VueCrud
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,295 @@
1
+ $(document).ajaxStart(function() { Pace.restart(); });
2
+ var suffix = '.json';
3
+ Vue.config.devtools = true;
4
+ Pace.on('done', function() {
5
+ $('#form-progress').val('0');
6
+ });
7
+ var event_hub = new Vue();
8
+ function sleep(time) {
9
+ return new Promise((resolve) => setTimeout(resolve, time));
10
+ }
11
+ function obj_to_json(obj) {
12
+ return JSON.parse(JSON.stringify(obj));
13
+ }
14
+ var model_row_mixin = {}
15
+ var root_mixin = {}
16
+ function updateQueryStringParam(key, value) {
17
+ baseUrl = [location.protocol, '//', location.host, location.pathname].join('');
18
+ urlQueryString = document.location.search;
19
+ var newParam = key + '=' + value,
20
+ params = '?' + newParam;
21
+
22
+ // If the "search" string exists, then build params from it
23
+ if (urlQueryString) {
24
+ keyRegex = new RegExp('([\?&])' + key + '[^&]*');
25
+ // If param exists already, update it
26
+ if (urlQueryString.match(keyRegex) !== null) {
27
+ params = urlQueryString.replace(keyRegex, "$1" + newParam);
28
+ } else { // Otherwise, add it to end of query string
29
+ params = urlQueryString + '&' + newParam;
30
+ }
31
+ }
32
+ window.history.replaceState({}, "", baseUrl + params);
33
+ }
34
+ function getParameterByName(name) {
35
+ var url = window.location.href;
36
+ name = name.replace(/[\[\]]/g, "\\$&");
37
+ var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
38
+ results = regex.exec(url);
39
+ if (!results) return '';
40
+ if (!results[2]) return '';
41
+ return decodeURIComponent(results[2].replace(/\+/g, " "));
42
+ }
43
+ function vue_init() {
44
+ Vue.filter('datetime', function (value) {
45
+ return new Date(value).toLocaleString();
46
+ })
47
+
48
+ var modelRowComponent = Vue.component('model-row', {
49
+ mixins: [model_row_mixin],
50
+ template: '#model-row',
51
+ props: {
52
+ model: Object,
53
+ selected_attribute: String,
54
+ info: Object
55
+ },
56
+ data: function() {
57
+ return {
58
+ progress: '0',
59
+ errors: {},
60
+ modified: false,
61
+ customMode: false,
62
+ deleteMode: false,
63
+ is_success: false
64
+ }
65
+ },
66
+ watch: {
67
+ model: {
68
+ handler: function (value, old_value) {
69
+ // old_value and value(model self) will be changed on Computed method
70
+ // Only watch model's data change so set value === old_value
71
+ // value === old_value means model not change
72
+ if(value === old_value) {
73
+ this.modified = true;
74
+ this.is_success = false;
75
+ }
76
+ },
77
+ deep: true
78
+ }
79
+ },
80
+ mounted: function() {
81
+ event_hub.$on('update_progress', function(progress) {
82
+ this.progress = progress;
83
+ }.bind(this));
84
+
85
+ event_hub.$on('cancel_customMode', function() {
86
+ this.customMode = false;
87
+ }.bind(this));
88
+ },
89
+ methods: {
90
+ deleteModel: function () {
91
+ var that = this;
92
+ that.deleteMode = true;
93
+ if(confirm("Are you sure?") == true) {
94
+ $.ajax({
95
+ method: 'DELETE',
96
+ url: that.info.url_prefix + '/' + that.model.id + suffix,
97
+ success: function(res) {
98
+ $(that.$el).remove();
99
+ },
100
+ error: function(res) {
101
+ that.deleteMode = false;
102
+ }
103
+ })
104
+ }
105
+ else {
106
+ that.deleteMode = false;
107
+ }
108
+ },
109
+ updateModel: function() {
110
+ var that = this;
111
+ var modal = $('#editModal_' + that.model.id);
112
+ $.ajax({
113
+ method: 'PATCH',
114
+ data: {
115
+ model: that.model,
116
+ },
117
+ url: that.info.url_prefix + '/' + that.model.id + suffix,
118
+ beforeSend: function() {
119
+ modal.find('.dimmer').toggleClass('active');
120
+ $('.progress-bar').css('width', '0');
121
+ },
122
+ success: function(res) {
123
+ that.errors = {};
124
+ that.modified = false;
125
+ that.is_success = true;
126
+ sleep(500).then(() => {
127
+ modal.find('.dimmer').toggleClass('active');
128
+ modal.modal('hide');
129
+ });
130
+ sleep(1500).then(() => {
131
+ that.is_success = false;
132
+ });
133
+ },
134
+ error: function(res) {
135
+ that.errors = res.responseJSON.errors;
136
+ modal.find('.dimmer').toggleClass('active');
137
+ }
138
+ });
139
+ }
140
+ }
141
+ })
142
+
143
+ var modelsVue = new Vue({
144
+ mixins: [root_mixin],
145
+ el: '#models',
146
+ data: {
147
+ models: [],
148
+ info: {
149
+ url_prefix: '',
150
+ titles: {},
151
+ structure: {},
152
+ model_attributes: []
153
+ },
154
+ model: {},
155
+ errors: {},
156
+ progress: '0',
157
+ countOfPage: 9,
158
+ currentPage: getParameterByName("p") || 1,
159
+ searchQuery: getParameterByName("q"),
160
+ filteredModelCount: null,
161
+ is_calculating: false,
162
+ model_prefix: getParameterByName("mp"),
163
+ selected_attribute: getParameterByName("sa")
164
+ },
165
+ mounted: function() {
166
+ var that = this;
167
+ $.ajax({
168
+ url: window.location.pathname + '/info' + suffix,
169
+ success: function(res) {
170
+ that.info = res;
171
+ that.model = obj_to_json(that.info.structure);
172
+ $.ajax({
173
+ url: that.info.url_prefix + suffix,
174
+ success: function(res) {
175
+ that.models = res;
176
+ }
177
+ });
178
+ }
179
+ });
180
+ event_hub.$on('update_progress', function(progress) {
181
+ this.progress = progress;
182
+ }.bind(this));
183
+ $('#form-progress').change(function(){
184
+ event_hub.$emit('update_progress', $(this).val());
185
+ });
186
+ $(document).delegate('.attribute_option', 'click', function(event) {
187
+ var model_prefix = $('.attribute_select').find('.item.selected').attr('model_prefix');
188
+ var selected_attribute = $('.attribute_select').find('.item.selected').attr('target') || "id";
189
+ that.model_prefix = model_prefix;
190
+ that.selected_attribute = selected_attribute;
191
+ updateQueryStringParam('mp', that.model_prefix);
192
+ updateQueryStringParam('sa', that.selected_attribute);
193
+ });
194
+ },
195
+ computed: {
196
+ searchStatus: function() {
197
+ if (this.is_calculating) {
198
+ return 'Loading...'
199
+ } else {
200
+ return '✓ Done';
201
+ }
202
+ },
203
+ pageStart: function() {
204
+ var that = this;
205
+ return (that.currentPage - 1) * that.countOfPage;
206
+ },
207
+ totalPage: function() {
208
+ var that = this;
209
+ if(that.searchQuery.trim() === '') {
210
+ return Math.ceil(that.models.length / that.countOfPage);
211
+ }
212
+ else{
213
+ return Math.ceil(that.filteredModelCount / that.countOfPage);
214
+ }
215
+ },
216
+ filteredModels: function() {
217
+ var that = this;
218
+ that.is_calculating = true;
219
+ var result = that.models.filter(function (model) {
220
+ if(that.model_prefix.length > 0) {
221
+ return String(model[that.model_prefix][that.selected_attribute]).indexOf(that.searchQuery) !== -1;
222
+ }
223
+ else {
224
+ return String(model[that.selected_attribute]).indexOf(that.searchQuery) !== -1;
225
+ }
226
+ });
227
+ that.filteredModelCount = result.length
228
+ setTimeout(function () {
229
+ that.is_calculating = false
230
+ }, 500)
231
+ return result.slice(
232
+ that.pageStart,
233
+ that.countOfPage + that.pageStart
234
+ );
235
+ }
236
+ },
237
+ watch: {
238
+ searchQuery: function () {
239
+ this.currentPage = 1;
240
+ updateQueryStringParam('q', this.searchQuery);
241
+ updateQueryStringParam('p', 1);
242
+ }
243
+ },
244
+ methods: {
245
+ setPage: function(idx){
246
+ if( idx <= 0 || idx > this.totalPage ){
247
+ return;
248
+ }
249
+ this.currentPage = idx;
250
+ updateQueryStringParam('p', this.currentPage);
251
+ },
252
+ createModel: function () {
253
+ var that = this;
254
+ $.ajax({
255
+ method: 'POST',
256
+ data: {
257
+ model: that.model,
258
+ },
259
+ url: that.info.url_prefix + suffix,
260
+ before: function() {
261
+ $('.new_modal').find('.dimmer').toggleClass('active');
262
+ $('.progress-bar').css('width', '0');
263
+ },
264
+ success: function(res) {
265
+ var modal = $(that.$el).parents('.modal');
266
+ that.errors = {};
267
+ that.model = obj_to_json(that.info.structure);
268
+ that.models.push(res);
269
+ sleep(500).then(() => {
270
+ $('.new_modal').find('.dimmer').toggleClass('active');
271
+ $('.new_modal').modal('hide');
272
+ });
273
+ },
274
+ error: function(res) {
275
+ that.errors = res.responseJSON.errors;
276
+ $('.new_modal').find('.dimmer').toggleClass('active');
277
+ }
278
+ });
279
+ }
280
+ }
281
+ })
282
+ }
283
+ $(document).ready(function() {
284
+ $(document).delegate('[data-modal]', 'click', function(event) {
285
+ var target = $(this).data('modal');
286
+ $(target).modal({
287
+ onShow: function() {
288
+ $(this).find('select.ui.dropdown').dropdown();
289
+ },
290
+ onHide: function() {
291
+ event_hub.$emit('cancel_customMode');
292
+ }
293
+ }).modal('show');
294
+ });
295
+ });
@@ -0,0 +1,19 @@
1
+ .ui.cards > .card > .extra a.save_now {
2
+ color: rgb(33, 133, 208);
3
+ opacity: 1;
4
+ }
5
+ .progress {
6
+ margin-bottom: 0;
7
+ border-radius: 0;
8
+ height: 10px;
9
+ }
10
+ #form-progress {
11
+ position: fixed;
12
+ top: -9999px;
13
+ }
14
+ .summary.highlight {
15
+ border: 2px solid #a90000;
16
+ }
17
+ .inline-block {
18
+ display: inline-block;
19
+ }
data/vue_crud.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vue_crud/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vue_crud"
8
+ spec.version = VueCrud::VERSION
9
+ spec.authors = ["Donald Chiang"]
10
+ spec.email = ["dc@mynet.com.tw"]
11
+ spec.license = "MIT"
12
+ spec.summary = %q{Vue js CRUD scaffold}
13
+ spec.description = %q{Vue js CRUD scaffold}
14
+ spec.homepage = "http://www.mynet.com.tw"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = 'http://mygemserver.com'
20
+ # else
21
+ # raise "RubyGems 2.0 or newer is required to protect against " \
22
+ # "public gem pushes."
23
+ # end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.13"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "minitest", "~> 5.0"
35
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vue_crud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Donald Chiang
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-11-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: Vue js CRUD scaffold
56
+ email:
57
+ - dc@mynet.com.tw
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - README.md
66
+ - Rakefile
67
+ - bin/console
68
+ - bin/setup
69
+ - lib/generators/vue_crud/install_generator.rb
70
+ - lib/generators/vue_crud/templates/vue_crud.html
71
+ - lib/vue_crud.rb
72
+ - lib/vue_crud/engine.rb
73
+ - lib/vue_crud/version.rb
74
+ - vendor/assets/javascripts/vue_crud.js
75
+ - vendor/assets/stylesheets/vue_crud.css
76
+ - vue_crud.gemspec
77
+ homepage: http://www.mynet.com.tw
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.5.1
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Vue js CRUD scaffold
101
+ test_files: []