Tableau de bord Yammer sous SharePoint 2013

Preview:

Citation preview

ERYEM CAMPS

Dashboard Yammer sous SharePoint

Partie 2/2

1

Présenté par : Barbar MITRI bmitri@eryem.comPhilippe SFEIR psfeir@eryem.com

Levallois 15/01/2015

Plan

1. Présentation du sujet1. Concept de Single Page Application2. Architecture applicative

2. Démo et architecture projet

3. Conclusion

4. Références

2

Single Page Application

3

Une nouvelle façon d’envisager la navigation web

Serveur WebCloud

navigateur client

Chargement de la page d’accueil: charge une fois pour toutes l’ensemble des fichiers html, js, css

Action utilisateur: insertion dynamique de données dans la page, jamais de rechargement complet de la page

4

Architecture applicative

4

Un niveau de portabilité inédit !!

1°)

2°)

3°)

6°)

Serveur SharePoint

Poste client

1 => Connexion à l’application SharePoint

2 => Sharepoint renvoie le contenu Statique au client : html + CSS + JS

3=> avec l’autorisation de Sharepoint on redirige le client vers le serveur Proxy (NodeJS)

4=> proxy solicite le serveur de base de données

5=> réponse de la base

6=> le proxy retourne les données vers le client

proxy nodeJS

SQL Server

4°)

5°)

Démo

5

Démo

6

Données globales

Clic sur un login -> navigation vers la page des données par utilisateur

Démo

7

Données par utilisateur

Démo

8

Exemple de graphe obtenu: nombre de messages postés par utilisateur du réseau Yammer

9

Architecture du projet Durandal

dossier « app » lui-même composé d’un dossier « services » contenant le fichier avec les méthodes de service, d’un dossier « viewmodels », d’un dossier « views »

dossier « css » contenant les feuilles de style

dossier « lib » contenant les librairies jsDurandal et les plugins js

10

Index.html

<!DOCTYPE html><html><head>

<title>Durandal</title><!– références vers fichiers css --><script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}"></script></head><body>

<div id="applicationHost"><div class="splash">

<div class="message">Je charge le contenu statique: pages html, scripts js, fichier css, <b> UNE FOIS POUR TOUTES

!!</b></div><i class="fa fa-spinner fa-spin"></i>

</div></div>

<script src="lib/require/require.js" data-main="app/main"></script>

</body></html>

référence l’api google utilisée pour dessiner les graphiques

charge require.js et l’attribut data-main indique le fichier jsservant de point d’entrée, ici main.js

11

main.js requirejs.config({paths: {

'text': '../lib/require/text','durandal':'../lib/durandal/js','plugins' : '../lib/durandal/js/plugins','transitions' : '../lib/durandal/js/transitions','knockout': '../lib/knockout/knockout-3.1.0','bootstrap': '../lib/bootstrap/js/bootstrap','jquery': '../lib/jquery/jquery-1.9.1','services': '../app/services','async': '../lib/durandal/js/plugins/async','propertyParser': '../lib/durandal/js/plugins/propertyParser','goog': '../lib/durandal/js/plugins/goog'

}});

define('gmaps', ['async!http://maps.google.com/maps/api/js?sensor=false'],function () {

console.log('Google maps loaded');return window.google.maps;

});

define(['durandal/system', 'durandal/app', 'durandal/viewLocator'], function (system, app, viewLocator) {//>>excludeStart("build", true);system.debug(true);//>>excludeEnd("build");

app.title = 'Durandal Starter Kit';

app.configurePlugins({router:true,dialog: true

});

app.start().then(function() { viewLocator.useConvention();app.setRoot('viewmodels/shell', 'entrance');

});});

permet d’enregistrer un raccourci pour chaque fichier javascript ou dossier utilisé

permet de charger les fichiers js référencés de manière asynchrone et d’exécuter le code personnalisé dans le callback, avec un espace de nommage isolé de l’espace de nommage global de javascript

