Merge branch 'demarches-simplifiees:main' into poc-self_hosted_runners
This commit is contained in:
commit
258c7657c8
161 changed files with 2661 additions and 1196 deletions
|
@ -20,7 +20,8 @@ module.exports = {
|
||||||
'prettier/prettier': 'error',
|
'prettier/prettier': 'error',
|
||||||
'react-hooks/rules-of-hooks': 'error',
|
'react-hooks/rules-of-hooks': 'error',
|
||||||
'react-hooks/exhaustive-deps': 'error',
|
'react-hooks/exhaustive-deps': 'error',
|
||||||
'react/prop-types': 'off'
|
'react/prop-types': 'off',
|
||||||
|
'react/no-deprecated': 'off'
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
react: { version: 'detect' }
|
react: { version: 'detect' }
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
16.14.0
|
18.17.0
|
||||||
|
|
153
Gemfile.lock
153
Gemfile.lock
|
@ -4,47 +4,47 @@ GEM
|
||||||
aasm (5.2.0)
|
aasm (5.2.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
acsv (0.0.1)
|
acsv (0.0.1)
|
||||||
actioncable (7.0.5.1)
|
actioncable (7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (7.0.5.1)
|
actionmailbox (7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
activejob (= 7.0.5.1)
|
activejob (= 7.0.7.2)
|
||||||
activerecord (= 7.0.5.1)
|
activerecord (= 7.0.7.2)
|
||||||
activestorage (= 7.0.5.1)
|
activestorage (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
actionmailer (7.0.5.1)
|
actionmailer (7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
actionview (= 7.0.5.1)
|
actionview (= 7.0.7.2)
|
||||||
activejob (= 7.0.5.1)
|
activejob (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (7.0.5.1)
|
actionpack (7.0.7.2)
|
||||||
actionview (= 7.0.5.1)
|
actionview (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
rack (~> 2.0, >= 2.2.4)
|
rack (~> 2.0, >= 2.2.4)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actiontext (7.0.5.1)
|
actiontext (7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
activerecord (= 7.0.5.1)
|
activerecord (= 7.0.7.2)
|
||||||
activestorage (= 7.0.5.1)
|
activestorage (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (7.0.5.1)
|
actionview (7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
|
@ -62,26 +62,26 @@ GEM
|
||||||
activemodel (>= 5.2.0)
|
activemodel (>= 5.2.0)
|
||||||
activestorage (>= 5.2.0)
|
activestorage (>= 5.2.0)
|
||||||
activesupport (>= 5.2.0)
|
activesupport (>= 5.2.0)
|
||||||
activejob (7.0.5.1)
|
activejob (7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (7.0.5.1)
|
activemodel (7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
activerecord (7.0.5.1)
|
activerecord (7.0.7.2)
|
||||||
activemodel (= 7.0.5.1)
|
activemodel (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
activestorage (7.0.5.1)
|
activestorage (7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
activejob (= 7.0.5.1)
|
activejob (= 7.0.7.2)
|
||||||
activerecord (= 7.0.5.1)
|
activerecord (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
mini_mime (>= 1.1.0)
|
mini_mime (>= 1.1.0)
|
||||||
activestorage-openstack (1.5.1)
|
activestorage-openstack (1.6.0)
|
||||||
fog-openstack (~> 1.0)
|
fog-openstack (>= 1.0.9)
|
||||||
marcel
|
marcel
|
||||||
rails (>= 5.2.2)
|
rails (>= 5.2.2)
|
||||||
activesupport (7.0.5.1)
|
activesupport (7.0.7.2)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
@ -236,7 +236,7 @@ GEM
|
||||||
tzinfo
|
tzinfo
|
||||||
ethon (0.15.0)
|
ethon (0.15.0)
|
||||||
ffi (>= 1.15.0)
|
ffi (>= 1.15.0)
|
||||||
excon (0.79.0)
|
excon (0.102.0)
|
||||||
factory_bot (6.1.0)
|
factory_bot (6.1.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
ffi (1.15.5)
|
ffi (1.15.5)
|
||||||
|
@ -254,26 +254,25 @@ GEM
|
||||||
rack (>= 1.4, < 3)
|
rack (>= 1.4, < 3)
|
||||||
rack-protection (>= 1.5.3, <= 4.0.0)
|
rack-protection (>= 1.5.3, <= 4.0.0)
|
||||||
sanitize (< 7)
|
sanitize (< 7)
|
||||||
fog-core (2.2.3)
|
fog-core (2.3.0)
|
||||||
builder
|
builder
|
||||||
excon (~> 0.71)
|
excon (~> 0.71)
|
||||||
formatador (~> 0.2)
|
formatador (>= 0.2, < 2.0)
|
||||||
mime-types
|
mime-types
|
||||||
fog-json (1.2.0)
|
fog-json (1.2.0)
|
||||||
fog-core
|
fog-core
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
fog-openstack (1.0.11)
|
fog-openstack (1.1.0)
|
||||||
fog-core (~> 2.1)
|
fog-core (~> 2.1)
|
||||||
fog-json (>= 1.0)
|
fog-json (>= 1.0)
|
||||||
ipaddress (>= 0.8)
|
formatador (1.1.0)
|
||||||
formatador (0.2.5)
|
|
||||||
fugit (1.4.2)
|
fugit (1.4.2)
|
||||||
et-orbi (~> 1.1, >= 1.1.8)
|
et-orbi (~> 1.1, >= 1.1.8)
|
||||||
raabro (~> 1.4)
|
raabro (~> 1.4)
|
||||||
geo_coord (0.2.0)
|
geo_coord (0.2.0)
|
||||||
geocoder (1.6.5)
|
geocoder (1.6.5)
|
||||||
globalid (1.1.0)
|
globalid (1.2.1)
|
||||||
activesupport (>= 5.0)
|
activesupport (>= 6.1)
|
||||||
gon (6.4.0)
|
gon (6.4.0)
|
||||||
actionpack (>= 3.0.20)
|
actionpack (>= 3.0.20)
|
||||||
i18n (>= 0.7)
|
i18n (>= 0.7)
|
||||||
|
@ -349,7 +348,6 @@ GEM
|
||||||
ruby-vips (>= 2.0.17, < 3)
|
ruby-vips (>= 2.0.17, < 3)
|
||||||
invisible_captcha (2.0.0)
|
invisible_captcha (2.0.0)
|
||||||
rails (>= 5.0)
|
rails (>= 5.0)
|
||||||
ipaddress (0.8.3)
|
|
||||||
jquery-rails (4.5.1)
|
jquery-rails (4.5.1)
|
||||||
rails-dom-testing (>= 1, < 3)
|
rails-dom-testing (>= 1, < 3)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
|
@ -386,7 +384,7 @@ GEM
|
||||||
actionmailer (>= 3.2)
|
actionmailer (>= 3.2)
|
||||||
letter_opener (~> 1.0)
|
letter_opener (~> 1.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
listen (3.4.1)
|
listen (3.8.0)
|
||||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
rb-inotify (~> 0.9, >= 0.9.10)
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
llhttp-ffi (0.4.0)
|
llhttp-ffi (0.4.0)
|
||||||
|
@ -414,21 +412,21 @@ GEM
|
||||||
matrix (0.4.2)
|
matrix (0.4.2)
|
||||||
memory_profiler (1.0.0)
|
memory_profiler (1.0.0)
|
||||||
method_source (1.0.0)
|
method_source (1.0.0)
|
||||||
mime-types (3.3.1)
|
mime-types (3.5.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2021.0212)
|
mime-types-data (3.2023.0808)
|
||||||
mina (1.2.4)
|
mina (1.2.4)
|
||||||
open4 (~> 1.3.4)
|
open4 (~> 1.3.4)
|
||||||
rake
|
rake
|
||||||
mini_magick (4.11.0)
|
mini_magick (4.11.0)
|
||||||
mini_mime (1.1.2)
|
mini_mime (1.1.5)
|
||||||
mini_portile2 (2.8.4)
|
mini_portile2 (2.8.4)
|
||||||
minitest (5.18.1)
|
minitest (5.20.0)
|
||||||
msgpack (1.4.2)
|
msgpack (1.4.2)
|
||||||
multi_json (1.15.0)
|
multi_json (1.15.0)
|
||||||
mustermann (3.0.0)
|
mustermann (3.0.0)
|
||||||
ruby2_keywords (~> 0.0.1)
|
ruby2_keywords (~> 0.0.1)
|
||||||
net-imap (0.3.6)
|
net-imap (0.3.7)
|
||||||
date
|
date
|
||||||
net-protocol
|
net-protocol
|
||||||
net-pop (0.1.2)
|
net-pop (0.1.2)
|
||||||
|
@ -439,7 +437,7 @@ GEM
|
||||||
net-protocol
|
net-protocol
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
nio4r (2.5.9)
|
nio4r (2.5.9)
|
||||||
nokogiri (1.15.3)
|
nokogiri (1.15.4)
|
||||||
mini_portile2 (~> 2.8.2)
|
mini_portile2 (~> 2.8.2)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
open4 (1.3.4)
|
open4 (1.3.4)
|
||||||
|
@ -493,7 +491,7 @@ GEM
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
raabro (1.4.0)
|
raabro (1.4.0)
|
||||||
racc (1.7.1)
|
racc (1.7.1)
|
||||||
rack (2.2.7)
|
rack (2.2.8)
|
||||||
rack-attack (6.5.0)
|
rack-attack (6.5.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rack-mini-profiler (3.0.0)
|
rack-mini-profiler (3.0.0)
|
||||||
|
@ -513,26 +511,27 @@ GEM
|
||||||
rack_session_access (0.2.0)
|
rack_session_access (0.2.0)
|
||||||
builder (>= 2.0.0)
|
builder (>= 2.0.0)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rails (7.0.5.1)
|
rails (7.0.7.2)
|
||||||
actioncable (= 7.0.5.1)
|
actioncable (= 7.0.7.2)
|
||||||
actionmailbox (= 7.0.5.1)
|
actionmailbox (= 7.0.7.2)
|
||||||
actionmailer (= 7.0.5.1)
|
actionmailer (= 7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
actiontext (= 7.0.5.1)
|
actiontext (= 7.0.7.2)
|
||||||
actionview (= 7.0.5.1)
|
actionview (= 7.0.7.2)
|
||||||
activejob (= 7.0.5.1)
|
activejob (= 7.0.7.2)
|
||||||
activemodel (= 7.0.5.1)
|
activemodel (= 7.0.7.2)
|
||||||
activerecord (= 7.0.5.1)
|
activerecord (= 7.0.7.2)
|
||||||
activestorage (= 7.0.5.1)
|
activestorage (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 7.0.5.1)
|
railties (= 7.0.7.2)
|
||||||
rails-controller-testing (1.0.5)
|
rails-controller-testing (1.0.5)
|
||||||
actionpack (>= 5.0.1.rc1)
|
actionpack (>= 5.0.1.rc1)
|
||||||
actionview (>= 5.0.1.rc1)
|
actionview (>= 5.0.1.rc1)
|
||||||
activesupport (>= 5.0.1.rc1)
|
activesupport (>= 5.0.1.rc1)
|
||||||
rails-dom-testing (2.0.3)
|
rails-dom-testing (2.2.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 5.0.0)
|
||||||
|
minitest
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-erd (1.6.1)
|
rails-erd (1.6.1)
|
||||||
activerecord (>= 4.2)
|
activerecord (>= 4.2)
|
||||||
|
@ -545,9 +544,9 @@ GEM
|
||||||
rails-i18n (7.0.3)
|
rails-i18n (7.0.3)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 8)
|
railties (>= 6.0.0, < 8)
|
||||||
railties (7.0.5.1)
|
railties (7.0.7.2)
|
||||||
actionpack (= 7.0.5.1)
|
actionpack (= 7.0.7.2)
|
||||||
activesupport (= 7.0.5.1)
|
activesupport (= 7.0.7.2)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
|
@ -555,7 +554,7 @@ GEM
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
rake (13.0.6)
|
rake (13.0.6)
|
||||||
rake-progressbar (0.0.5)
|
rake-progressbar (0.0.5)
|
||||||
rb-fsevent (0.10.4)
|
rb-fsevent (0.11.2)
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
redcarpet (3.6.0)
|
redcarpet (3.6.0)
|
||||||
|
@ -777,7 +776,7 @@ GEM
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
hashdiff (>= 0.4.0, < 2.0.0)
|
hashdiff (>= 0.4.0, < 2.0.0)
|
||||||
websocket (1.2.9)
|
websocket (1.2.9)
|
||||||
websocket-driver (0.7.5)
|
websocket-driver (0.7.6)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
xmlenc (0.8.0)
|
xmlenc (0.8.0)
|
||||||
|
@ -789,7 +788,7 @@ GEM
|
||||||
nokogiri (~> 1.11)
|
nokogiri (~> 1.11)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.6.8)
|
zeitwerk (2.6.11)
|
||||||
zip_tricks (5.6.0)
|
zip_tricks (5.6.0)
|
||||||
zipline (1.4.1)
|
zipline (1.4.1)
|
||||||
actionpack (>= 6.0, < 8.0)
|
actionpack (>= 6.0, < 8.0)
|
||||||
|
|
|
@ -310,24 +310,6 @@ ul.dropdown-items {
|
||||||
width: 340px;
|
width: 340px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
|
||||||
width: 100px;
|
|
||||||
display: inline-block;
|
|
||||||
margin-bottom: 2 * $default-spacer;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:not(.fr-btn),
|
|
||||||
select {
|
|
||||||
width: 200px;
|
|
||||||
display: inline-block;
|
|
||||||
background-color: $light-grey;
|
|
||||||
border: 1px solid $border-grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
[disabled] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,21 @@ fieldset {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.fr-tag-bug {
|
||||||
|
background-color: $blue-france-500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #1212FF;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-dismiss {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// on veut ferrer à droite le dropdown de sélecteur de langue
|
// on veut ferrer à droite le dropdown de sélecteur de langue
|
||||||
@media (min-width: 62em) {
|
@media (min-width: 62em) {
|
||||||
.fr-nav__item.custom-fr-translate-flex-end {
|
.fr-nav__item.custom-fr-translate-flex-end {
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fr-input-group {
|
.fr-input-group,
|
||||||
|
.fr-select-group {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,16 +117,8 @@
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move checkbox to the top-left side of the label
|
|
||||||
&.editable-champ-checkbox {
|
|
||||||
label.admin-default-zone {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.editable-champ-checkbox {
|
&.editable-champ-checkbox {
|
||||||
label {
|
label {
|
||||||
padding-left: 28px;
|
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,18 +203,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fr-label {
|
.fr-label .fr-hint-text > *,
|
||||||
|
.fr-fieldset__legend .fr-hint-text > * {
|
||||||
// la description d'un champ peut contenir du markup (markdown->html),
|
// la description d'un champ peut contenir du markup (markdown->html),
|
||||||
// on herite donc la fontsize/mrgin/padding du fr-hint-text
|
// on herite donc la fontsize/mrgin/padding du fr-hint-text
|
||||||
.fr-hint-text > * {
|
font-size: inherit;
|
||||||
font-size: inherit;
|
margin: inherit;
|
||||||
margin: inherit;
|
padding: inherit;
|
||||||
padding: inherit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=password],
|
input[type=password],
|
||||||
select {
|
select:not(.fr-select) {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
@ -246,9 +238,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=text]:not([data-address='true']),
|
input[type=text]:not([data-address='true']) {
|
||||||
select {
|
|
||||||
border-radius: 4px;
|
|
||||||
border: solid 1px $border-grey;
|
border: solid 1px $border-grey;
|
||||||
padding: $default-padding;
|
padding: $default-padding;
|
||||||
|
|
||||||
|
@ -524,7 +514,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset ~ .spinner {
|
fieldset + .spinner {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -($default-fields-spacer / 2);
|
top: -($default-fields-spacer / 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,18 @@
|
||||||
|
|
||||||
.type-de-champ {
|
.type-de-champ {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #FAFDFF;
|
margin-bottom: $default-padding;
|
||||||
border: 1px solid $border-grey;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: $default-padding * 2;
|
|
||||||
box-shadow: 0px 2px 4px -4px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
.type-de-champ-container {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FAFDFF;
|
||||||
|
border: 1px solid $border-grey;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: $default-padding;
|
||||||
|
box-shadow: 0px 2px 4px -4px;
|
||||||
|
}
|
||||||
|
|
||||||
.handle.icon {
|
.handle.icon {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -71,6 +76,10 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.last .type-de-champ-add-button.root {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.head {
|
.head {
|
||||||
background-color: #FAFDFF;
|
background-color: #FAFDFF;
|
||||||
|
|
||||||
|
@ -91,10 +100,6 @@
|
||||||
&.section {
|
&.section {
|
||||||
padding: $default-spacer $default-spacer 0;
|
padding: $default-spacer $default-spacer 0;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
input {
|
|
||||||
background-color: $white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hr {
|
&.hr {
|
||||||
|
|
|
@ -2,13 +2,6 @@ class ApplicationComponent < ViewComponent::Base
|
||||||
include ViewComponent::Translatable
|
include ViewComponent::Translatable
|
||||||
include FlipperHelper
|
include FlipperHelper
|
||||||
|
|
||||||
# Takes a Hash of { class_name: boolean }.
|
|
||||||
# Returns truthy class names in an array. Array can be passed as-it in rails helpers,
|
|
||||||
# and is still manipulable if needed.
|
|
||||||
def class_names(class_names)
|
|
||||||
class_names.filter { _2 }.keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
controller.current_user
|
controller.current_user
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
= form_tag add_filter_instructeur_procedure_path(procedure), method: :post, class: 'dropdown-form large', id: 'filter-component', data: { turbo: true, controller: 'autosubmit' } do
|
= form_tag add_filter_instructeur_procedure_path(procedure), method: :post, class: 'dropdown-form large', id: 'filter-component', data: { turbo: true, controller: 'autosubmit' } do
|
||||||
= label_tag :field, t('.column')
|
.fr-select-group
|
||||||
= select_tag :field, options_for_select(filterable_fields_for_select, field_id), include_blank: field_id.nil?
|
= label_tag :field, t('.column'), class: 'fr-label fr-m-0'
|
||||||
%input.hidden{ type: 'submit', formaction: update_filter_instructeur_procedure_path(procedure), data: { autosubmit_target: 'submitter' } }
|
= select_tag :field, options_for_select(filterable_fields_for_select, field_id), include_blank: field_id.nil?, class: 'fr-select'
|
||||||
%br
|
|
||||||
= label_tag :value, t('.value'), for: 'value'
|
%input.hidden{ type: 'submit', formaction: update_filter_instructeur_procedure_path(procedure), data: { autosubmit_target: 'submitter' } }
|
||||||
|
|
||||||
|
= label_tag :value, t('.value'), for: 'value', class: 'fr-label'
|
||||||
- if field_type == :enum
|
- if field_type == :enum
|
||||||
= select_tag :value, options_for_select(options_for_select_of_field), id: 'value', name: 'value', data: { no_autosubmit: true }
|
= select_tag :value, options_for_select(options_for_select_of_field), id: 'value', name: 'value', class: 'fr-select', data: { no_autosubmit: true }
|
||||||
- else
|
- else
|
||||||
%input#value{ type: field_type, name: :value, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH, disabled: field_id.nil? ? true : false, data: { no_autosubmit: true } }
|
%input#value.fr-input{ type: field_type, name: :value, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH, disabled: field_id.nil? ? true : false, data: { no_autosubmit: true } }
|
||||||
|
|
||||||
= hidden_field_tag :statut, statut
|
= hidden_field_tag :statut, statut
|
||||||
= submit_tag t('.add_filter'), class: 'fr-btn fr-btn--secondary fr-mt-2w'
|
= submit_tag t('.add_filter'), class: 'fr-btn fr-btn--secondary fr-mt-2w'
|
||||||
|
|
|
@ -17,6 +17,10 @@ class Dsfr::InputComponent < ApplicationComponent
|
||||||
@required = required
|
@required = required
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dsfr_champ_container
|
||||||
|
:div
|
||||||
|
end
|
||||||
|
|
||||||
# add invalid class on input when input is invalid
|
# add invalid class on input when input is invalid
|
||||||
# and and valid on input only if another input is invalid
|
# and and valid on input only if another input is invalid
|
||||||
def input_group_opts
|
def input_group_opts
|
||||||
|
@ -50,6 +54,10 @@ class Dsfr::InputComponent < ApplicationComponent
|
||||||
get_slot(:label).presence || default_label
|
get_slot(:label).presence || default_label
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
|
|
||||||
# kind of input helpers
|
# kind of input helpers
|
||||||
def password?
|
def password?
|
||||||
@input_type == :password_field
|
@input_type == :password_field
|
||||||
|
|
|
@ -8,6 +8,30 @@ module Dsfr
|
||||||
|
|
||||||
renders_one :hint
|
renders_one :hint
|
||||||
|
|
||||||
|
def dsfr_group_classname
|
||||||
|
if dsfr_champ_container == :fieldset
|
||||||
|
'fr-fieldset'
|
||||||
|
else
|
||||||
|
"#{dsfr_input_classname}-group"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def input_group_error_class_names
|
||||||
|
{
|
||||||
|
"#{dsfr_group_classname}--error" => errors_on_attribute?,
|
||||||
|
"#{dsfr_group_classname}--valid" => !errors_on_attribute? && errors_on_another_attribute?
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def errors_on_attribute?
|
||||||
|
errors.has_key?(attribute_or_rich_body)
|
||||||
|
end
|
||||||
|
|
||||||
|
# errors helpers
|
||||||
|
def error_full_messages
|
||||||
|
errors.full_messages_for(attribute_or_rich_body)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# lookup for edge case from `form.rich_text_area`
|
# lookup for edge case from `form.rich_text_area`
|
||||||
|
@ -21,15 +45,14 @@ module Dsfr
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def input_group_error_class_names
|
def fr_fieldset?
|
||||||
{
|
!['fr-input', 'fr-radio', 'fr-select'].include?(dsfr_input_classname)
|
||||||
"fr-input-group--error": errors_on_attribute?,
|
|
||||||
"fr-input-group--valid": !errors_on_attribute? && errors_on_another_attribute?
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def input_error_class_names
|
def input_error_class_names
|
||||||
{ 'fr-input--error': errors_on_attribute? }
|
{
|
||||||
|
"#{dsfr_input_classname}--error": errors_on_attribute?
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def input_error_opts
|
def input_error_opts
|
||||||
|
@ -70,23 +93,10 @@ module Dsfr
|
||||||
@opts
|
@opts
|
||||||
end
|
end
|
||||||
|
|
||||||
def describedby_id
|
|
||||||
dom_id(@champ, :error_full_messages)
|
|
||||||
end
|
|
||||||
|
|
||||||
def errors_on_another_attribute?
|
def errors_on_another_attribute?
|
||||||
!errors.empty?
|
!errors.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def errors_on_attribute?
|
|
||||||
errors.has_key?(attribute_or_rich_body)
|
|
||||||
end
|
|
||||||
|
|
||||||
# errors helpers
|
|
||||||
def error_full_messages
|
|
||||||
errors.full_messages_for(attribute_or_rich_body)
|
|
||||||
end
|
|
||||||
|
|
||||||
def map_array_to_hash_with_true(array_or_string_or_nil)
|
def map_array_to_hash_with_true(array_or_string_or_nil)
|
||||||
Array(array_or_string_or_nil).to_h { [_1, true] }
|
Array(array_or_string_or_nil).to_h { [_1, true] }
|
||||||
end
|
end
|
||||||
|
|
13
app/components/dsfr/input_status_message_component.rb
Normal file
13
app/components/dsfr/input_status_message_component.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
module Dsfr
|
||||||
|
class InputStatusMessageComponent < ApplicationComponent
|
||||||
|
def initialize(errors_on_attribute:, error_full_messages:, described_by:)
|
||||||
|
@errors_on_attribute = errors_on_attribute
|
||||||
|
@error_full_messages = error_full_messages
|
||||||
|
@described_by = described_by
|
||||||
|
end
|
||||||
|
|
||||||
|
def render?
|
||||||
|
@errors_on_attribute
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
.fr-messages-group{ id: @describedby_id }
|
||||||
|
- @error_full_messages.each do |error_message|
|
||||||
|
%p{ class: class_names('fr-message' => true, "fr-message--#{@errors_on_attribute ? 'error' : 'valid'}" => true) }= error_message
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::AnnuaireEducationComponent < EditableChamp::ComboSearchComponent
|
class EditableChamp::AnnuaireEducationComponent < EditableChamp::ComboSearchComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
= # we do this trick because some html elements should use 'label' and some should be plain paragraphs
|
= # we do this trick because some html elements should use 'label' and some should be plain paragraphs
|
||||||
|
|
||||||
- if @champ.html_label?
|
- if @champ.html_label?
|
||||||
= @form.label @champ.main_value_name, id: @champ.labelledby_id, for: @champ.input_id, class: 'fr-label' do
|
= @form.label @champ.main_value_name, id: @champ.labelledby_id, for: @champ.input_id, class: 'fr-label' do
|
||||||
- render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
- render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
|
- elsif @champ.legend_label?
|
||||||
|
%legend.fr-fieldset__legend.fr-text--regular{ id: @champ.labelledby_id }= render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
|
- elsif @champ.single_checkbox?
|
||||||
|
-# no label to add
|
||||||
- else
|
- else
|
||||||
.fr-label.mb-4{ id: @champ.labelledby_id }
|
.fr-label.mb-4{ id: @champ.labelledby_id }
|
||||||
= render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
= render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,9 @@
|
||||||
class EditableChamp::CheckboxComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::CheckboxComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_champ_container
|
||||||
|
:fieldset
|
||||||
|
end
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-radio'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
= @form.check_box :value,
|
.fr-fieldset__element
|
||||||
{ required: @champ.required?, id: @champ.input_id, checked: @champ.true?, aria: { describedby: @champ.describedby_id }, class: class_names('required' => @champ.required?)},
|
.fr-checkbox-group
|
||||||
'true',
|
= @form.check_box :value,
|
||||||
'false'
|
{ required: @champ.required?, id: @champ.input_id, checked: @champ.true?, aria: { describedby: @champ.describedby_id }, class: class_names('required' => @champ.required?)},
|
||||||
|
'true',
|
||||||
|
'false'
|
||||||
|
%label.fr-label{ for: @champ.input_id, id: @champ.labelledby_id }
|
||||||
|
= render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
%fieldset.radios
|
%fieldset.fr-fieldset
|
||||||
%legend.mandatory-explanation
|
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
||||||
Sélectionnez une des valeurs
|
Sélectionnez une des valeurs
|
||||||
%label
|
.fr-fieldset__element.fr-fieldset__element--inline
|
||||||
= @form.radio_button :value, Individual::GENDER_FEMALE, id: @champ.female_input_id
|
.fr-radio-group
|
||||||
= Individual.human_attribute_name('gender.female')
|
= @form.radio_button :value, Individual::GENDER_FEMALE, id: @champ.female_input_id
|
||||||
|
%label.fr-label{ for: @champ.female_input_id }
|
||||||
%label
|
= Individual.human_attribute_name('gender.female')
|
||||||
= @form.radio_button :value, Individual::GENDER_MALE, id: @champ.male_input_id
|
.fr-fieldset__element.fr-fieldset__element--inline
|
||||||
= Individual.human_attribute_name('gender.male')
|
.fr-radio-group
|
||||||
|
= @form.radio_button :value, Individual::GENDER_MALE, id: @champ.male_input_id
|
||||||
|
%label.fr-label{ for: @champ.male_input_id }
|
||||||
|
= Individual.human_attribute_name('gender.male')
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
class EditableChamp::CommunesComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::CommunesComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
|
def dsfr_champ_container
|
||||||
|
:fieldset
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def commune_options
|
def commune_options
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
en:
|
en:
|
||||||
postal_code: Enter the postal code then select the municipality from the list
|
postal_code: "Enter <strong>the postal code</strong>"
|
||||||
|
commune: "Select <strong>the municipality</strong> from the list"
|
||||||
not_found: No municipality found for postal code %{postal_code}. Please check that you haven't made any mistakes.
|
not_found: No municipality found for postal code %{postal_code}. Please check that you haven't made any mistakes.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
fr:
|
fr:
|
||||||
postal_code: Renseignez le code postal puis sélectionnez la commune dans la liste
|
postal_code: "Renseignez le <strong>code postal</strong>"
|
||||||
|
commune: "Sélectionnez la commune dans la liste"
|
||||||
not_found: Aucune commune trouvée pour le code postal %{postal_code}. Verifiez que vous n'avez pas fait d’erreur.
|
not_found: Aucune commune trouvée pour le code postal %{postal_code}. Verifiez que vous n'avez pas fait d’erreur.
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
%label.notice{ for: code_postal_input_id }= t('.postal_code')
|
.fr-fieldset__element.fr-mb-0
|
||||||
= @form.text_field :code_postal, required: @champ.required?, id: code_postal_input_id, class: "width-33-desktop width-100-mobile small-margin"
|
.fr-input-group
|
||||||
- if @champ.code_postal?
|
= @form.label :code_postal, t('.postal_code').html_safe, class: 'fr-label', for: code_postal_input_id
|
||||||
|
= @form.text_field :code_postal, required: @champ.required?, id: code_postal_input_id, class: "width-33-desktop width-100-mobile small-margin fr-input"
|
||||||
|
- if @champ.code_postal?
|
||||||
|
- if commune_options.empty?
|
||||||
|
.fr-error-text.mb-4= t('.not_found', postal_code: @champ.code_postal)
|
||||||
|
|
||||||
|
.fr-fieldset__element.fr-mb-0
|
||||||
- if commune_options.empty?
|
- if commune_options.empty?
|
||||||
.fr-error-text.mb-4= t('.not_found', postal_code: @champ.code_postal)
|
-# noop
|
||||||
- elsif commune_options.size <= 3
|
- elsif commune_options.size <= 3
|
||||||
%fieldset.radios
|
%fieldset.fr-fieldset
|
||||||
|
.fr-fieldset__legend--regular.fr-fieldset__legend= t('.commune').html_safe
|
||||||
|
|
||||||
- commune_options.each.with_index do |(option, value), index|
|
- commune_options.each.with_index do |(option, value), index|
|
||||||
%label
|
.fr-fieldset__element
|
||||||
= @form.radio_button :value, value, checked: @champ.selected == value, id: index == 0 ? @champ.input_id : nil
|
.fr-radio-group
|
||||||
= option
|
= @form.radio_button :value, value, checked: @champ.selected == value, id: index == 0 ? @champ.input_id : "radio-#{index}-#{value.parameterize}"
|
||||||
|
= @form.label :value, option, for: index == 0 ? @champ.input_id : "radio-#{index}-#{value.parameterize}", class: 'fr-label'
|
||||||
- else
|
- else
|
||||||
= @form.select :value, commune_options, commune_select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
= @form.label :value, t('.commune').html_safe, for: @champ.input_id, class: 'fr-label'
|
||||||
|
= @form.select :value, commune_options, commune_select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile fr-select"
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::DateComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::DateComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class EditableChamp::DatetimeComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::DatetimeComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
|
|
||||||
def formatted_value_for_datetime_locale
|
def formatted_value_for_datetime_locale
|
||||||
if @champ.valid? && @champ.value.present?
|
if @champ.valid? && @champ.value.present?
|
||||||
# convert to a format that the datetime-local input can understand
|
# convert to a format that the datetime-local input can understand
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::DecimalNumberComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::DecimalNumberComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,10 @@ class EditableChamp::DepartementsComponent < EditableChamp::EditableChampBaseCom
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-select'
|
||||||
|
end
|
||||||
|
|
||||||
def options
|
def options
|
||||||
APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", _1[:code]] }
|
APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", _1[:code]] }
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= @form.select :value, options, select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
= @form.select :value, options, select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "fr-select"
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::DgfipComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::DgfipComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class EditableChamp::DossierLinkComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::DossierLinkComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
|
|
||||||
def dossier
|
def dossier
|
||||||
@dossier ||= @champ.blank? ? nil : Dossier.visible_by_administration.find_by(id: @champ.to_s)
|
@dossier ||= @champ.blank? ? nil : Dossier.visible_by_administration.find_by(id: @champ.to_s)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
class EditableChamp::DropDownListComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::DropDownListComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def select_class_names
|
def select_class_names
|
||||||
class_names('width-100': contains_long_option?)
|
class_names('width-100': contains_long_option?, 'fr-select': true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-select'
|
||||||
|
end
|
||||||
|
|
||||||
|
def dsfr_champ_container
|
||||||
|
@champ.render_as_radios? ? :fieldset : :div
|
||||||
end
|
end
|
||||||
|
|
||||||
def contains_long_option?
|
def contains_long_option?
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
- if @champ.options?
|
- if @champ.options?
|
||||||
- if @champ.render_as_radios?
|
- if @champ.render_as_radios?
|
||||||
%fieldset.radios
|
.fr-fieldset__content
|
||||||
- @champ.enabled_non_empty_options.each do |option|
|
- @champ.enabled_non_empty_options.each_with_index do |option, index|
|
||||||
%label
|
.fr-radio-group
|
||||||
= @form.radio_button :value, option
|
= @form.radio_button :value, option, id: "#{@champ.id}_radio_option_#{index}"
|
||||||
= option
|
%label.fr-label{ for: "#{@champ.id}_radio_option_#{index}" }
|
||||||
|
= option
|
||||||
|
|
||||||
- if !@champ.mandatory?
|
- if !@champ.mandatory?
|
||||||
%label.blank-radio
|
.fr-radio-group
|
||||||
= @form.radio_button :value, '', checked: @champ.value.blank? && !@champ.other?
|
= @form.radio_button :value, '', checked: @champ.value.blank? && !@champ.other?, id: "#{@champ.id}_radio_option_blank"
|
||||||
Non renseigné
|
%label.fr-label{ for: "#{@champ.id}_radio_option_blank" }
|
||||||
|
Non renseigné
|
||||||
|
|
||||||
- if @champ.drop_down_other?
|
- if @champ.drop_down_other?
|
||||||
%label
|
.fr-radio-group
|
||||||
= @form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: @champ.other?
|
= @form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: @champ.other?, id: "#{@champ.id}_radio_option_other"
|
||||||
Autre
|
%label.fr-label{ for: "#{@champ.id}_radio_option_other" }
|
||||||
|
Autre
|
||||||
- else
|
- else
|
||||||
= @form.select :value, @champ.options_without_empty_value_when_mandatory(@champ.options), { selected: @champ.selected }, required: @champ.required?, id: @champ.input_id, class: select_class_names, aria: { describedby: @champ.describedby_id }
|
= @form.select :value,
|
||||||
|
@champ.options.compact_blank,
|
||||||
|
{ selected: @champ.selected, include_blank: true },
|
||||||
|
required: @champ.required?,
|
||||||
|
id: @champ.input_id,
|
||||||
|
class: select_class_names,
|
||||||
|
aria: { describedby: @champ.describedby_id }
|
||||||
|
|
||||||
- if @champ.drop_down_other?
|
- if @champ.drop_down_other?
|
||||||
= render EditableChamp::DropDownOtherInputComponent.new(form: @form, champ: @champ)
|
= render EditableChamp::DropDownOtherInputComponent.new(form: @form, champ: @champ)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.drop_down_other
|
.drop_down_other.fr-mt-2w
|
||||||
.notice
|
.fr-input-group
|
||||||
%label{ for: dom_id(@champ, :value_other) } Veuillez saisir votre autre choix
|
%label.fr-label{ for: dom_id(@champ, :value_other) } Veuillez saisir votre autre choix
|
||||||
= @form.text_field :value_other, maxlength: 200, size: nil, id: dom_id(@champ, :value_other)
|
|
||||||
|
= @form.text_field :value_other, maxlength: 200, size: nil, id: dom_id(@champ, :value_other), class: 'fr-input'
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
class EditableChamp::EditableChampBaseComponent < ApplicationComponent
|
class EditableChamp::EditableChampBaseComponent < ApplicationComponent
|
||||||
include Dsfr::InputErrorable
|
include Dsfr::InputErrorable
|
||||||
|
|
||||||
|
def dsfr_champ_container
|
||||||
|
:div
|
||||||
|
end
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def describedby_id
|
||||||
|
@champ.describedby_id
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(form:, champ:, seen_at: nil, opts: {})
|
def initialize(form:, champ:, seen_at: nil, opts: {})
|
||||||
@form, @champ, @seen_at, @opts = form, champ, seen_at, opts
|
@form, @champ, @seen_at, @opts = form, champ, seen_at, opts
|
||||||
@attribute = :value
|
@attribute = :value
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
class EditableChamp::EditableChampComponent < ApplicationComponent
|
class EditableChamp::EditableChampComponent < ApplicationComponent
|
||||||
include Dsfr::InputErrorable
|
|
||||||
|
|
||||||
def initialize(form:, champ:, seen_at: nil)
|
def initialize(form:, champ:, seen_at: nil)
|
||||||
@form, @champ, @seen_at = form, champ, seen_at
|
@form, @champ, @seen_at = form, champ, seen_at
|
||||||
@attribute = :value
|
@attribute = :value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def champ_component
|
||||||
|
@champ_component ||= component_class.new(form: @form, champ: @champ, seen_at: @seen_at)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def has_label?(champ)
|
def has_label?(champ)
|
||||||
types_without_label = [
|
types_without_label = [
|
||||||
TypeDeChamp.type_champs.fetch(:header_section),
|
TypeDeChamp.type_champs.fetch(:header_section),
|
||||||
TypeDeChamp.type_champs.fetch(:explication),
|
TypeDeChamp.type_champs.fetch(:explication),
|
||||||
TypeDeChamp.type_champs.fetch(:repetition)
|
TypeDeChamp.type_champs.fetch(:repetition),
|
||||||
|
TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
|
||||||
]
|
]
|
||||||
!types_without_label.include?(@champ.type_champ)
|
!types_without_label.include?(@champ.type_champ)
|
||||||
end
|
end
|
||||||
|
@ -28,8 +31,8 @@ class EditableChamp::EditableChampComponent < ApplicationComponent
|
||||||
'editable-champ': true,
|
'editable-champ': true,
|
||||||
"editable-champ-#{@champ.type_champ}": true,
|
"editable-champ-#{@champ.type_champ}": true,
|
||||||
"hidden": !@champ.visible?,
|
"hidden": !@champ.visible?,
|
||||||
"fr-input-group": true
|
champ_component.dsfr_group_classname => true
|
||||||
}.merge(input_group_error_class_names)
|
}.merge(champ_component.input_group_error_class_names)
|
||||||
),
|
),
|
||||||
id: @champ.input_group_id,
|
id: @champ.input_group_id,
|
||||||
data: { controller: stimulus_controller, **data_dependent_conditions, **stimulus_values }
|
data: { controller: stimulus_controller, **data_dependent_conditions, **stimulus_values }
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
= content_tag(:div, html_options) do
|
= content_tag((champ_component.dsfr_champ_container), html_options) do
|
||||||
- if has_label?(@champ)
|
- if has_label?(@champ)
|
||||||
= render EditableChamp::ChampLabelComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
= render EditableChamp::ChampLabelComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
= render component_class.new(form: @form, champ: @champ, seen_at: @seen_at)
|
|
||||||
|
|
||||||
- if errors_on_attribute?
|
= render champ_component
|
||||||
- if error_full_messages.size == 1
|
|
||||||
%p.fr-error-text{ id: describedby_id }= error_full_messages.first
|
= render Dsfr::InputStatusMessageComponent.new(errors_on_attribute: champ_component.errors_on_attribute?, error_full_messages: champ_component.error_full_messages, described_by: @champ.describedby_id)
|
||||||
- else
|
|
||||||
.fr-error-text{ id: describedby_id }
|
|
||||||
%ul.list-style-type-none.fr-pl-0
|
|
||||||
- error_full_messages.each do |error_message|
|
|
||||||
%li= error_message
|
|
||||||
|
|
||||||
= @form.hidden_field :id, value: @champ.id
|
= @form.hidden_field :id, value: @champ.id
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class EditableChamp::EmailComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::EmailComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
|
|
||||||
def email?
|
def email?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
class EditableChamp::EpciComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::EpciComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
|
def dsfr_champ_container
|
||||||
|
:fieldset
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def departement_options
|
def departement_options
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
%label.notice{ for: @champ.code_departement_input_id } Le département de l’EPCI
|
.fr-fieldset__element
|
||||||
= @form.select :code_departement, departement_options, departement_select_options, required: @champ.required?, id: @champ.code_departement_input_id, class: "width-33-desktop width-100-mobile"
|
= @form.label :code_departement, for: @champ.code_departement_input_id, class: 'fr-label' do
|
||||||
|
- "Le département de l’EPCI"
|
||||||
|
= @form.select :code_departement, departement_options, departement_select_options, required: @champ.required?, id: @champ.code_departement_input_id, class: "width-33-desktop width-100-mobile fr-select"
|
||||||
|
|
||||||
- if @champ.departement?
|
- if @champ.departement?
|
||||||
= @form.label "EPCI", for: @champ.epci_input_id
|
.fr-fieldset__element
|
||||||
= @form.select :value, epci_options, epci_select_options, required: @champ.required?, id: @champ.epci_input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
.fr-select-group
|
||||||
|
= @form.label :value, for: @champ.epci_input_id, class: 'fr-label' do
|
||||||
|
- "EPCI"
|
||||||
|
= @form.select :value, epci_options, epci_select_options, required: @champ.required?, id: @champ.epci_input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile fr-select"
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::IbanComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::IbanComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::IntegerNumberComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::IntegerNumberComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class EditableChamp::LinkedDropDownListComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::LinkedDropDownListComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_champ_container
|
||||||
|
:fieldset
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def secondary_label
|
def secondary_label
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
- if @champ.options?
|
- if @champ.options?
|
||||||
= @form.select :primary_value, @champ.primary_options, {}, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }
|
.fr-fieldset__element.fr-mb-0
|
||||||
|
.fr-select-group
|
||||||
|
= render EditableChamp::ChampLabelComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
|
|
||||||
|
= @form.select :primary_value, @champ.primary_options, {}, required: @champ.required?, class: 'fr-select fr-mb-3v', id: @champ.input_id, aria: { describedby: @champ.describedby_id }
|
||||||
|
|
||||||
- if @champ.has_secondary_options_for_primary?
|
- if @champ.has_secondary_options_for_primary?
|
||||||
.secondary
|
.secondary
|
||||||
= @form.label :secondary_value, for: "#{@champ.input_id}-secondary" do
|
.fr-fieldset__element
|
||||||
- sanitize(secondary_label)
|
.fr-select-group
|
||||||
- if @champ.drop_down_secondary_description.present?
|
= @form.label :secondary_value, for: "#{@champ.input_id}-secondary", class: 'fr-label' do
|
||||||
.notice{ id: "#{@champ.describedby_id}-secondary" }
|
- sanitize(secondary_label)
|
||||||
= render SimpleFormatComponent.new(@champ.drop_down_secondary_description, allow_a: true)
|
- if @champ.drop_down_secondary_description.present?
|
||||||
= @form.select :secondary_value, @champ.secondary_options[@champ.primary_value], {}, required: @champ.required?, id: "#{@champ.input_id}-secondary", aria: { describedby: "#{@champ.describedby_id}-secondary" }
|
.notice{ id: "#{@champ.describedby_id}-secondary" }
|
||||||
|
= render SimpleFormatComponent.new(@champ.drop_down_secondary_description, allow_a: true)
|
||||||
|
= @form.select :secondary_value, @champ.secondary_options[@champ.primary_value], {}, required: @champ.required?, class: 'fr-select', id: "#{@champ.input_id}-secondary", aria: { describedby: "#{@champ.describedby_id}-secondary" }
|
||||||
- else
|
- else
|
||||||
= @form.hidden_field :secondary_value, value: ''
|
= @form.hidden_field :secondary_value, value: ''
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::MesriComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::MesriComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
class EditableChamp::MultipleDropDownListComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::MultipleDropDownListComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-select'
|
||||||
|
end
|
||||||
|
|
||||||
|
def dsfr_champ_container
|
||||||
|
@champ.render_as_checkboxes? ? :fieldset : :div
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
- if @champ.options?
|
- if @champ.options?
|
||||||
- if @champ.render_as_checkboxes?
|
- if @champ.render_as_checkboxes?
|
||||||
= @form.collection_check_boxes(:value, @champ.enabled_non_empty_options, :to_s, :to_s) do |b|
|
= @form.collection_check_boxes :value, @champ.enabled_non_empty_options, :to_s, :to_s do |b|
|
||||||
- tag.div(class: 'editable-champ editable-champ-checkbox') do
|
- capture do
|
||||||
- b.label(for: @champ.checkbox_id(b.value)) do
|
.fr-fieldset__element
|
||||||
- b.check_box({ multiple: true, checked: @champ.selected_options.include?(b.value), aria: { describedby: @champ.describedby_id }, id: @champ.checkbox_id(b.value) }) + b.text
|
.fr-checkbox-group
|
||||||
|
= b.check_box(checked: @champ.selected_options.include?(b.value), aria: { describedby: @champ.describedby_id }, id: @champ.checkbox_id(b.value), class: 'fr-checkbox-group__checkbox')
|
||||||
|
%label.fr-label{ for: @champ.checkbox_id(b.value) }
|
||||||
|
= b.text
|
||||||
|
|
||||||
- else
|
- else
|
||||||
%div{ 'data-turbo-focus-group': true }
|
%div{ 'data-turbo-focus-group': true }
|
||||||
- if @champ.selected_options.present?
|
- if @champ.selected_options.present?
|
||||||
.fr-mb-2w
|
.fr-mb-2w{ "data-turbo": "true" }
|
||||||
- @champ.selected_options.each do |option|
|
- @champ.selected_options.each do |option|
|
||||||
= render NestedForms::OwnedButtonComponent.new(formaction: champs_options_path(@champ.id, option:), http_method: :delete, opt: { class: 'fr-tag fr-tag--dismiss fr-mb-1w fr-mr-1w', id: @champ.checkbox_id(option) }) do
|
= render NestedForms::OwnedButtonComponent.new(formaction: champs_options_path(@champ.id, option:), http_method: :delete, opt: { aria: {pressed: true }, class: 'fr-tag fr-tag-bug fr-mb-1w fr-mr-1w', id: @champ.checkbox_id(option) }) do
|
||||||
= option
|
= option
|
||||||
- if @champ.unselected_options.present?
|
- if @champ.unselected_options.present?
|
||||||
= @form.select :value, @champ.unselected_options, { selected: '', include_blank: '' }, id: @champ.input_id, aria: { describedby: @champ.describedby_id }
|
= @form.select :value, @champ.unselected_options, { selected: '', include_blank: '' }, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: 'fr-select fr-mt-2v'
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::NumberComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::NumberComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
class EditableChamp::PaysComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::PaysComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-select'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def options
|
def options
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= @form.select :value, options, select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
= @form.select :value, options, select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile fr-select"
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::PhoneComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::PhoneComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class EditableChamp::PieceJustificativeComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::PieceJustificativeComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
|
|
||||||
def view_as
|
def view_as
|
||||||
if @champ.dossier.brouillon?
|
if @champ.dossier.brouillon?
|
||||||
:link
|
:link
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
class EditableChamp::RegionsComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::RegionsComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-select'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def options
|
def options
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= @form.select :value, options, select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
= @form.select :value, options, select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile fr-select"
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::RNAComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::RNAComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::SiretComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::SiretComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
= @form.text_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.etablissement.blank?, turbo_input_url_value: champs_siret_path(@champ.id) }, required: @champ.required?, pattern: "[0-9]{14}", title: t(".title"), class: "width-33-desktop", maxlength: 14))
|
= @form.text_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.etablissement.blank?, turbo_input_url_value: champs_siret_path(@champ.id) }, required: @champ.required?, pattern: "[0-9]{14}", title: t(".title"), class: "width-33-desktop", maxlength: 14))
|
||||||
.spinner.right.hidden
|
|
||||||
.siret-info{ id: dom_id(@champ, :siret_info) }
|
.siret-info{ id: dom_id(@champ, :siret_info) }
|
||||||
- if @champ.etablissement.present?
|
- if @champ.etablissement.present?
|
||||||
= render EditableChamp::EtablissementTitreComponent.new(etablissement: @champ.etablissement)
|
= render EditableChamp::EtablissementTitreComponent.new(etablissement: @champ.etablissement)
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::TextComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::TextComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
class EditableChamp::TextareaComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::TextareaComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include HtmlToStringHelper
|
include HtmlToStringHelper
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class EditableChamp::TitreIdentiteComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::TitreIdentiteComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_input_classname
|
||||||
|
'fr-input'
|
||||||
|
end
|
||||||
|
|
||||||
def user_can_destroy?
|
def user_can_destroy?
|
||||||
!@champ.mandatory? || @champ.dossier.brouillon?
|
!@champ.mandatory? || @champ.dossier.brouillon?
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
class EditableChamp::YesNoComponent < EditableChamp::EditableChampBaseComponent
|
class EditableChamp::YesNoComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
def dsfr_champ_container
|
||||||
|
:fieldset
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
%fieldset.fr-fieldset
|
|
||||||
%legend.fr-fieldset__legend.visually-hidden
|
|
||||||
= t(".legend")
|
|
||||||
|
|
||||||
%label{ for: @champ.yes_input_id }
|
.fr-fieldset__element.fr-fieldset__element--inline
|
||||||
|
.fr-radio-group
|
||||||
= @form.radio_button :value, true, id: @champ.yes_input_id
|
= @form.radio_button :value, true, id: @champ.yes_input_id
|
||||||
= t(".yes")
|
%label.fr-label{ for: @champ.yes_input_id }
|
||||||
|
= t(".yes")
|
||||||
%label{ for: @champ.no_input_id }
|
.fr-fieldset__element.fr-fieldset__element--inline
|
||||||
|
.fr-radio-group
|
||||||
= @form.radio_button :value, false, id: @champ.no_input_id
|
= @form.radio_button :value, false, id: @champ.no_input_id
|
||||||
= t(".no")
|
%label.fr-label{ for: @champ.no_input_id }
|
||||||
|
= t(".no")
|
||||||
|
|
|
@ -26,11 +26,13 @@ class Instructeurs::SVASVRDecisionBadgeComponent < ApplicationComponent
|
||||||
class_names(
|
class_names(
|
||||||
'fr-badge fr-badge--sm': true,
|
'fr-badge fr-badge--sm': true,
|
||||||
'fr-badge--warning': soon?,
|
'fr-badge--warning': soon?,
|
||||||
'fr-badge--info': !soon?
|
'fr-badge--info': !without_date? && !soon?
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def soon?
|
def soon?
|
||||||
|
return false if object.sva_svr_decision_on.nil?
|
||||||
|
|
||||||
object.sva_svr_decision_on < 7.days.from_now.to_date
|
object.sva_svr_decision_on < 7.days.from_now.to_date
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,16 +53,36 @@ class Instructeurs::SVASVRDecisionBadgeComponent < ApplicationComponent
|
||||||
end
|
end
|
||||||
|
|
||||||
def label_for_badge
|
def label_for_badge
|
||||||
sva? ? "SVA :" : "SVR :"
|
"#{human_decision} : "
|
||||||
end
|
end
|
||||||
|
|
||||||
def title
|
def title
|
||||||
return if without_date?
|
if previously_termine?
|
||||||
|
t('.previously_termine_title')
|
||||||
if pending_correction?
|
elsif depose_before_configuration?
|
||||||
|
t('.depose_before_configuration_title', decision: human_decision)
|
||||||
|
elsif without_date?
|
||||||
|
t('.manual_decision_title', decision: human_decision)
|
||||||
|
elsif pending_correction?
|
||||||
t(".dossier_terminated_x_days_after_correction", count: days_count)
|
t(".dossier_terminated_x_days_after_correction", count: days_count)
|
||||||
else
|
else
|
||||||
t(".dossier_terminated_on", date: helpers.l(object.sva_svr_decision_on))
|
t(".dossier_terminated_on", date: helpers.l(object.sva_svr_decision_on))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def human_decision
|
||||||
|
procedure.sva_svr_configuration.human_decision
|
||||||
|
end
|
||||||
|
|
||||||
|
def previously_termine?
|
||||||
|
return if !object.respond_to?(:previously_termine?)
|
||||||
|
|
||||||
|
object.previously_termine?
|
||||||
|
end
|
||||||
|
|
||||||
|
def depose_before_configuration?
|
||||||
|
return if !object.respond_to?(:sva_svr_decision_triggered_at)
|
||||||
|
|
||||||
|
object.sva_svr_decision_on.nil? && object.sva_svr_decision_triggered_at.nil?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
---
|
---
|
||||||
en:
|
en:
|
||||||
no_sva: Submitted before SVA
|
manual_decision: Manual instruction
|
||||||
no_svr: Submitted before SVR
|
manual_decision_title: The file must be processed by an instructor, either because it was submitted before the %{decision} configuration, or because it has been returned to the instruction stage.
|
||||||
|
depose_before_configuration: Submitted before %{decision}
|
||||||
|
depose_before_configuration_title: This file was submitted before the %{decision} configuration.
|
||||||
|
previously_termine_title: The file has been returned to the instruction stage. It must now be processed by an instructor.
|
||||||
in_days:
|
in_days:
|
||||||
zero: Today
|
zero: Today
|
||||||
one: Tomorrow
|
one: Tomorrow
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
---
|
---
|
||||||
fr:
|
fr:
|
||||||
no_sva: Déposé avant SVA
|
manual_decision: Instruction manuelle
|
||||||
no_svr: Déposé avant SVR
|
manual_decision_title: Le dossier doit être traité par un instructeur, soit car il a été déposé avant la configuration %{decision}, soit car il a été repassé en instruction.
|
||||||
|
depose_before_configuration: Déposé avant %{decision}
|
||||||
|
depose_before_configuration_title: Ce dossier a été déposé avant la configuration %{decision}.
|
||||||
|
previously_termine_title: Le dossier a été repassé en instruction. Il doit être traité par un instructeur.
|
||||||
in_days:
|
in_days:
|
||||||
zero: Aujourd’hui
|
zero: Aujourd’hui
|
||||||
one: Demain
|
one: Demain
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
- if without_date?
|
%span{ class: classes, title: title }
|
||||||
%span.fr-badge.fr-badge--sm
|
- if with_label.present?
|
||||||
= t(sva? ? '.no_sva' : '.no_svr')
|
= label_for_badge
|
||||||
- else
|
|
||||||
%span{ class: classes, title: title }
|
- if previously_termine?
|
||||||
- if with_label.present?
|
= t('.manual_decision')
|
||||||
= label_for_badge
|
- elsif depose_before_configuration?
|
||||||
- if pending_correction?
|
= t('.depose_before_configuration', decision: human_decision)
|
||||||
= t('.remaining_days_after_correction', count: days_count)
|
- elsif without_date? # generic case without SVA/SVR date, when we have a projection
|
||||||
- else
|
= t('.manual_decision')
|
||||||
= t('.in_days', count: days_count)
|
- elsif pending_correction?
|
||||||
|
= t('.remaining_days_after_correction', count: days_count)
|
||||||
|
- else
|
||||||
|
= t('.in_days', count: days_count)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to admin_procedure_administrateurs_path(@procedure), id: 'administrateurs', class: 'fr-tile fr-enlarge-link' do
|
= link_to admin_procedure_administrateurs_path(@procedure), id: 'administrateurs', class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
%p.fr-tile-status-accept Validé
|
%p.fr-tile-status-accept Validé
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to annotations_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link', title: error_messages do
|
= link_to annotations_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link', title: error_messages do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if error_messages.present?
|
- if error_messages.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.refuse
|
%span.icon.refuse
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to jeton_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to jeton_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.api_entreprise_token.present?
|
- if @procedure.api_entreprise_token.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to admin_procedure_api_particulier_path(@procedure), class: 'fr-tile fr-enlarge-link', id: 'api-particulier' do
|
= link_to admin_procedure_api_particulier_path(@procedure), class: 'fr-tile fr-enlarge-link', id: 'api-particulier' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.api_particulier_token.present?
|
- if @procedure.api_particulier_token.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to edit_admin_procedure_attestation_template_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to edit_admin_procedure_attestation_template_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.attestation_template&.activated?
|
- if @procedure.attestation_template&.activated?
|
||||||
%div
|
%div
|
||||||
- if error_messages.present?
|
- if error_messages.present?
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to champs_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link', title: error_messages do
|
= link_to champs_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link', title: error_messages do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if error_messages.present?
|
- if error_messages.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.refuse
|
%span.icon.refuse
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to edit_admin_procedure_dossier_submitted_message_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to edit_admin_procedure_dossier_submitted_message_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.active_dossier_submitted_message.present?
|
- if @procedure.active_dossier_submitted_message.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to admin_procedure_mail_templates_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to admin_procedure_mail_templates_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
%div
|
%div
|
||||||
- if error_messages.present?
|
- if error_messages.present?
|
||||||
%span.icon.refuse
|
%span.icon.refuse
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to admin_procedure_experts_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to admin_procedure_experts_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
%div
|
%div
|
||||||
%span.icon.preview
|
%span.icon.preview
|
||||||
%p.fr-tile-status-todo À configurer
|
%p.fr-tile-status-todo À configurer
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to admin_procedure_groupe_instructeurs_path(@procedure), id: 'groupe-instructeurs', class: 'fr-tile fr-enlarge-link' do
|
= link_to admin_procedure_groupe_instructeurs_path(@procedure), id: 'groupe-instructeurs', class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.routing_enabled? || @procedure.instructeurs.present?
|
- if @procedure.routing_enabled? || @procedure.instructeurs.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to modifications_admin_procedure_path(@procedure), id: 'modifications', class: 'fr-tile fr-enlarge-link' do
|
= link_to modifications_admin_procedure_path(@procedure), id: 'modifications', class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
%p.fr-tile-status-accept Activée
|
%p.fr-tile-status-accept Activée
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to monavis_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to monavis_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.monavis_embed.present?
|
- if @procedure.monavis_embed.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to edit_admin_procedure_path(@procedure), id: 'presentation', class: 'fr-tile fr-enlarge-link' do
|
= link_to edit_admin_procedure_path(@procedure), id: 'presentation', class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
%p.fr-tile-status-accept Validé
|
%p.fr-tile-status-accept Validé
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to service_link, class: 'fr-tile fr-enlarge-link', id: 'service' do
|
= link_to service_link, class: 'fr-tile fr-enlarge-link', id: 'service' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.service_id.present?
|
- if @procedure.service_id.present?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to edit_admin_procedure_sva_svr_path(@procedure), class: 'fr-tile fr-enlarge-link', id: 'sva' do
|
= link_to edit_admin_procedure_sva_svr_path(@procedure), class: 'fr-tile fr-enlarge-link', id: 'sva' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.sva_svr_enabled?
|
- if @procedure.sva_svr_enabled?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
= link_to zones_admin_procedure_path(@procedure), id: 'zones', class: 'fr-tile fr-enlarge-link' do
|
= link_to zones_admin_procedure_path(@procedure), id: 'zones', class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if @procedure.zones.size >= 1
|
- if @procedure.zones.size >= 1
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
|
|
|
@ -17,6 +17,10 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent
|
||||||
@groupe_instructeur.routing_rule&.right || empty
|
@groupe_instructeur.routing_rule&.right || empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def operator_name
|
||||||
|
@groupe_instructeur.routing_rule&.class&.name || empty
|
||||||
|
end
|
||||||
|
|
||||||
def targeted_champ_tag
|
def targeted_champ_tag
|
||||||
select_tag(
|
select_tag(
|
||||||
'targeted_champ',
|
'targeted_champ',
|
||||||
|
@ -39,6 +43,21 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent
|
||||||
.map { |tdc| [tdc.libelle, champ_value(tdc.stable_id).to_json] }
|
.map { |tdc| [tdc.libelle, champ_value(tdc.stable_id).to_json] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def operator_tag
|
||||||
|
select_tag('operator_name',
|
||||||
|
options_for_select(
|
||||||
|
options_for_operator_tag,
|
||||||
|
selected: operator_name
|
||||||
|
),
|
||||||
|
class: 'fr-select')
|
||||||
|
end
|
||||||
|
|
||||||
|
def options_for_operator_tag
|
||||||
|
[Eq, NotEq]
|
||||||
|
.map(&:name)
|
||||||
|
.map { |name| [t(name, scope: 'logic.operators'), name] }
|
||||||
|
end
|
||||||
|
|
||||||
def value_tag
|
def value_tag
|
||||||
select_tag(
|
select_tag(
|
||||||
'value',
|
'value',
|
||||||
|
|
|
@ -40,7 +40,8 @@
|
||||||
.fr-mr-2w.no-wrap si le champ
|
.fr-mr-2w.no-wrap si le champ
|
||||||
.target.fr-mr-2w
|
.target.fr-mr-2w
|
||||||
= targeted_champ_tag
|
= targeted_champ_tag
|
||||||
.operator.fr-mr-2w.no-wrap est égal à
|
.operator.fr-mr-2w.no-wrap
|
||||||
|
= operator_tag
|
||||||
.value
|
.value
|
||||||
= value_tag
|
= value_tag
|
||||||
.fr-hint-text
|
.fr-hint-text
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
||||||
def initialize(revision:, parent: nil, is_annotation: false)
|
def initialize(revision:, parent: nil, is_annotation: false, after_stable_id: nil)
|
||||||
@revision = revision
|
@revision = revision
|
||||||
@parent = parent
|
@parent = parent
|
||||||
@is_annotation = is_annotation
|
@is_annotation = is_annotation
|
||||||
|
@after_stable_id = after_stable_id
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -25,8 +26,7 @@ class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
||||||
|
|
||||||
def button_options
|
def button_options
|
||||||
{
|
{
|
||||||
class: "button",
|
class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-line",
|
||||||
form: { class: @parent ? "add-to-block" : "add-to-root" },
|
|
||||||
method: :post,
|
method: :post,
|
||||||
params: {
|
params: {
|
||||||
type_de_champ: {
|
type_de_champ: {
|
||||||
|
@ -34,7 +34,7 @@ class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
||||||
type_champ: TypeDeChamp.type_champs.fetch(:text),
|
type_champ: TypeDeChamp.type_champs.fetch(:text),
|
||||||
private: annotations? ? true : nil,
|
private: annotations? ? true : nil,
|
||||||
parent_stable_id: @parent&.stable_id,
|
parent_stable_id: @parent&.stable_id,
|
||||||
after_stable_id: ''
|
after_stable_id: @after_stable_id
|
||||||
}.compact
|
}.compact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
|
||||||
controller: 'type-de-champ-editor',
|
controller: 'type-de-champ-editor',
|
||||||
type_de_champ_editor_move_url_value: move_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_url_value: move_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
||||||
type_de_champ_editor_move_up_url_value: move_up_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_up_url_value: move_up_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
||||||
type_de_champ_editor_move_down_url_value: move_down_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_down_url_value: move_down_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id)
|
||||||
type_de_champ_editor_type_de_champ_stable_id_value: type_de_champ.stable_id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,117 +1,123 @@
|
||||||
%li.type-de-champ.flex.column.justify-start{ html_options }
|
%li.type-de-champ.flex.column.justify-start{ html_options }
|
||||||
.flex.justify-between.section.head.hr
|
.type-de-champ-container
|
||||||
.handle.small.icon-only.icon.move-handle{ title: "Déplacer le champ vers le haut ou vers le bas" }
|
.flex.justify-between.section.head.hr
|
||||||
|
.handle.small.icon-only.icon.move-handle{ title: "Déplacer le champ vers le haut ou vers le bas" }
|
||||||
|
|
||||||
- if coordinate.used_by_routing_rules?
|
- if coordinate.used_by_routing_rules?
|
||||||
.flex.align-center
|
.flex.align-center
|
||||||
%span
|
%span
|
||||||
utilisé pour
|
utilisé pour
|
||||||
= link_to('le routage', admin_procedure_groupe_instructeurs_path(revision.procedure_id, anchor: 'routing-rules'))
|
= link_to('le routage', admin_procedure_groupe_instructeurs_path(revision.procedure_id, anchor: 'routing-rules'))
|
||||||
- else
|
- else
|
||||||
.flex.justify-start.delete
|
.flex.justify-start.delete
|
||||||
= button_to type_de_champ_path, class: 'button small icon-only danger', method: :delete, form: { data: { turbo_confirm: 'Êtes vous sûr de vouloir supprimer ce champ ?' } } do
|
= button_to type_de_champ_path, class: 'fr-btn fr-btn--sm fr-btn--secondary fr-icon-delete-line', title: "Supprimer le champ", method: :delete, form: { data: { turbo_confirm: 'Êtes vous sûr de vouloir supprimer ce champ ?' } } do
|
||||||
.icon.delete
|
.icon.delete
|
||||||
%span.sr-only Supprimer
|
%span.sr-only Supprimer
|
||||||
|
|
||||||
- if @errors.present?
|
- if @errors.present?
|
||||||
.types-de-champ-errors
|
.types-de-champ-errors
|
||||||
= @errors
|
= @errors
|
||||||
|
|
||||||
.flex.justify-start.section.ml-1
|
.flex.justify-start.section.ml-1
|
||||||
= form_for(type_de_champ, form_options) do |form|
|
= form_for(type_de_champ, form_options) do |form|
|
||||||
.flex.justify-start
|
.flex.justify-start
|
||||||
.flex.justify-start.width-33
|
.flex.justify-start.width-33
|
||||||
.flex.justify-start.column
|
.flex.justify-start.column
|
||||||
%button.move-up.cell.mb-1{ move_button_options(:up) }
|
%button.move-up.cell.mb-1{ move_button_options(:up) }
|
||||||
.icon.arrow-up.small
|
.icon.arrow-up.small
|
||||||
%span.sr-only Déplacer le champ vers le haut
|
%span.sr-only Déplacer le champ vers le haut
|
||||||
%button.move-down.cell{ move_button_options(:down) }
|
%button.move-down.cell{ move_button_options(:down) }
|
||||||
.icon.arrow-down.small
|
.icon.arrow-down.small
|
||||||
%span.sr-only Déplacer le champ vers le bas
|
%span.sr-only Déplacer le champ vers le bas
|
||||||
.cell.flex.justify-start.column.flex-grow
|
.cell.flex.justify-start.column.flex-grow
|
||||||
= form.label :type_champ, "Type de champ", for: dom_id(type_de_champ, :type_champ)
|
= form.label :type_champ, "Type de champ", for: dom_id(type_de_champ, :type_champ)
|
||||||
= form.select :type_champ, grouped_options_for_select(types_of_type_de_champ, type_de_champ.type_champ), {}, class: 'small-margin small inline width-100', id: dom_id(type_de_champ, :type_champ), disabled: coordinate.used_by_routing_rules?
|
= form.select :type_champ, grouped_options_for_select(types_of_type_de_champ, type_de_champ.type_champ), {}, class: 'fr-select small-margin small inline width-100', id: dom_id(type_de_champ, :type_champ), disabled: coordinate.used_by_routing_rules?
|
||||||
.flex.column.justify-start.flex-grow
|
|
||||||
.cell
|
|
||||||
.flex.align-center
|
|
||||||
= form.label :libelle, "Libellé du champ", class: 'flex-grow', for: dom_id(type_de_champ, :libelle)
|
|
||||||
- if can_be_mandatory?
|
|
||||||
.cell.flex.align-center
|
|
||||||
= form.check_box :mandatory, class: 'small-margin small', id: dom_id(type_de_champ, :mandatory)
|
|
||||||
= form.label :mandatory, "Champ obligatoire", for: dom_id(type_de_champ, :mandatory)
|
|
||||||
= form.text_field :libelle, class: 'small-margin small width-100', id: dom_id(type_de_champ, :libelle), data: input_autofocus
|
|
||||||
- if type_de_champ.header_section?
|
|
||||||
%p
|
|
||||||
%small Nous numérotons automatiquement les titres lorsqu’aucun de vos titres ne commence par un chiffre.
|
|
||||||
|
|
||||||
- if !type_de_champ.header_section? && !type_de_champ.titre_identite?
|
|
||||||
.cell.mt-1
|
|
||||||
= form.label :description, "Description du champ (optionnel)", for: dom_id(type_de_champ, :description)
|
|
||||||
= form.text_area :description, class: 'small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :description)
|
|
||||||
- if type_de_champ.header_section?
|
|
||||||
.cell.mt-1
|
|
||||||
= render TypesDeChampEditor::HeaderSectionComponent.new(form: form, tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.flex.justify-start.mt-1
|
|
||||||
- if type_de_champ.drop_down_list?
|
|
||||||
.flex.column.justify-start.width-33
|
|
||||||
.cell
|
|
||||||
= form.label :drop_down_list_value, "Options de la liste", for: dom_id(type_de_champ, :drop_down_list_value)
|
|
||||||
= form.text_area :drop_down_list_value, class: 'small-margin small width-100', rows: 7, id: dom_id(type_de_champ, :drop_down_list_value)
|
|
||||||
- if type_de_champ.simple_drop_down_list?
|
|
||||||
.cell
|
|
||||||
= form.label :drop_down_other, for: dom_id(type_de_champ, :drop_down_other) do
|
|
||||||
Proposer une option « autre » avec un texte libre
|
|
||||||
= form.check_box :drop_down_other, class: "small-margin small", id: dom_id(type_de_champ, :drop_down_other)
|
|
||||||
|
|
||||||
- if type_de_champ.linked_drop_down_list?
|
|
||||||
.flex.column.justify-start.flex-grow
|
.flex.column.justify-start.flex-grow
|
||||||
.cell
|
.cell
|
||||||
= form.label :drop_down_secondary_libelle, "Libellé du champ secondaire", class: 'flex-grow', for: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
.flex.align-center
|
||||||
= form.text_field :drop_down_secondary_libelle, class: 'small-margin small width-100', id: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
= form.label :libelle, "Libellé du champ", class: 'flex-grow', for: dom_id(type_de_champ, :libelle)
|
||||||
.cell.mt-1
|
- if can_be_mandatory?
|
||||||
= form.label :drop_down_secondary_description, "Description du champ secondaire (optionnel)", for: dom_id(type_de_champ, :drop_down_secondary_description)
|
.cell.flex.align-center
|
||||||
= form.text_area :drop_down_secondary_description, class: 'small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :drop_down_secondary_description)
|
= form.check_box :mandatory, class: 'small-margin small', id: dom_id(type_de_champ, :mandatory)
|
||||||
- if type_de_champ.piece_justificative?
|
= form.label :mandatory, "Champ obligatoire", for: dom_id(type_de_champ, :mandatory)
|
||||||
.cell
|
= form.text_field :libelle, class: 'fr-input small-margin small width-100', id: dom_id(type_de_champ, :libelle), data: input_autofocus
|
||||||
= form.label :piece_justificative_template, "Modèle", for: dom_id(type_de_champ, :piece_justificative_template)
|
- if type_de_champ.header_section?
|
||||||
= render Attachment::EditComponent.new(**piece_justificative_template_options)
|
%p
|
||||||
|
%small Nous numérotons automatiquement les titres lorsqu’aucun de vos titres ne commence par un chiffre.
|
||||||
|
|
||||||
- if type_de_champ.titre_identite?
|
- if !type_de_champ.header_section? && !type_de_champ.titre_identite?
|
||||||
%p Dans le cadre de la RGPD, le titre d’identité sera supprimé lors de l’acceptation du dossier
|
.cell.mt-1
|
||||||
- elsif procedure.piece_justificative_multiple?
|
= form.label :description, "Description du champ (optionnel)", for: dom_id(type_de_champ, :description)
|
||||||
%p Les usagers pourront envoyer plusieurs fichiers si nécessaire.
|
= form.text_area :description, class: 'fr-input small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :description)
|
||||||
- if type_de_champ.carte?
|
- if type_de_champ.header_section?
|
||||||
- type_de_champ.editable_options.each do |slice|
|
.cell.mt-1
|
||||||
|
= render TypesDeChampEditor::HeaderSectionComponent.new(form: form, tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.flex.justify-start.mt-1
|
||||||
|
- if type_de_champ.drop_down_list?
|
||||||
|
.flex.column.justify-start.width-33
|
||||||
|
.cell
|
||||||
|
= form.label :drop_down_list_value, "Options de la liste", for: dom_id(type_de_champ, :drop_down_list_value)
|
||||||
|
= form.text_area :drop_down_list_value, class: 'fr-input small-margin small width-100', rows: 7, id: dom_id(type_de_champ, :drop_down_list_value)
|
||||||
|
- if type_de_champ.simple_drop_down_list?
|
||||||
|
.cell
|
||||||
|
= form.label :drop_down_other, for: dom_id(type_de_champ, :drop_down_other) do
|
||||||
|
Proposer une option « autre » avec un texte libre
|
||||||
|
= form.check_box :drop_down_other, class: "small-margin small", id: dom_id(type_de_champ, :drop_down_other)
|
||||||
|
|
||||||
|
- if type_de_champ.linked_drop_down_list?
|
||||||
|
.flex.column.justify-start.flex-grow
|
||||||
|
.cell
|
||||||
|
= form.label :drop_down_secondary_libelle, "Libellé du champ secondaire", class: 'flex-grow', for: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
||||||
|
= form.text_field :drop_down_secondary_libelle, class: 'fr-input small-margin small width-100', id: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
||||||
|
.cell.mt-1
|
||||||
|
= form.label :drop_down_secondary_description, "Description du champ secondaire (optionnel)", for: dom_id(type_de_champ, :drop_down_secondary_description)
|
||||||
|
= form.text_area :drop_down_secondary_description, class: 'fr-input small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :drop_down_secondary_description)
|
||||||
|
- if type_de_champ.piece_justificative?
|
||||||
.cell
|
.cell
|
||||||
.carte-options
|
= form.label :piece_justificative_template, "Modèle", for: dom_id(type_de_champ, :piece_justificative_template)
|
||||||
= form.fields_for :editable_options do |form|
|
= render Attachment::EditComponent.new(**piece_justificative_template_options)
|
||||||
- slice.each do |(name, checked)|
|
|
||||||
= form.label name, for: dom_id(type_de_champ, "layer_#{name}") do
|
|
||||||
= form.check_box name, checked: checked, class: 'small-margin small', id: dom_id(type_de_champ, "layer_#{name}")
|
|
||||||
= t(".layers.#{name}")
|
|
||||||
- if type_de_champ.explication?
|
|
||||||
.cell.width-66
|
|
||||||
= form.label :collapsible_explanation_enabled, for: dom_id(type_de_champ, :collapsible_explanation_enabled) do
|
|
||||||
Afficher un texte complementaire affichable au clic
|
|
||||||
= form.check_box :collapsible_explanation_enabled, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_enabled)
|
|
||||||
- if form.object.collapsible_explanation_enabled?
|
|
||||||
= form.label :collapsible_explanation_text, for: dom_id(type_de_champ, :collapsible_explanation_text) do
|
|
||||||
= "Texte à afficher quand l'utiliser a choisi de l'afficher"
|
|
||||||
= form.text_area :collapsible_explanation_text, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_text)
|
|
||||||
- if type_de_champ.textarea?
|
|
||||||
.cell
|
|
||||||
= form.label :character_limit, for: dom_id(type_de_champ, :character_limit) do
|
|
||||||
Spécifier un nombre maximal conseillé de caractères :
|
|
||||||
= form.select :character_limit, options_for_character_limit, id: dom_id(type_de_champ, :character_limit)
|
|
||||||
|
|
||||||
- if type_de_champ.block?
|
- if type_de_champ.titre_identite?
|
||||||
.flex.justify-start.section.ml-1
|
%p Dans le cadre de la RGPD, le titre d’identité sera supprimé lors de l’acceptation du dossier
|
||||||
.editor-block.flex-grow.cell
|
- elsif procedure.piece_justificative_multiple?
|
||||||
= render TypesDeChampEditor::BlockComponent.new(block: coordinate, coordinates: coordinate.revision_types_de_champ, upper_coordinates: @upper_coordinates)
|
%p Les usagers pourront envoyer plusieurs fichiers si nécessaire.
|
||||||
= render TypesDeChampEditor::AddChampButtonComponent.new(revision: coordinate.revision, parent: coordinate, is_annotation: coordinate.private?)
|
- if type_de_champ.carte?
|
||||||
|
- type_de_champ.editable_options.each do |slice|
|
||||||
|
.cell
|
||||||
|
.carte-options
|
||||||
|
= form.fields_for :editable_options do |form|
|
||||||
|
- slice.each do |(name, checked)|
|
||||||
|
= form.label name, for: dom_id(type_de_champ, "layer_#{name}") do
|
||||||
|
= form.check_box name, checked: checked, class: 'small-margin small', id: dom_id(type_de_champ, "layer_#{name}")
|
||||||
|
= t(".layers.#{name}")
|
||||||
|
- if type_de_champ.explication?
|
||||||
|
.cell.width-66
|
||||||
|
= form.label :collapsible_explanation_enabled, for: dom_id(type_de_champ, :collapsible_explanation_enabled) do
|
||||||
|
Afficher un texte complementaire affichable au clic
|
||||||
|
= form.check_box :collapsible_explanation_enabled, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_enabled)
|
||||||
|
- if form.object.collapsible_explanation_enabled?
|
||||||
|
= form.label :collapsible_explanation_text, for: dom_id(type_de_champ, :collapsible_explanation_text) do
|
||||||
|
= "Texte à afficher quand l'utiliser a choisi de l'afficher"
|
||||||
|
= form.text_area :collapsible_explanation_text, class: "fr-input small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_text)
|
||||||
|
- if type_de_champ.textarea?
|
||||||
|
.cell
|
||||||
|
= form.label :character_limit, for: dom_id(type_de_champ, :character_limit) do
|
||||||
|
Spécifier un nombre maximal conseillé de caractères :
|
||||||
|
= form.select :character_limit, options_for_character_limit, id: dom_id(type_de_champ, :character_limit), class: 'fr-select'
|
||||||
|
|
||||||
- if conditional_enabled?
|
- if type_de_champ.block?
|
||||||
= render(TypesDeChampEditor::ConditionsComponent.new(tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ), procedure_id: procedure.id))
|
.flex.justify-start.section.ml-1
|
||||||
|
.editor-block.flex-grow.cell
|
||||||
|
= render TypesDeChampEditor::BlockComponent.new(block: coordinate, coordinates: coordinate.revision_types_de_champ, upper_coordinates: @upper_coordinates)
|
||||||
|
.type-de-champ-add-button{ id: dom_id(coordinate, :type_de_champ_add_button), class: class_names(hidden: !coordinate.empty?) }
|
||||||
|
= render TypesDeChampEditor::AddChampButtonComponent.new(revision: coordinate.revision, parent: coordinate, is_annotation: coordinate.private?)
|
||||||
|
|
||||||
|
- if conditional_enabled?
|
||||||
|
= render(TypesDeChampEditor::ConditionsComponent.new(tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ), procedure_id: procedure.id))
|
||||||
|
|
||||||
|
.type-de-champ-add-button{ class: class_names(root: !coordinate.child?) }
|
||||||
|
= render TypesDeChampEditor::AddChampButtonComponent.new(revision: coordinate.revision, parent: coordinate&.parent, is_annotation: coordinate.private?, after_stable_id: type_de_champ.stable_id)
|
||||||
|
|
|
@ -9,7 +9,13 @@ module Administrateurs
|
||||||
|
|
||||||
right = targeted_champ_changed? ? empty : value
|
right = targeted_champ_changed? ? empty : value
|
||||||
|
|
||||||
groupe_instructeur.update!(routing_rule: ds_eq(left, right))
|
new_routing_rule = case operator_name
|
||||||
|
when Eq.name
|
||||||
|
ds_eq(left, right)
|
||||||
|
when NotEq.name
|
||||||
|
ds_not_eq(left, right)
|
||||||
|
end
|
||||||
|
groupe_instructeur.update!(routing_rule: new_routing_rule)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_defaut_groupe_instructeur
|
def update_defaut_groupe_instructeur
|
||||||
|
@ -27,6 +33,10 @@ module Administrateurs
|
||||||
Logic.from_json(params[:targeted_champ])
|
Logic.from_json(params[:targeted_champ])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def operator_name
|
||||||
|
params[:operator_name]
|
||||||
|
end
|
||||||
|
|
||||||
def value
|
def value
|
||||||
Logic.from_json(params[:value])
|
Logic.from_json(params[:value])
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ class API::Public::V1::DossiersController < API::Public::V1::BaseController
|
||||||
)
|
)
|
||||||
dossier.build_default_individual
|
dossier.build_default_individual
|
||||||
if dossier.save
|
if dossier.save
|
||||||
dossier.prefill!(PrefillParams.new(dossier, params.to_unsafe_h).to_a)
|
dossier.prefill!(PrefillChamps.new(dossier, params.to_unsafe_h).to_a, PrefillIdentity.new(dossier, params.to_unsafe_h).to_h)
|
||||||
render json: serialize_dossier(dossier), status: :created
|
render json: serialize_dossier(dossier), status: :created
|
||||||
else
|
else
|
||||||
render_bad_request(dossier.errors.full_messages.to_sentence)
|
render_bad_request(dossier.errors.full_messages.to_sentence)
|
||||||
|
|
|
@ -25,6 +25,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
before_action do
|
before_action do
|
||||||
Current.request_id = request.uuid
|
Current.request_id = request.uuid
|
||||||
|
Current.user = current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def staging_authenticate
|
def staging_authenticate
|
||||||
|
|
|
@ -25,6 +25,6 @@ class PrefillDescriptionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def prefill_description_params
|
def prefill_description_params
|
||||||
params.require(:type_de_champ).permit(:selected_type_de_champ_ids)
|
params.require(:procedure).permit(:selected_type_de_champ_ids, :identity_items_selected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -78,11 +78,11 @@ module Users
|
||||||
end
|
end
|
||||||
|
|
||||||
def commencer_page_is_reloaded?
|
def commencer_page_is_reloaded?
|
||||||
session[:prefill_token].present? && session[:prefill_params_digest] == PrefillParams.digest(params)
|
session[:prefill_token].present? && session[:prefill_params_digest] == PrefillChamps.digest(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def prefill_params_present?
|
def prefill_params_present?
|
||||||
params.keys.find { |param| param.split('_').first == "champ" }
|
params.keys.find { ['champ', 'identite'].include?(_1.split('_').first) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def retrieve_procedure
|
def retrieve_procedure
|
||||||
|
@ -101,10 +101,10 @@ module Users
|
||||||
)
|
)
|
||||||
@prefilled_dossier.build_default_individual
|
@prefilled_dossier.build_default_individual
|
||||||
if @prefilled_dossier.save
|
if @prefilled_dossier.save
|
||||||
@prefilled_dossier.prefill!(PrefillParams.new(@prefilled_dossier, params.to_unsafe_h).to_a)
|
@prefilled_dossier.prefill!(PrefillChamps.new(@prefilled_dossier, params.to_unsafe_h).to_a, PrefillIdentity.new(@prefilled_dossier, params.to_unsafe_h).to_h)
|
||||||
end
|
end
|
||||||
session[:prefill_token] = @prefilled_dossier.prefill_token
|
session[:prefill_token] = @prefilled_dossier.prefill_token
|
||||||
session[:prefill_params_digest] = PrefillParams.digest(params)
|
session[:prefill_params_digest] = PrefillChamps.digest(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def retrieve_prefilled_dossier(prefill_token)
|
def retrieve_prefilled_dossier(prefill_token)
|
||||||
|
|
|
@ -14,6 +14,8 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
aasm_state: ProcedureStateField,
|
aasm_state: ProcedureStateField,
|
||||||
dossiers: Field::HasMany,
|
dossiers: Field::HasMany,
|
||||||
administrateurs: Field::HasMany,
|
administrateurs: Field::HasMany,
|
||||||
|
instructeurs: Field::HasMany,
|
||||||
|
groupe_instructeurs: Field::HasMany,
|
||||||
id: Field::Number.with_options(searchable: true),
|
id: Field::Number.with_options(searchable: true),
|
||||||
libelle: Field::String,
|
libelle: Field::String,
|
||||||
description: Field::String,
|
description: Field::String,
|
||||||
|
@ -68,6 +70,8 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
:path,
|
:path,
|
||||||
:aasm_state,
|
:aasm_state,
|
||||||
:administrateurs,
|
:administrateurs,
|
||||||
|
:instructeurs,
|
||||||
|
:groupe_instructeurs,
|
||||||
:libelle,
|
:libelle,
|
||||||
:description,
|
:description,
|
||||||
:tags,
|
:tags,
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type { Style } from 'maplibre-gl';
|
||||||
|
|
||||||
import invariant from 'tiny-invariant';
|
import invariant from 'tiny-invariant';
|
||||||
|
|
||||||
import { useStyle } from './hooks';
|
import { useStyle, useElementVisible } from './hooks';
|
||||||
import { StyleControl } from './StyleControl';
|
import { StyleControl } from './StyleControl';
|
||||||
|
|
||||||
const Context = createContext<{ map?: Map | null }>({});
|
const Context = createContext<{ map?: Map | null }>({});
|
||||||
|
@ -35,6 +35,7 @@ export function MapLibre({ children, layers }: MapLibreProps) {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const visible = useElementVisible(containerRef);
|
||||||
const [map, setMap] = useState<Map | null>();
|
const [map, setMap] = useState<Map | null>();
|
||||||
|
|
||||||
const onStyleChange = useCallback(
|
const onStyleChange = useCallback(
|
||||||
|
@ -48,7 +49,7 @@ export function MapLibre({ children, layers }: MapLibreProps) {
|
||||||
const { style, ...mapStyleProps } = useStyle(layers, onStyleChange);
|
const { style, ...mapStyleProps } = useStyle(layers, onStyleChange);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSupported && !map) {
|
if (isSupported && visible && !map) {
|
||||||
invariant(containerRef.current, 'Map container not found');
|
invariant(containerRef.current, 'Map container not found');
|
||||||
const map = new Map({
|
const map = new Map({
|
||||||
container: containerRef.current,
|
container: containerRef.current,
|
||||||
|
@ -59,7 +60,7 @@ export function MapLibre({ children, layers }: MapLibreProps) {
|
||||||
setMap(map);
|
setMap(map);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [map, style, isSupported]);
|
}, [map, style, visible, isSupported]);
|
||||||
|
|
||||||
if (!isSupported) {
|
if (!isSupported) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import { useCallback, useEffect, useState, useMemo } from 'react';
|
import {
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
useMemo,
|
||||||
|
type RefObject
|
||||||
|
} from 'react';
|
||||||
import type {
|
import type {
|
||||||
LngLatBoundsLike,
|
LngLatBoundsLike,
|
||||||
LngLat,
|
LngLat,
|
||||||
|
@ -118,3 +124,30 @@ export function useStyle(
|
||||||
|
|
||||||
return { style, layers, setStyle, setLayerEnabled, setLayerOpacity };
|
return { style, layers, setStyle, setLayerEnabled, setLayerOpacity };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isElementVisible(
|
||||||
|
element: HTMLElement,
|
||||||
|
callback: (visible: boolean) => void
|
||||||
|
) {
|
||||||
|
if (element.offsetWidth > 0 && element.offsetHeight > 0) {
|
||||||
|
callback(true);
|
||||||
|
} else {
|
||||||
|
callback(false);
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => callback(entries[0].isIntersecting == true),
|
||||||
|
{ threshold: [0] }
|
||||||
|
);
|
||||||
|
observer.observe(element);
|
||||||
|
return () => observer.unobserve(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useElementVisible(element: RefObject<HTMLElement>) {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (element.current) {
|
||||||
|
return isElementVisible(element.current, setVisible);
|
||||||
|
}
|
||||||
|
}, [element]);
|
||||||
|
return visible;
|
||||||
|
}
|
||||||
|
|
|
@ -124,12 +124,12 @@ export class AutosaveController extends ApplicationController {
|
||||||
private showSpinner(champElement: Element) {
|
private showSpinner(champElement: Element) {
|
||||||
this.#spinnerTimeoutId = setTimeout(() => {
|
this.#spinnerTimeoutId = setTimeout(() => {
|
||||||
// do not do anything if there is already a spinner for this champ, like SIRET champ
|
// do not do anything if there is already a spinner for this champ, like SIRET champ
|
||||||
if (!champElement.querySelector('.spinner')) {
|
if (!champElement.nextElementSibling?.classList.contains('spinner')) {
|
||||||
const spinner = document.createElement('div');
|
const spinner = document.createElement('div');
|
||||||
spinner.classList.add('spinner', 'spinner-removable');
|
spinner.classList.add('spinner', 'spinner-removable');
|
||||||
spinner.setAttribute('aria-live', 'live');
|
spinner.setAttribute('aria-live', 'live');
|
||||||
spinner.setAttribute('aria-label', 'Chargement en cours…');
|
spinner.setAttribute('aria-label', 'Chargement en cours…');
|
||||||
champElement.appendChild(spinner);
|
champElement.insertAdjacentElement('afterend', spinner);
|
||||||
}
|
}
|
||||||
}, AUTOSAVE_CONDITIONAL_SPINNER_DEBOUNCE_DELAY);
|
}, AUTOSAVE_CONDITIONAL_SPINNER_DEBOUNCE_DELAY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
isTextInputElement,
|
isTextInputElement,
|
||||||
getConfig
|
getConfig
|
||||||
} from '@utils';
|
} from '@utils';
|
||||||
import { useIntersection } from 'stimulus-use';
|
|
||||||
import { AutoUpload } from '../shared/activestorage/auto-upload';
|
import { AutoUpload } from '../shared/activestorage/auto-upload';
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
declare readonly moveUrlValue: string;
|
declare readonly moveUrlValue: string;
|
||||||
declare readonly moveUpUrlValue: string;
|
declare readonly moveUpUrlValue: string;
|
||||||
declare readonly moveDownUrlValue: string;
|
declare readonly moveDownUrlValue: string;
|
||||||
declare readonly typeDeChampStableIdValue: string;
|
|
||||||
declare readonly isVisible: boolean;
|
declare readonly isVisible: boolean;
|
||||||
|
|
||||||
#latestPromise = Promise.resolve();
|
#latestPromise = Promise.resolve();
|
||||||
|
@ -36,8 +34,6 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
#inFlightForms: Map<HTMLFormElement, AbortController> = new Map();
|
#inFlightForms: Map<HTMLFormElement, AbortController> = new Map();
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
useIntersection(this, { threshold: 0.6 });
|
|
||||||
|
|
||||||
this.#latestPromise = Promise.resolve();
|
this.#latestPromise = Promise.resolve();
|
||||||
this.on('change', (event) => this.onChange(event));
|
this.on('change', (event) => this.onChange(event));
|
||||||
this.on('input', (event) => this.onInput(event));
|
this.on('input', (event) => this.onInput(event));
|
||||||
|
@ -62,10 +58,6 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
this.requestSubmitForm(form);
|
this.requestSubmitForm(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
appear() {
|
|
||||||
this.updateAfterId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private onChange(event: Event) {
|
private onChange(event: Event) {
|
||||||
const target = event.target as HTMLElement & { form?: HTMLFormElement };
|
const target = event.target as HTMLElement & { form?: HTMLFormElement };
|
||||||
|
|
||||||
|
@ -144,28 +136,8 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
this.#inFlightForms.set(form, controller);
|
this.#inFlightForms.set(form, controller);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAfterId() {
|
|
||||||
const parent = this.element.closest<HTMLElement>(
|
|
||||||
'.editor-block, .editor-root'
|
|
||||||
);
|
|
||||||
if (parent) {
|
|
||||||
const selector = parent.classList.contains('editor-block')
|
|
||||||
? '.add-to-block'
|
|
||||||
: '.add-to-root';
|
|
||||||
const input = parent.querySelector<HTMLInputElement>(
|
|
||||||
`${selector} ${AFTER_STABLE_ID_INPUT_SELECTOR}`
|
|
||||||
);
|
|
||||||
if (input) {
|
|
||||||
input.value = this.typeDeChampStableIdValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AFTER_STABLE_ID_INPUT_SELECTOR =
|
|
||||||
'input[name="type_de_champ[after_stable_id]"]';
|
|
||||||
|
|
||||||
function createForm(action: string, method: string) {
|
function createForm(action: string, method: string) {
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
form.action = action;
|
form.action = action;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createGraphiQLFetcher } from '@graphiql/toolkit';
|
import { createGraphiQLFetcher } from '@graphiql/toolkit';
|
||||||
import { useExplorerPlugin } from '@graphiql/plugin-explorer';
|
import { explorerPlugin } from '@graphiql/plugin-explorer';
|
||||||
import { GraphiQL } from 'graphiql';
|
import { GraphiQL } from 'graphiql';
|
||||||
import { createElement, useState } from 'react';
|
import { createElement, useState } from 'react';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
|
@ -17,15 +17,11 @@ const fetcher = createGraphiQLFetcher({
|
||||||
|
|
||||||
function GraphiQLWithExplorer() {
|
function GraphiQLWithExplorer() {
|
||||||
const [query, setQuery] = useState(defaultQuery);
|
const [query, setQuery] = useState(defaultQuery);
|
||||||
const explorerPlugin = useExplorerPlugin({
|
const explorer = explorerPlugin({ showAttribution: false });
|
||||||
query: query ?? '',
|
|
||||||
onEdit: setQuery,
|
|
||||||
showAttribution: false
|
|
||||||
});
|
|
||||||
return createElement(GraphiQL, {
|
return createElement(GraphiQL, {
|
||||||
fetcher: fetcher,
|
fetcher: fetcher,
|
||||||
defaultEditorToolsVisibility: true,
|
defaultEditorToolsVisibility: true,
|
||||||
plugins: [explorerPlugin],
|
plugins: [explorer],
|
||||||
query: query,
|
query: query,
|
||||||
variables: defaultVariables,
|
variables: defaultVariables,
|
||||||
onEditQuery: setQuery,
|
onEditQuery: setQuery,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'fog/openstack'
|
||||||
|
|
||||||
class PjsMigrationJob < ApplicationJob
|
class PjsMigrationJob < ApplicationJob
|
||||||
queue_as :pj_migration_jobs
|
queue_as :pj_migration_jobs
|
||||||
|
|
||||||
|
@ -7,7 +9,6 @@ class PjsMigrationJob < ApplicationJob
|
||||||
return if already_moved?(blob)
|
return if already_moved?(blob)
|
||||||
|
|
||||||
service = blob.service
|
service = blob.service
|
||||||
client = service.client
|
|
||||||
container = service.container
|
container = service.container
|
||||||
old_key = blob.key
|
old_key = blob.key
|
||||||
new_key = "#{blob.created_at.strftime('%Y/%m/%d')}/#{old_key[0..1]}/#{old_key}"
|
new_key = "#{blob.created_at.strftime('%Y/%m/%d')}/#{old_key[0..1]}/#{old_key}"
|
||||||
|
@ -28,4 +29,14 @@ class PjsMigrationJob < ApplicationJob
|
||||||
def already_moved?(blob)
|
def already_moved?(blob)
|
||||||
blob.key.include?('/')
|
blob.key.include?('/')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def client
|
||||||
|
@client ||= begin
|
||||||
|
credentials = Rails.application.config.active_storage
|
||||||
|
.service_configurations['openstack']['credentials']
|
||||||
|
Fog::OpenStack::Storage.new(credentials)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'fog/openstack'
|
||||||
|
|
||||||
class ActiveStorage::DownloadableFile
|
class ActiveStorage::DownloadableFile
|
||||||
def self.create_list_from_dossiers(
|
def self.create_list_from_dossiers(
|
||||||
dossiers,
|
dossiers,
|
||||||
|
@ -20,7 +22,6 @@ class ActiveStorage::DownloadableFile
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
service = file.blob.service
|
service = file.blob.service
|
||||||
client = service.client
|
|
||||||
begin
|
begin
|
||||||
client.head_object(service.container, file.blob.key)
|
client.head_object(service.container, file.blob.key)
|
||||||
true
|
true
|
||||||
|
@ -33,6 +34,13 @@ class ActiveStorage::DownloadableFile
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def self.client
|
||||||
|
credentials = Rails.application.config.active_storage
|
||||||
|
.service_configurations['openstack']['credentials']
|
||||||
|
|
||||||
|
Fog::OpenStack::Storage.new(credentials)
|
||||||
|
end
|
||||||
|
|
||||||
def self.bill_and_path(bill)
|
def self.bill_and_path(bill)
|
||||||
[
|
[
|
||||||
bill,
|
bill,
|
||||||
|
|
|
@ -160,6 +160,14 @@ class Champ < ApplicationRecord
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def legend_label?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def single_checkbox?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def input_group_id
|
def input_group_id
|
||||||
"champ-#{html_id}"
|
"champ-#{html_id}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,11 +7,23 @@ class Champs::CheckboxChamp < Champs::BooleanChamp
|
||||||
mandatory? && (blank? || !true?)
|
mandatory? && (blank? || !true?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def legend_label?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
# TODO remove when normalize_checkbox_values is over
|
# TODO remove when normalize_checkbox_values is over
|
||||||
def true?
|
def true?
|
||||||
value_with_legacy == TRUE_VALUE
|
value_with_legacy == TRUE_VALUE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def html_label?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def single_checkbox?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# TODO remove when normalize_checkbox_values is over
|
# TODO remove when normalize_checkbox_values is over
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue