Vue normale

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierBlog Microsoft Power Apps

Sécurisez les éléments d’une liste SharePoint

Groupes de sécurité Azure AD, Groupes de sécurité SharePoint, liste de distribution Exchange, droits nominatifs … Il y a plusieurs façon de sécuriser les données d’une liste SharePoint.

Pour explorer ces différentes options, je vous invite à consulter la vidéo de Reza Dorrani, MVP et youtubeur Power Apps extrêmement pertinent que je vous conseille de suivre.

Il explique dans cette vidéo comment utiliser les différents groupes de sécurité disponibles et leurs impacts.

J’apporte un élément supplémentaire à sa vidéo en vous partageant un flow pour sécuriser vos données en se basant non pas sur le créateur, mais sur son rôle ou son équipe.

Partons du principe que votre application contienne des familles d’utilisateurs sectionnés par rôle ou pas équipe, vous souhaitez qu’un élément créé soit automatiquement partagé à l’ensemble des collaborateurs de la même famille sans que les autres puissent y accéder.

Nous allons passer par un flow Power Automate pour gérer ces différents droits.

Avant de commencer le Flow, les utilisateurs doivent être placés dans des groupes de sécurité SharePoint. Un groupe par rôle ou par équipe.

  1. créez un Flow automatisé avec pour déclencheur : « Lorsqu’un élément est créé ».

2. Arrêtez le partage de l’élément avec l’action : « Arrêter le partage d’un élément ou d’un fichier ».

3. Obtenez les groupes de l’utilisateur avec l’action : « Envoyer une requête HTTP à SharePoint ».

_api/web/SiteUsers/getbyemail('@{triggerBody()?['Author']?['Email']}')/Groups

4. Sélectionnez les groupes auxquels l’utilisateur appartient avec l’action : « Sélectionner ».


4.1 Placez dans « De » la réponse de l’action précédente avec le code suivant.

outputs('Envoyer_une_requête_HTTP_à_SharePoint')?['body']?['d']?['results']


4.2 Cliquez sur l’option « basculer carte en mode texte ».
4.3 Ajoutez « item()?[‘Id’] » dans le champ Carte

5. Dans un « Appliquer à chacun », avec pour valeur la sortie de l’action précédente, ajoutez l’action « Envoyer une requête HTTP à SharePoint ».

_api/lists/getByTitle('Demandes')/items(@{triggerOutputs()?['body/ID']})/roleAssignments/addroleassignment(principalId=@{item()}, roledefId=1073741827)

Pour rappel, voici les différents ID de rôle :


– Lecture : 1073741826
– Modification : 1073741827
– Contrôle total : 1073741829

Attention : Il peut il y avoir quelques secondes entre le moment où l’élément est créé et le lancement du Flow. Si vous souhaitez bloquer la visualisation de l’item pendant ce laps de temps, vous pouvez :

  1. Créer une colonne de type Boolean dans votre liste avec une valeur Non par défaut.
  2. Créer une vue de liste qui n’affiche que les éléments dont la valeur est vraie
  3. Empêcher les utilisateurs de créer des vues personnalisées
  4. Modifier le champs à Oui une fois la modification des droits effectuée

J’espère que cet article vous aidera à mieux sécuriser vos données. N’hésitez pas à partager en commentaire d’autres façons de faire. Comme dit Reza, partager, c’est aimer.

jason-dent-3wpjxh-pirw-unsplash

g2i365

Créer une app en 2h : Fait !

Suite à un challenge que j’ai lancé sur ce blog, j’ai reçu quelques propositions d’app que je devais créer en live sur Youtube en 2h.

Vous pouvez télécharger les différentes ressources sur Github.

Suivez ces étapes pour implémenter l’app dans votre environnement.

  1. Créez un site SharePoint ou choisissez-en un existant.

2. Importez le flow dans Power Automate et configurez-le avec votre site SharePoint de destination

3. Importez l’application dans Power Apps et liez les boutons « Button2_3 » et « Button2_5 » à votre Flow


J’espère que cette vidéo et ces ressources vous seront utiles d’une manière ou d’une autre.

Des idées de fonctionnalités sur l’app ? Proposez-les en commentaire

jukan-tateisi-bJhT_8nbUA0-unsplash

g2i365

Exécuter un Flow sous condition après enregistrement d’un formulaire

Difficulté 1/5

À la soumission d’un formulaire, vous souhaitez lancer un flow en fonction d’une condition. Le problème est que si vous liez votre flow au Onsuccess, il se déclenchera même si la condition n’est pas remplie.

Exemple :

Votre application gère des demandes d’accès à un site.

