Kahden edellisviikon kirjoituksissa olemme käyneet läpi, miten Power Appsilla toteutetaan muokattava dynaaminen taulukko.
- Osa 1 – Muokattavan taulukon käyttöliittymän toteutus siten, että rivit ja sarakkeet luetaan eri listasta/taulukosta/entiteetistä
- Osa 2 – Rivien hierarkinen esittäminen, muutosten tallentaminen tehokkaasti
Tänään jatketaan samalla aiheella ja täydennetään tehtyä ratkaisua siten että käyttäjä voi muokata taulukossa hierarkisesti esitettävän projektin rakennetta.
Eli lisätä uusia ja järjestellä vanhoja rivejä.
Rivien järjestäminen ja uusien rivien lisääminen
Jotta rivejä voisi uudelleenjärjestellä Power Appsissa, tulee tieto niiden keskinäisestä järjetyksestä tietenkin tallentaa. Lisätään projektin vaiheille (Project phases) tätä varten uusi sarake (OrderID).

OrderID-sarakkeessa ylläpidetään rivin järjestysnumeroa hierarkiatason sisällä. Rivit täytyy muistaa järjestää kaikkialla ko sarakkeen mukaan.

Mutta se itse järjestäminen..
Ensimmäinen yritys – Järjestystoiminnot alkuperäisen taulukon yhteydessä
Päätetään seuraavaksi, millainen käyttöliittymä rivien uudelleenjärjestelyä varten toteutetaan. Ensimmäisessä versiossa lisäsin taulukkoon ”Edit” -painikkeen, jota painamalla esiin ilmestyi työkalusarake. Siinä olevilla painikkeilla lisättiin uusia rivejä ja järjesteltiin vanhoja.
Ratkaisu oli pikkuriikkisen tahmea. Syy hitauteen on ilmeinen. Vaihdettaessa rivien järjestystä, piirtää Power Apps uudelleen koko gallerian sekä sen sisältämät varausgalleriat.
Toteutetaan ratkaisu mieluummin siten, että rivien manipulointi tehdään galleriasta erillään. Näin siitä tulee huomattavasti kevyempi.
Erillinen dialogi-ikkuna rivien muokkaamista varten
Lisätään aluksi taulukkoon painike, josta projektihierarkiaa pääsee muokkaamaan.

Painikkeella luodaan uusi kokoelma (colProjectHiearchyForEdit), joka on kopio projektihierarkiasta. Näin katkaisemme yhteyden alkuperäiseen galleriaan.
Lisätään uuteen kokoelmaan sarakkeet updated ja newitem. Niiden avulla ylläpidetään tietoa siitä, tarvitseeko kyseisiä rivejä lopulta tallentaa.
ClearCollect(colProjectHiearchyForEdit, AddColumns(colForProjectGallery, "updated", false, "newitem", false) ); UpdateContext({varEditProjects: true});
Lopuksi asetetaan varEditProjects-muuttujan arvoksi true.
Rakennetaan näytölle dialogi-ikkuna. Käytetään container-kontrollia (preview), jonka sisälle asetellaan omina kontrolleinaan otsikko ja tallennus- sekä peruuta-painikkeet.
Dialogin näkyvyyden (visible) arvona käytetään varEditProjects-muuttujaa. Näin dialogi ilmestyy näytölle käyttäjän painettua ”Edit”-painiketta.

Lisätään dialogiin galleria, jonka tietolähteenä (items) on juuri luomamme colProjectHiearchyForEdit-kokoelma. Gallerian ainoa kontrolli on tekstin syöttökenttä (Text Input), jonka arvona on vaiheen nimi (Title).
Sisennys toteutetaan samalla tapaa kuin päägalleriassa.
X = ThisItem.Level * 15
Toteutus alkaa hahmottumaan.

Rivin siirto ylöspäin
Lisätään riville ikoni, jota painamalla rivi siirtyy ylöspäin. Käytännössä vaihdamme rivin ja sitä edeltävän rivin OrderID arvot päittäin. Tämä tehdään ikonin OnSelect-tapahtumassa.

Haetaan ensin kokoelmasta riviä edeltävä rivi.
Set(varItemForSwap, LookUp( Sort(colProjectHiearchyForEdit,OrderID,Descending), ParentID = ThisItem.ParentID And OrderID < ThisItem.OrderID ) );
Jonka jälkeen voimme suorittaa vaihdon. Samalla päivitämme updated-sarakkeen arvoksi true, jotta voimme päivittää tiedon myöhemmin myös tietovarastoon.
Patch(colProjectHiearchyForEdit, varItemForSwap, {OrderID: ThisItem.OrderID, updated: true} ); Patch(colProjectHiearchyForEdit, ThisItem, {Title: inpProjectPhaseTitle_1.Text, OrderID: varItemForSwap.OrderID, updated: true} );
Vaihto ei näy käyttäjälle, ennen kuin olemme muodostaneet uudelleen gallerian takana olevan kokoelman.
Koska teemme täsmälleen saman kokoelman uudelleenluonnin myös siirrettäessä riviä alaspäin ja lisätessämme uuden rivin, luomme sitä varten piilotetun painikkeen jonka OnSelect-tapahtumaan lisäämme tarvittavan koodin.
ClearCollect(colTmp, colProjectHiearchyForEdit); ClearCollect(colProjetHiearchyForEdit,LookUp(colTmp,Level = 1)); ForAll(Sort(Filter(colTmp,Level = 2),OrderID,Ascending), Collect(colProjectHiearchyForEdit,ThisRecord); With({varCurrentItem: ThisRecord}, ForAll(Sort( Filter(colTmp,ParentID =varCurrentItem.ID), OrderID,Ascending), Collect(colProjectHiearchyForEdit,ThisRecord) ) ) )
Näin voimme suorittaa saman koodipätkän usean eri toiminnon yhteydessä.
Yksittäisen rivin siirto ylöspäin näyttää kokonaisuudessaan seuraavalta. Lopussa suoritetaan painikkeen sisältämä koodi Select-komennolla.

