Thibault Milan Get In Touch

Get In Touch

Prefer using email? Say hi at hello@thibaultmilan.com

#nocode Thursday: Simple contact tracing

  For/At #nocode Thursday  This event is now finished Ce talk est en Français

Tout les jeudis, j'organise un stream sur Twitch où j'explore une des idées ci-dessous et construit, à l'aide d'outil no-code ou low-code une solution. C'est l'occasion de vous faire découvrir ou re-découvrir des outils simples et intuitifs pour démarrer vos projets, mais aussi d'avoir des conversations franches à propos des limites qui peuvent exister.


Pour cette session, on va continuer avec l'app de 🦠 contact tracing que l'on a conçue la semaine dernière et on va explorer comment ajouter un peu de logique, d'automatisation, à l'aide de plusieurs outils.

  • Zapier, plateforme vous permettant d'executer des "actions" à la suite de "déclencheurs"
  • Google App Script, qui permet en écrivant quelques lignes de code de manipuler rapidement notre feuille Google Spreadsheet

Vous l'aurez compris, ici nous mettrons en parallèle une approche purement no-code avec une approche low-code.

📱L'app de la semaine dernière est dispo ici si vous voulez jouer avec en attendant-

La feuille Google Spreadsheet est dispo ici

Ici vous trouverez le "zap" utilisé par l'app pour supprimer automatiquement les données au bout de 21 jours. Vous pouvez le copier mais il vous faudra un compte payant (même le plus petit) pour utiliser le multi-step.

Et le code pour le Google App Script est le suivant (avec en 1er mon petit fichier utilitaire).

/**
* Activate the filtering on the active sheet
* @method setFilter
* @param {Number} columnId Column number you want to filter out (start at 0)
* @param {Array} filteredValues Array of value to filter out
*/
function setFilter(columnId,filteredValues) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var filterSettings = {};
// The range of data on which you want to apply the filter.
// optional arguments: startRowIndex, startColumnIndex, endRowIndex, endColumnIndex
filterSettings.range = {
sheetId: ss.getActiveSheet().getSheetId()
};
// Criteria for showing/hiding rows in a filter
// https://developers.google.com/sheets/api/reference/rest/v4/FilterCriteria
filterSettings.criteria = {};
var columnIndex = columnId;
filterSettings['criteria'][columnIndex] = {
'hiddenValues': filteredValues
};
var request = {
"setBasicFilter": {
"filter": filterSettings
}
};
Sheets.Spreadsheets.batchUpdate({'requests': [request]}, ss.getId());
}
/**
* Reset the filtering on the active sheet
* @method resetFilter
*/
function resetFilter(){
let ss = SpreadsheetApp.getActiveSpreadsheet();
let ssId = ss.getId();
let dataSheet = ss.getActiveSheet();
let lastRow = dataSheet.getLastRow();
let lastColumn = dataSheet.getLastColumn();
let sheetId = dataSheet.getSheetId();
var filterSettings = {
"range": {
"sheetId": sheetId,
"startRowIndex": 0,
"endRowIndex": lastRow,
"startColumnIndex": 0,
"endColumnIndex": lastColumn
}
};
var requests = [{
"setBasicFilter": {
"filter": filterSettings
}
}];
Sheets.Spreadsheets.batchUpdate({'requests': requests}, ssId);
}
/**
* Clear / remove all filters
* @method clearFilter
*/
function clearFilter() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssId = ss.getId();
var sheetId = ss.getActiveSheet().getSheetId();
var requests = [{
"clearBasicFilter": {
"sheetId": sheetId
}
}];
Sheets.Spreadsheets.batchUpdate({'requests': requests}, ssId);
}
/**
* Get all the filtered row in an array
* @method getIndexesOfFilteredRows
*/
function getIndexesOfFilteredRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssId = ss.getId();
var sheetId = ss.getActiveSheet().getSheetId();
var hiddenRows = [];
// limit what's returned from the API
var fields = "sheets(data(rowMetadata(hiddenByFilter)),properties/sheetId)";
var sheets = Sheets.Spreadsheets.get(ssId, {fields: fields}).sheets;
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].properties.sheetId == sheetId) {
var data = sheets[i].data;
var rows = data[0].rowMetadata;
for (var j = 0; j < rows.length; j++) {
if (rows[j].hiddenByFilter) hiddenRows.push(j);
}
}
}
return hiddenRows;
}
view raw _filtering.gs hosted with ❤ by GitHub
function clearChecking() {
// On récupère la feuille Check-in
let checkingSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('🕰 Check-In');
// On selectionne cette feuille
SpreadsheetApp.setActiveSheet(checkingSheet);
// On utilise la fonction setFilter pour filtrer toute les valeurs qui sont TRUE
// En conséquence on ne verra plus que les FALSE et null
setFilter(3, ['TRUE']);
// On récypère toutes le n° des lignes qui ont été filtrées (donc = TRUE)
let checkingRows = getIndexesOfFilteredRows();
// On supprime le filtre car on en a plus besoin
clearFilter();
// S'il n'y a rien à supprimer on sort.
if (checkingRows.length == 0) return null;
// On affiche la tableau de ligne dans la console.
// On voit qu'on a une progression croissante 1-2-3-4
Logger.log("Lignes à supprimer %s", checkingRows);
// On inverse les valeurs pour avoir un ordre décroissant 4-3-2-1
checkingRow = checkingRows.reverse();
// On itère sur chaque élément en commensant par la dernière ligne
for (item in checkingRows) {
// On corrige la valeur de la ligne
let row = checkingRows[item] + 1;
// On log dans la console la ligne qu'on va supprimer
Logger.log("Supression de la ligne %s", row);
// On supprime la ligne
checkingSheet.deleteRow(row);
}
}
view raw Code.gs hosted with ❤ by GitHub

Hello time-travellers

The event is finished now. Thanks for your interest.
You can take a look to all my talks or contact me if you have any questions / inquiries.


Hey, I’m Thibault, nice to meet you!

I’m a service and UX designer with over 10 years of experience under my belt.

My skills include product design, interactive design, aesthetic art direction, prototyping, mobile design, branding, front-end development and team leadership. I’m interested in making, creative thinking, unusual typography, traveling and simplistic UX solutions. I may also have a soft spot for CSS tricks.

I’d love to learn about your company and see how I can help, feel free to send me an email!

Get in Touch