À la validation d’une demande, vous souhaitez en informer le demandeur via Teams, lui envoyer un plan d’accès par email et ajouter une tâche dans Planner aux équipes en charge de configurer les badges.

Si vous déclenchez votre Flow directement sur le OnSuccess de votre formulaire, même si vous l’avez placé dans une condition, les différentes actions se réaliseront même en cas de refus.

Pour contourner le problème, créez un bouton et liez le flow sur sa propriété OnSelect. Changez le OnSuccess de votre formulaire en passant de :

If( FormulaireDeDemande.LastSubmit.Statut.Value = "Acceptée"; Run.FlowDeValidation( FormulaireDeDemande.LastSubmit.Statut .ID))

à :

 If( FormulaireDeDemande.LastSubmit.Statut.Value = "Acceptée";  Select(BoutonFlow))

Puis masquez votre bouton. Ainsi le flow est déporté et ne s’executera que si la condition est remplie.

Note 1 : ne placez pas votre bouton dans le formulaire mais directement dans le Screen.

Note 2 : utilisez les fonctions RestForm ou NewForm après l’utilisation de LastSubmit.

Note 3 : si vous souhaitez revenir sur l’écran précédent après enregistrement, placez la fonction Back après l’exécution du Flow. La fonction Select interagie uniquement avec les contrôles présents dans son écran.

free-to-use-sounds-zxn-zuztohu-unsplash

g2i365

Set ou UpdateContext ?

Résumé en bas de page

Difficulté : 1/5

Ces deux fonctions permettent de stocker provisoirement des données dans Power Apps.

Vous pourrez vous en servir pour garder en mémoire du texte, des chiffres, des dates, des objets et tout autre type de données présent dans votre application.

Il est important de souligner que les valeurs qu’elles contiennent sont supprimées une fois l’application fermée.

Si vous souhaitez les conserver, vous devrez utiliser un formulaire ou la fonction Patch pour les enregistrer sur votre base de données ou SaveData pour les sauvegarder localement sur votre téléphone ou tablette.

Une mauvaise utilisation de ces variables peut engendrer des calculs inutiles et impacter la performance de votre application.

SET

Cette fonction permet de définir une variable que vous pourrez utiliser sur l’intégralité des écrans de votre application.

Dans l’idéal, il faudrait qu’un set soit initialisé et jamais modifié. Etant présent dans l’intégralité des pages, un changement pourra avoir une répercussion sur tous les contrôles qui en font l’usage. En fonction de la complexité de votre app, cela peut générer beaucoup de calculs et impacter sérieusement ses performances.

Exemple :

Vous souhaitez gérer l’accès à différents espaces ou fonctionnalités de votre app en fonction de la personne connectée.
Créez la variable _RoleUtilisateurActuel sur la propriété OnStart de votre application et définissez-la par le rôle de la personne enregistrée dans une table de droit.

Set(_RoleUtilisateurActuel ; LookUp( BaseDeDroits; User().Email = EmailDeLaBaseDeDroit ).Role)

Vous pourrez ainsi modifier la propriété Visible d’un bouton pour l’afficher uniquement aux utilisateurs qui ont un rôle de gestionnaire.

_RoleUtilisateurActuel = "Gestionnaire"

Cette variable est initialisée une seul fois, elle ne sera pas modifiée et pourra être utilisée sur tous les écrans.


UpdateContext

A l’inverse du set, cette variable est exploitable dans un écran à la fois.

Ainsi, même si vous utilisez cette variables sur l’intégralité de votre app, aucun calcul ne sera réalisé sur les écrans non visibles.

Elle peut également stocker des tables cependant Collect ou Table sont plus adaptés.

Cette fonction peut s’utiliser de deux façons :

– Stocker une information dans une page : UpdateContext({ _NomDeLaVariable : Valeur })
– Conserver une information en changeant d’écran : Navigate(Ecran2 ; ScreenTransition.Cover ; { _NomDeLaVariable : Valeur })

Résumé

SetUpdateContext
DisponibilitéToute l’applicationUne page
Point fortDisponible partout et initiable dans OnStartSa modification n’engendre pas de calculs sur d’autres écrans
Point faiblePeut ralentir le fonctionnement de l’applicationDoit être initialisé sur chaque écran
Bonne pratiqueStoker des informations légères et ne pas les modifierEmbarquer d’un écran à un autre uniquement les informations utiles

Aller plus loin dans la compréhension des variables : https://docs.microsoft.com/fr-fr/powerapps/maker/canvas-apps/working-with-variables

Pour en savoir plus sur l’optimisation des performances de votre application : https://docs.microsoft.com/fr-fr/powerapps/maker/canvas-apps/performance-tips


