admin_it 1.0.9 → 1.0.10
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 +4 -4
- data/README.md +9 -0
- data/README_RU.md +82 -3
- data/app/assets/stylesheets/admin_it/admin_it.css +1 -0
- data/app/views/admin_it/context/_show.html.slim +26 -5
- data/app/views/admin_it/context/_table.html.slim +5 -1
- data/app/views/layouts/admin_it.html.slim +1 -1
- data/app/views/layouts/admin_it_dialog.html.slim +1 -1
- data/lib/admin_it/context/collection_context.rb +6 -1
- data/lib/admin_it/context/single_context.rb +23 -9
- data/lib/admin_it/data/active_record.rb +20 -3
- data/lib/admin_it/field/field.rb +20 -17
- data/lib/admin_it/helpers/table.rb +7 -0
- data/lib/admin_it/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b4af7fc6796fe6d148a1d91d62449d2cca40e44
|
4
|
+
data.tar.gz: dcd1542a809878391c15ed5604e74d26b1d7572d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70d197f764d7b3126e564d7aeaf53cc47ef999f06d00a79db152defaad223725accbc64b7000cc07e92d55e964e2c856e48237c0176df300214081fec304cb62
|
7
|
+
data.tar.gz: b8886811264b9aaef4cbed1c6404eba4a93de24361785322cc86ed8ae7d65a9665136ff3d7cbc4359cf3b50ab872eed31dee8032c4f277d329582d239891240d
|
data/README.md
CHANGED
data/README_RU.md
CHANGED
@@ -23,19 +23,98 @@ bundle install
|
|
23
23
|
|
24
24
|
Конфигурация производится в файле `config/initializers/admin_it.rb`. На данный момент доступны следующие переменные:
|
25
25
|
|
26
|
+
`config.root`: папка, содержащая определения ресурсов и другие настройки. По умолчанию: `app/admin_it`.
|
27
|
+
|
28
|
+
`config.controller`: класс контроллера, от которого наследуются все контроллеры, используемые библиотекой `admin_it`. По умолчанию для Rails: `ActionController::Base`.
|
29
|
+
|
30
|
+
Пример файла конфигурации:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'admin_it'
|
34
|
+
|
35
|
+
AdminIt.config do |config|
|
36
|
+
config.root = 'admin_it'
|
37
|
+
end
|
38
|
+
```
|
26
39
|
|
27
40
|
# Использование
|
28
41
|
|
42
|
+
Библиотека оперирует такими понятиями, как:
|
43
|
+
|
44
|
+
* **Ресурс (resource)** - набор данных, который можно просматривать или изменять. Как правило, ресурс соответствует таблице базы данных. Для каждого ресурса библиотека создаёт отдельный класс контроллера.
|
45
|
+
* **Контекст (context)** - представление данных, или форма отображения данных. Контекст может быть для отдельной записи (`единичный контекст`) или для набора данных (`множественный контекст`). На данный момент библиотека предоставляет следующие контексты:
|
46
|
+
- единичные:
|
47
|
+
+ `show` - отображение или удаление записи
|
48
|
+
+ `edit` - форма для редактирования записи
|
49
|
+
+ `new` - форма для создания записи
|
50
|
+
- множественные:
|
51
|
+
+ `table` - таблица данных
|
52
|
+
+ `tiles` - набор плиток
|
53
|
+
+ `list` - список (пока не работает)
|
54
|
+
* **Поле (field)** - представляет поле (колонку) данных. Имеет следующие атрибуты:
|
55
|
+
- readable
|
56
|
+
- writable
|
57
|
+
- visible
|
58
|
+
* **Фильтр (filter)** - фильтр данных. Пока не закончено.
|
59
|
+
|
60
|
+
Для создания интерфейса управления данными, необходимо определить ресурс. Делается это в файле с расширением `.rb` в папке, указанной в конфигурации, например:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
AdminIt.resource :location do
|
64
|
+
icon 'globe'
|
65
|
+
|
66
|
+
use_contexts except: :list
|
67
|
+
|
68
|
+
collection do
|
69
|
+
use_fields except: %i(created_at updated_at geo_point geo_data okato
|
70
|
+
kladr_code lowcase_name short_name area_children
|
71
|
+
region_children region area)
|
72
|
+
use_filters :type_name_value, :level_value
|
73
|
+
end
|
74
|
+
|
75
|
+
context :tiles do
|
76
|
+
header :name
|
77
|
+
end
|
78
|
+
|
79
|
+
context :table do
|
80
|
+
use_fields :name, :level, :*
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
В данном файле создается ресурс для данных класса `Location`. Ресурс использует для отображения иконку "глобус". (Все иконки можно найти [здесь](http://fortawesome.github.io/Font-Awesome/icons/) - имена необходимо указывать без суффикса `fa-`).
|
86
|
+
|
87
|
+
Далее указывается, что не нужно использовать (использовать все, кроме) контекст `:list`, посокльку его описание ещё не закончено.
|
88
|
+
|
89
|
+
Далее выполняется блок для всех множественных контекстов (поскольку `:list` исключён, то это `:table` и `:tiles`). Т.е. все множественные контексты будут использовать указанные в данном блоке настройки. В нашем случае это сокращенный список полей для удобства отображения и также, сокращённый список фильтров, имеющиё смысл в данном контексте.
|
90
|
+
|
91
|
+
Далее идет индивидуальная настройка каждого контекста (не указанные явно контексты принимают все значения по-умолчанию).
|
92
|
+
|
93
|
+
Для контекста `:tiles` указывается имя поля, служащее заголоком плитки
|
94
|
+
|
95
|
+
Для контекста `:table` указывается порядок следования полей: сначала `:name`, затем `:level`, затем все остальные в порядке по-умолчанию. Символ `:*` заменяется на все имеющиеся для данного контекста поля, не указанные в команде явно.
|
96
|
+
|
29
97
|
# Планы
|
30
98
|
|
31
99
|
* Поркытие тестами
|
32
100
|
* Редактирование/создание записей
|
33
101
|
|
34
|
-
|
102
|
+
# Изменения
|
35
103
|
|
36
|
-
|
104
|
+
`1.0.10`
|
37
105
|
|
38
|
-
|
106
|
+
* добавлен индикатор сортировки в заголовках таблиц
|
107
|
+
* добавлены вкладки для единичных контекстов
|
108
|
+
|
109
|
+
`1.0.9`
|
110
|
+
|
111
|
+
* добавлена кнопка фильтров в заголоки таблиц
|
112
|
+
|
113
|
+
`1.0.8`
|
114
|
+
|
115
|
+
* полностью переработан код DSL
|
116
|
+
* увеличено покрытие тестами
|
117
|
+
* добавлена возможность выбора набора фильтров для контекста
|
39
118
|
|
40
119
|
`1.0.7`
|
41
120
|
|
@@ -16,11 +16,32 @@
|
|
16
16
|
- if for_context.confirm == :destroy
|
17
17
|
p = t('admin_it.confirm.destroy.header')
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
-
|
22
|
-
|
23
|
-
|
19
|
+
- if for_context.sections.size > 0
|
20
|
+
ul class="nav nav-tabs"
|
21
|
+
- for_context.sections.each do |section|
|
22
|
+
li class="#{section.name == for_context.section ? 'active' : ''}"
|
23
|
+
a href="##{section.name}" data-toggle="tab"
|
24
|
+
= section.display_name
|
25
|
+
div class="tab-content"
|
26
|
+
- for_context.sections.each do |section|
|
27
|
+
div class="tab-pane #{section.name == for_context.section ? 'active' : ''}" id==section.name
|
28
|
+
- if section.fields.size > 0
|
29
|
+
dl class="dl-horizontal"
|
30
|
+
- section.fields.each do |f_name|
|
31
|
+
- f = for_context.field(f_name)
|
32
|
+
- next if f.type == :relation
|
33
|
+
dt = f.display_name
|
34
|
+
- value = f.show(for_context.entity)
|
35
|
+
- value = value.nil? ? ' '.html_safe : value.to_s
|
36
|
+
= field value, tag: 'dd'
|
37
|
+
- else
|
38
|
+
dl class="dl-horizontal"
|
39
|
+
- for_context.fields.each do |f|
|
40
|
+
- next if f.type == :relation
|
41
|
+
dt = f.display_name
|
42
|
+
- value = f.show(for_context.entity)
|
43
|
+
- value = value.nil? ? ' '.html_safe : value.to_s
|
44
|
+
= field value, tag: 'dd'
|
24
45
|
div class="clearfix"
|
25
46
|
|
26
47
|
- if for_context.confirm?
|
@@ -10,9 +10,13 @@
|
|
10
10
|
= _table.header do |header|
|
11
11
|
- for_context.headers.each do |k, h|
|
12
12
|
- opts = { :'data-toggle' => 'popup' }
|
13
|
-
-
|
13
|
+
- active_sorting = for_context.sorting.find { |s| s.index("#{k}:") == 0 }
|
14
|
+
- opts[:class] = 'text-info' unless active_sorting.nil?
|
14
15
|
= header.cell opts do
|
15
16
|
= h
|
17
|
+
- unless active_sorting.nil?
|
18
|
+
= ' '
|
19
|
+
i class="fa fa-caret-#{active_sorting.split(':').last == 'asc' ? 'down' : 'up'}"
|
16
20
|
- filter_class = for_context.all_filters(scope: :value).find do |f|
|
17
21
|
- f.field.field_name == k
|
18
22
|
- unless filter_class.nil?
|
@@ -12,6 +12,7 @@ module AdminIt
|
|
12
12
|
dsl do
|
13
13
|
dsl_block :entities, variable: :entities_getter
|
14
14
|
dsl_accessor :default_sorting
|
15
|
+
dsl_boolean :show_in_dialog
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.before_configure
|
@@ -25,6 +26,10 @@ module AdminIt
|
|
25
26
|
]
|
26
27
|
end
|
27
28
|
|
29
|
+
def self.show_in_dialog?
|
30
|
+
@show_in_dialog.nil? ? @show_in_dialog = true : @show_in_dialog == true
|
31
|
+
end
|
32
|
+
|
28
33
|
def self.collection?
|
29
34
|
true
|
30
35
|
end
|
@@ -41,7 +46,7 @@ module AdminIt
|
|
41
46
|
end
|
42
47
|
|
43
48
|
attr_accessor :entity
|
44
|
-
class_attr_reader :entities_getter, :path
|
49
|
+
class_attr_reader :entities_getter, :path, :show_in_dialog?
|
45
50
|
|
46
51
|
before_load do |store: {}, params: {}|
|
47
52
|
self.sorting = store[:sorting] || self.class.default_sorting
|
@@ -4,25 +4,39 @@ module AdminIt
|
|
4
4
|
include ExtendIt::Dsl
|
5
5
|
include Renderable
|
6
6
|
|
7
|
-
attr_reader :name, :display_name
|
7
|
+
attr_reader :name, :display_name, :fields
|
8
8
|
|
9
9
|
dsl do
|
10
10
|
dsl_accessor :name, :display_name
|
11
11
|
dsl_boolean :visible
|
12
|
+
|
13
|
+
def use_fields(*names, except: nil)
|
14
|
+
names = names.ensure_symbols
|
15
|
+
fields =
|
16
|
+
if names.nil? || names.empty?
|
17
|
+
dsl_get(:fields, default: [])
|
18
|
+
else
|
19
|
+
context = dsl_get(:context, default: nil)
|
20
|
+
names & context.fields.map(&:field_name)
|
21
|
+
end
|
22
|
+
fields -= except.ensure_symbols unless except.nil?
|
23
|
+
dsl_set(:fields, fields.uniq)
|
24
|
+
end
|
12
25
|
end
|
13
26
|
|
14
27
|
def visible?
|
15
28
|
@visible.nil? ? @visible = true : @visible == true
|
16
29
|
end
|
17
30
|
|
18
|
-
def
|
19
|
-
names.empty? ? @fields ||= [] : @fields = names
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(name, *fields, display_name: nil)
|
31
|
+
def initialize(name, context, display_name: nil)
|
23
32
|
@name = name
|
24
33
|
@display_name = display_name || name
|
25
|
-
@
|
34
|
+
@context = context
|
35
|
+
@fields = context.fields.map(&:field_name)
|
36
|
+
context.sections.each do |section|
|
37
|
+
next if section.name == name
|
38
|
+
@fields -= section.fields
|
39
|
+
end
|
26
40
|
end
|
27
41
|
end
|
28
42
|
|
@@ -53,12 +67,12 @@ module AdminIt
|
|
53
67
|
#general.display_name(I18n.t('admin_it.collection.no_data'))
|
54
68
|
general = Section.new(
|
55
69
|
:general,
|
56
|
-
|
70
|
+
self,
|
57
71
|
display_name: 'Основные свойства'
|
58
72
|
)
|
59
73
|
@sections[:general] = general
|
60
74
|
end
|
61
|
-
Section.new(name)
|
75
|
+
name == :general ? @sections[:general] : Section.new(name, self)
|
62
76
|
end
|
63
77
|
end
|
64
78
|
|
@@ -3,6 +3,21 @@ module AdminIt
|
|
3
3
|
module Resource
|
4
4
|
protected
|
5
5
|
|
6
|
+
TYPE_MAPPING = {
|
7
|
+
primary_key: :integer,
|
8
|
+
string: :string,
|
9
|
+
text: :string,
|
10
|
+
integer: :integer,
|
11
|
+
float: :float,
|
12
|
+
decimal: :float,
|
13
|
+
datetime: :datetime,
|
14
|
+
timestamp: :datetime,
|
15
|
+
time: :time,
|
16
|
+
date: :date,
|
17
|
+
binary: :binary,
|
18
|
+
boolean: :boolean
|
19
|
+
}
|
20
|
+
|
6
21
|
def default_display_name
|
7
22
|
entity_class
|
8
23
|
.model_name
|
@@ -24,7 +39,7 @@ module AdminIt
|
|
24
39
|
entity_class.columns_hash.each do |name, c|
|
25
40
|
next if exclude.include?(name)
|
26
41
|
name = name.to_sym
|
27
|
-
opts = { type: c.type }
|
42
|
+
opts = { type: TYPE_MAPPING[c.type] }
|
28
43
|
if name == :id
|
29
44
|
opts[:visible] = false
|
30
45
|
opts[:writable] = false
|
@@ -50,7 +65,7 @@ module AdminIt
|
|
50
65
|
module CollectionContext
|
51
66
|
def entities=(value)
|
52
67
|
super(value)
|
53
|
-
@count =
|
68
|
+
@count = @entities.nil? ? 0 : @entities.count
|
54
69
|
end
|
55
70
|
|
56
71
|
protected
|
@@ -70,7 +85,9 @@ module AdminIt
|
|
70
85
|
name, order = _sort.split(':')
|
71
86
|
sort[name.to_sym] = order.to_sym
|
72
87
|
end
|
73
|
-
|
88
|
+
unless collection.nil? || sort.empty?
|
89
|
+
collection = collection.order(sort)
|
90
|
+
end
|
74
91
|
collection
|
75
92
|
end
|
76
93
|
end
|
data/lib/admin_it/field/field.rb
CHANGED
@@ -15,7 +15,8 @@ module AdminIt
|
|
15
15
|
extend DisplayableName
|
16
16
|
include ExtendIt::Callbacks
|
17
17
|
|
18
|
-
TYPES = %i(unknown integer float string date relation enum
|
18
|
+
TYPES = %i(unknown integer float string date datetime time relation enum
|
19
|
+
binary)
|
19
20
|
|
20
21
|
define_callbacks :initialize
|
21
22
|
|
@@ -29,16 +30,16 @@ module AdminIt
|
|
29
30
|
dsl_block :read, :write, :render, :display
|
30
31
|
|
31
32
|
def hide
|
32
|
-
|
33
|
+
dsl_set(:visible, false)
|
33
34
|
end
|
34
35
|
|
35
36
|
def show
|
36
|
-
|
37
|
+
dsl_set(:visible, true)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
41
|
class << self
|
41
|
-
attr_reader :
|
42
|
+
attr_reader :read, :write, :render, :display, :type
|
42
43
|
|
43
44
|
protected
|
44
45
|
|
@@ -65,27 +66,29 @@ module AdminIt
|
|
65
66
|
|
66
67
|
inherited_class_reader :field_name, :entity_class
|
67
68
|
|
68
|
-
def self.create(name, _entity_class,
|
69
|
-
type: :unknown,
|
70
|
-
readable: true,
|
71
|
-
writable: true,
|
72
|
-
visible: true,
|
73
|
-
sortable: true
|
74
|
-
)
|
69
|
+
def self.create(name, _entity_class, **opts)
|
70
|
+
# type: :unknown,
|
71
|
+
# readable: true,
|
72
|
+
# writable: true,
|
73
|
+
# visible: true,
|
74
|
+
# sortable: true
|
75
|
+
# )
|
75
76
|
base = self
|
77
|
+
# _type, _readable, _writable, _visible, _sortable =
|
78
|
+
# type, readable, writable, visible, sortable
|
76
79
|
Class.new(base) do
|
77
80
|
@field_name, @entity_class = name, _entity_class
|
78
81
|
import_data_module(base)
|
79
|
-
@readable = readable == true
|
80
|
-
@writable = writable == true
|
81
|
-
@visible = visible == true
|
82
|
-
@sortable = sortable == true
|
83
|
-
self.type = type
|
82
|
+
@readable = opts[:readable].nil? ? true : opts[:readable] == true
|
83
|
+
@writable = opts[:writable].nil? ? true : opts[:writable] == true
|
84
|
+
@visible = opts[:visible].nil? ? true : opts[:visible] == true
|
85
|
+
@sortable = opts[:sortable].nil? ? true : opts[:sortable] == true
|
86
|
+
self.type = opts[:type]
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
87
90
|
def self.type=(value)
|
88
|
-
TYPES.include?(value) ? value : TYPES[0]
|
91
|
+
@type = TYPES.include?(value) ? value : TYPES[0]
|
89
92
|
end
|
90
93
|
|
91
94
|
def self.placeholder
|
@@ -25,11 +25,18 @@ module AdminIt
|
|
25
25
|
resource = parent.parent.resource
|
26
26
|
single = resource.singles.select { |c| !(c <= NewContext) }
|
27
27
|
buttons = single.map do |_context|
|
28
|
+
if _context <= ShowContext && context.show_in_dialog?
|
29
|
+
'<a class="btn btn-xs btn-info" ' +
|
30
|
+
%Q{data-toggle="modal" data-target="#confirm_modal" } +
|
31
|
+
%Q{href="#{_context.path(entity)}?layout=dialog">} +
|
32
|
+
%Q{<i class="fa fa-#{_context.icon}"></i></a>}
|
33
|
+
else
|
28
34
|
cl = _context <= ShowContext ? 'info' : 'default'
|
29
35
|
href = _context.path(entity)
|
30
36
|
"<a class=\"btn btn-xs btn-#{cl}\" href=\"#{href}\">" \
|
31
37
|
"<i class=\"fa fa-#{_context.icon}\"></i></a>"
|
32
38
|
end
|
39
|
+
end
|
33
40
|
if resource.destroyable?
|
34
41
|
if context.confirm_destroy?
|
35
42
|
confirm = single.find { |c| c.context_name == :confirm } ||
|
data/lib/admin_it/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: admin_it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey Ovchinnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|