flexite 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/flexite/tree.js.erb +7 -0
- data/app/controllers/flexite/application_controller.rb +0 -6
- data/app/controllers/flexite/histories_controller.rb +14 -0
- data/app/forms/flexite/config/form.rb +4 -0
- data/app/forms/flexite/entry/array_form.rb +4 -0
- data/app/forms/flexite/entry/form.rb +8 -0
- data/app/helpers/flexite/entries_helper.rb +2 -1
- data/app/models/concerns/flexite/with_history.rb +49 -0
- data/app/models/flexite/bool_entry.rb +8 -2
- data/app/models/flexite/config.rb +6 -1
- data/app/models/flexite/entry.rb +6 -1
- data/app/models/flexite/history.rb +21 -0
- data/app/models/flexite/history_attribute.rb +6 -0
- data/app/models/flexite/int_entry.rb +1 -0
- data/app/models/flexite/sym_entry.rb +1 -0
- data/app/services/flexite/action_service.rb +2 -2
- data/app/services/flexite/entry/update_service.rb +6 -1
- data/app/views/flexite/configs/_form.html.haml +3 -0
- data/app/views/flexite/entries/_form.html.haml +3 -1
- data/app/views/flexite/entries/types/_bool_entry.html.haml +2 -0
- data/app/views/flexite/entries/types/_int_entry.html.haml +2 -0
- data/app/views/flexite/entries/types/_str_entry.html.haml +2 -0
- data/app/views/flexite/entries/types/_sym_entry.html.haml +1 -1
- data/app/views/flexite/histories/_history.html.haml +11 -0
- data/app/views/flexite/histories/index.js.haml +1 -0
- data/app/views/flexite/histories/restore.js.haml +4 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20180618104507_create_flexite_histories.rb +12 -0
- data/db/migrate/20180618115057_create_flexite_history_attributes.rb +13 -0
- data/lib/flexite/configuration.rb +2 -1
- data/lib/flexite/engine.rb +1 -0
- data/lib/flexite/version.rb +1 -1
- data/test/dummy/config/application.yml +1 -598
- data/test/dummy/config/environments/development.rb +0 -2
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +21 -1
- data/test/dummy/log/development.log +140255 -0
- data/test/dummy/tmp/cache/assets/C67/060/sprockets%2Ffaf176441f0544dd2b51901280044b40 +0 -0
- data/test/dummy/tmp/cache/assets/C9D/530/sprockets%2Fdcd49c063327c12052812f41c20a8e74 +0 -0
- data/test/dummy/tmp/cache/assets/CA3/270/sprockets%2F502b740063f8ec15e7e12811da71c772 +0 -0
- data/test/dummy/tmp/cache/assets/CDC/060/sprockets%2F8ff1d307d1b36810549d0829722b7aea +0 -0
- data/test/dummy/tmp/cache/assets/CDE/120/sprockets%2F5fd8b3fa3724451579552aed373410ce +0 -0
- data/test/dummy/tmp/cache/assets/CF8/980/sprockets%2F4e5077b95460dc34d7c9d7d9880e7b47 +0 -0
- data/test/dummy/tmp/cache/assets/D00/4C0/sprockets%2F603c6d7b825c2f4a6422b3d4af4e6203 +0 -0
- data/test/dummy/tmp/cache/assets/D00/C40/sprockets%2F999847c008fb4ce26fff5607c39d8358 +0 -0
- data/test/dummy/tmp/cache/assets/D09/A30/sprockets%2F2a71e20a2f3544acb51956504cd8d8e9 +0 -0
- data/test/dummy/tmp/cache/assets/D0D/E60/sprockets%2F90ea9eaa4671ec2d76703bae31972634 +0 -0
- data/test/dummy/tmp/cache/assets/D2A/160/sprockets%2Fbe17d4d0be4b381500e2824bbe273d70 +0 -0
- data/test/dummy/tmp/cache/assets/D2E/700/sprockets%2Fb21f85e0940bbcb3a8914c9cb0b07218 +0 -0
- data/test/dummy/tmp/cache/assets/D39/CD0/sprockets%2F0e8f6981475e49ea9fe14698fa57e4e9 +0 -0
- data/test/dummy/tmp/cache/assets/D40/590/sprockets%2F181dd5673b58f1ec4c89e50028bfad60 +0 -0
- data/test/dummy/tmp/cache/assets/D46/870/sprockets%2Fd880bdf72c5d0009b88fda8521439dc8 +0 -0
- data/test/dummy/tmp/cache/assets/D48/5F0/sprockets%2Fe6a83afb2d92f4692ffb391b5285a518 +0 -0
- data/test/dummy/tmp/cache/assets/D4B/A20/sprockets%2Febde89014596e655c35df9c4a01ee636 +0 -0
- data/test/dummy/tmp/cache/assets/D54/A50/sprockets%2Ff49839d906f69fd92904ebac07a3a38e +0 -0
- data/test/dummy/tmp/cache/assets/D69/B50/sprockets%2F4186e2787004e19ceb0c4afed46cf04b +0 -0
- data/test/dummy/tmp/cache/assets/D6D/C20/sprockets%2F112e96fea93f5f1e31d2077f1cdaf283 +0 -0
- data/test/dummy/tmp/cache/assets/D7A/8F0/sprockets%2F8eefc5f9824d950317a5c4a2e68b3c4e +0 -0
- data/test/dummy/tmp/cache/assets/DB3/360/sprockets%2F24b1f98ad736884b91d6ebeb2fc68ed8 +0 -0
- data/test/dummy/tmp/cache/assets/DD2/E90/sprockets%2Ff01f48c96ba588d15b20dd57ed3ccb7f +0 -0
- data/test/dummy/tmp/cache/assets/DEE/0C0/sprockets%2Feedcd74856542eedb5ea3ab1b1502ca4 +0 -0
- data/test/dummy/tmp/cache/assets/DF1/210/sprockets%2Ff4fe7dba1445ba1b668aaa1bd34ca984 +0 -0
- data/test/dummy/tmp/cache/assets/E44/790/sprockets%2Fefb8d8ea9e97da9d675a8bfa1d5de343 +0 -0
- data/test/fixtures/flexite/histories.yml +11 -0
- data/test/fixtures/flexite/history_attributes.yml +11 -0
- data/test/unit/flexite/history_attribute_test.rb +9 -0
- data/test/unit/flexite/history_test.rb +9 -0
- metadata +47 -4
- data/test/dummy/db/test.sqlite3 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e56e14f785289341cecf9f123fcdff29203d6c3
|
4
|
+
data.tar.gz: df1b2dd7892a9aa29bc89fc80523eaac105db6bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 358346c815e81f5f9e08e23a020dba9604872b8d52b65e448a0d96c1e5d8019a597ba2471c564f28f80ee205b5f4e4c8b592f7f57629c8b1c888a71665d96e63
|
7
|
+
data.tar.gz: 2127e0c6ded192a39a38ce9ffb7b95fd7d9b981281e173cf016f3e16744b21d8ede07484e499f829992060aab63151a32f7996dae9f187dd2a608385eea96cb6
|
@@ -58,6 +58,7 @@ function Tree(selector) {
|
|
58
58
|
},
|
59
59
|
onNodeUnselected: function (event, node) {
|
60
60
|
$flexite("#section-2").html("");
|
61
|
+
$flexite("#section-3").html("");
|
61
62
|
}
|
62
63
|
})
|
63
64
|
})
|
@@ -68,6 +69,12 @@ function Tree(selector) {
|
|
68
69
|
self.init();
|
69
70
|
}
|
70
71
|
|
72
|
+
this.unselectAll = function () {
|
73
|
+
tree.treeview("getSelected").forEach(function (node) {
|
74
|
+
tree.treeview("unselectNode", node);
|
75
|
+
});
|
76
|
+
}
|
77
|
+
|
71
78
|
this.addNode = function (jsonNode, parentId) {
|
72
79
|
tree.treeview(true).addToParent(JSON.parse(jsonNode), parentId);
|
73
80
|
}
|
@@ -2,12 +2,6 @@ require_dependency 'flexite/service_factory'
|
|
2
2
|
|
3
3
|
module Flexite
|
4
4
|
class ApplicationController < ActionController::Base
|
5
|
-
append_view_path File.join(Flexite::Engine.root, "app/views/flexite/#{controller_name}")
|
6
|
-
|
7
|
-
def self.inherited(subclass)
|
8
|
-
subclass.append_view_path File.join(Flexite::Engine.root, "app/views/flexite/#{subclass.controller_name}")
|
9
|
-
end
|
10
|
-
|
11
5
|
private
|
12
6
|
|
13
7
|
def service_response(result)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_dependency 'flexite/application_controller'
|
2
|
+
|
3
|
+
module Flexite
|
4
|
+
class HistoriesController < ApplicationController
|
5
|
+
def index
|
6
|
+
@histories = History.includes(:history_attributes).where(entity_id: params[:entity_id], entity_type: params[:entity_type].camelize)
|
7
|
+
end
|
8
|
+
|
9
|
+
def restore
|
10
|
+
History.includes(:history_attributes).find(params[:id]).restore
|
11
|
+
flash[:success] = 'Entity was restored from history'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -33,11 +33,12 @@ module Flexite
|
|
33
33
|
concat(form.simple_fields_for(:entries, entry_form, index: index) do |fields|
|
34
34
|
delete_link = link_to 'Delete', destroy_array_entries_path(id: entry.id, selector: "#{fields.object_name}-#{index}-#{entry.id}"),
|
35
35
|
remote: true, method: :delete, class: 'btn btn-danger'
|
36
|
+
history_link = link_to 'History', entity_history_path(entry_form.id, entry_form.history_type), remote: true, class: 'btn btn-default'
|
36
37
|
|
37
38
|
concat(content_tag(:div, id: "#{fields.object_name}-#{index}-#{entry.id}") do
|
38
39
|
concat fields.input :id, as: :hidden
|
39
40
|
concat fields.input :type, as: :hidden
|
40
|
-
concat render "types/#{entry_form.view_type}", f: fields, delete_link: delete_link
|
41
|
+
concat render "flexite/entries/types/#{entry_form.view_type}", f: fields, delete_link: delete_link, history_link: history_link
|
41
42
|
end)
|
42
43
|
end)
|
43
44
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Flexite
|
2
|
+
module WithHistory
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
after_save :save_history
|
7
|
+
|
8
|
+
def self.history_attributes(*attributes)
|
9
|
+
define_method :history_attributes do
|
10
|
+
attributes
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def restore(history)
|
16
|
+
history.history_attributes.each do |attr|
|
17
|
+
self[attr.name] = attr.value
|
18
|
+
end
|
19
|
+
|
20
|
+
self.class.skip_callback(:save, :after, :save_history)
|
21
|
+
|
22
|
+
begin
|
23
|
+
save!
|
24
|
+
ensure
|
25
|
+
self.class.set_callback(:save, :after, :save_history)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def save_history
|
32
|
+
return unless changed?
|
33
|
+
|
34
|
+
history = histories.build
|
35
|
+
|
36
|
+
History.transaction do
|
37
|
+
history_attributes.each do |attr|
|
38
|
+
history.history_attributes.build(name: attr, value: self[attr])
|
39
|
+
end
|
40
|
+
|
41
|
+
history.save
|
42
|
+
end
|
43
|
+
|
44
|
+
if history.invalid?
|
45
|
+
errors.set(:history, history.full_messages)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Flexite
|
2
2
|
class BoolEntry < Entry
|
3
3
|
def value
|
4
|
-
self[:value].to_i
|
4
|
+
self[:value].to_i == 1 ? true : false
|
5
5
|
end
|
6
6
|
|
7
7
|
def form
|
@@ -11,8 +11,14 @@ module Flexite
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def check_value
|
14
|
+
unless self[:value].respond_to?(:to_i)
|
15
|
+
errors.add(:value, 'should respond to #to_i')
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
|
14
19
|
unless [1, 0].include?(self[:value].to_i)
|
15
|
-
errors.add(:value, 'not a boolean')
|
20
|
+
errors.add(:value, 'not a valid boolean')
|
21
|
+
false
|
16
22
|
end
|
17
23
|
end
|
18
24
|
end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
module Flexite
|
2
2
|
class Config < ActiveRecord::Base
|
3
|
+
include WithHistory
|
3
4
|
attr_accessible :name
|
5
|
+
history_attributes :name, :config_id
|
6
|
+
delegate :value, to: :entry, allow_nil: true
|
7
|
+
|
4
8
|
belongs_to :config, touch: true
|
5
9
|
belongs_to :owner, foreign_key: :created_by
|
6
10
|
has_one :entry, as: :parent, dependent: :destroy
|
7
11
|
has_many :configs, dependent: :destroy
|
12
|
+
has_many :histories, as: :entity, dependent: :destroy
|
8
13
|
|
9
14
|
scope :not_selectable, -> { select([:id, :name]).where(selectable: false) }
|
10
|
-
|
15
|
+
|
11
16
|
validates :name, uniqueness: { scope: :config_id }
|
12
17
|
|
13
18
|
def to_tree_node
|
data/app/models/flexite/entry.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
module Flexite
|
2
2
|
class Entry < ActiveRecord::Base
|
3
|
-
|
3
|
+
include WithHistory
|
4
4
|
attr_accessible :value
|
5
|
+
history_attributes :value
|
6
|
+
|
7
|
+
belongs_to :parent, polymorphic: true, touch: true
|
8
|
+
has_many :histories, as: :entity, dependent: :destroy
|
9
|
+
|
5
10
|
before_save :check_value, :cast_value
|
6
11
|
|
7
12
|
def view_value
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Flexite
|
2
|
+
class History < ActiveRecord::Base
|
3
|
+
belongs_to :entity, polymorphic: true
|
4
|
+
has_many :history_attributes, dependent: :destroy
|
5
|
+
|
6
|
+
after_save :check_limit
|
7
|
+
|
8
|
+
validates_presence_of :entity
|
9
|
+
|
10
|
+
def restore
|
11
|
+
entity.restore(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def check_limit
|
17
|
+
return if entity.histories.count <= Flexite.config.history_limit
|
18
|
+
entity.histories.order(:id).first.destroy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,6 +1,4 @@
|
|
1
1
|
class Flexite::ActionService
|
2
|
-
extend ActiveSupport::Autoload
|
3
|
-
autoload :Result
|
4
2
|
|
5
3
|
def initialize(form, params = {})
|
6
4
|
@form = form
|
@@ -33,3 +31,5 @@ class Flexite::ActionService
|
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
34
|
+
|
35
|
+
require_dependency 'flexite/action_service/result'
|
@@ -6,8 +6,13 @@ module Flexite
|
|
6
6
|
if @form.invalid?
|
7
7
|
return failure
|
8
8
|
end
|
9
|
+
record = @form.type.constantize.find(@form.id)
|
10
|
+
record.value = @form.value
|
11
|
+
|
12
|
+
if record.changed?
|
13
|
+
record.save
|
14
|
+
end
|
9
15
|
|
10
|
-
@form.type.constantize.update(@form.id, value: @form.value)
|
11
16
|
success
|
12
17
|
end
|
13
18
|
|
@@ -5,3 +5,6 @@
|
|
5
5
|
input_html: { class: 'form-control', placeholder: 'Parent' }, label: false, prompt: 'Select parent'
|
6
6
|
= f.input :selectable, as: :boolean, label: false, wrapper_html: { class: 'checkbox' }
|
7
7
|
= f.button :submit, class: 'btn btn-success'
|
8
|
+
|
9
|
+
- if @config_form.persisted?
|
10
|
+
= link_to 'History', entity_history_path(@config_form.id, @config_form.history_type), remote: true, class: 'btn btn-default'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
= simple_form_for @entry_form, remote: true do |f|
|
2
2
|
- if @entry_form.type.present?
|
3
|
-
= render "types/#{@entry_form.view_type}", f: f
|
3
|
+
= render "flexite/entries/types/#{@entry_form.view_type}", f: f
|
4
4
|
= f.input :id, as: :hidden
|
5
5
|
= f.input :type, as: :hidden
|
6
6
|
= f.input :parent_id, as: :hidden
|
@@ -9,3 +9,5 @@
|
|
9
9
|
|
10
10
|
- if @entry_form.persisted?
|
11
11
|
= link_to 'Delete', entry_path(f.object, type: @entry_form.type), method: :delete, remote: true, class: 'btn btn-danger'
|
12
|
+
- if @entry_form.with_history?
|
13
|
+
= link_to 'History', entity_history_path(@entry_form.id, @entry_form.history_type), remote: true, class: 'btn btn-default'
|
@@ -1 +1 @@
|
|
1
|
-
= render 'types/str_entry', f: f, delete_link: local_assigns[:delete_link]
|
1
|
+
= render 'flexite/entries/types/str_entry', f: f, delete_link: local_assigns[:delete_link]
|
@@ -0,0 +1,11 @@
|
|
1
|
+
- history.history_attributes.each do |attr|
|
2
|
+
.history-attribute
|
3
|
+
= "#{attr.name}: "
|
4
|
+
= attr.value
|
5
|
+
|
6
|
+
.history-created-at
|
7
|
+
created at:
|
8
|
+
= history.created_at.to_s(:db)
|
9
|
+
|
10
|
+
.history-restore
|
11
|
+
= link_to 'Restore', history_restore_path(history), remote: true, class: 'btn btn-warning'
|
@@ -0,0 +1 @@
|
|
1
|
+
$flexite("#section-3").html("#{j render @histories}");
|
data/config/routes.rb
CHANGED
@@ -13,5 +13,7 @@ Flexite::Engine.routes.draw do
|
|
13
13
|
get :reload, on: :collection
|
14
14
|
end
|
15
15
|
|
16
|
+
get ':entity_id/:entity_type/history', to: 'histories#index', as: :entity_history, constraints: { entity_type: /.*/ }
|
17
|
+
get ':id/restore', to: 'histories#restore', as: :history_restore
|
16
18
|
root to: 'application#index'
|
17
19
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateFlexiteHistories < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :flexite_histories do |t|
|
4
|
+
t.references :entity, polymorphic: true
|
5
|
+
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :flexite_histories, :entity_id
|
10
|
+
add_index :flexite_histories, :entity_type
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateFlexiteHistoryAttributes < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :flexite_history_attributes do |t|
|
4
|
+
t.references :history
|
5
|
+
t.string :name
|
6
|
+
t.string :value
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :flexite_history_attributes, :history_id
|
12
|
+
end
|
13
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Flexite
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :paths, :root_cache_key, :source_roots, :hierarchy
|
4
|
-
attr_accessor :app_link, :app_name
|
4
|
+
attr_accessor :app_link, :app_name, :history_limit
|
5
5
|
attr_reader :cache
|
6
6
|
|
7
7
|
def initialize
|
@@ -11,6 +11,7 @@ module Flexite
|
|
11
11
|
@app_link = '/'
|
12
12
|
@source_roots = {}
|
13
13
|
@hierarchy = {}
|
14
|
+
@history_limit = 10
|
14
15
|
end
|
15
16
|
|
16
17
|
def cache_store=(*args)
|
data/lib/flexite/engine.rb
CHANGED
data/lib/flexite/version.rb
CHANGED