Skip to content

Releases: klee-contrib/focus4

v8.3

09 Nov 14:52
Compare
Choose a tag to compare

Drag and drop depuis une liste

dnd

Il est désormais possible d'utiliser du drag and drop pour manipuler les éléments d'une liste. La fonctionnalité utilise react-dnd de façon standard et s'interface donc naturellement avec d'autres containers issus de la librarie (les éléments sont des DragSource).

Pour l'utilisation, se référer à la documentation de react-dnd. Le drag and drop s'active dans une liste via la prop hasDragAndDrop et le type d'élément par la prop dragItemType. La liste insère dans le monitor de react-dnd la liste des éléments sélectionnés (même s'il n'y en a qu'un), que l'on peut récupérer par la méthode utilitaire getDraggedItems(monitor).

Exemple de code ici

Remarque : Aucune action sur les objets sélectionnés n'est implémentée par défaut, c'est à l'utilisateur de faire ce qui lui convient dans la méthode drop de la DropTarget.

Autres changements

  • breaking : Le message de sauvegarde dans un AutoForm est maintenant ajouté dans la méthode onFormSaved au lieu de save, ce qui veut dire qu'il est maintenant possible de le supprimer/remplacer dans cette méthode. Cela veut aussi dire que si vous avez des onFormSaved existants qui n'appellent pas super, vous n'aurez plus le message. Pour conserver le comportement actuel dans ce cas là, il suffit d'appeler la méthode parente par super.onFormSaved().
  • Le Select traduit les labels des options
  • Les décorateurs de réaction (@classAutorun et autres) s'exécutent maintenant après l'éventuel componentWillMount et plus avant. La raison principale de ce changement et de passer après init() dans un AutoForm pour pouvoir utiliser this.entity, ce qui était impossible avant. Aussi, les réactions seront exécutées dans l'ordre de déclaration dans la classe (avant c'était à l'envers).

v8.2

27 Oct 18:07
Compare
Choose a tag to compare

Refonte de l'API du Menu

Le Menu a été renommé en MainMenu (et tous ces composants ont été préfixés par "Main"), pour éviter la confusion avec le Menu de React-Toolbox qui est en fait ce qu'on appelait "Dropdown". La clé de thème a également été renommée "mainMenu".

Le MainMenu n'a plus de prop menus : à la place, il suffit de lui donner des MainMenuItems directement en tant que children. Pour gérer les sous-menus (à la place de subMenus), il suffit de donner des MainMenuItems comme children du MainMenuItem en question (comme avant, un seul niveau est supporté).

Par exemple :

Avant :

<Menu
    activeRoute={router.currentStore.prefix}
    menus={[{
        icon: "home",
        onClick: () => router.to("home")
        route: "home"
    }, {
        icon: "business",
        route: "business",
        subMenus: [{
            label: "Sous menu 1",
            onClick: () => businessStore.setView({page: "1"})
        }, {
            label: "Sous menu 2",
            onClick: () => businessStore.setView({page: "2"})
        }]
    }]}
/>

Après :

<MainMenu activeRoute={router.currentStore.prefix}>
    <MainMenuItem
        icon="home"
        onClick={() => router.to("home")}
        route="home"
    />
    <MainMenuItem
        icon="business"
        route="business"
    >
        <MainMenuItem
            label="Sous menu 1",
            onClick={() => businessStore.setView({page: "1"})}
        />
        <MainMenuItem
            label="Sous menu 2"
            onClick={() => businessStore.setView({page: "2"})}
        />
    </MainMenuItem>
</MainMenu>

Outre l'API plus facile à utiliser, il est aussi maintenant possible d'insérer des composants quelconque n'importe où dans le MainMenu, par exemple tout en haut, entre des MainMenuItems, dans le sous-menu...

InputDate : gestion de l'heure avec la date choisie

Avant, le composant retournait toujours une date à minuit UTC, soit l'ISOString correspondant pour la date de la release : 2017-10-27T00:00:00Z, indépendamment du fuseau horaire de l'utilisateur.

Maintenant, l'InputDate possède un paramètre ISOStringFormat qui propose 3 modes différents :

  • utc-midnight, le comportement ci-dessus, choisi par défaut (= pas de breaking change)
  • local-midnight, qui choisit minuit dans le fuseau horaire de l'utilisateur : 2017-10-27T00:00:00+02:00
  • local-utc-midnight, qui choisit minuit dans le fuseau horaire de l'utilisateur en UTC : 2017-10-26T22:00:00Z