J’espère vous avoir aidé à y voir plus clair. Si vous avez des contre-exemples ou d’autres précisions à apporter, partagez-les en commentaire 🙂

burst-aoN3HWLbhdI-unsplash

g2i365

Comprendre et adapter l’écran calendrier au format français

Niveau de difficulté : 3/5

Ressource disponible en fin d’article

Nombreux sont les cas où l’on a besoin d’un calendrier. Celui proposé dans le bouton « Nouvel écran » est un très bon début mais n’est pas au format français, c’est selon moi l’un des éléments les plus complexes à prendre en main.

Voici son fonctionnement et comment l’adapter.

  1. Son fonctionnement

Une liste déroulante permet de sélectionner un de nos calendriers. Dans sa propriété « OnSelect », des variables sont définies pour afficher les évènements dans une gallery. Voici le détail et les explications de chacune des variables.

If(IsBlank(_userDomain); // Permet de définir les variables suivantes si elles ne l'ont pas déjà été.
         
	UpdateContext({_showLoading: true});; // Permet d'afficher un loader ou autre élément permettant d'afficher un message de chargement.
         
	Set(_userDomain; Right(User().Email; Len(User().Email) - Find("@"; User().Email)));; // Ajoute dans une variable le domaine de l'utilisateur connecté.
        
	Set(_dateSelected; Today());; // Ajoute dans une variable la date du jour 
         
	Set(_firstDayOfMonth; DateAdd(Today(); 1 - Day(Today()); Days));; // Ajoute dans une variable le premier jour du mois    

	Set(_firstDayInView; DateAdd(_firstDayOfMonth; -(Weekday(_firstDayOfMonth) - 2 + 1); Days));; // Définit dans une variable le premier jour à afficher dans la gallery de date 
        
	Set(_lastDayOfMonth; DateAdd(DateAdd(_firstDayOfMonth; 1; Months); -1; Days)));;   // Définit dans une variable le dernier jour à afficher dans la gallery de date 
        
       
Set(_calendarVisible; false);;  // Permet de masquer la gallery calendrier pendant le chargement.  
     
UpdateContext({_showLoading: true});; // Affiche l'élément de chargement et masque la gallery de date
     
Set(_myCalendar; Self.Selected);;   // Place le choix effectué dans la liste  
     
Set(_minDate; DateAdd(_firstDayOfMonth; -(Weekday(_firstDayOfMonth) - 2 + 1); Days));; // Sert de mémoire tampon en définissant la date de début pour éviter les doublons

Set(_maxDate; DateAdd(DateAdd(_firstDayOfMonth; -(Weekday(_firstDayOfMonth) - 2 + 1); Days); 40; Days));;  // Sert de mémoire tampon en définissant la date de fin pour éviter les doublons       

ClearCollect(MyCalendarEvents; Office365Outlook.GetEventsCalendarViewV2(_myCalendar.Name; Text(_minDate; UTC); Text(_maxDate; UTC)).value);; // Place dans une collection les évènements du mois en cours du calendrier sélectionné     
   
UpdateContext({_showLoading: false});; // Masque l'élément de chargement pour afficher la gallery de date
      
Set(_calendarVisible; true) // Permet d'afficher la gallery calendrier une fois le chargement terminé

Le calendrier est composé de 5 éléments :

  • Un texte affichant le mois et l’année
  • Un bouton pour charger le mois précédent
  • Un bouton pour charger le mois suivant
  • Une gallery de semaine
  • Une gallery de date

Les deux boutons modifient les variables initialisées dans la liste déroulante pour charger les éléments du mois suivant ou précédent.

La gallery de date a pour « Items » un tableau de chiffres allants de 0 à 41, soit 42 éléments, soit 6 semaines. Divisée en 7 colonnes, elle permet d’afficher une ligne par semaine et se compose de 3 éléments :

  • Un label affichant le numéro du jour. Sa propriété « OnSelect » définit la variable _dateSelected avec le jour sélectionné. Le numéro affiché est l’adition de la variable _firstDayInView et de la valeur de l’élément. Ainsi on aurait pour un début de mois commençant en début de semaine :
    Lundi : 1 + 0 = 1
    Mardi : 1 + 1 = 2
    Mercredi 1 + 2 = 3 etc…
    Sa propriété « Visible » permet d’être masquée si la semaine complète n’est pas dans le mois en cours. On évite ainsi du « bruit ».
  • Un cercle permettant d’afficher la sélection de l’utilisateur (Subcircle). Il se rend visible lorsque la date sélectionnée est égale au jour de la gallery.
  • Un cercle signalant qu’un évènement est présent dans le calendrier (Circle). Il se rend visible quand un élément dans la collection MyCalendarEvents correspond au jour de la gallery.

