Envia una notificació a l'equip quan s'actualitzi l'estat de l'element de treball a l'aplicació d'exemple Fites

L'aplicació d'exemple de Fites per al Microsoft Teams permet als usuaris fer un seguiment del progrés de la finalització dels elements de treball en projectes en diferents fites. Si bé l'aplicació permet actualitzar i mantenir elements de treball, actualment no hi ha notificacions estàndard sobre les actualitzacions dels elements de treball per a l'equip.

En aquest article aprendrem a crear un flux del Power Automate per enviar una notificació de targeta adaptativa a l'equip (en què està instal·lada l'aplicació) quan canviï l'estat de l'element de treball.

Requisits previs

Per completar aquest exercici, hauríem de tenir la capacitat d'iniciar sessió als equips que estaran disponibles com a part de les subscripcions seleccionades del Microsoft 365 i també haurem de tenir instal·lada la plantilla de Fites del Power Apps per al Teams. Aquesta aplicació es pot instal·lar des de https://aka.ms/TeamsInspection.

Iniciar la sessió a l'aplicació Fites

  1. Seleccioneu la icona del Power Apps a la part esquerra i aneu a la pestanya Compilació.

  2. Seleccioneu l'equip on s'instal·la l'aplicació Fites des del menú esquerre de l'aplicació.

  3. Seleccioneu Aplicacions instal·lades i seleccioneu Fites per obrir l'aplicació. S'obrirà l'aplicació Fites.

