Crearea de tablouri de bord live cu Airtable și React
Publicat: 2022-03-11Indiferent dacă o companie este o întreprindere mare sau un startup în devenire, colectarea datelor de la utilizatori și clienți și raportarea sau vizualizarea acestor date este crucială pentru afacere.
Am lucrat recent cu un startup de telemedicină cu sediul în Brazilia. Misiunea sa este de a oferi îngrijire și monitorizare la distanță prin conectarea pacienților cu profesioniștii medicali și antrenorii din domeniul sănătății. Nevoia principală a fost de a crea o interfață pentru antrenori și profesioniști din domeniul sănătății pentru a revizui cu ușurință informațiile unui pacient și cele mai importante valori legate de situația lor particulară: un tablou de bord.
Introduceți Typeform și Airtable.
Typeform
Typeform este unul dintre instrumentele de colectare a datelor care permite utilizatorilor care completează un sondaj experiențe web receptive. De asemenea, vine cu câteva funcții care fac sondajele mai inteligente, mai ales atunci când sunt combinate:
- Salturi logice
- Câmpuri Ascunse
Sondajele pot fi partajate prin adrese URL care pot fi pre-însămânțate cu valori pentru câmpurile ascunse, care pot fi apoi folosite pentru a implementa salturi logice și pentru a modifica comportamentul sondajului pentru utilizatorul cu linkul.
Utilizări pentru masa de aerisire
Airtable este un hibrid foaie de calcul-bază de date și o platformă cloud colaborativă. Concentrarea sa pe funcționalitatea punct și clic înseamnă că utilizatorii netehnici o pot configura fără codare. Airtable are o multitudine de cazuri de utilizare în orice afacere sau proiect.
Puteți folosi o bază Airtable pentru:
- CRM (Managementul relațiilor cu clienții)
- HRIS (Sistem Informațional pentru Resurse Umane)
- Management de proiect
- Planificarea conținutului
- Planificarea evenimentului
- Feedback utilizator
Există mai multe cazuri potențiale de utilizare. Puteți explora studii de caz Airtable aici.
Dacă nu sunteți familiarizat cu Airtable, modelul conceptual de date se descompune astfel:
- Spațiu de lucru - Compus din Baze
- Baza - Compusă din Mese
- Tabel - Compus din Câmpuri (coloane) și rânduri
- Vizualizare - O perspectivă asupra datelor din tabel cu filtre opționale și câmpuri reduse
- Câmp - O coloană a unui tabel cu un tip de câmp; consultați aici pentru mai multe informații despre Tipurile de câmpuri
În afară de furnizarea unei baze de date găzduite în cloud cu funcții familiare de foi de calcul, iată câteva dintre motivele pentru care platforma este atât de puternică:
Pentru utilizatorii non-tehnici, Airtable oferă:
- O interfață front-end ușor de utilizat
- Automatizări care pot fi create cu configurarea punct-and-click pentru a trimite e-mailuri, a procesa rânduri de date, a programa întâlniri în calendare și multe altele
- Mai multe tipuri de vizualizări care permit echipelor să colaboreze pe aceeași bază și tabele
- Aplicații Airtable care pot fi instalate de pe piață pentru a supraîncărca o bază
Pentru dezvoltatori, Airtable oferă:
- Un API back-end bine documentat
- Un mediu de scripting care permite dezvoltatorilor să automatizeze acțiunile dintr-o bază
- Automatizări care pot declanșa și scripturi personalizate dezvoltate care rulează în mediul Airtable, extinzând capacitățile automatizărilor
Puteți afla mai multe despre Airtable aici.
Noțiuni introductive: Typeform la Airtable
Sondajele Typeform au fost deja configurate de client, iar următorul pas a fost planificarea modului în care aceste date vor ajunge în Airtable și apoi vor fi transformate într-un tablou de bord. Există multe întrebări de luat în considerare atunci când creați tablouri de bord deasupra oricărei baze de date: Cum ar trebui să structurem datele? Ce date vor trebui prelucrate înainte de vizualizare? Ar trebui să sincronizăm baza cu Google Sheets și să folosim Google Data Studio? Ar trebui să exportăm și să găsim un alt instrument terță parte?
Din fericire pentru dezvoltatori, Airtable nu numai că oferă automatizări și scripturi pentru a gestiona pașii de procesare a datelor, dar a făcut posibilă și construirea de aplicații și interfețe personalizate deasupra unei baze Airtable cu aplicații Airtable.
Aplicații personalizate în Airtable
Aplicațiile personalizate din Airtable există de când SDK-ul Airtable Blocks a fost lansat la începutul anului 2018 și au fost redenumite recent în Apps. Lansarea Blocks a fost uriașă, deoarece a însemnat că creatorii au acum capacitatea de a dezvolta, așa cum spune Airtable, „Un kit Lego infinit recombinabil”.
Mai recent, odată cu modificarea aplicațiilor, Airtable Marketplace a făcut posibilă partajarea publică a aplicațiilor.
Aplicațiile Airtable oferă companiilor un kit Lego infinit recombinabil pe care îl pot adapta nevoilor lor.
Pentru a construi o aplicație personalizată în Airtable, un dezvoltator JavaScript trebuie să știe cum să folosească React, una dintre cele mai populare biblioteci JavaScript pentru construirea de interfețe cu utilizatorul. Airtable oferă o bibliotecă de componente de componente și cârlige funcționale React, care sunt de mare ajutor pentru construirea rapidă a unei interfețe de utilizare consistente și pentru a determina modul în care veți gestiona starea aplicației și a componentelor acesteia.
Consultați articolul Noțiuni introductive din Airtable pentru mai multe informații și Airtable pe GitHub pentru exemple de aplicații.
Cerințe pentru tabloul de bord Airtable
După revizuirea machetelor tabloului de bord cu echipa client, tipurile de date care trebuiau utilizate au fost clare. Am avea nevoie de o serie de componente de tablou de bord care să fie afișate ca text pe tabloul de bord și diagrame cu diferite valori care ar putea fi urmărite în timp.
Antrenorii și profesioniștii medicali trebuiau să poată construi un tablou de bord personalizat pentru fiecare pacient, așa că aveam nevoie de o modalitate flexibilă de a adăuga și elimina diagrame. Alte date statice referitoare la fiecare pacient vor fi afișate indiferent de pacientul selectat.
În acest caz, secțiunile tabloului de bord s-au redus la:
- Informații generale - Numele pacientului, e-mail, număr de telefon, preferințe de contact, data nașterii, vârstă
- Obiective - Obiectivele pe care pacientul le are pe baza rezultatelor sondajului
- Unele statistici - IMC, înălțime și greutate
- Utilizarea medicamentelor - Listarea tuturor medicamentelor prescrise deja utilizate de un pacient
- Istoric familial de afecțiuni - util în diagnosticarea anumitor afecțiuni
- Diagrame - O secțiune în care utilizatorul tabloului de bord Airtable ar putea adăuga o diagramă și configura ce măsură va vizualiza în timp
O modalitate de a aborda toate secțiunile, cu excepția diagramelor, ar fi să codificați toate coloanele pentru obiective, utilizarea medicamentelor și istoricul familiei în tabloul de bord. Cu toate acestea, acest lucru nu ar permite echipei client să adauge noi întrebări la un sondaj Typeform și nici să adauge o nouă coloană la un tabel Airtable pentru a prezenta acele date pe tabloul de bord fără ca un dezvoltator să actualizeze aplicația personalizată.
O soluție mai elegantă și mai extensibilă la această provocare a fost găsirea unei modalități de a eticheta coloanele ca fiind relevante pentru o anumită secțiune a tabloului de bord și de a prelua acele coloane folosind metadatele pe care Airtable le expune atunci când se utilizează modelele Table și Field.
Acest lucru a fost realizat folosind Descrierile câmpurilor ca loc pentru a eticheta o coloană din Tabel ca fiind relevantă pentru o secțiune de tablou de bord care urmează să fie afișată utilizatorului. Apoi, ne-am putea asigura că numai cei cu rolul de Creator (administratorii) pentru bază au capacitatea de a modifica aceste descrieri de câmpuri pentru a modifica ceea ce apare pe tabloul de bord. Pentru a ilustra această soluție, ne vom concentra mai ales pe elementele din Informații generale și pe modul de prezentare a diagramelor.
Crearea unui sistem #TAG#
Având în vedere secțiunile tabloului de bord, era logic să se creeze etichete reutilizabile pentru unele secțiuni și etichete specifice pentru anumite coloane. Pentru elemente precum numele pacientului, e-mailul și numărul de telefon, #NAME# , #EMAIL# și, respectiv, #PHONE# au fost adăugate la descrierea fiecărui câmp. Acest lucru ar permite ca aceste informații să fie preluate prin metadatele Tabelului, astfel:
const name = table ? table.fields.filter(field => field.description?.includes("#NAME#"))Pentru zonele tabloului de bord care ar trebui să se deseneze din multe coloane etichetate, am avea următoarele etichete pentru fiecare secțiune a tabloului de bord:
- OBJ - Obiective
- FAM - Istoricul familiei
- MED - Utilizarea medicamentelor
- CAN - Istoric familial specific cancerului
- CHART - Orice coloană care ar trebui să fie sursă pentru adăugarea de diagrame; trebuie să fie o cantitate
În plus, era important să se separe numele unei coloane dintr-un tabel de eticheta pe care o va primi pe tabloul de bord, astfel încât orice a primit un #TAG# ar avea, de asemenea, capacitatea de a primi două etichete #LABEL# în descrierea câmpului său . O descriere a câmpului ar arăta astfel:
În cazul în care etichetele #LABEL# lipsesc, vom afișa numele coloanei din Tabel.
Putem analiza setul de etichete din descriere cu o funcție simplă ca aceasta după ce recuperăm câmpul cu exemplul de cod anterior:
// utils.js export const setLabel = (field, labelTag = "#LABEL#") => { const labelTags = (field.description?.match(new RegExp(labelTag, "g")) || []).length; let label; if (labelTags === 2) label = field.description?.split(`${labelTag}`)[1]; if (!label || label?.trim() === '') label = field.name; return {...field, label, name: field.name, description: field.description}; } Cu acest sistem #TAG# , realizăm trei lucruri principale:
- Numele coloanelor (câmpurile) din Tabel pot fi modificate după cum doriți.
- Etichetele pentru datele din tabloul de bord pot fi diferite de numele coloanelor.
- Secțiunile tabloului de bord pentru Obiective, Utilizarea medicamentelor, Istoricul familial și Diagramele pot fi actualizate de echipa client fără a atinge o linie de cod.
Stare persistentă în Airtable
În React, folosim starea și o transmitem componentelor ca elemente de recuzită pentru a reda acea componentă dacă starea ei se schimbă. În mod normal, acest lucru este legat de un apel API care alimentează o componentă a tabloului de bord, dar în Airtable avem deja toate datele și pur și simplu trebuie să filtram ceea ce afișăm în funcție de pacientul pe care îl vedem. În plus, dacă folosim stare, nu va persista datele după o reîmprospătare în tabloul de bord în sine.
Deci, cum putem persista o valoare trecută de reîmprospătare pentru a păstra un tablou de bord filtrat? Din fericire, Airtable oferă un cârlig pentru acest lucru numit useGlobalConfig în care menține un magazin cheie-valoare pentru instalarea unei aplicații pe un tablou de bord. Trebuie pur și simplu să implementăm logica de recuperare a valorilor din acest magazin cheie-valoare atunci când aplicația se încarcă pentru a alimenta componentele tabloului de bord.
Ceea ce este și mai util despre utilizarea cârligului useGlobalConfig este că, atunci când valorile sale sunt setate, componenta tabloului de bord și componentele sale secundare se redau din nou, astfel încât să puteți utiliza Global Config așa cum ați folosi o variabilă de stare într-o implementare tipică React.
Prezentarea diagramelor
Airtable oferă exemple de diagrame cu aplicația sa Simple Chart, care utilizează React Charts, un înveliș React pe Chart.js (chart-ception).

