assemblee-virtuelle / archipelago

Fostering interconnections between communities by creating synergies between their platforms
Apache License 2.0
15 stars 6 forks source link

[frontend] Ajout d'un second layout #200

Open mguihal opened 2 weeks ago

mguihal commented 2 weeks ago

Tension Actuellement, le layout actuel (avec le menu à gauche) n'est utilisé que sur un seul des Archipelago déployés, et ne convient pas à tous les usages, où seules deux ou trois ressources ont besoin d'être mises en avant.

Proposition Ajouter la possibilité de sélectionner le layout qu'on souhaite via un fichier de configuration (possiblement avec des options paramétrables pour chaque layout), et ajouter un nouveau layout avec -entre autres- les modifications suivantes :

Plus de détails s'ajouteront au fil de l'analyse de faisabilité en commentaire de cette issue.

mguihal commented 1 week ago

Après analyses, je propose l'architecture suivante :

Architecture

Exemples d'utilisation

// App.js
import config from './config/config';
...
<LayoutProvider layoutOptions={config.layout}>
    <Admin />
</LayoutProvider>
// Dans un des composants du projet (par exemple le composant common/layout/List/ListView.tsx)

const CreateView = ({ title, actions, children }: PropsWithChildren<Props>) => {
  ...
  const Layout = useLayoutContext();

  return(
    <Layout.BaseView title={title} actions={actions}>
      {children}
    </Layout.BaseView>
  )
};
// Dans un composant dont le rendu serait différent entre les layouts (par exemple resources/.../OrganizationFilterSidebar.js)

const OrganizationFilterSidebar = () => {
  ...
  const Layout = useLayoutContext();

  return(
    <Layout.Aside>
      {Layout.name === '<NOM DU LAYOUT 2>' && (
          <div>Champ de recherche</div>
      )}
      <ReferenceFilter reference="Type" ... >
      <ReferenceFilter reference="Theme"... >
    </Layout.Aside>
  )
};
// Dans un composant ayant besoin des options du layout

const BaseView = () => {
  ...
  const Layout = useLayoutContext<LayoutOptions>(); // <- On peut typer ici pour être sûr d'utiliser les options du bon layout

  return(
    <div>
        {Layout.options.title || 'App title'} 
        {Layout.options.componentPlacement === 'left ? <div>left</div> : <div>right</div>} 
    </div>
  )
};

Options des layouts

Pas d'options, la configuration par défaut sera donc

{ 
    name: '<NOM DU LAYOUT>'
}
{
    name: '<NOM DU LAYOUT 2>',
    options: Partial<{
        // Position de la sideBar des filtres (optionnel, défaut à gauche)
        sideBarPlacement: 'left' | 'right'; 

        // Lien vers une image de logo dans la TopBar (optionnel, par défaut pas de logo)
        logo: string; 

        // Composant pour afficher le titre dans la TopBar (optionnel, par défaut le titre défini dans App)
        title: () => JSX.Element; 

        // Configuration des boutons affichés dans la topBar (4 maxi selon le référentiel Material UI), aucun par défaut
        mainMenu: {
          // Resource correspondante au lien (sert à la masquer dans le menu dropdown si déjà dans la topBar)
          resource: string; 

          // Texte affiché
          label: string; 

          // Lien éventuel (optionnel?, par défaut le lien de la resource?)
          link?: string; 

          // Icone affichée à gauche du texte (optionnelle ?)
          icon?: () => JSX.Element; 
        }[]
      }>
}

Etapes

Vu que le sujet va provoquer de nombreuses modifications de fichiers, pour que les PR d'implémentation soient lisibles et facilement reviewables, je propose de les séparer avec des jalons atomiques suivants :

Questions restants en suspens

La question que je n'arrive pas à trancher pour l'instant c'est comment nommer ces layouts ? 🤔 Si vous avez des idées je prends avec grand plaisir !

Pour le layout actuel (avec le menu à gauche) : leftMenu ? default ? virtualAssembly ? ... ? Pour le second layout (avec le menu en haut) : topMenu ? fullPage ? transiscope ? ... ?

N'hésitez pas à me faire un retour si cette architecture vous parait satisfaisante ou pas :)