2) L’adapter au format français

Le principe sera de positionner le lundi en première colonne de la gallery et d’indiquer dans les différentes variables que le premier jour de la semaine n’est pas le dimanche mais le lundi.

Voici les différents espaces à configurer et le code à remplacer :

  • La propriété « Items » de la gallery de semaine :
["lun";"mar";"mer";"jeu";"ven";"sam";"dim"]
  • La propriété « OnSelect » du menu déroulant :
If(IsBlank(_userDomain);         
	UpdateContext({_showLoading: true});;         
	Set(_userDomain; Right(User().Email; Len(User().Email) - Find("@"; User().Email)));;         
    Set(_dateSelected;Today());;
    Set(_firstDayOfMonth;DateAdd(Today();1-Day(Today());Days));;
    Set(_firstDayInView;DateAdd(_firstDayOfMonth;-(Weekday(_firstDayOfMonth;StartOfWeek.Monday)-2+1);Days));;
    Set(_lastDayOfMonth;DateAdd(DateAdd(_firstDayOfMonth;1;Months);-1;Days));;   
);;   
      
Set(_calendarVisible; false);;         
UpdateContext({_showLoading: true});;         
Set(_myCalendar; Self.Selected);;         
Set(_minDate;DateAdd(_firstDayOfMonth;-(Weekday(_firstDayOfMonth)-2+1);Days));;
Set(_maxDate;DateAdd(DateAdd(_firstDayOfMonth;-(Weekday(_firstDayOfMonth)-2+1);Days);40;Days));;        
ClearCollect(MyCalendarEvents; Office365Outlook.GetEventsCalendarViewV2(_myCalendar.Name; Text(_minDate; UTC); Text(_maxDate; UTC)).value);;         
UpdateContext({_showLoading: false});;         
Set(_calendarVisible; true)
  • La propriété « OnSelect » du bouton de gauche
/*Change les variables avec le mois précédant*/
Set(_firstDayOfMonth; DateAdd(_firstDayOfMonth; -1; Months));;
Set(_firstDayInView; DateAdd(_firstDayOfMonth; -(Weekday(_firstDayOfMonth;Monday) - 2 + 1); Days));;
Set(_lastDayOfMonth; DateAdd(DateAdd(_firstDayOfMonth; 1; Months); -1; Days));;

/*Collecte les évènnement du calendrier du mois précédent. Met à jour _minDate pour éviter les doublons si l'utilisateur reviens sur ce mois*/
If(_lastDayOfMonth > _maxDate; Set(_maxDate; _lastDayOfMonth);; 
Collect(MyCalendarEvents; Office365Outlook.GetEventsCalendarViewV2(_myCalendar.Name; Text(_minDate; UTC); Text(_lastDayOfMonth; UTC)).value))
  • La propriété « OnSelect » du bouton de droite
/*Modifie les variables pour afficher le mois précedant*/
Set(_firstDayOfMonth; DateAdd(_firstDayOfMonth; 1; Months));;
Set(_firstDayInView; DateAdd(_firstDayOfMonth; -(Weekday(_firstDayOfMonth;Monday) - 2 + 1); Days));;
/*Collecte les évènement du calendrier du mois suivant. Met à jour _maxDate pour éviter les doublons si 'utilisateur reviens sur ce mois.*/
Set(_lastDayOfMonth; DateAdd(DateAdd(_firstDayOfMonth; 1; Months); -1; Days));;
If(_lastDayOfMonth > _maxDate; Set(_maxDate; _lastDayOfMonth);;
 Collect(MyCalendarEvents; Office365Outlook.GetEventsCalendarViewV2(_myCalendar.Name; Text(_firstDayOfMonth; UTC); Text(_maxDate; UTC)).value))
  • La propriété « Visible » du label de la gallery de date
 !(DateAdd(_firstDayInView;ThisItem.Value;Days) - Weekday(DateAdd(_firstDayInView;ThisItem.Value;Days);StartOfWeek.Monday) +1  > _lastDayOfMonth)

Vous pouvez télécharger une application via ce lien dont les changements ci-dessus ont déjà été réalisés.


Bonus

Griser les évènements antérieur à aujourd’hui. Dans la propriété « Fill » du cercle d’évènement :

If(DateAdd(_firstDayInView;ThisItem.Value;Days)>=Today();RGBA(186; 202; 226; 1);
RGBA(128; 128; 128; 1))

J’espère que cet article vous aidera à y voir plus clair et vous aidera dans votre développement.

