4.4 Tekninen toteutus
4.4.2 Kustomoidut komponentit
Käyttöliittymän ohjelmoinnillisesti vaativimpia osia olivat projektia varten rakennetut komponentit PropsComponent, CodeBox sekä kuvien vaihto valintapainikkeiden avulla. Tässä luvussa esitellään nämä komponentit ja toiminnallisuudet lähdekoodita-solla.
PropsComponent
PropsComponent -komponentin tarkoitus on koota dokumentoidun käyttöliittymä-komponentin metodit ja attribuutit jäsenneltyyn taulukkoon. Taulukon rakentami-seen käytettiin Material UI:n valmiita taulukkokomponetteja TableCell, TableRow, TableContainer, TableBody, Table ja TableHead. Jokaisella käyttöliittymän alasivulla (view) on alustettu propsRows-niminen taulukko, joka viedään propsComponentille.
Alla taulukon alustus lähdekoodissa.
const propsRows: Array<{
name: string;
type: string;
defaultValue: string;
description: string;
}>
PropsComponent -komponentin lähdekoodissa taas määriteltiin interface Icontent, joka määrittää, millaisessa muodossa edellä mainittu taulukko tulee esittää. Seuraa-vaksi määriteltiin vielä tyyppi PropsContent, joka taas kertoo, että sisällön, joka kom-ponentille välitetään, tulee olla taulukko. Alla interfacen ja tyypin lähdekoodit.
export interface Icontent { name: string;
type: string;
defaultValue: string;
description: string;
}
export type PropsContent = { content: Icontent[];
};
Seuraavaksi käytetään kustomoitua komponenttia sivunäkymässä. Lähdekoodista sel-viää, kuinka komponenttia käytetään Paper-komponentin sisällä, ja sille viedään aiemmin määritelty propsRows-taulukko vaaditussa muodossa taulukkona.
<Grid item xs={9}>
<Paper className={classes.paper}>
<Typography variant="h6" gutterBottom>
Props & Methods </Typography>
<PropsComponent content={propsRows} />
</Paper>
</Grid>
Komponentin lähdekoodi kokonaisuudessaan on tarkasteltavissa liitteessä 2.
CodeBox
CodeBox -komponentin tavoite on nimensä mukaisesti esittää dokumentoitavan käyttöliittymäkomponentin lähdekoodi. Komponentin toiminnallisuuksiin kuuluu myös lähdekoodin kopiointi, jota varten luotiin painike, joka kopioi koodin leikepöy-dälle sekä näyttää sivulla tiedon, kun kopiointi on onnistunut.
Koodin esittämistä varten luotiin jokaisen komponentin lähdekoodille oma tsx-tie-dosto, johon alustettiin muuttuja, joka sisältää koko lähdekoodin sellaisenaan. Tie-dosto tuotiin jokaiseen sivunäkymään, josta se välitettiin edelleen codeBox -kom-ponentille. Alla tiedoston tuonti sivunäkymään ja sen välittäminen komponentille nä-kymän lähdekoodissa. Tiedoston nimi on osittain piilotettu tietosuojasyistä.
import *****Code from "../code/*****Code";
{/** Code */}
<Grid item xs={9}>
<Paper elevation={2} className={classes.paper}>
<Typography variant="h6" gutterBottom>
Code
</Typography>
<CodeBox content={*****Code} />
</Paper>
</Grid>
CodeBox -komponentissa alkuperäinen lähdekoodi esitettiin Material UI:n valmiin CardContent -komponentin sisällä. Sen sisällä käytettiin vielä html <pre> -tagia teke-mään koodi luettavammaksi. Komponentille määriteltiin maksimikorkeus, jotta läh-dekoodin esittäminen ei pitkien koodien tapauksissa veisi koko näytön verran tilaa.
Alla lähdekoodin esittäminen CardContent -komponentissa.
<CardContent>
<pre>{code}</pre>
</CardContent>
Lähdekoodin kopiointia varten käytettiin valmista Copy to clipboard React-kompo-nenttia. Komponentilla on text -attribuutti, jonka arvoksi annetaan lähdekoodin muuttuja. Komponentin sisään luotiin myös painike, joka kutsuu handleClick-funk-tiota. Funktio näyttää alert -viestin kun teksti on kopioitu, CopyToClipboard -kompo-nentti itsessään hoitaa tekstin kopioimisen. Alla näiden toimintojen lähdekoodi.
const [copied, isCopied] = React.useState(false);
const handleClick = () => { isCopied(!copied);
};
<CopyToClipboard text={code}>
<Button
className={classes.button}
onClick={handleClick}
variant="contained"
startIcon={<FileCopyOutlinedIcon />}
>
Copy </Button>
</CopyToClipboard>
Komponentin lähdekoodi kokonaisuudessaan on tarkasteltavissa liitteessä 3.
Kuvien vaihto valintapainikkeiden avulla
Koska dokumentoitavassa järjestelmässä on useita brändejä, joilla kaikilla on oman-laisensa ulkoasu käyttöliittymässä, oli tämä otettava huomioon myös komponenttien
dokumentoinnissa. Ratkaisuksi luotiin osio, jossa voi valintapainikkeita painamalla vaihtaa dokumentoidun komponentin ulkoasua brändien välillä.
Osion rakennus aloitettiin keräämällä ja tallentamalla kuvakaappaukset jokaisesta dokumentoitavasta komponentista jokaisen brändin omalla ulkoasulla. Kuvat tallen-nettiin img-kansioon, josta ne tuotiin jokaiseen näkymään.
Näkymässä määriteltiin ensin tyyppi imgProps, jonka img-nimisen muuttujan tiedos-totyypiksi määriteltiin merkkijono (string). Tämän jälkeen varsinaisen näkymän luo-van funktion sisällä määriteltiin muuttuja ”value”, jolle annettiin Reactin State-hookia käyttäen arvoksi ensimmäisen brändin näyttökuvan nimi. Sen jälkeen määriteltiin vielä muuttuja imgSrc, joka käyttää ensin määriteltyä tyyppiä, ja jossa muuttujan img arvoksi annetaan State-hookilla määrätty arvo value. Näiden muuttujien avulla voi-daan muuttaa kuvatiedostoa käyttöliittymässä valintapainikkeen arvoa vastaavaksi.
Muuttujien lähdekoodi alla.
export type imgProps = { img: string;
};
const [value, setValue] = React.useState(imgBRAND1);
const imgSrc: imgProps = { img: value,
};
Muuttujien alustuksen jälkeen tarvittiin vielä funktio, joka palauttaa kuvan käyttöliit-tymään sen perusteella, mikä valintapainikkeista on valittuna, sekä toinen funktio, joka käsittelee valintapainikeryhmässä tapahtuneet muutokset. Ensimmäiselle alla määritellylle funktiolle viedään edellisessä vaiheessa luotu img-muuttuja, joka siis saa arvokseen kuvatiedoston nimen.
/** Render image based on radiogroup value */
function imgCard(props: imgProps) { const img = props.img;
return <img className={classes.img} src={img} alt="screenshot" />; }
/** Handle RadioGroup value change */
const handleImgChange = (event: React.ChangeEvent<HTMLInputElement>)
=> {setValue((event.target as HTMLInputElement).value); };
Käyttöliittymässä käytettiin Material UI:n RadioGroup-komponenttia, joka luo ryh-män valintapainikkeita. Valintapainikeryhmälle annettiin määreiksi aiemmin luotu funktio handleImgChange, joka käsittelee valinnan muutoksen, sekä value-määree-seen aiemmin määritelty samanniminen muuttuja. Näin valintapainikkeen arvo on sama kuin kuvatiedoston nimi, ja kuva voidaan vaihtaa käyttöliittymässä suoraan va-lintapainikeryhmän value-muuttujan arvon perusteella. Alla lähdekoodi painikeryh-mästä, sekä esimerkkinä yksittäinen painike.
<RadioGroup row onChange={handleImgChange} value={value}>
<FormControlLabel value={imgBRAND1}
control={<Radio />}
label="BRAND1"/>
</RadioGroup>
Painikeryhmän jälkeen käyttöliittymään tarvittiin vielä paikka itse kuvalle. Tämä to-teutettiin yksinkertaisesti yhdellä divillä, jonka sisällä kutsuttiin aiemmin alustettua funktiota imgCard, joka palauttaa kuvan käyttöliittymään. Funktiokutsun lähdekoodi alla.
<div>{imgCard(imgSrc)}</div>
Toiminnallisuuden lähdekoodi kokonaisuudessaan on tarkasteltavissa liitteessä 4.
5 Tulokset
Aiheen rajaus
Komponenttikirjaston rakentaminen on niin laaja kokonaisuus, että aihetta piti heti työn alussa rajata koskemaan vain yhtä järjestelmän näkymää. Komponenttien inven-tointi ja tarvittavien tietojen kerääminen oli työlästä ja aikaa vievää, etenkin kun ky-seessä on olemassa oleva järjestelmä. Uskon, että suunnittelukirjaston rakentaminen heti projektin alussa olisi ollut nopeampaa ja helpompaa, sillä silloin mitään ei ole vielä valmiina eikä käyttöliittymässä ole epäjohdonmukaisuuksia. Kun projekti oli jo
olemassa ja dokumentoinnin kohteena oleva sovellus käytössä, jäi suunnittelujärjes-telmän rakentaminen lähinnä valmiiden komponenttien dokumentoinniksi. Doku-mentoinnissa päänvaivaa aiheutti hieman myös se, että projektissa oli käytössä Bootstrap-kirjasto, joka tarjoaa valmiina tiettyjä komponentteja, esimerkiksi painik-keita. Näiden valmiiden komponenttien dokumentointi olisi ollut turhaa työtä, sillä Bootstrapin omista dokumentaatioista löytyy helposti laajat tiedot sen tarjoamista komponenteista. Nämä komponentit päätettiin tämän vuoksi jättää työn ulkopuo-lelle.
Tavoitteiden saavuttaminen
Opinnäytetyön tutkimuskysymyksiin saatiin vastattua yleisellä tasolla ja perusteltua suunnittelujärjestelmän hyödyt koko ohjelmistoprojektille. Lisäksi käsiteltiin kette-rien menetelmien käyttöä ohjelmistoprojektissa sekä pohdittiin suunnittelujärjestel-män käyttöä tässä viitekehyksessä.
Soveltavan kehittämistyön tavoitteena oli dokumentoida yhden näkymän kom-ponentit, ja tämä tavoite opinnäytetyössä saavutettiin. Komponentit saatiin doku-mentoitua loogisessa järjestyksessä ja niistä kerättiin uudelleenkäytön ja dokumen-toinnin kannalta oleelliset tiedot. Jälkeenpäin ajateltuna dokumentoinnissa olisi kan-nattanut keskittyä enemmän yleisiin komponentteihin, jotka ovat käytössä läpi koko järjestelmän yhden näkymän sijaan. Tällaisia olivat esimerkiksi kustomoidut painik-keet, sivuston valikot, tekstinsyöttö- ja hakukentät sekä listat. Yhden näkymän doku-mentointi tuli kuitenkin toiveena toimeksiantajalta, joten tähän en voinut itse vaikut-taa.
Komponenttikirjaston käyttöliittymän ulkoasussa pyrittiin jäljittelemään dokumentoi-tavan järjestelmän ulkoasua värimaailman ja sivun asettelun osalta, jotta kompo-nenttikirjasto antaisi käyttäjälleen mielikuvan niiden yhteenkuuluvuudesta. Käyttöliit-tymän asettelun sekä sisältöjen suunnittelussa otettiin mallia olemassa olevista de-sign systemeistä, ja mielestäni se saatiin rakennettua relevantiksi ja helppokäyt-töiseksi.
Material UI:n käyttö
Sivuston rakentamisessa käytettiin Material UI -komponenttikirjastoa. Tämä valittiin työhön, sillä halusin kokeilla millaista komponenttikirjaston käyttö on käytännössä.
Valmis kirjasto helpotti ja nopeutti työn tekemistä huomattavasti, sillä moniin tarvit-semiini ominaisuuksiin (taulukot, painikkeet, sivuvalikko, asettelu…) löytyi valmis komponentti. Material UI on erittäin hyvin dokumentoitu, joten sen käyttö oli help-poa, vaikka siitä ei ollut ollenkaan aiempaa kokemusta.
Jatkokehitys ja suunnittelujärjestelmän käyttö
Jotta suunnittelujärjestelmästä saadaan koko projektiryhmää hyödyttävä työkalu, on sitä vielä jatkokehitettävä koko järjestelmän laajuiseksi siten, että se sisältää loppu-jen komponenttien lisäksi myös tyylit, värit ja komponenttien käyttöohjeet. Aiemmin järjestelmästä ei ole ollut olemassa laajaa käyttöliittymädokumentaatiota, joten opinnäytetyön tuloksena syntynyt komponenttikirjasto helpottaa jatkokehitettynä uusien työntekijöiden perehdyttämistä sekä nopeuttaa kehitystyötä, kun komponen-tit ovat valmiina kopioitavissa suunnittelujärjestelmässä. Suunnittelujärjestelmä vaa-tii myös työtä, sillä sitä on pidettävä ajan tasalla koko ajan, mutta kaiken kaikkiaan sillä saadaan paljon hyötyä ajan säästön sekä käyttäjäkokemuksen parantumisen myötä.
6 Pohdinta
Opinnäytetyön myötä opin todella paljon ohjelmistokehitystiimin työstä, projektin vaiheista sekä suunnittelutyön tärkeydestä koko projektille. Opin käytännössä hyvän dokumentoinnin tärkeyden komponenttikirjaston kokoamisen ja ohjelmoinnin yhtey-dessä, sillä Material UI helpotti ohjelmointityötä valtavasti; se tarjosi valmiita ratkai-suja käyttöliittymään, eikä kaikkia komponentteja tarvinnut tehdä alusta saakka itse.
Koin dokumentoinnin tärkeyden myös aiemmin suorittaessani opintoihin kuuluvaa harjoittelua Cinia Oy: ssa ja samassa projektiryhmässä, jolle nyt toteutin komponent-tikirjaston. Täysin uutena projektin jäsenenä front end -kehitykseen hyppääminen oli hankalaa, sillä käyttöliittymistä ja tyyleistä ei ollu valmista dokumentaatiota, vaan asiat piti opetella ns. “kantapään kautta” ja komponentteja ja niiden toteutustapoja
etsiä valmiin koodin seasta. Suunnittelujärjestelmä olisi helpottanut tätä työtä ja no-peuttanut huomattavasti projektiin perehtymistä.
Uskon, että suunnittelujärjestelmä on parhaimmillaan suurissa, pitkäkestoisissa oh-jelmistoprojekteissa tai koko yrityksen laajuisena. Sen suunnittelu, rakentaminen ja ylläpito vievät niin paljon aikaa, ettei sen käyttö pienissä, kertaluotoisissa projek-teissa, joissa ei tarvita jatkokehitystä ole taloudellisesti järkevää. Erityisen hyödyl-liseksi koen koko yritykselle rakennetun suunnittelujärjestelmän, jota voi hyödyntää kaikissa ohjelmistoprojekteissa soveltuvilta osin. Vaikka design systemin suunnittelu ja ylläpito vaatii investointeja, aikaa ja työtunteja, on se ehdottoman hyödyllinen työ-kalu niin kehitystiimille kuin koko yrityksellekin.
Lähteet
About Us. N.d. Material UI:n verkkosivut. Viitattu 17.9.2020. https://material-ui.com/company/about/
Agile 101. N.d. Agile Allieancen verkkosivut. Viitattu 23.10.2020. https://www.agileal-liance.org/agile101/
Agile practice guide. 2017. Newtown Square, Pennsylvania: Project Management In-stitute.
Beck, K., Beedle, M., van Bennekum, A., Cockburn, A., Cunningham, W., Fowler, M., Grenning, J., Highsmith, J., Hunt, A., Jeffries, R., Kern, J., Marick, B., Martin, RC., Mellor, S., Schwaber, K., Sutherland, J. & Thomas, D. 2001. The Agile Manifesto. Vii-tattu 23.10.2020. http://agilemanifesto.org/
Beck, K., Beedle, M., van Bennekum, A., Cockburn, A., Cunningham, W., Fowler, M., Grenning, J., Highsmith, J., Hunt, A., Jeffries, R., Kern, J., Marick, B., Martin, RC., Mellor, S., Schwaber, K., Sutherland, J. & Thomas, D. 2001. Pronciples behind the Ag-ile Manifesto. Viitattu 23.10.2020. http://agAg-ilemanifesto.org/principles.html
Cinia yrityksenä. N.d. Cinia Oy:n verkkosivut. Viitattu 4.9.2020. www.cinia.fi/yri-tys.html
Design System: What is it and who is it for?. 2019. Artikkeli Medium -verkkosivus-tolla. Viitattu 23.10.2020. https://medium.com/agileactors/design-system-what-is-it-and-who-is-it-for-9a536e2e8c23
Hills, C. 2018. Design systems and Agility. Artikkeli Medium -vrkkosivustolla. Viitattu 23.10.2020. https://medium.com/interactive-mind/design-systems-and-agility-part-1-of-2-b96c188acfca
Iddo, D. 2019. Agile Development. Moodah-POS -IT-projektin blogi Medium -verk-kosivustolla. Viitattu 23.10.2020. https://medium.com/moodah-pos/agile-develop-ment-95cad3573abf
Kholmatova, A. 2017. Design systems - A practical guide to creating design languages for digital products. Freiburg, Germany: Smashing media.
Levitt, D. N.d. Agile UX: How to Incorporate UX and Product Design into Agile. Artik-keli Toptal.com -verkkosivuilla. Viitattu 2.11.2020. https://www.toptal.com/product-managers/agile/agile-ux-design-explained
Llobera, L. 2020. Getting started. Create-react-appin tekninen dokumentaatio. Vii-tattu 25.9.2020. https://create-react-app.dev/docs/getting-started/
Miinalainen, M. 2020. Cinia Agile Cookbook. Cinia Oy:n intranet. Vain sisäiseen käyt-töön. Viitattu 4.11.2020.
Nielsen, J. 2012. Usability 101: Introduction to Usability. Artikkeli Nielsen Norman Groupin verkkosivuilla. Viitattu 4.9.2020. https://www.nngroup.com/articles/usabi-lity-101-introduction-to-usability/
Opinnäytetyön ohjaajan käsikirja: Soveltavasta tutkimuksesta. N.d. Jyväskylän am-mattikorkeakoulun oppimateriaalit opinnäyteyön ohjaajalle. Viitattu 11.9.2020.
https://oppimateriaalit.jamk.fi/yamk-kasikirja/soveltavat-tutkimusmenetelmat/
Pressman, R. & Maxim, B. 2014. Software Engineering: A Practitioner's Approach.
New York: McGraw-Hill Education.
Rehkopf, M. N.d. Sprints. Artikkeli Atlassianin Agile-oppaan verkkosivuilla. Viitattu 23.10.2020. https://www.atlassian.com/agile/scrum/sprints
Sengupta, A. 2019. Importance and Strategy of a Design System. Artikkeli Wiprodigi-talin verkkosivuilla. Viitattu 9.10.2020. https://wiprodigital.com/2019/06/26/the-im-portance-and-strategy-of-a-design-system/
Vaisala’s new Design System. 2019. Artikkeli Eficoden verkkosivuilla. Vii-tattu 2.11.2020. https://www.eficode.com/cases/vaisala
Vesselov, S. & Davis, T. 2019. Building Design Systems: Unify User Experiences through a Shared Design Language. Berkeley, CA: Apress.