Ces 3 possibilités doivent couvrir tous les cas d'usages potentiels, dans une application où les fuseaux horaires sont importants.

v8.1

04 Oct 17:02
Compare
Choose a tag to compare

application déprécié, remplacé par layout

Le module application est maintenant déprécié et ne contient plus que l'applicationStore et le Header par défaut qui l'utilise. Tout le reste (Menu, Layout, composants de Header) ont été déplacés dans un nouveau module layout (qui correspond à ce qu'était application/layout avant).

Le Layout a suivi le modèle du Header et est maintenant ouvert à la construction manuelle par projet. Désormais, il ne pose plus que le MessageCenter et le ErrorCenter, et il prend tous les autres composants dans ses enfants.

Par exemple, ce qui était avant :

<Layout Menu={Menu} Header={Header}>
    <Main />
</Layout>

est maintenant

<Layout>
    <Header />
    <Menu />
    <LayoutContent>
         <Main />
    </LayoutContent>
</Layout>

Attention a bien utiliser le composant LayoutContent pour bénéficier du margin-left du Menu (qui est d'ailleurs maintenant bien undefined s'il n'y a pas de Menu).

Suppression du "scope" dans la recherche.

Le scope n'existe maintenant plus, bien que son ancien fonctionnement soit reproductible "à la main" avec un critère supplémentaire "scope" et quelques petits ajustements.

Cela implique les changements de props suivants :

  • hideSummaryScope, scopes, scopeFacetKey n'existent plus
  • (line|mosaic)ComponentMapper redeviennent (Line|Mosaic)Component
  • (line|group)OperationLists perdent le pluriel et la construction en objet dépendant du scope. lineOperationList est donc une fonction de data et groupOperationList est une fonction de group (GroupResult, contenant le code, le libellé, la liste et le nombre d'élements du groupe).
  • hideSummaryGroup et hideSummarySort ont été ajoutés

Le constructeur de SearchStore n'a plus le second paramètre obligatoire (qui servait obligatoirement à spécifier au moins le scope) et les paramètres de définition de critère et de propriétés par défaut sont interchangables.

Les critères sont maintenant affichés avant les facettes dans le Summary.

En bonus, La recherche est maintenant proprement documentée (du moins, aussi bien que le reste)

En vrac

  • Les composants sont également mieux documentés et le Select un peu retravaillé.
  • La Popin s'affiche maintenant en dehors du react-root comme une vraie Popin
  • On utilise prop-types pour un warning en moins (et compat future pour React 16).
  • Et quelques corrections de bug.

v8

27 Sep 09:02
Compare
Choose a tag to compare
v8

focus-components (et donc MDL) a été complètement retiré

C'est la fin de la migration focus-components/MDL -> React-Toolbox qui a commencé avec la 7.0. Le CSS global de MDL a été recopié à l'identique (ou presque), importé par le Layout.

Les composants mis à jour par cette version sont :

  • Le menu
  • Le centre d'erreurs
  • Les boutons de lignes et de listes
  • Le tableau
  • Les chips et la SearchBar pour la recherche.
  • La popin

Allez, c'est la dernière fois qu'il faudra mettre à jour du CSS dans les applis existantes !

v7.6

22 Sep 15:37
Compare
Choose a tag to compare

lineProps n'existe plus

Pour les composants de listes (et la recherche), la propriété lineProps a été retirée. S'il y a besoin de passer des props particulières à un composant de ligne, il faut le faire explicitement soi-même maintenant :

listFor({
    data: myList,
    LineComponent: props => <MyLine {...props} onLineClick={this.onLineClick} />
});

Cela permet de simplifier le typage des composants de liste, de leur retirer la responsabilité de passer des props qui ne les concernent pas, et ça permet de faire marcher le typage des composants de ligne à tous les coups. En particulier, data est obligatoire, data? ne marche plus et les data!.XXX ne sont plus nécessaires.

L'objet props passé au composant de ligne est maintenant toujours LineProps<T>, qui contient data et openDetail.

Au passage, EmptyProps<T> et DetailProps<T> ont été ajoutés et mis au propre pour les props des composants d'empty state et de détail dans les listes.

v7.5

07 Sep 16:55
Compare
Choose a tag to compare

List

Le composant de liste passe maintenant une prop openDetail à ses lignes pour ouvrir (ou fermer) le détail et une prop closeDetail au composant de détail.

Par conséquent, le openDetail n'est plus posé par défaut par la liste sur la ligne entière et il faut le poser manuellement

De plus, il n'y a donc plus le div entre le wrapper de ligne et la ligne (il servait à poser le openDetail), ce qui peut impacter du CSS.

Autres

Il y a eu quelques corrections sur la recherche non scopée (il faut dire que personne n'avait testé jusque-là...)

v7.4

04 Sep 12:36
Compare
Choose a tag to compare

Attention, cette release nécessite une mise à jour du générateur de modèle

EntityStore

Les objets composés et listes sont maintenant accessibles directement dans un noeud de store, au lieu de passer par .value.

Cela veut dire que les définitions d'entités Node doivent être modifiées comme ceci :

  • field: EntityField<MyObjectNode> => field: MyObjectNode
  • list: EntityList<StoreListNode<MyObjectNode>> => list: StoreListNode<MyObjectNode>

De plus, les définitions d'entité Entity pour les objets composés s'écrivent maintenant comme des définitions de liste (au type près), au lieu d'une définition de field comme avant :

field: {
    type: "object" as "object",
    entityName: "myObject"
}

Après cette mise à jour, vous allez avoir plein de rouge partout à cause des .value en pagaille, mais c'est simple à corriger : il suffit de les enlever.

Cette mise à jour à permis de préciser le contenu d'un EntityField<T> : ce T ne peut être que string, number, boolean, string[], number[] ou boolean[]. De plus, value a maintenant T | undefined comme type, ce qui reflète la réalité, et qui n'était pas possible avant à cause des objets composés.

v7.3.5

28 Aug 18:17
Compare
Choose a tag to compare
  • Les boutons de l'ActionBar ont été mis à jour vers React-Toolbox (sauf les boutons d'actions de sélection).

  • Le ButtonMenu, remplaçant du Dropdown de focus-components, est maintenant totalement fonctionnel et peut remplacer ce dernier partout. En particulier :

    • l'affichage du menu se fait bien en dessous/au dessus du bouton comme attendu
    • il est possible de mettre une icône différente quand le menu est ouvert
    • il est possible d'ajouter une action au clic sur le bouton

La mise à jour du ButtonMenu est donc également effective pour les boutons d'actions transverses du header.

v7.3

24 Aug 09:49
Compare
Choose a tag to compare

Nouveaux composants : ScrollspyContainer et ButtonBackToTop

Ces deux composants ont été repris et réécrit depuis focus-components, avec un fonctionnement à peu près similaire.

Attention : le nouveau ScrollspyContainer ne fonctionne qu'avec les nouveaux panels, les nouveaux panels ne fonctionnent plus avec l'ancien scrollspy et les anciens panels ne fonctionnent pas avec le nouveau scrollspy.

Store de référence

  • Attention : Le premier paramètre de makeReferenceStore est maintenant directement le service de chargement de référence (ce qui aurait toujours dû être le cas...)
  • Une méthode reload(refName?) a été ajoutée pour forcer le rechargement d'une liste ou de tout le store.
  • La durée du cache (1h par défaut) est maintenant paramétrable dans focus4/config.

v7.2

02 Aug 13:19
Compare
Choose a tag to compare

Nouveaux composants : Autocomplete et Display

L'autocomplete de la V2 a été ré-implémenté à peu près à l'identique avec React-Toolbox. Pas de sélection multiple (même si RT le permet) pour l'instant.

Le composant Display intègre la résolution de liste de référence (qui était dans le Field avant) ainsi que la résolution de libellé avec service de chargement (pour l'autocomplete à priori, mais c'est indépendant). Il est utilisé comme composant d'affichage par défaut.

Le service de chargement keyResolver est une prop du Field (car partagé entre le composant d'input (Autocomplete) et le composant d'affichage (Display), alors que le service de recherche querySearcher est une prop spécifique à l'Autocomplete.

Dès lors, réaliser un autocomplete, il faut faire comme-ceci :

this.fieldFor(node, {
    InputComponent: Autocomplete, 
    keyResolver: resolveValueService, 
    inputProps: {
        querySearcher: searchService
    }
})