app.setRoot définit la page d’accueil de l’application, ici shell.html

12

shell.jsdefine(['plugins/router', 'durandal/app'], function (router, app) {

return {router: router,search: function() {

//It's really easy to show a message box.//You can add custom options too. Also, it returns a promise for the user's response.app.showMessage('Search not yet implemented...');

},activate: function () {

router.map([{ route: '', title:'Welcome', moduleId: 'viewmodels/welcome', nav: true },{ route: 'flickr', moduleId: 'viewmodels/flickr', nav: true },{ route: 'yamhisto', moduleId: 'viewmodels/yamhisto', nav: true },{ route: 'map', moduleId: 'viewmodels/mapgoogle', nav: false },{ route: 'chart', moduleId: 'viewmodels/chart', nav: true },{ route: 'userStats/:UserId', moduleId: 'viewmodels/userStats', nav: false }

]).buildNavigationModel();

return router.activate();}

};});

shell.js est le viewmodeljavascript associé à la page d’accueil.

La fonction activates’exécute à chaque fois que la page est atteinte.

router.map permet de définir des routes pour la navigation côté client. Lorsque le client requête une route, commençant par #, le fichier javascriptcorrespondant est exécuté et la page html chargée. Aucun appel serveur n’est effectué, l’ensemble des fichiers étant déjà chargés dans le navigateur client.

13

chart.jsvar activate = function () {

jQuery.when(services.getStatMsgByUser(), services.getStatFileByUser()).then(function(msgByUser, fileByUser) {

msgArray[0] = ['Nom', 'Nombre de messages'];fileArray[0] = ['Nom', 'Nombre de fichiers partagés'];jQuery.each(msgByUser[0], function (index, item) {

msgArray[index + 1] = [item.name, item.number_msg];});jQuery.each(fileByUser[0], function (index, item) {

fileArray[index + 1] = [item.name, item.number_file];});

});};

var compositionComplete = function (view, parent) {

var msgData = google.visualization.arrayToDataTable(msgArray);var fileData = google.visualization.arrayToDataTable(fileArray);

var msgOptions = {title: 'Nombre de messages par utilisateur'

};var fileOptions = {

title: 'Nombre de fichiers partagés par utilisateur'};

var msgChart = newgoogle.visualization.PieChart(document.getElementById('msgChart'));

msgChart.draw(msgData, msgOptions);

var fileChart = newgoogle.visualization.PieChart(document.getElementById('fileChart'));

fileChart.draw(fileData, fileOptions);};

chart.js est le fichier associé à la route #chart.

La fonction activate est exécutée en premier chaque fois que la page est requêtée. Elle construit un tableau avec les données Yammerrécupérées par les web services.

La fonction compositionCompleteest exécutée après activate, une fois que l’ensemble des éléments HTML du DOM a été chargé dans le navigateur. C’est dans cette fonction que sont réalisées les manipulation sur le DOM permettant d’afficher les graphiques grâce aux APIs de google.

14

Chart.html

<section><h2 data-bind="html: displayName"></h2><table>

<tr><td>

<div id="msgChart" style="width: 900px; height: 500px;"></div></td><td>

<div id="fileChart" style="width: 900px; height: 500px;"></div></td>

</tr></table>

</section>

Le fichier chart.html contient le squelette html de la page. Les méthodes google appelées dans le viewmodel vont insérer les graphes dans les deux div.

Conclusion

15

Avec DurandalJS on peut construire des applications JavaScript dynamiques et simples.

Inclus : JQuery , Knockout et RequireJS

Riche en fonctionnalités et multiplateforme

Références

16

Tutoriels et exemples javascript – jQuery: http://www.w3schools.com/

Tutoriels et exemples knockoutJS (MVVM): http://learn.knockoutjs.com/

Exemples DurandalJS: http://durandaljs.com/

Proxy : http://nodejs.org/

Recommended