Skip to content

Commit

Permalink
Reprise des travaux de la branche 58 https://github.com/spyrales/shin…
Browse files Browse the repository at this point in the history
  • Loading branch information
jengelaere committed Jul 19, 2023
1 parent d888a87 commit cbaee9a
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 91 deletions.
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ representative at an online or offline event.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at juliette.engelaere-lefebvre@developpement-durable.gouv.fr.
reported to the community leaders responsible for enforcement at juliette.engelaere@developpement-durable.gouv.fr.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
Expand Down
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Package: shinygouv
Title: Implement the DSFR for your shiny applications
Version: 1.0.2
Authors@R: c(
person("Juliette", "ENGELARE-LEFEBVRE", , "juliette.engelaere-lefebvre@developpement-durable.gouv.fr", role = c("aut", "cre")),
person("Juliette", "ENGELAERE-LEFEBVRE", , "juliette.engelaere-lefebvre@developpement-durable.gouv.fr", role = c("aut", "cre")),
person("Sébastien", "Rochette", , "sebastien@thinkr.fr", role = "aut",
comment = c(ORCID = "0000-0002-1565-9313")),
person("Murielle", "Delmotte", , "murielle@thinkr.fr", role = "aut",
Expand All @@ -11,6 +11,7 @@ Authors@R: c(
comment = c(ORCID = "0000-0002-4816-4624")),
person("Yohann", "Mansiaux", , "yohann@thinkr.fr", role = "aut",
comment = c(ORCID = "0000-0002-8905-6603")),
person("Jean-Daniel", "LOMENEDE", , "jean-daniel.lomenede@seine-maritime.gouv.fr", role = "aut"),
person("David", "Granjon", role = "ctb"),
person("Alan", "Dipert", role = "ctb")
)
Expand Down
2 changes: 1 addition & 1 deletion R/run_app.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#' Run the Shiny Application
#' Run the shinygouv-demo Application
#'
#' @param ... arguments to pass to golem_opts.
#' See `?golem::get_golem_options` for more details.
Expand Down
9 changes: 6 additions & 3 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ knitr::opts_chunk$set(

# {shinygouv}

Le package {shinygouv} permet d'utiliser le template existant pour le `Système de Design de l'Etat` (DSFR) dans vos applications Shiny.
Le package {shinygouv} permet d'utiliser le [`Système de Design de l'Etat` (DSFR)](https://www.systeme-de-design.gouv.fr/) dans vos applications Shiny.

Il s'installe depuis github :

Expand Down Expand Up @@ -54,14 +54,17 @@ shinyApp(
```


# Visualiser un application de démonstration comprenant les composants déjà implémentés:
# Visualiser une application de démonstration comprenant les composants déjà implémentés:

[shinygouv-demo](https://ssm-ecologie.shinyapps.io/shinygouv-demo/)
[shinygouv-demo version de dev](https://ssm-ecologie.shinyapps.io/shinygouv-demo-dev/)

# Contribuer au développement du package

Voir les vignettes à l'intention des développeurs du [site de présentation du packages et de ses fonctions](https://spyrales.github.io/shinygouv/articles/index.html)

# Code of Conduct

Please note that the {shinygouv} project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
Notez svp qu'un Code de conduite ([Contributor Code of Conduct](https://spyrales.github.io/shinygouv/CODE_OF_CONDUCT.html)) encadre la participation au projet {shinygouv}.

En contribuant à ce projet, vous acceptez de le respecter.
2 changes: 1 addition & 1 deletion app.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Launch the ShinyApp (Do not remove this comment)
# Launch the ShinyApp shinygouv-demo (Do not remove this comment)
# To deploy, run: rsconnect::deployApp()
# Or use the blue button on top of this file

Expand Down
2 changes: 1 addition & 1 deletion dev/flat_composants/flat_new_one.Rmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "flat_new_one.Rmd empty"
title: "flat_nom_composant_shiny.Rmd empty"
output: html_document
editor_options:
chunk_output_type: console
Expand Down
4 changes: 2 additions & 2 deletions inst/test.convert.dsfr/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Package: test.convert.dsfr
Title: PKG_TITLE
Title: App Shiny Test Convert DSFR
Version: 0.0.0.9000
Authors@R:
person("AUTHOR_FIRST", "AUTHOR_LAST", , "AUTHOR@MAIL.COM", role = c("cre", "aut"))
Description: PKG_DESC.
Description: App shiny test.convert.dsfr pour tester convert_to_dsfr().
License: MIT + file LICENSE
Imports:
config (>= 0.3.1),
Expand Down
80 changes: 45 additions & 35 deletions vignettes/A-convertir-une-app-shiny-en-app-shiny-dsfr.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,69 +18,79 @@ knitr::opts_chunk$set(
library(shinygouv)
```

# convert_to_dsfr
# Fonction `convert_to_dsfr()`

La fonction expérimentale `convert_to_dsfr()` convertit tous les composants shiny présents dans les fichiers du dossier "R/" d'une application shiny, en composant dsfr, si et seulement si ceux ci ont été implémentés dans la {version} définie en paramètre.
La fonction `convert_to_dsfr()` a été pensée pour faciliter la conversion d'applications Shiny existantes au Design system de l'Etat.

Cette fonction va modifier les fichiers de votre application, présents dans le répertoire `path`.
Il reste des points de vigilances sur la conversion des tabPanel dans les navbarPage et les tabsetPanel.

## Principe : Réécriture d'une application existante

## Table de correspondance
La fonction `convert_to_dsfr()` convertit tous les composants shiny présents dans les fichiers du dossier "R/" d'une application shiny, en composant shinygouv dsfr, dès lors qu'ils existent et qu'ils ont été implémentés dans le package, pour la {version} définie en paramètre.

Elle se base alors sur la table de correspondance des composants implémentés :

Par exemple pour la version "1.7.2" ([v1.7.2/table_correspondance_shiny_dsfr.csv](https://github.com/spyrales/shinygouv/blob/main/inst/v1.7.2/table_correspondance_shiny_dsfr.csv))
Attention, cette fonction modifie les fonctions des composants UI de votre application existante.
Pour un simple test, appliquez là sur une copie.

Il reste des points de vigilances sur la conversion des tabPanel dans les navbarPage et les tabsetPanel.
Cette fonction est encore expérimentale.

```{r echo = FALSE, message = FALSE}
read.csv2(
system.file("v1.7.2/table_correspondance_shiny_dsfr.csv", package = "shinygouv")
) %>%
DT::datatable()
```

## Dépendances

De plus, elle ajoute la dépendance au package {shinygouv} dans le fichier `app_ui.R`
Le fonction `convert_to_dsfr()` ajoute automatiquement la dépendance au package {shinygouv} dans le fichier `app_ui.R` de votre application shiny Golem.

Dans le cadre d'une application non packagée avec {golem}, vous devrez ajouter à la main la dépendance à {shinygouv}, souvent avec un `library(shinygouv)` dans votre fichier global.R.

## Conversion

Pour cela, il suffit de lancer dans la console depuis votre projet contenant l'application shiny :
## Conversion

La conversion est réalisée en lançant dans la console, depuis votre projet contenant l'application shiny :

```{r eval = FALSE}
convert_to_dsfr()
```

Si l'ensemble des scripts `.R` de votre application ne se trouve pas dans un dossier "R/" à la racine de votre projet, vous pouvez passer en argument le `path` du dossier contenant l'ensemble de ces fichiers.
Comme par exemple:
Si l'ensemble des scripts `.R` de votre application ne se trouvent pas dans un dossier "R/" à la racine de votre projet, vous pouvez passer en argument le `path` du dossier contenant l'ensemble de ces fichiers.

Comme par exemple:

```{r eval = FALSE}
convert_to_dsfr(path = "le_chemin_de_mon_application")
```

*Attention*, dans le cadre d'une application hors {golem}, vous devrez ajouter la dépendance à {shinygouv} pour que votre application puisse utiliser les composants dsfr


```{r examples-convert_to_dsfr}
if (FALSE) {
mydir <- tempfile(pattern = "app")
dir.create(mydir)
golem::install_dev_deps(
force_install = TRUE
)
golem::create_golem(
mydir,
overwrite = TRUE,
open = FALSE
)
convert_to_dsfr(path = file.path(mydir, "R"))
}
*Attention*, dans le cadre d'une application simple (hors {golem}), vous devrez ajouter la dépendance à {shinygouv} pour que votre application puisse utiliser les composants dsfr (avec `library(shingouv)`).


## Table de correspondance

Elle se base alors sur la table de correspondance des composants implémentés :

Par exemple pour la version "1.7.2" ([v1.7.2/table_correspondance_shiny_dsfr.csv](https://github.com/spyrales/shinygouv/blob/main/inst/v1.7.2/table_correspondance_shiny_dsfr.csv))


```{r echo = FALSE, message = FALSE}
read.csv2(
system.file("v1.7.2/table_correspondance_shiny_dsfr.csv", package = "shinygouv")
) %>%
DT::datatable()
```

# Quels sont les composants implémentés dans {shinygouv} ?

Les composants d'interface utilisateur implémentés dans `{shinygouv}` et leur correspondance avec les fonctions habituelles de `{Shiny}` sont listées ici :


```{r echo = FALSE, message = FALSE}
read.csv2(
system.file(get_dsfr_version(with_v = TRUE), "/table_correspondance_shiny_dsfr.csv", package = "shinygouv")
) %>%
dplyr::select(composant_shiny, composant_dsfr) %>%
DT::datatable()
```

Ils ne sont pas encore très nombreux et peuvent être améliorés, n'hésitez pas à contribuer, un guide est là pour vous aider à rejoindre les auteurs de {shinygouv} !


# Connaître la version du dsfr actuelle

Pour savoir quelle version du dsfr est utilisée dans votre installation de {shinygouv}, vous pouvez exécuter `get_dsfr_version()`
Expand Down
4 changes: 4 additions & 0 deletions vignettes/Dev-A-guide-du-developpeur.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ knitr::opts_chunk$set(echo = TRUE, eval = FALSE)

Ceci est un dossier de documentation dédié aux développeurs et développeuses.


## Contribuer à {shinygouv} - Introduction
Pour des contributions au code de ce projet, svp regardez le guide général de contribution à https://spyrales.github.io/shinygouv/CONTRIBUTING.html

## Structuration du repo (a compléter)

Le développement de ce package a été réalisé [avec {fusen}](https://thinkr-open.github.io/fusen/) : les fonctions, vignettes et test sont générées par des fichiers Rmd dans le dossier /dev.
Expand Down
57 changes: 33 additions & 24 deletions vignettes/Dev-B-comment-faire-un-composant-shiny.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ _Ici nous prenons l'exemple d'un composant développé pour la version 1.7.2 du

#### Première étape

- Copier dans le dossier `inst/v1.7.2/composant` le template html du bouton pour dsfr
- Se rendre sur <https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/bouton/>
- Enregistrer le code html par défaut du bouton dans un fichier `inst/v1.7.2/composant/bouton.html`
- Copier dans le dossier `inst/v1.7.2/composant` le template html du bouton pour dsfr

- Se rendre sur <https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/bouton/>

- Enregistrer le code html par défaut du bouton dans un fichier `inst/v1.7.2/composant/bouton.html`


```
<button class="fr-btn">Label bouton</button>
Expand All @@ -57,10 +60,11 @@ _Ici nous prenons l'exemple d'un composant développé pour la version 1.7.2 du

#### Deuxième étape

- Modifier le code html pour mettre les paramètres nécessaires à son bon fonctionnement dans {shiny}
- Ajouter un `id` pour le futur `inputId`
- Ajouter la classe permettant de déclencher l’évènement côté {shiny}
- Ajouter/Remplacer aussi les autres paramètres nécessaires à la personnalisation du composant
- Modifier le code html pour mettre les paramètres nécessaires à son bon fonctionnement dans {shiny}

- Ajouter un `id` pour le futur `inputId`
- Ajouter la classe permettant de déclencher l'évènement côté {shiny}
- Ajouter/Remplacer aussi les autres paramètres nécessaires à la personnalisation du composant

Après retravail sur le composant `actionButton()`, voici son template html:

Expand All @@ -74,7 +78,7 @@ Après retravail sur le composant `actionButton()`, voici son template html:
Dans notre cas, nous traitons le `actionButton()` et la classe a ajouter est `action-button`.
Comment savoir ?

Le plus simple est d'exécuter la fonction de l'input dans shiny dans la console:
Le plus simple est d'exécuter la fonction de l'input dans shiny dans la console :

```{r eval = FALSE}
shiny::actionButton("test", "test")
Expand All @@ -84,7 +88,11 @@ shiny::actionButton("test", "test")
`<button id="test" type="button" class="btn btn-default action-button">test</button>`
```

> On observe alors que dans "class" nous avons des classes liées à bootstrap `btn-*` et une classe à part `action-button`. C'est souvent cette classe qui permet de déclencher l’évènement coté server. Si cela n'est pas suffisant, il faudra chercher dans le code du package {shiny}. Le code se trouve [ici](https://github.com/rstudio/shiny/tree/main/srcts/src/bindings/input) et en ouvrant le fichier `.ts` vous trouverez alors un endroit ou on recherche la classe qui active l'input :
> On observe alors que dans "class" nous avons des classes liées à bootstrap `btn-*` et une classe à part `action-button`.
> C'est souvent cette classe qui permet de déclencher l’évènement coté server.
> Si cela n'est pas suffisant, il faudra chercher dans le code du package {shiny}.
Le code se trouve [ici](https://github.com/rstudio/shiny/tree/main/srcts/src/bindings/input) et en ouvrant le fichier `.ts` vous trouverez alors un endroit ou on recherche la classe qui active l'input :

```
find(scope: HTMLElement): JQuery<HTMLElement> {
return $(scope).find(".action-button");
Expand All @@ -94,14 +102,15 @@ shiny::actionButton("test", "test")

#### Troisième étape

- Créer la fonction qui permettra d'utiliser ce nouveau bouton.
- Copier coller le flat se trouvant dans [dev/flat_composants/flat_new_one.Rmd](https://github.com/spyrales/shinygouv/blob/main/dev/flat_composants/flat_new_one.Rmd) dans
`dev/flat_composants/` et le renommer "flat_nom_du_composant_shiny.Rmd". Dans cet exemple, `flat_actionButton.Rmd`
- Dans votre nouveau flat, il faut remplacer "nom_composant_shiny" par le nom du composant shiny (dans cet exemple, `actionButton`)
- Changer le chemin du fichier de votre `.html` dans la fonction `*_template`
- Compléter les paramètres et leur documentation dans vos fonctions selon la personnalisation de votre `.html`
- Adapter les tests unitaires en fonction des paramètres choisis (y compris la date du snapshot).
- Puis lancer le dernier chunck `fusen::inflate()`
- Créer la fonction qui permettra d'utiliser ce nouveau bouton :

- Copier/coller le flat se trouvant dans [dev/flat_composants/flat_new_one.Rmd](https://github.com/spyrales/shinygouv/blob/main/dev/flat_composants/flat_new_one.Rmd) dans
`dev/flat_composants/` et le renommer "flat_nom_du_composant_shiny.Rmd". Dans cet exemple, `flat_actionButton.Rmd`.
- Dans votre nouveau flat, il faut remplacer "nom_composant_shiny" par le nom du composant shiny (dans cet exemple, `actionButton`).
- Changer le chemin du fichier de votre `.html` dans la fonction `*_template`.
- Compléter les paramètres et leur documentation dans vos fonctions selon la personnalisation de votre `.html`.
- Adapter les tests unitaires en fonction des paramètres choisis (y compris la date du snapshot).
- Puis lancer le dernier chunk `fusen::inflate()`.


Voir exemple [dev/flat_composants/flat_actionButton.Rmd](https://github.com/spyrales/shinygouv/blob/main/dev/flat_composants/flat_actionButton.Rmd)
Expand All @@ -112,12 +121,12 @@ Ayez une attention particulière pour les tests unitaires qui sont la garantie d

#### Quatrième étape

- Créer la fonction qui permettra de mettre à jour votre input (si nécessaire).
- Certains composants comme l'actionButton() n'ont pas besoin de mise à jour, c'est le cas pour beaucoup d'autres composants.
- Certains fonctions de mise à jour de composants correspondent en fait à l'appel de la fonction native `{shiny}` correspondante (voir par ex `updateNumericInput_dsfr()`).
- Pour certains composants non présents nativement dans `{shiny}`, des implémentations adhoc ont dû être réalisées (voir par ex `updateRadioGroupButtons_dsfr()`).
+ Dans ce cas précis il faut être vigilant sur l'utilisation de la fonction `ns()` dans le nom des inputId. Il est indispensable de prendre en compte la fonction `ns()` partout, sauf dans le cas d'un appel à la fonction shiny `session$sendInputMessage()` car le ns() est géré en interne. Le plus simple reste d'observer la fonction `updateRadioGroupButtons_dsfr()`.

- Créer la fonction qui permettra de mettre à jour votre input (si nécessaire).
- Certains composants comme l' `actionButton()` n'ont pas besoin de mise à jour, c'est le cas pour beaucoup d'autres composants.
- Certains fonctions de mise à jour de composants correspondent en fait à l'appel de la fonction native `{shiny}` correspondante (voir par ex `updateNumericInput_dsfr()`).
- Pour certains composants non présents nativement dans `{shiny}`, des implémentations adhoc ont dû être réalisées (voir par ex `updateRadioGroupButtons_dsfr()`).
+ Dans ce cas précis il faut être vigilant sur l'utilisation de la fonction `ns()` dans le nom des inputId. Il est indispensable de prendre en compte la fonction `ns()` partout, sauf dans le cas d'un appel à la fonction shiny `session$sendInputMessage()` car le ns() est géré en interne. Le plus simple reste d'observer la fonction `updateRadioGroupButtons_dsfr()`.

#### Cinquième étape

Expand All @@ -129,4 +138,4 @@ La colonne `composant_shiny` restera vide si le composant dsfr n'a pas d'équiva

Cette table de correspondance permettra le bon déroulement de la conversion d'une app shiny en une app shiny dsfr (en utilisant `convert_to_dsfr()`)


Vous pouvez également ajouter votre composant dans l'[application de démonstration]("https://github.com/spyrales/shinygouv/tree/main/dev/R).
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "Faire tourner les applications shiny du package shinygouv"
output: github_document
vignette: >
%\VignetteIndexEntry{Dev-D-Faire-tourner-les-applications-shiny-du-package-shinygouv}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```

Ce package contient 2 applications shiny Golem :

- une première application au design classique a été placée dans [inst/test.convert.dsfr]("https://github.com/spyrales/shinygouv/tree/main/inst/inst/test.convert.dsfr), pour tester la fonction de conversion `convert_to_dsfr()` ;
- une seconde application, mise au design DSFR, permet de visualiser les composants de `{shinygouv}`, elle déployée par intégration continue.

## Application au design classique inst/test.convert.dsfr

Pour faire fonctionner localement l'app Shiny incluse dans "inst/", il faut lancer:
```{r eval = FALSE}
withr::with_dir("inst/inst/test.convert.dsfr/", {
pkgload::load_all(export_all = FALSE, helpers = FALSE, attach_testthat = FALSE, quiet = TRUE)
test.convert.dsfr::run_app()
})
```

Et pour tester la conversion à la volée avec
```{r eval = FALSE}
pkgload::load_all()
mydir <- tempfile(pattern = "app")
fs::dir_copy("inst/test.convert.dsfr/", mydir)
withr::with_dir(mydir, {
convert_to_dsfr()
pkgload::load_all(export_all = FALSE, helpers = FALSE, attach_testthat = FALSE, quiet = TRUE)
test.convert.dsfr::run_app()
})
```

## Application de demo du package

Le package `{shinygouv}` contient une application de démo, qui permet de visualiser les composants implémentés.

Elle peut être lancée en local avec :

```{r eval=FALSE}
shinygouv::run_app()
```

Cette application est déployée par intégration continue sur :

- https://ssm-ecologie.shinyapps.io/shinygouv-demo/ pour la branche principale, en production
- https://ssm-ecologie.shinyapps.io/shinygouv-demo-dev/ pour la branche de dev
Loading

0 comments on commit cbaee9a

Please sign in to comment.