Voiko riviä siirtää ylöspäin?
Hierarkiatason ensimmäistä riviä ei voi siirtää ylöspäin. Asetetaan painike passiiviseksi (Disabled), mikäli rivin OrderID on 1.

Rivin siirto alaspäin
Rivin siirto alaspäin toteutetaan vastaavalla tavalla kuin ylöspäin. Hierarkian viimeistä riviä ei voi tietenkään siirtää alaspäin, eli passivoimme viimeisen rivin painikkeen.

Rivin otsikon muokkaaminen
Rivien (projektin vaiheiden) nimiä voi muokata. Muuttunut nimi päivitetään kokoelmaan kentän OnChange-tapahtumassa. Samalla asetetaan rivin updated-sarakkeen arvoksi true.

Uuden rivin lisääminen
Lisätään galleriaan ikoni, jolla käyttäjä voi lisätä uuden rivin. Rivejä voi lisätä ainoastaan tasoille 2 ja 3, joten ikoni piilotetaan tasolta 3.

Uuden rivin lisääminen kokoelmaan on suoraviivaista. Kunhan ensin selvitetetään, mikä uuden rivin OrderID on… Vaihtoehtoina ovat:
- Viimeisen rivin OrderId +1
- 1 (mikäli rivi on ensimmäinen kyseisen hierarkiatason rivi)
Koodi näyttää kokonaisuudessaan seuraavalta.
With({varNewItemOrderID: Max( Last(Sort(Filter(colProjectHiearchyForEdit, ParentID = ThisItem.ID), OrderID,Ascending)).OrderID + 1, 1) }, Patch(colProjetHiearchyForEdit, Defaults(colProjectHiearchyForEdit), { Title: "new item", ProjectID: ThisItem.ProjectID, Level: ThisItem.Level + 1, ParentID: ThisItem.ID, OrderID: varNewItemOrderID, newitem:true } ) ); Select(btnUpdateCollection)
Muutosten tallentaminen
Tähän asti kaikki muutokset on tehty kokoelmaan. Mitään ei ole tallennettu tietovarastoon. Se tehdään vasta dialogin Save-painikkeella.

Ensimmäisenä tallennetaan yhdellä Patch-komennolla kaikki vanhoille riveille tehdyt muutokset (updated = true And newitem = false),
Patch('Project phases', ShowColumns( Filter( colProjectHierarchyForEdit, updated = true And newitem = false), "ID", "OrderID", "Title" ) );
Tämän jälkeen lisätään kaikki uudet rivit. Tämä tehdään Flow’lla. Miksi? Lue lisää aiheesta juttusarjan edellisestä osasta.
'PA-Createnewprojectphases'.Run( JSON(Filter(colProjectHierarchyForEdit,newitem = true), JSONFormat.IgnoreBinaryData) );
Lopuksi päivitetään ratkaisun päägallerian käyttämä colForProjectgallery-kokoelma vastaamaan muokattua kokoelmaa (colProjectHierarchyForEdit). Dialogi katoaa näkyvistä asetettamalla varEditProjects-muuttujan arvoksi false.
ClearCollect(colForProjectGallery, DropColumns( colProjectHierarchyForEdit, "updated", "newitem") ); UpdateContext({varEditProjects: false});
Ja kas, olemme valmiit!
Yhteenveto
Gallerian rivien uudelleenjärjestäminen on yleinen toiminnallisuus. Sen voi toteuttaa mainiosti myös ilman kokoelmaa, jolloin siitä tulee helposti hidas.
Galleria + tietovarasto
Kun galleria on kytketty suoraan tietovarastoon, pysyy tekeminen yksinkertaisena. Kun tietovarastoa päivitetään Power Appsista käsin, päivittyvät tiedot automaattisesti myös galleriaan käyttäjän nähtäville.

Galleria + kokoelma + tietovarasto
Ratkaisu monimutkaistuu heti, kun siinä hyödynnetään kokoelmaa. Gallerian ja tietovaraston välillä ei ole enää automaattista yhteyttä, se on katkaistu tunkemalla väliin kokoelma (Collection).

Aloittelevalta tekijältä jää helposti kokonaisuudesta joku yksityiskohta toteuttamatta, eikä ratkaisu enää toimikkaan kaikissa tilanteissa toivotulla tavalla.
Pidä siis seuraavat mielessä
- Käyttäjän tekemät muutokset tulee lopulta tallentaa myös tietovarastoon. Muutoksia ei (yleensä) kannata tallentaa tietovarastoon sitä mukaa kun niitä tehdään.
- Muutokset tulee tehdä myös kokoelmaan. Galleria esittää kokoelmassa olevia tietoja.
- Mieti missä tilanteissa sinun tarvitsee ladata kokoelman tiedot uudestaan tietovarastosta (tai muodostaa kokoelma paikallisesti uudelleen). Voi olla ettei sinun aina tarvikaan. Mikäli olet muistanut päivittää kaikki muutokset myös paikalliseen kokoelmaasi.
Thanks. It is a great job.
TykkääTykkää