În aplicația Simple Chart, avem o diagramă pentru întreaga aplicație, dar în aplicația noastră Dashboard, avem nevoie de capacitatea utilizatorului de a adăuga și de a elimina propriile diagrame din propriul tablou de bord. Mai mult, în discuția cu echipa client, se pare că anumite metrici ar fi mai bine vizualizate pe aceeași diagramă (cum ar fi citirile pentru tensiunea arterială diastolică și sistolica).
Prin aceasta avem de abordat următoarele elemente:
- Stare persistentă pentru diagrama fiecărui utilizator (sau chiar mai bine folosind Global Config)
- Permite mai multe valori pe diagramă
Aici este utilă puterea Global Config, deoarece putem folosi magazinul cheie-valoare pentru a menține valorile selectate și orice altceva despre lista noastră de diagrame. Pe măsură ce configurăm o diagramă în UI, componenta diagramă în sine va fi redată din nou din cauza actualizărilor la configurația globală. Pentru secțiunea de diagrame a tabloului de bord, iată o esențială cu componentele pentru referință, concentrându-se pe tabloul de bord charts.js și single chart.js.
Tabelul transmis fiecărei diagrame este ceea ce este folosit pentru metadatele sale pentru a găsi câmpurile, în timp ce înregistrările transmise au fost deja filtrate de pacientul selectat la componenta tabloului de bord de nivel superior care importă dashboard_charts/index.js .
Rețineți că câmpurile enumerate ca opțiuni în meniul drop-down pentru o diagramă sunt extrase folosind eticheta #CHART# pe care am menționat-o mai înainte, cu această linie într-un cârlig useEffect :
// single_chart/index.js … useEffect(() => { (async () => { ... if (table) { const tempFieldOptions = table.fields.filter(field => field.description?.includes('#CHART#')).map(field => { return { ...setLabel(field), value: field.id } }); setFieldSelectOptions([...tempFieldOptions]); } })(); }, [table, records, fields]); ... Codul de mai sus arată modul în care funcția setLabel menționată mai devreme este utilizată cu #TAG# pentru a adăuga orice furnizat în etichetele #LABEL# și pentru a-l afișa pentru opțiunea din meniul drop-down.
Componenta noastră diagramă profită de capabilitățile multi-axe oferite de Chart.js, care este afișată cu React Charts. Tocmai l-am extins prin interfața de utilizare cu capacitatea utilizatorului de a adăuga un set de date și un tip de diagramă (linie sau bară).
Cheia pentru utilizarea Global Config, în acest caz, este să știți că fiecare cheie poate conține doar un șir | boolean | număr | nul | GlobalConfigArray | GlobalConfigObject (consultați referința Global Config Value).
Avem următoarele elemente de menținut pe diagramă:
- chartTitle care este generat automat și poate fi redenumit de utilizator
- matrice de câmpuri în care fiecare articol are:
- câmp ca fieldId din Airtable
- chartOption ca o linie | bară, după cum indică documentele Chart.js
- culoare ca culoarea Airtable din colorUtils
- hex ca cod hexadecimal referitor la culoarea Airtable
Pentru a gestiona acest lucru, mi s-a părut cel mai convenabil să string aceste date ca obiect în loc să setați cheile și valorile Global Config până la capăt. Vedeți exemplul de mai jos (globalConfig.json în esență), care include valori Global Config pentru a filtra înregistrările de către pacient și câteva variabile asociate utilizate pentru a susține o componentă de filtrare typeahead (mulțumită react-bootstrap-typeahead):
{ "xCharts": { "chart-1605425876029": "{\"fields\":[{\"field\":\"fldxLfpjdmYeDOhXT\",\"chartOption\":\"line\",\"color\":\"blueBright\",\"hex\":\"#2d7ff9\"},{\"field\":\"fldqwG8iFazZD5CLH\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425876288": "{\"fields\":[{\"field\":\"fldGJZIdRlq3V3cKu\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425876615": "{\"fields\":[{\"field\":\"fld1AnNcfvXm8DiNs\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"},{\"field\":\"fldryX5N6vUYWbdzy\",\"chartOption\":\"line\",\"color\":\"blueDark1\",\"hex\":\"#2750ae\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425994036": "{\"fields\":[{\"field\":\"fld9ak8Ja6DPweMdJ\",\"chartOption\":\"line\",\"color\":\"blueLight2\",\"hex\":\"#cfdfff\"},{\"field\":\"fldxVgXdZSECMVEj6\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:39:54 AM\"}", "chart-1605430015978": "{\"fields\":[{\"field\":\"fldwdMJkmEGFFSqMy\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"},{\"field\":\"fldqwG8iFazZD5CLH\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"}],\"chartTitle\":\"New Chart\"}", "chart-1605430916029": "{\"fields\":[{\"field\":\"fldCuf3I2V027YAWL\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"},{\"field\":\"fldBJjtRkWUTuUf60\",\"chartOption\":\"line\",\"color\":\"blueDark1\",\"hex\":\"#2750ae\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 4:01:56 AM\"}", "chart-1605431704374": "{\"fields\":[{\"field\":\"fld7oBtl3iiHNHqoJ\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 4:15:04 AM\"}" }, "xPatientEmail": "[email protected]", "xTypeaheadValue": "Elle Gold ([email protected])", "xSelectedValue": "[{\"label\":\"Elle Gold ([email protected])\",\"id\":\"[email protected]\",\"name\":\"Elle Gold\",\"email\":\"[email protected]\"}]" }Notă: Toate datele conținute mai sus și datele incluse în animațiile de mai jos nu sunt date reale ale pacientului.
Iată o privire asupra rezultatului final:
Dar Typeahead?
Pentru a filtra după pacient, aveam nevoie de o modalitate de a selecta un pacient și apoi de a filtra înregistrările pe baza acestui pacient. În această secțiune, vom analiza modul în care a fost realizat acest lucru.
Pentru typeahead, react-bootstrap-typeahead a fost o alegere ușoară, deoarece singurii pași rămasi au fost pregătirea opțiunilor pentru typeahead, amestecarea acesteia cu o intrare Airtable pentru stilarea și încărcarea bootstrap-ului și alte câteva stiluri pentru meniul nostru. Plasarea componentelor din bibliotecile de componente preferate într-o aplicație Airtable nu este la fel de simplă ca în dezvoltarea web tipică React; cu toate acestea, există doar câțiva pași suplimentari pentru ca totul să arate așa cum v-ați aștepta.
Iată rezultatul final:
Pentru a reda intrarea Airtable și pentru a menține toate stilurile noastre consistente, react-bootstrap-typeahead vine cu o prop pentru renderInput. Vedeți mai multe despre cum să modificați redarea componentei aici.
Pentru stilurile bootstrap și pentru a suprascrie elementele noastre de meniu, au fost utilizate următoarele două utilitare din Airtable:
- loadCSSFromString
- loadCSSFromURLAsync
Vedeți frontend.js în general pentru un extras al implementării typeahead.
Această linie a fost folosită pentru a încărca bootstrap la nivel global:
// frontend/index.js loadCSSFromURLAsync('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'); Veți observa o logică adăugată pentru lucruri precum gestionarea modificărilor de stil la trecerea cu mouse-ul sau restyling-urile ( <a></a> ) pentru a obține aspectul și senzația de bootstrap familiară. Aceasta include, de asemenea, gestionarea setării valorilor de configurare globală pentru tipul înainte și filtrarea înregistrărilor, astfel încât, dacă un utilizator își părăsește tabloul de bord, își reîmprospătează pagina sau dorește să partajeze acest tablou cu alții, aplicația păstrează pacientul selectat în Tabloul de bord. App. Acest lucru permite, de asemenea, utilizatorilor să instaleze mai multe copii ale aceleiași aplicații una lângă alta în același tablou de bord Airtable cu diferiți pacienți selectați sau cu diagrame diferite.
Rețineți că un tablou de bord în Airtable este disponibil și pentru toți utilizatorii bazei, astfel încât aceste instalări de aplicații personalizate pe un tablou de bord vor fi filtrate pentru aceiași pacienți și diagrame, indiferent de utilizatorii care se uită la tabloul de bord în același timp.
Să recapitulăm ceea ce am acoperit până acum:
- Airtable permite atât utilizatorilor non-tehnici, cât și utilizatorilor tehnici să colaboreze în Airtable.
- Typeform vine cu o integrare Airtable care permite utilizatorilor non-tehnici să mapeze rezultatele Typeform la Airtable.
- Aplicațiile Airtable oferă o modalitate puternică de a-și supraîncărca baza Airtable, fie că selectează de pe piață sau creează o aplicație personalizată.
- Dezvoltatorii pot extinde Airtable rapid în aproape orice mod imaginabil cu aceste aplicații. Exemplul nostru de mai sus a durat doar trei săptămâni pentru a proiecta și implementa (cu ajutorul enorm de la bibliotecile existente, desigur).
- Un sistem
#TAG#poate fi folosit pentru a modifica tabloul de bord fără a necesita modificarea codului de către dezvoltatori. Există cazuri de utilizare mai bune și mai rele pentru acest lucru. Asigurați-vă că limitați permisiunile la rolul de Creator dacă utilizați această strategie. - Utilizarea Global Config permite dezvoltatorilor să persiste datele într-o instalare a aplicației. Combinați acest lucru în strategia dvs. de management de stat pentru a genera date pentru componentele dvs.
- Nu vă așteptați să trageți și să plasați componente din alte biblioteci și proiecte direct în aplicația dvs. Airtable. Stilurile pot fi încărcate folosind aplicațiile
loadCSSFromStringșiloadCSSFromURLAsyncfurnizate de Airtable.
Pregătire pentru viitor
Utilizați un middleware mai sofisticat
Cu Typeform și Airtable, este ușor și rentabil să configurați maparea întrebărilor pe coloane.
Cu toate acestea, există un mare dezavantaj: dacă aveți un sondaj de peste 100 de întrebări mapate la Airtable și trebuie să modificați o mapare, trebuie să ștergeți întreaga mapare și să începeți din nou. În mod clar, acest lucru nu este ideal, dar pentru o integrare gratuită, putem face față acestui lucru.
Alte opțiuni ar fi ca o integrare Zapier (sau similară) să gestioneze datele între Typeform și Airtable. Apoi, puteți modifica maparea oricărei întrebări la orice coloană fără a începe de la zero. Acest lucru ar avea propriile sale considerații de cost de luat în considerare, de asemenea.
Sperăm că unele dintre lecțiile învățate și comunicate aici îi vor ajuta pe alții care doresc să construiască soluții cu Airtable.
În cele din urmă, puteți verifica esenta cu fișierele discutate în acest articol.
