Focus – Pourquoi Focus? – Klee fait des applications sur mesure



Focus – Pourquoi Focus? – Klee fait des applications sur mesure

1 0


formation-focus

Slide support for training people on focus basics.

On Github get-focus / formation-focus

Focus

http://get-focus.github.io/formation-focus

Pourquoi Focus?

Klee fait des applications sur mesure

Les missions de Focus

Remettre l'humain au centre UX

Capter et digérer l'innovation

Developer Experience DX

Les livrables

  • Support de communication et d'aide à la vente
  • Les templates de page
  • Libraries JS
  • Showcase de composants
  • Blog d'articles UX / Tech
  • Documentation technique focus-docs
  • Extensions prêtes à l'emploi (notifs, comments, ...)

Objectifs

Faire rapidement et facilement 80 % des écrans de l'application

  • Respecter les maquettes
  • Composants UX prêt à l'emploi

Faire facilement du sur mesure 20 % des écrans de l'application

Le bureau Focus

  • Validation de choix avant de se lancer ?
  • Conception de maquettes
  • Validation des maquettes
  • Conception technique d'écran
  • Pour partager vos bonnes idées

Je n'arrive pas à faire rentrer mon écran dans le pattern

Mon client veut un écran un peu funky

Je trouve un bug sur Focus

Des suggestions ou problèmes:

  • focus-bureau@kleegroup.com
  • Slack Focus community
  • Validation des maquettes
  • Conception technique d'écran
  • Pour partager vos bonnes idées.

github

GetFocus.io

Les librairies coeur

Focus Core

Focus Components

Les extensions

Focus file

Focus Notification

Focus Comments

Documentation

Focus Showcase

Focus docs

Focus demo

Outils

Focus eslint

Focus webpack

Contribuez à Focus

Articles, Fork, issues, PR, doc, tuto, DX ...

Focus.js

Le router de l'application

Router

Et voici l'exemple

import React from 'react';
import { Route, IndexRoute } from 'react-router';
import AppLayout from '../components/layout'
import HomeRoute from './home-route';
import MasterdataRoutes from './masterdata-routes';
import MoviesRoutes from './movies-route';
import PersonsRoutes from './persons-route';
import SearchRoutes from './advanced-search-route';
import ErrorRoutes from './error-route';

export default {
    path: `${__BASE_URL__}`,
    indexRoute: { onEnter: ({ params }, replace) => replace(`${__BASE_URL__}home`) },
    component: AppLayout,
    childRoutes: [...HomeRoute, ...MasterdataRoutes, ...MoviesRoutes, ...PersonsRoutes, ...SearchRoutes, ...ErrorRoutes]
};

import React from 'react';
import MovieDetailView from '../views/movie/detail';

const route = [
    {
        path: 'movies/:id',
        component: (props) => ()
    }
];

export default route;

Les domaines et les définitions

les domaines

  • Responsable de la validation
  • Du composant de rendu (consultation, édition)
  • formatage des données
  • On peut les utiliser pour le style
  • Utilisation intelligente avec fieldFor

example du domaine do-date.js

import moment from 'moment';
import {Date as DateComponent} from 'focus-components/components/input';

export default {
    InputComponent: DateComponent,
    formatter: date => date ? moment(date, moment.ISO_8601).format('DD/MM/YYYY') : '',
    format: ['DD/MM/YYYY', 'DD-MM-YYYY', 'D MMM YYYY']
};

Les définitions

  • Générées depuis le modèle de données
  • Lie le modèle de données ayu domaines
  • Chaque table a des champs
  • Chaque champ a un domaine
  • Chaque champ porte l'information requis / non requis

example de définitions

export const movie = {
    code: {
        domain: 'DO_ID',
        required: true
    },
    title: {
        domain: 'DO_LABEL_LONG',
        required: true
    },
    creationDate: {
        domain: 'DO_DATE',
        required: false
    }
}

// fieldFor(creationDate)

Flux by Focus

flux by Facebook

Architecture

les stores

Flux

flux

Service

  • Un service est une fonction
  • Un service appelle une url construite grâce à urlbuilder
  • Un service retourne une Promise
  • On peut utiliser la méthode fetch de focus

Exemple de service (retourne impérativement une Promise)

						
import fetch from 'focus-core/network/fetch';
//Fait une reqête ajax
import movieUrl from '../config/server/movies';
// Les urls de ws sont configurées
export default {
    loadMovie(id) {
        return fetch(movieUrl.loadMovie({urlData: {id}}));
    },
    saveMovieSynopsis(data) {
        return fetch(movieUrl.saveMovie({urlData: {id: data.id}, data: {data}}));
    },
    saveMovieCaracteristics(data) {
        return fetch(movieUrl.saveMovie({urlData: {id: data.id}, data: {data}}));
    }
}
						
					

store

  • Un store est un objet qui contient une grappe de données
  • Associé à une notion de grappe d'objet (corestore)
  • Il existe des stores spécialisées (recherche, liste)
  • Il peut notifier: d'un changement, d'une erreur
  • Chaque noeud de données peut avoir un statut

Exemple de store

						
import {CoreStore} from 'focus-core/store';
const movieStore = new CoreStore({
    definition: {
        movie: 'movie',
		actors: 'actors'
    }
});

export default movieStore;
						
					

action

  • Une action est une fonction
  • Une action doit appeller un service
  • Avec le retour (après l'appel serveur)
  • Dispatch le résultat dans le dispatcher
  • On peut utiliser le actionBuilder (detail, recherche, liste)

Exemple d'action

						
import actionBuilder from 'focus-core/application/action-builder';
import {loadMovie, saveMovieSynopsis} from '../services/movie';

export const synopsisActions = {
    load: actionBuilder({
        node: 'movie',
        service: loadMovie,
        shouldDumpStoreOnActionCall: true,
        status: 'loaded'
    }),
    save: actionBuilder({
        node: 'movie',
        service: saveMovieSynopsis,
        shouldDumpStoreOnActionCall: true,
        status: 'saved'
    })
}
						
					

Un exemple de composant mis en musique

						
//librairies
import React, {PropTypes} from 'react';
import FocusComponents from 'focus-components';

// web components
import Panel from 'focus-components/components/panel';
import {mixin as formMixin} from 'focus-components/common/form';

//stores & actions
import movieStore from '../../../stores/movie';
import {caracteristicsActions} from '../../../action/movie';

export default React.createClass({
    displayName: 'MovieCaracteristics',
    propTypes: {
        id: PropTypes.number
    },
    mixins: [formMixin],
    definitionPath: 'movie',
    stores: [{store: movieStore, properties: ['movie']}],
    action: caracteristicsActions,

    /** @inheritDoc */
    renderContent() {
        return (
            <panel actions="{this._renderActions}" title="movie.detail.caracteristics">
                {this.fieldFor('title')}
                {this.fieldFor('originalTitle')}
                {this.fieldFor('keywords')}
                {this.fieldFor('runtime')}
                {this.fieldFor('movieType')}
                {this.fieldFor('productionYear')}
                {this.fieldFor('trailerName')}
                {this.fieldFor('trailerHRef')}
            </panel>
        );
    }
});
						
					

tutos

Structure applicative

Focus http://get-focus.github.io/formation-focus