clir-data_manager 0.3.1
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/.gitignore +10 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +44 -0
- data/Manual/Manuel_fr.md +784 -0
- data/Manual/Manuel_fr.pdf +0 -0
- data/README.md +279 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/clir-data_manager.gemspec +34 -0
- data/lib/clir/data_manager/Displayer.rb +30 -0
- data/lib/clir/data_manager/Editor.rb +208 -0
- data/lib/clir/data_manager/Manager.rb +1184 -0
- data/lib/clir/data_manager/Periode.rb +366 -0
- data/lib/clir/data_manager/PrecedencedList.rb +98 -0
- data/lib/clir/data_manager/Property.rb +438 -0
- data/lib/clir/data_manager/Validator.rb +157 -0
- data/lib/clir/data_manager/constants.rb +14 -0
- data/lib/clir/data_manager/errors_and_messages.rb +123 -0
- data/lib/clir/data_manager/module_constants.rb +13 -0
- data/lib/clir/data_manager/version.rb +5 -0
- data/lib/clir/data_manager.rb +21 -0
- metadata +114 -0
Binary file
|
data/README.md
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
# Clir::DataManager
|
2
|
+
|
3
|
+
1. You define (deeply) the instance properties,
|
4
|
+
2. you "attach" the DataManager to your class,
|
5
|
+
3. you can then create, edit, remove and save your instances in command line.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'clir/data_manager'
|
13
|
+
```
|
14
|
+
|
15
|
+
En attendant que le gem soit complet, mettre le code suivant dans le programme devant l'utiliser (pas besoin de faire `bundle install` etc.) :
|
16
|
+
|
17
|
+
~~~
|
18
|
+
|
19
|
+
$LOAD_PATH.unshift File.join(Dir.home,'Programmes','Gems','clir-data_manager','lib')
|
20
|
+
|
21
|
+
~~~
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle install
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install clir-data_manager
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
Pour qu'une classe quelconque puisse utiliser le gem, lui mettre :
|
34
|
+
|
35
|
+
~~~ruby
|
36
|
+
module MonModule
|
37
|
+
class MaClasse
|
38
|
+
include ClirDataManagerConstants # <==== usefull
|
39
|
+
|
40
|
+
DATA_PROPERTIES = [...] # <== see below
|
41
|
+
@@save_system = :card # <== see below
|
42
|
+
@@save_format = :yaml # <== see below
|
43
|
+
@@save_location = '/path/to/folder' # <== see below
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Clir::DataManager.new(MonModule::MaClasse)
|
48
|
+
|
49
|
+
~~~
|
50
|
+
|
51
|
+
### Définition du système de sauvegarde
|
52
|
+
|
53
|
+
Il y a 6 façons de sauvegarder les données avec `Clir::DataManager` :
|
54
|
+
|
55
|
+
* dans un unique fichier, au format CSV ou YAML,
|
56
|
+
* dans des fiches individuelles, au format CSV ou YAML,
|
57
|
+
* par un fichier de configuration, au format CSV ou YAML [Ce système n'est pas encore implémenté, il fonctionnera sur la base d'un fichier de configuration qui définira la façon de sauvegarder les données, toujours en CSV ou YAML]
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
### Définition des propriétés de l'instance
|
62
|
+
|
63
|
+
Le module `ClirDataManagerConstants` permet de charger les constants comme `REQUIRED`, `EDITABLE`, etc.
|
64
|
+
|
65
|
+
Il faut ensuite définir les propriétés des instances de cette classe, à l'aide la constante `DATA_PROPERTIES` :
|
66
|
+
|
67
|
+
~~~ruby
|
68
|
+
module MonModule
|
69
|
+
class MaClasse
|
70
|
+
|
71
|
+
DATA_PROPERTIES = [
|
72
|
+
{prop: :id, type: :id, name: "ID", specs: REQUIRED, default: :new_id},
|
73
|
+
{prop: :name, type: :string, name:"Votre nom", specs:REQUIRED|EDITABLE|DISPLAYABLE},
|
74
|
+
{prop: :name, type: :string, name:"Votre genre", specs:ALL, default: 'F'}
|
75
|
+
# ...
|
76
|
+
]
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
~~~
|
81
|
+
|
82
|
+
On pourrait aussi envoyer les données lors de l'installation du manager de propriétés :
|
83
|
+
|
84
|
+
~~~ruby
|
85
|
+
|
86
|
+
pdata = [
|
87
|
+
{prop: :id, ...}
|
88
|
+
]
|
89
|
+
|
90
|
+
Clir::DataManager.new(MonModule::MaClasse, pdata)
|
91
|
+
|
92
|
+
~~~
|
93
|
+
|
94
|
+
Pour créer la première instance, il suffit ensuite de faire :
|
95
|
+
|
96
|
+
~~~ruby
|
97
|
+
|
98
|
+
MonModule::MaClasse.new.create
|
99
|
+
|
100
|
+
~~~
|
101
|
+
|
102
|
+
Pour éditer ou afficher une instance de la classe :
|
103
|
+
|
104
|
+
~~~ruby
|
105
|
+
i = MonModule::MaClasse.new()
|
106
|
+
|
107
|
+
i.edit
|
108
|
+
|
109
|
+
i.show
|
110
|
+
|
111
|
+
~~~
|
112
|
+
|
113
|
+
Les données sont toujours placées dans la propriété `@data` de l'instance, qui peut être définie à l'instanciation, une fois qu'on a les données :
|
114
|
+
|
115
|
+
~~~ruby
|
116
|
+
|
117
|
+
module MonModule
|
118
|
+
class MaClasse
|
119
|
+
|
120
|
+
def initialize(data)
|
121
|
+
@data = data
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
~~~
|
126
|
+
|
127
|
+
Noter qu'il n'est pas nécessaire de faire `attribute_reader: :data` puisque data est automatiquement défini en accesseur.
|
128
|
+
|
129
|
+
Noter qu'il n'est pas non plus nécessaire de créer toutes les méthodes-propriété qui sont nécessaires habituellement pour récupérer et définir les valeurs.
|
130
|
+
|
131
|
+
À partir du moment où `DATA_PROPERTIES` définit :
|
132
|
+
|
133
|
+
~~~ruby
|
134
|
+
DATA_PROPERTIES = [
|
135
|
+
# ...
|
136
|
+
{prop: :maprop, ...}
|
137
|
+
# ...
|
138
|
+
]
|
139
|
+
~~~
|
140
|
+
|
141
|
+
… alors le manager de propriétés définit les méthodes :
|
142
|
+
|
143
|
+
~~~ruby
|
144
|
+
module MonModule
|
145
|
+
class MaClasse
|
146
|
+
|
147
|
+
def maprop
|
148
|
+
return @data[:maprop]
|
149
|
+
end
|
150
|
+
|
151
|
+
def maprop=(value)
|
152
|
+
@data.merge!(maprop: value)
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
157
|
+
~~~
|
158
|
+
|
159
|
+
Donc, on récupère et définit les valeurs de cette manière :
|
160
|
+
|
161
|
+
~~~ruby
|
162
|
+
|
163
|
+
i = MonModule::MaClasse.new({maprop: "Valeur courante"})
|
164
|
+
|
165
|
+
i.maprop
|
166
|
+
# => "Valeur courante"
|
167
|
+
|
168
|
+
i.maprop = "Nouvelle valeur"
|
169
|
+
|
170
|
+
i.maprop
|
171
|
+
# => "Nouvelle valeur"
|
172
|
+
|
173
|
+
~~~
|
174
|
+
|
175
|
+
### Définition des propriétés
|
176
|
+
|
177
|
+
C'est donc la grosse partie pour utiliser profitablement de `DataManager`. Une bonne définition des propriétés conduit à une utilisation tout à fait efficace.
|
178
|
+
|
179
|
+
#### Identifiant de la propriété
|
180
|
+
|
181
|
+
Cet identifiant se définit à l'aide de l'attribut `:prop`.
|
182
|
+
|
183
|
+
~~~ruby
|
184
|
+
DATA_PROPERTIES = [
|
185
|
+
{ prop: :maprop }
|
186
|
+
]
|
187
|
+
~~~
|
188
|
+
|
189
|
+
C'est par ce nom que l'instance connaitra la valeur consignée. Pour définir quelqu'un, par exemple, on aura :
|
190
|
+
|
191
|
+
~~~ruby
|
192
|
+
DATA_PROPERTIES = [
|
193
|
+
{ prop: :prenom },
|
194
|
+
{ prop: :nom },
|
195
|
+
]
|
196
|
+
~~~
|
197
|
+
|
198
|
+
Et une instance pourra utiliser :
|
199
|
+
|
200
|
+
~~~ruby
|
201
|
+
simone = MaClasse.new
|
202
|
+
simone.prenom
|
203
|
+
# => "Simone"
|
204
|
+
simone.nom
|
205
|
+
# => "De Beauvoir"
|
206
|
+
~~~
|
207
|
+
|
208
|
+
#### Question personnalisée
|
209
|
+
|
210
|
+
Par défaut, la question « Nouvelle valeur pour “`<propriété>`” » est posée pour modifier une propriété.
|
211
|
+
|
212
|
+
On peut néanmoins définir une autre question avec l'attribut `:quest` qui peut contenir des valeurs de template <b>qui ne doivent utiliser que les valeurs dans les `data` de l'instance</b>.
|
213
|
+
|
214
|
+
TODO: Plus tard on pourra aussi imaginer évaluer la question ou fournir d'autres valeurs au template (par exemple un attribut `:quest_values` qui pourrait être définie en dur ou par une procédure qui utiliserait l'instance en premier argument).
|
215
|
+
|
216
|
+
#### Valeur par défaut dans les propriétés
|
217
|
+
|
218
|
+
Une donnée propriété peut définir la valeur par défaut de cette propriété pour une instance donnée.
|
219
|
+
|
220
|
+
~~~ruby
|
221
|
+
DATA_PROPERTIES = [
|
222
|
+
{prop: :maprop ... default: <...> }
|
223
|
+
]
|
224
|
+
~~~
|
225
|
+
|
226
|
+
Cette valeur peut être de diférent type :
|
227
|
+
|
228
|
+
* une valeur explicite :
|
229
|
+
|
230
|
+
~~~ruby
|
231
|
+
default: "Ma valeur par défafut"
|
232
|
+
default: 12
|
233
|
+
default: true
|
234
|
+
~~~
|
235
|
+
|
236
|
+
* une procédure :
|
237
|
+
|
238
|
+
~~~ruby
|
239
|
+
default: Proc.new() { |instance| instance.name.length }
|
240
|
+
~~~
|
241
|
+
|
242
|
+
> Noter que l'instance est toujours transmise en premier argument.
|
243
|
+
|
244
|
+
* une méthode d'instance :
|
245
|
+
|
246
|
+
~~~ruby
|
247
|
+
class MaClasse
|
248
|
+
def valeur_default_pour_prop
|
249
|
+
return "oui"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
default: :valeur_default_pour_prop
|
254
|
+
~~~
|
255
|
+
|
256
|
+
* une méthode de classe :
|
257
|
+
|
258
|
+
~~~ruby
|
259
|
+
class MaClasse
|
260
|
+
def self.valeur_default_pour_prop
|
261
|
+
@@valeur_prop += 1
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
default: :valeur_default_pour_prop
|
266
|
+
~~~
|
267
|
+
|
268
|
+
|
269
|
+
|
270
|
+
## Development
|
271
|
+
|
272
|
+
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.
|
273
|
+
|
274
|
+
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).
|
275
|
+
|
276
|
+
## Contributing
|
277
|
+
|
278
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/clir-data_manager.
|
279
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "clir/data_manager"
|
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(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'lib/clir/data_manager/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "clir-data_manager"
|
5
|
+
s.version = Clir::DataManager::VERSION
|
6
|
+
s.authors = ["PhilippePerret"]
|
7
|
+
s.email = ["philippe.perret@yahoo.fr"]
|
8
|
+
s.licenses = ['Nonstandard']
|
9
|
+
|
10
|
+
s.summary = %q{Properties Manager for classes and instances}
|
11
|
+
s.description = %q{This gem provides useful Classes and methods to deal with instances properties edition and display}
|
12
|
+
s.homepage = "https://github.com/PhilippePerret/clir-data_manager"
|
13
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
|
+
|
15
|
+
# s.metadata["allowed_push_host"] = "https://github.com/PhilippePerret/clir-data_manager"
|
16
|
+
s.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
|
18
|
+
s.add_dependency 'clir', '~> 0.4'
|
19
|
+
s.add_development_dependency 'minitest', '~> 5.10'
|
20
|
+
s.add_development_dependency 'minitest-color', '>= 5'
|
21
|
+
|
22
|
+
s.metadata["homepage_uri"] = s.homepage
|
23
|
+
s.metadata["source_code_uri"] = s.homepage
|
24
|
+
s.metadata["changelog_uri"] = "https://github.com/PhilippePerret/clir-data_manager/CHANGELOG.md"
|
25
|
+
|
26
|
+
# Specify which files should be added to the gem when it is released.
|
27
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
+
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|features)/}) }
|
30
|
+
end
|
31
|
+
s.bindir = "exe"
|
32
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
=begin
|
2
|
+
Clir::DataManager::Manager::Displayer
|
3
|
+
-------------------------------------
|
4
|
+
To display a instance values
|
5
|
+
=end
|
6
|
+
module Clir
|
7
|
+
module DataManager
|
8
|
+
class Manager
|
9
|
+
class Displayer
|
10
|
+
|
11
|
+
attr_reader :manager
|
12
|
+
|
13
|
+
def initialize(manager)
|
14
|
+
@manager = manager
|
15
|
+
end
|
16
|
+
|
17
|
+
def show(instance, options)
|
18
|
+
liste = []
|
19
|
+
manager.each_property do |property|
|
20
|
+
next if not(property.displayable?(instance))
|
21
|
+
# puts "Je dois afficher la propriété @#{property.prop} de specs #{property.specs}"
|
22
|
+
liste << [property.name, property.formated_value_in(instance)]
|
23
|
+
end
|
24
|
+
puts labelize(liste)
|
25
|
+
end
|
26
|
+
|
27
|
+
end #/class Displayer
|
28
|
+
end #/class Manager
|
29
|
+
end #/module DataManager
|
30
|
+
end #/module Clir
|
@@ -0,0 +1,208 @@
|
|
1
|
+
=begin
|
2
|
+
Clir::DataManager::Manager::Editor
|
3
|
+
-------------------------------------
|
4
|
+
To edit a instance values (i.e. a proprerty)
|
5
|
+
|
6
|
+
2 editing system:
|
7
|
+
|
8
|
+
1. Property after property
|
9
|
+
2. [default] All properties are displayed and user chose which
|
10
|
+
one to edit. When all required properties are defined, the
|
11
|
+
user can save the values.
|
12
|
+
|
13
|
+
|
14
|
+
=end
|
15
|
+
module Clir
|
16
|
+
module DataManager
|
17
|
+
class Manager
|
18
|
+
class Editor
|
19
|
+
|
20
|
+
attr_reader :manager
|
21
|
+
|
22
|
+
def initialize(manager)
|
23
|
+
@manager = manager
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit(instance, options)
|
27
|
+
data_modified = false
|
28
|
+
data_saved = false
|
29
|
+
error = nil
|
30
|
+
while true
|
31
|
+
#
|
32
|
+
# Pour choisir la propriété à définir (et l'index par défaut)
|
33
|
+
#
|
34
|
+
choices, index_default = set_choices_with(instance)
|
35
|
+
clear unless debug?
|
36
|
+
#
|
37
|
+
# Si une erreur a été rencontrée
|
38
|
+
#
|
39
|
+
puts error.rouge unless error.nil?
|
40
|
+
#
|
41
|
+
# L'user peut choisir la propriété à définir ou le choix
|
42
|
+
# "Enregistrer" pour enregistrer l'instance
|
43
|
+
#
|
44
|
+
case prop = Q.select((options[:question]||(MSG[:define_thing] % instance.class.class_name)).jaune, choices, { per_page:choices.count, default: (index_default unless choices.empty?), filter:true, show_help:false, echo:false} )
|
45
|
+
when NilClass
|
46
|
+
break
|
47
|
+
when :save
|
48
|
+
if not(all_required?(instance))
|
49
|
+
error = MSG[:all_required_data_must_be_defined]
|
50
|
+
elsif data_modified && confirmed?(instance)
|
51
|
+
instance.save
|
52
|
+
data_saved = true
|
53
|
+
break
|
54
|
+
end
|
55
|
+
else
|
56
|
+
modified = prop.edit(instance, options)
|
57
|
+
data_modified = true if modified
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# / while
|
61
|
+
if data_modified && not(data_saved)
|
62
|
+
unless Q.yes?(MSG[:data_not_saved_cancel].orange)
|
63
|
+
instance.save # on sauve les données, finalement
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Confirmation (ou non) des données de l'instance
|
69
|
+
def confirmed?(instance)
|
70
|
+
clear unless debug?
|
71
|
+
instance.show
|
72
|
+
puts "\n\n"
|
73
|
+
return Q.yes?(MSG[:q_confirm_data].jaune)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return TRUE si toutes les propriétés requises sont définies
|
77
|
+
# pour l'instance donnée
|
78
|
+
def all_required?(instance)
|
79
|
+
manager.properties.each do |property|
|
80
|
+
if property.required?(instance) && instance.send(property.prop).nil?
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
return true
|
85
|
+
end
|
86
|
+
|
87
|
+
# Tty-prompt choices panel
|
88
|
+
# Should be update after each user input
|
89
|
+
#
|
90
|
+
# @return [choices, index_default]
|
91
|
+
# At creation, index_default is the first required property which
|
92
|
+
# is undefined (1-start)
|
93
|
+
#
|
94
|
+
def set_choices_with(instance)
|
95
|
+
requirement_missing = false
|
96
|
+
max_label_width = 0
|
97
|
+
cs = manager.properties.map do |property|
|
98
|
+
next if not(property.editable?(instance))
|
99
|
+
pvalue = property.formated_value_in(instance)
|
100
|
+
pname = property.name(instance)
|
101
|
+
pname || raise(ERRORS[:no_name_for_property] % property.prop.inspect)
|
102
|
+
max_label_width = pname.length if pname.length > max_label_width
|
103
|
+
[pname, pvalue]
|
104
|
+
end.compact
|
105
|
+
|
106
|
+
# Ajout de la gouttière entre label et valeur
|
107
|
+
max_label_width += 4
|
108
|
+
|
109
|
+
#
|
110
|
+
# Le menu qui devra être sélectionné
|
111
|
+
#
|
112
|
+
index_default = nil
|
113
|
+
#
|
114
|
+
# Index courant réel
|
115
|
+
#
|
116
|
+
# Avant qu'il existe des propriétés conditionnelles (:if) on
|
117
|
+
# pouvait prendre l'index de la propriété pour savoir quel menu
|
118
|
+
# sélectionner. Maintenant, on doit utiliser cette variable
|
119
|
+
# +real_current_index+ pour connaitre l'index réel du menu à
|
120
|
+
# sélectionner ensuite.
|
121
|
+
#
|
122
|
+
# On commence à 1 pour avoir le premier choix à 2 car le
|
123
|
+
# premier item est toujours l'item "Enregistrer"
|
124
|
+
#
|
125
|
+
real_current_index = 1
|
126
|
+
|
127
|
+
#
|
128
|
+
# Boucle pour récupérer tous les menus à afficher
|
129
|
+
#
|
130
|
+
cs = manager.properties.map do |property|
|
131
|
+
#
|
132
|
+
# Si ce n'est pas une propriété éditable (pas ses :specs), on
|
133
|
+
# la passe.
|
134
|
+
#
|
135
|
+
next if not(property.editable?(instance))
|
136
|
+
#
|
137
|
+
# Est-ce une propriété requise ? (en fonction ou non de l'instance)
|
138
|
+
#
|
139
|
+
is_required = property.required?(instance)
|
140
|
+
|
141
|
+
real_current_index += 1 if index_default.nil?
|
142
|
+
curval = instance.send(property.prop)
|
143
|
+
isdef = curval != nil
|
144
|
+
#
|
145
|
+
# Si c'est une création d'instance, on se placera automati-
|
146
|
+
# quement sur le premier champ (property) qui n'est pas défini
|
147
|
+
#
|
148
|
+
if index_default.nil? && instance.new? && not(isdef)
|
149
|
+
index_default = real_current_index
|
150
|
+
end
|
151
|
+
#
|
152
|
+
# Si c'est une propriété requise et qu'elle n'est pas définie,
|
153
|
+
# on indique qu'il manque des définitions avant d'avoir la
|
154
|
+
# possibilité d'enregistrer. On en profite aussi, si c'est la
|
155
|
+
# première, pour définir l'index par défaut
|
156
|
+
#
|
157
|
+
if is_required && not(isdef)
|
158
|
+
requirement_missing = true
|
159
|
+
index_default = real_current_index if index_default.nil?
|
160
|
+
end
|
161
|
+
# choix = cs.shift
|
162
|
+
# choix = "#{property.name(instance).ljust(max_label_width)}#{curval}"
|
163
|
+
#
|
164
|
+
# Faut-il utiliser une méthode de formatage d'affichage
|
165
|
+
#
|
166
|
+
fvalue = property.formated_value_in(instance)
|
167
|
+
choix = "#{property.name(instance).ljust(max_label_width)}#{fvalue}"
|
168
|
+
#
|
169
|
+
# Couleur en fonction de propriété requise ou non
|
170
|
+
#
|
171
|
+
choix = choix.send(isdef ? :bleu : :orange) if is_required
|
172
|
+
#
|
173
|
+
# Marque de propriété requise
|
174
|
+
#
|
175
|
+
choix = (is_required ? '* '.rouge : ' ') + choix
|
176
|
+
#
|
177
|
+
# Le choice à utiliser
|
178
|
+
#
|
179
|
+
{name: choix, value: property}
|
180
|
+
end.compact
|
181
|
+
|
182
|
+
#
|
183
|
+
# Si toutes les valeurs requises sont définies, on peut ajouter
|
184
|
+
# un menu pour enregistrer
|
185
|
+
#
|
186
|
+
savable = not(requirement_missing)
|
187
|
+
choix_save = {name: MSG[:save].send(savable ? :bleu : :gris), value: :save}
|
188
|
+
choix_save.merge!(disabled: "(#{MESSAGES[:still_required_values]})".gris) if not(savable)
|
189
|
+
cs.unshift(choix_save)
|
190
|
+
#
|
191
|
+
# On a toujours la possibilité d'annuler l'édition
|
192
|
+
#
|
193
|
+
cs << CHOIX_RENONCER
|
194
|
+
#
|
195
|
+
# Si l'index par défaut n'a pas pu être déterminé, on prend le
|
196
|
+
# milieu de la liste de propriétés
|
197
|
+
#
|
198
|
+
index_default = cs.count / 2 if index_default.nil?
|
199
|
+
#
|
200
|
+
# On retourne la liste des choix et l'item sélectionné
|
201
|
+
#
|
202
|
+
return [cs, index_default]
|
203
|
+
end
|
204
|
+
|
205
|
+
end #/class Editor
|
206
|
+
end #/class Manager
|
207
|
+
end #/module DataManager
|
208
|
+
end #/module Clir
|