Si vous avez des idées d’optimisation, n’hésitez pas à les partager en commentaire.

whatsapp-video-2021-03-07-at-20.42.47-1

g2i365

Les 4 étapes à ne pas oublier à la création d’une app Power Apps

Certaines choses simples sont à faire dès la création de l’application pour s’éviter des problèmes plus tard. Avant même de placer un bouton ou le logo de votre entreprise, voici les étapes à ne pas manquer :

1) Créer l’application au format tablette (ou paysage)

Créer l’application dans ce format vous permettra de basculer vers le format téléphone (portrait). Alors que ce n’est pas possible en mode téléphone.

2) Augmenter la délégation à 2000

Si vous utilisez des listes SharePoint ou des tableaux Excel (ce que je déconseille) comme base de données, vous allez vous confronter à la délégation de Power Apps.
Même si l’idéal est d’arriver à contourner cette délégation, il est préférable de placer ce paramètre au maximum. Notamment si vous réalisez des collections à partir de jeux de données importants.

Pour ce faire, allez dans Fichier / Paramètre / Paramètre avancé et passez le paramètre à 2 000

3) Changer la tailler de l’app au format full HD

Comme tout le monde n’a pas forcément la chance de travailler sur un UltraWild en 4K, le full HD est le compromis idéal pour que tous les utilisateurs puissent avoir une bonne expérience sur votre application.

Allez dans Fichier / Paramètre / Taille et orientation de l’écran, placez le paramètre à « Personnalisé » et changez les hauteur et largeur avec 1920 / 1080.

Si votre application est destinée à un usage mobile et que par chance votre flotte est uniforme, n’hésitez pas à reprendre le même format.

Si vous décidez de faire ce changement en cours de route, tous vos items garderont la même proportion qu’ils prenaient dans votre app avant le changement. Vous devrez donc reprendre chacun des éléments pour lui attribuer une taille convenable. Bonne chance.

4) Enregistrez l’application

Nombreuses sont les fois où j’ai commencé à travailler sur une application sans l’avoir enregistrée une première fois. Et, avec l’habitude de l’enregistrement automatique, je ferme le navigateur. Jusqu’au moment où je cherche à l’ouvrir de nouveau et que … Elle n’existe pas. S’il vous plait, évitez-vous ça : ça fait mal !


J’espère que cette liste vous sera utile et que vous ne tomberez pas dans les mêmes pièges que moi.

N’hésitez pas à placer en commentaire une autre habitude que vous avez.

sigmund-By-tZImt0Ms-unsplash

g2i365

Enregistrer une photo sur SharePoint / OneDrive

L’enregistrement d’une photo prise depuis Power Apps vers SharePoint ou OneDrive se fait via un flow créé sur Power Automate.

Niveau de licence requis : A partir de la licence Business

Temps nécessaire : 5-10 minutes

Niveau de difficulté : 3 / 5

Sur power Automate

Créez un nouveau Flow avec Power Apps comme déclencheur.

Dans une variable de type message, ajouter « Demander dans PowerApps »

Ajouter un bloc message depuis « Opération de données ». Renommer le bloc afin de rendre le nom de la variable plus explicite dans Power Apps. Dans l’entrée, ajoutez « Demander à Power Apps » depuis la fenêtre dynamique. Une fois ajouté, supprimez la du bloc et ajoutez la fonction dataUriToBinary suivi de la variable Power Apps précédemment créée.

Ajoutez un bloc de création de création de fichier OneDrive ou SharePoint. Ajouter le chemin d’accès où sera enregistré l’image, le nom du fichier qui sera saisi dans Power Apps puis la sortie du bloc précédent.

Sur l’app

Commencez par ajouter un contrôle Caméra a votre application.

Sur la propriété OnSelect du contrôle camera, ajoutez la photo dans une collection. En fonction de votre usage, vous pouvez aussi choisir de créer la collection depuis un bouton ou un icône.

ClearCollect(colPhoto;Self.Photo)

Vous pouvez ajouter une entrée de texte (TextInput) pour ajouter un titre à l’image.

Ajoutez un bouton ou un icône d’enregistrement. Depuis celui-ci, nous allons lancer le flow qui se chargera de l’enregistrement de l’image. Faites le lien avec le bouton et le Flow depuis l’onglet « Action » et « Power Automate » puis renseignez l’image sélectionnée ainsi que le texte dans le contenu du flow.

DemoImportImage.Run(First(colPhoto).Url;TextInput1.Text&".jpg")

J’espère que cette fonctionnalité n’aura plus de secret pour vous.

20210204_000351

g2i365

❌
❌