Afegir una condició per cridar al flux del Power Automate

  1. A la visualització en arbre de la subfinestra esquerra, seleccioneu la pantalla Projectes.

  2. A la pantalla, premeu la tecla Alt i seleccioneu qualsevol projecte per obrir-lo. S'obre la pantalla Afegeix o edita l'element de treball.

  3. Seleccioneu el botó Fet.

  4. Seleccioneu la propietat OnSelect del botó Fet.

  5. En seleccionar el botó Fet, juntament amb la resta d'actualitzacions que s'executen en segon terme, també voleu que s'activi un flux que enviï una actualització de la targeta adaptativa a l'equip si s'ha actualitzat l'estat de l'element de treball. Per fer aquest canvi, afegiu el següent a la part superior de la fórmula OnSelect:

    If(
    
        locEditWorkItem,
    
        //adding code to call a flow when status changes
    
            If(
    
                locSelectedWorkItem.'Work Item Status'.'Project Work Item Status' \<\>
                cmbAddWorkItemStatus.Selected.'Project Work Item Status',
    
        true //your flow call will come here
    
    ); 
    
  6. Copieu el codi sencer de la propietat OnSelect del botó Fet i enganxeu-lo en un editor de text per utilitzar-lo més endavant.

  7. Seleccioneu ... (punts suspensius) al costat de Configuració a la franja superior i seleccioneu Power Automate.

  8. S'obre la finestra emergent Dades amb l'opció per Crear un flux nou.

  9. Seleccioneu el botó Crea un flux nou. S'obre una finestra del navegador amb la nova pantalla de flux del Power Automate.

  10. Actualitzeu el nom del flux a: "Envia una notificació de targeta adaptativa quan canviï l'estat de l'ordre de treball".

  11. Seleccioneu l'opció per activar el Power Apps a la llista d'activadors. Es crea el nou flux i es carrega el pas del Power Apps a la pantalla.

Crear el flux del Power Automate

  1. Després de seguir els passos de la secció anterior, seleccioneu el botó +Nou.

  2. Seleccioneu l'acció Obtén una fila per ID i seleccioneu Nom de la taula com a Elements de treball del projecte.

  3. A ID de fila, obriu el contingut dinàmic i seleccioneu l'opció Pregunta al Power Apps.

  4. Canvieu el nom del pas per "Obtén el registre de l'element de treball".

  5. Torneu a seleccionar el botó de pas +Següent i seleccioneu l'acció Obtén una fila per ID i seleccioneu Nom de la taula com a Estats d'element de treball.

  6. A ID de fila, obriu el contingut dinàmic, seleccioneu Estat de l'element de treball (valor).

  7. Canvieu el nom del pas per Obtén el registre d'estat de l'element de treball.

  8. Afegiu un altre pas seleccionant un pas +Nou.

  9. Afegiu la variable Inicialitzar de l'acció.

    • Canvia el nom del pas per Inicialitzar variable - Títol de la targeta

    • Nom: "varCardTitle"

    • Tipus: "Cadena"

    • Valor = Actualització de l'estat de l'element de treball {i, a continuació, seleccioneu el nom del contingut dinàmic de l'element de treball afegit al pas 3}

  10. Afegiu un altre pas seleccionant un pas +Nou.

  11. Afegiu la variable Inicialitzar de l'acció.

    • Canviar el nom del pas per Inicialitzar variable - Revisar l'enllaç
    • Nom: "varReviewWorkItemLink"
    • Tipus: "Cadena"
    • Valor: deixeu-lo en blanc; s'afegirà més endavant.

    Nota

    Després d'afegir un pas nou, al comprovador de flux veureu un advertiment. Aquest advertiment és normal perquè el flux es crida des d'una aplicació del Power Apps i afegir un nou pas a un flux cridat des d'una aplicació del Power Apps pot trencar la connexió amb l'aplicació. Més endavant en l'exercici substituirem la connexió al flux per corregir aquest advertiment.

  12. Per a l'acció Revisa l'enllaç de l'element de treball, utilitzarem l'enllaç a l'aplicació. Per trobar aquest enllaç, obriu l'equip on està instal·lada l'aplicació Fites i copieu l'enllaç per a la pestanya on està instal·lada l'aplicació. Podeu copiar l'enllaç a la pestanya obrint la pestanya i, a continuació, seleccionant ... (punts suspensius) a la part superior dreta.

    L'adreça URL serà semblant a l'exemple següent:

    https://teams.microsoft.com/l/entity/GUID/_djb2_msteams_prefix_956529380?context=%7B%22subEntityId%22%3Anull%2C%22channelId%22%3A%2219%3AGUID%40thread.tacv2%22%7D&groupId=GUID&tenantId=GUID

  13. Per continuar, copieu la part de l'adreça URL que va després de context= i utilitzeu un decodificador d'URL com ara https://www.urldecoder.org/ per desxifrar l'adreça URL.

  14. Copieu el text descodificat i torneu al flux del Power Automate.

  15. Torneu a la variable Inicialitzar: revisar l'enllaç de element de treball.

  16. Definiu el camp Valor en el text d'adreça URL descodificada que heu copiat abans.

  17. Afegiu un pas nou amb l'acció Redacta i, al camp Entrades, enganxeu el fragment següent.

    replace(replace(replace(variables('varReviewWorkItemLink'),'{','%7B'),'"','%22'),'}','%7D')
    
  18. Afegiu un altre pas seleccionant +Pas nou.

  19. Seleccioneu l'acció Publica una targeta adaptativa en un xat o canal (versió preliminar).

    • Publica com a: usuari

    • Publica a: canal

    • Equip: {l'equip on està instal·lada l'aplicació}

    • Canal: general

    • Targeta adaptativa: enganxeu el codi JSON següent:

      Nota

      El codi JSON següent conté referències dinàmiques als valors dels passos de flux anteriors. Això hauria de resoldre's automàticament amb la referència correcta, però si no fos així, actualitzeu-ho manualment amb la referència correcta. Per exemple, @{outputs('Get_Work_Item_Status_record')?['body/msft_name']} fa referència a la columna de nom del pas Obtén l'estat de l'element de treball.

      {
                  "type": "AdaptiveCard",
                  "body": [
                  {
      
                         "type": "TextBlock",
      
             "size": "large",
      
             "weight": "Bolder",
      
             "text": "Status Update for
             @{outputs('Get_Work_Item_record')?['body/msft_name']}",
      
             "wrap": true
      
             },
      
             {
      
             "type": "TextBlock",
      
             "text": "Status for Work Item
             '@{outputs('Get_Work_Item_record')?['body/msft_name']}' has been updated to
             @{outputs('Get_Work_Item_Status_record')?['body/msft_name']}",
      
             "wrap": true
      
             }
      
             ],
      
             "actions": [
      
             {
      
             "type": "Action.OpenUrl",
      
             "title": "View @{variables('varCardTitle')}",
             //Update the part of the following URL before "context=" with the URL copied in step 12. 
             "url":
             "[https://teams.microsoft.com/l/entity/040880f4-0c68-4c38-8821-d5efd2b6ddbe/_djb2_msteams_prefix_956529380?context=@{outputs('Compose](https://teams.microsoft.com/l/entity/040880f4-0c68-4c38-8821-d5efd2b6ddbe/_djb2_msteams_prefix_956529380?context=@%7boutputs('Compose)')}"
      
             }
      
             ],
      
             "$schema": "<http://adaptivecards.io/schemas/adaptive-card.json>",
      
             "version": "1.2"
      
             }
      
  20. Desar el flux.

Activeu el flux des del Power Apps

  1. Un cop desat el flux, torneu al Teams i obriu l'aplicació al Power Apps.

  2. A la visualització d'arbre, seleccioneu la pantalla Afegeix o edita l'element de treball.

  3. Seleccioneu el botó Actualitza.

  4. Actualitzeu la propietat OnSelect per assegurar-vos que s'ha activat el flux.

  5. Copieu la fórmula des de qualsevol lloc on l'hagueu enganxat abans a la propietat OnSelect.

  6. A la primera condició If que s'ha afegit a la part superior, substituïu "true" per la funció d'execució utilitzada per disparar el disparador de flux. Vegeu l'exemple següent.

    If(
    
    locEditWorkItem,
    
    //adding code to call a flow when status changes
    
    If(
    
    locSelectedWorkItem.'Work Item Status'.'Project Work Item Status' \<\>
    cmbAddWorkItemStatus.Selected.'Project Work Item Status',
    SendAdaptivecardnotificationwhenthestatusoftheworkorderchanges.Run(locSelectedWorkItem.'Project Work item') //your flow call will come here
    
    );
    
    //end code
    

Actualitzar la pantalla de càrrega

  1. A la visualització d'arbre, seleccioneu Pantalla de càrrega.

  2. Expandiu la pantalla de càrrega i, a continuació, conLoading_HiddenHelper a sota.

  3. Seleccioneu el temporitzador tmrLoadingDelay i seleccioneu la propietat OnTimerEnd.

  4. Si l'aplicació s'obre a través de l'enllaç de la targeta adaptativa, hauria d'obrir directament el registre de l'element de treball que s'ha actualitzat, la qual cosa significa que necessitaríem una manera de comprovar si es passa un id. de l'element de treball a l'aplicació.

  5. Cal actualitzar la fórmula de la pàgina de càrrega per incloure-hi el número de l'element de treball, de manera que hem d'actualitzar la propietat OnTimerEnd a continuació:

    If(
        gblAppLoaded,// && !IsBlankOrError(gblAppStyles),
        If(
            !IsBlank(Param("subEntityId")), //check if the parameter is blank or not
            If( //if the parameter is not blank, check if the user is on a mobile device or desktop/web and then populate the relevant variables and collections to make deep linking work
                (!IsBlank(Param("hostClientType")) && (Param("hostClientType") = "android" Or Param("hostClientType") = "ios")) || (IsBlank(Param("hostClientType")) && (Acceleration.X > 0 || Acceleration.Y > 0 || Acceleration.Z > 0)) Or tglAdmin_Mobile.Value, 
                //project cover colors
                ClearCollect(
                    colMobileProjectCoverColors,
                    {
                        Color: "#F4B9B9",
                        Theme: "default",
                        Base: "Color1"
                    },
                    {
                        Color: "#94BFFF",
                        Theme: "default",
                        Base: "Color2"
                    },
                    {
                        Color: "#E6F0FF",
                        Theme: "default",
                        Base: "Color3"
                    },
                    {
                        Color: "#5AC6CC",
                        Theme: "default",
                        Base: "Color4"
                    },
                    {
                        Color: "#C5E9EA",
                        Theme: "default",
                        Base: "Color5"
                    },
                    {
                        Color: "#F0F9FA",
                        Theme: "default",
                        Base: "Color6"
                    },
                    {
                        Color: "#EE6F99",
                        Theme: "default",
                        Base: "Color7"
                    },
                    {
                        Color: "#F495BF",
                        Theme: "default",
                        Base: "Color8"
                    },
                    {
                        Color: "#F4D2DC",
                        Theme: "default",
                        Base: "Color9"
                    },
                    {
                        Color: "#CEF0CD",
                        Theme: "default",
                        Base: "Color10"
                    },
                    {
                        Color: "#BDBDE6",
                        Theme: "default",
                        Base: "Color11"
                    },
                    {
                        Color: "#E2E2F6",
                        Theme: "default",
                        Base: "Color12"
                    },
                    {
                        Color: "#F4F4FC",
                        Theme: "default",
                        Base: "Color13"
                    },
                    {
                        Color: "#FBF6D9",
                        Theme: "default",
                        Base: "Color14"
                    },
                    {
                        Color: "#791818",
                        Theme: "dark",
                        Base: "Color1"
                    },
                    {
                        Color: "#053385",
                        Theme: "dark",
                        Base: "Color2"
                    },
                    {
                        Color: "#6264A7",
                        Theme: "dark",
                        Base: "Color3"
                    },
                    {
                        Color: "#002F31",
                        Theme: "dark",
                        Base: "Color4"
                    },
                    {
                        Color: "#025C5F",
                        Theme: "dark",
                        Base: "Color5"
                    },
                    {
                        Color: "#03787C",
                        Theme: "dark",
                        Base: "Color6"
                    },
                    {
                        Color: "#461525",
                        Theme: "dark",
                        Base: "Color7"
                    },
                    {
                        Color: "#CC3D6D",
                        Theme: "dark",
                        Base: "Color8"
                    },
                    {
                        Color: "#EA5788",
                        Theme: "dark",
                        Base: "Color9"
                    },
                    {
                        Color: "#043615",
                        Theme: "dark",
                        Base: "Color10"
                    },
                    {
                        Color: "#33344A",
                        Theme: "dark",
                        Base: "Color11"
                    },
                    {
                        Color: "#6264A7",
                        Theme: "dark",
                        Base: "Color12"
                    },
                    {
                        Color: "#464775",
                        Theme: "dark",
                        Base: "Color13"
                    },
                    {
                        Color: "#FFAA44",
                        Theme: "dark",
                        Base: "Color14"
                    }
                );
    
    //local table of character widths, used for auto width labels
    ClearCollect(
                    colMobileCharsWidth,
                    staticCharWidths
                );
    
    //stock project cover images
    ClearCollect(
                    colMobileStockImages,
                    {appStockImage: Blank()},
                    {appStockImage: ProjectCover_Future},
                    {appStockImage: ProjectCover_Work},
                    {appStockImage: ProjectCover_Shapes},
                    {appStockImage: ProjectCover_Design},
                    {appStockImage: ProjectCover_Flow},
                    {appStockImage: ProjectCover_Abstract},
                    {appStockImage: ProjectCover_Mountain},
                    {appStockImage: ProjectCover_Vision},
                    {appStockImage: ProjectCover_DarkShapes},
                    {appStockImage: ProjectCover_Morning},
                    {appStockImage: ProjectCover_Sublime},
                    {appStockImage: ProjectCover_Tech},
                    {appStockImage: ProjectCover_Neon},
                    {appStockImage: ProjectCover_City}
                );
                Set(
                    gblMobileProject,
                    LookUp(
                        'Project Work Items',
                        'Project Work item' = GUID(Param("subEntityId"))
                    ).Project
                );
                ClearCollect(
                    colMobileWorkItems,
                    Filter(
                        'Project Work Items',
                        Project.Project = gblMobileProject.Project
                    )
                );
                UpdateContext(
                    {
                        locMobileCompletionStatus: First(
                            Sort(
                                'Project Work Item Statuses',
                                Sequence,
                                Ascending
                            )
                        )
                    }
                );
                Clear(colMobileWorkItemStatuses);
                ForAll(
                    Sort(
                        Filter(
                            'Project Work Item Statuses',
                            'Project Work Item Status' <> locMobileCompletionStatus.'Project Work Item Status'
                        ),
                        Sequence,
                        Ascending
                    ),
                    Collect(
                        colMobileWorkItemStatuses,
                        {
                            Name: ThisRecord.Name,
                            Color: ThisRecord.Color,
                            'Color Dark': ThisRecord.'Color Dark',
                            'Project Work Item Status': ThisRecord.'Project Work Item Status',
                            Sequence: ThisRecord.Sequence
                        }
                    )
                );
                Collect(
                    colMobileWorkItemStatuses,
                    {
                        Name: locMobileCompletionStatus.Name,
                        Color: locMobileCompletionStatus.Color,
                        'Color Dark': locMobileCompletionStatus.'Color Dark',
                        'Project Work Item Status': locMobileCompletionStatus.'Project Work Item Status',
                        Sequence: locMobileCompletionStatus.Sequence
                    }
                );
                Navigate(
                    'Mobile Work Item Details Screen',
                    ScreenTransition.None,
                    {
                        locMobileSelectedWorkItem: LookUp(
                            'Project Work Items',
                            'Project Work item' = GUID(Param("subEntityId"))
                        ),
                        locMobileShowWorkItemDetail: true,
                        locMobileShowSearchWorkItem: false,
                        locMobileNavToDetailFromAbout: true
                    }
                ),
                Set(
                    gblProject,
                    LookUp(
                        'Project Work Items',
                        'Project Work item' = GUID(Param("subEntityId"))
                    ).Project
                );
                UpdateContext(
                    {
                        locCompletionStatus: First(
                            Sort(
                                'Project Work Item Statuses',
                                Sequence,
                                Ascending
                            )
                        )
                    }
                );
                Clear(colWorkItemStatuses);
                ForAll(
                    Sort(
                        Filter(
                            'Project Work Item Statuses',
                            'Project Work Item Status' <> locCompletionStatus.'Project Work Item Status'
                        ),
                        Sequence,
                        Ascending
                    ),
                    Collect(
                        colWorkItemStatuses,
                        {
                            Name: ThisRecord.Name,
                            Color: ThisRecord.Color,
                            'Color Dark': ThisRecord.'Color Dark',
                            'Project Work Item Status': ThisRecord.'Project Work Item Status',
                            Sequence: ThisRecord.Sequence
                        }
                    )
                );
                Collect(
                    colWorkItemStatuses,
                    {
                        Name: locCompletionStatus.Name,
                        Color: locCompletionStatus.Color,
                        'Color Dark': locCompletionStatus.'Color Dark',
                        'Project Work Item Status': locCompletionStatus.'Project Work Item Status',
                        Sequence: locCompletionStatus.Sequence
                    }
                );
                Navigate(
                    'Add/Edit Work Item',
                    ScreenTransition.None,
                    {
                        locEditWorkItem: true,
                        locSelectedWorkItem: LookUp(
                            'Project Work Items',
                            'Project Work item' = GUID(Param("subEntityId"))
                        ),
                        locAddProject: false,
                        locExpandProjectList: true,
                        locProjectSortOrder: true,
                        locSortWorkItemBy: "eta",
                        locShowSearchWorkItem: false,
                        locAddWorkItem: false,
                        locProjectStatusSelection: "Milestone status",
                        locWorkItemSortOrder: true
                    }
                )
            ),
            If( //if the parameter is blank, check if the user is on a mobile device or desktop/web and redirect the user accordingly 
                (!IsBlank(Param("hostClientType")) && (Param("hostClientType") = "android" Or Param("hostClientType") = "ios")) || (IsBlank(Param("hostClientType")) && Acceleration.X > 0) Or tglAdmin_Mobile.Value,
                Navigate(
                    'Mobile Projects Screen',
                    ScreenTransition.None
                ),
                Navigate(
                    'Projects Screen',
                    ScreenTransition.None,
                    {
                        locShowFirstRun: gblFirstRun,
                        locShowPowerAppsPrompt: gblRecordUserSettings.'Display Splash (Power Apps)' = 'Display Splash (Power Apps) (Project User Settings)'.Yes
                    } 
                )
            )
        )
    )
    
    

Publicar l'aplicació Fites

Tots els canvis realitzats a l'aplicació Fites s'han completat. Ara, l'aplicació es pot publicar seleccionant el botó Publica a Teams de la part superior dreta.

Provar el flux del Power Automate

  1. Aneu al Teams i obriu l'aplicació Fites.

  2. Obriu un element de treball existent i actualitzeu l'estat a un valor diferent.

  3. Es rep una notificació de targeta adaptativa al canal del Teams on està instal·lada l'aplicació.

Consulteu també