Below, a color palette get using block css (u-color-nn) in a card template. Goal was to display scorecards with differents look and feels. CSS class has been set at the Card CSS classes level in the Attributes tab

For comparaison, the same palette with VITA Slate theme style. (Other VITA styles render colors identically)

J’ai eu l’occasion de faire une présentation sur le Low-Code et j’en ai profité pour faire auparavant un tour de l’offre des produits.

J’avais deux cas d’usage :

  • Publication d’un catalogue d’œuvres d’arts avec recherche et modification (CRUD classique)
  • Mini-Service après-ventes avec saisie des incidents via un formulaire et suivi des tickets sur une interface adaptée à un mobile

Dans la catégorie « Low-Code » Je connaissais essentiellement Oracle APEX

Je me suis plongé dans les autres produits suivants :

  • Microsoft Power Apps
  • Google Appsheet
  • OutSystems
  • Salesforce Lightning
  • Zoho Creator
  • Bubble
  • Glide
  • Zapier
  • Integromat
  • Airtable

Ce qui suit traduit mon ressenti. Ce n’est absolument pas un jugement sur les produits car ce ne serait pas leur rendre justice sans avoir été formé correctement au préalable.

Pour chacun, j’ai ouvert un compte trial, et cela n’a présenté aucune difficulté. A aucun moment je n’ai été obligé de présenter ma carte de crédit.

Microsoft PowerApps

PowerApps est parfaitement intégré dans l’écosystème Microsoft, évidemment.

Hyper complet et précis. Du bon ouvrage comme Microsoft sait faire. Des connecteurs à gogo Pas très intuitif, cependant.

Google Appsheet

Nouvelle mouture de leur outil de dev. Très facile d’emploi. On obtient un résultat de très bonne qualité sur mobile avec une intégration bluffante avec Maps ou une lecture intelligent de badge. Très bonne illustration du concept de no-code. J’apprécie énormément ce produit.

OutSystems

Pure player du low-code. Solide. Approche avec un IDE en local+ déploiement. Conçu à l’origine à Lisbonne. Du travail solide de « maçon ».

Salesforce Lightening

On rentre dans un monde préconstruit avec des objets métier prêts à l’emploi. Services de type CRM, vente, Field Service etc. et possibilité de créer ses propres applis en utilisant le même framework. C’est très impressionnant. Grand Clickodrome ! Modèle d’habilitation remarquable. L’écosystème est très stimulant car il est fait de telle manière qu’on peut gagner des points en augmentant son apprentissage.

Zoho Creator

Pas mal. J’ai survolé le produit.

Bubble

Typique du low code. Je n’ai fait que survoler le produit

Glide

Petit coup de cœur par rapport à la simplicité d’emploi et au résultat obtenu.

C’est du no-code pur. C’est le produit qui m’a fourni un catalogue d’œuvres d’art prêt à l’emploi sans que je n’ai à rien ajouter de plus. Glide a compris que certaines url contenaient des liens vers des images et il les a utilisées ainsi

Zapier

Service d’intégration. Le leader du domaine. Hyper simple à utiliser

Integromat

Service d’intégration. Sur le même domaine que Zapier. Très simple d’utilisation.

Airtable

Inclassable car il s’agit d’une sorte de mid-end qui ne s’occupe que de gérer les données dans des tableaux analogue à des sheets. Possibilité d’établir des associations entre les tableaux. On peut y ajouter des triggers qui déclencheront des actions. Google prépare un produit similaire qui s’appellera Google Table.

Le couple Airtable/Zapier est, par exemple, un bon moyen pour bâtir un backend gérant les données et les processus.

Oracle APEX

Je termine par celui que je connais le mieux. Je suis toujours épaté par le bon compromis proposé par ce produit. Le curseur est au bon endroit : Du no-code pour ceux qui veulent générer une application à partir d’un tableau Excel, par exemple, mais aussi la possibilité de construire une application plus sophistiquée, sans aucune limite.

Objet

Il est possible de manipuler des feuilles de calcul Google avec des APIs REST mais cela requiert un peu de codage pour la parsing du payload json.
— Ce POST n’est pas encore finalisé —

Normalement il est conseillé d’utiliser une API cliente selon le langage hôte (ph, python, nodejs…). Dans notre cas , PL/SQL, nous allons utiliser les appels REST natifs car il n’existe pas encore de client PL/SQL..

Pour lire une feuille Google Sheets, consulter la documentation Basic Reading: https://developers.google.com/sheets/api/samples/reading

Dans Oracle APEX, on pourrait utiliser une définition de REST Data Source mais le problème est que le parser ne reconnait pas les tableaux imbriqués dont voici un échantillon:
Exemple de payload renvoyé par l’API

{
"range": "'F2'!A2:D5",
"majorDimension": "ROWS",
"values": [
[
"test",
"4"
],
[
"test",
"3"
],
[
"test",
"2"
],
[
"zert",
"8"
]
]
}

1 error has occurred
Error during REST Data Source storage or discovery: ORA-40597: JSON path expression syntax error ('$.$.values[*]') JZN-00217: Key step contains unexpected characters at position 3
Found no data while parsing the service response.

Il faut donc se rabattre sur une approche manuelle. Celle qui est expliquée dans ce post consiste à effectuer un appel à la méthode GET dans un fonction PLSQL puis à retourner le contenu dans un pipe. Cela permet, au final, de manipuler la feuille à partir d’une requête SQL classique ou bien d’une vue.

l_clob := apex_web_service.make_rest_request(
p_url => 'https://sheets.googleapis.com/v4/spreadsheets/' || tsheet || '/values/' || trange,
p_http_method => 'GET',
p_token_url => 'https://oauth2.googleapis.com/token',
p_credential_static_id => 'GoogleSAV'
);

Pour le range, il faut remplacer les espaces éventuels dans le nom de la feuille par un signe +

ex: trange varchar2(200) := ‘Réponses+au+formulaire+4!A1:D5’;

Création optionnelle d’une vue

CREATE OR REPLACE FORCE EDITIONABLE VIEW "GOOGLE_SHEET1_V" ("C1", "C2", "C3", "C4", "C5", "C7", "C8", "C9", "C10") AS
select "C1","C2","C3","C4","C5","C7","C8","C9","C10" 
from google_pkg.get_rows('Réponses+au+formulaire+4')

Contrôle d’accès.

Comme pour la plupart des accès à des données privées de Google, il faut utiliser le protocole OAUTH2.

Celui-ci est bien expliqué dans le document de Google.

Même si on ne peut pas utiliser les sourec REST, on peut néanmoins s’appuyer sur les credentials pour alléger la partie authentification. Sans cela, il faut récupérer un code d’accès et le convertir en token.

Pour Gogle Drive, l’intégration est plus simple car les REST data source sont opérationnels.
… mais, comme il ‘agit d’une donnée privée, il faut une authentification lors de la phase de design ‘redirection vers la page Google) qui n’est pas supportée par l’assistant. Donc, il faut auparavant générer manuellement un token valide qu’on fournira en paramètre de type Header Authorization Bearer <TOKEN>. Le code pour générer ce token et decrit en annexe.

Une fois la découverte du data profile réalisée, on retire le paramètre Authorization qui devient superflu et on spécifie une autorisation basée sur un des credentials enregistrés (GoogleSAV dans notre exemple). L’emploi du paramètre p_credential_static_id dans l’appel de apex_web_service.make_rest_request est très pratique car il soulage la tâche du développeur de toute la gestion du cycle de vie du token

ANNEXES

Obtention d’un token pour tester une REST data source

Le principe consiste à :

Constituer une URL contenant les parametres :

  • response_code
  • access_type
  • redirect_url (https://xxxxxxxxxx.yyyyy.oraclecloudapps.com/ords/demo/mygoogle/token) . Cette url correspond à un module ORDS custom contenant un handler GET sur le template nommée token. Pour info, si on veut fourni un id de session qui sera retournée par Google, on ajoute le paramètre state qui contiendra ce qu’on veut bien y mettre.
  • client_id
  • Demande d’un code d’accès (dans une branch before Header d’une page afin de provoquer une redirection

Affichage d’un page d’authentification Google

Affichage optionnelle d’une page de consentement (envoyée par Google)

Redirection vers l’URL envoyée en paramètre

https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/drive
&response_type=code
&access_type=offline
&redirect_uri=
&P0_REDIRECT.
&client_id=xxxxxxxxxxxxxx.apps.googleusercontent.com

Comme la string ne peut pas depasser 255 caractères, on préenregistre l’url de redirection dans une variable globale P0_REDIRECT que l’on mentionne avec la syntaxe &P0_REDIRECT.

Conversion du code d’accès en token (cf code source du package GOOGLE_PKG en annexe)

Affichage du token pour utilisation ultérieure. La durée de vie de vie est d’une heure environ. Ce token devra être fourni dans la variable de header nommée AUTHORIZATION et devra être précédé par le mot clef Bearer suivi d’un espace.

declare
l_token varchar2(500);
l_code varchar2(500);
begin
l_code := utl_url.unescape(GOOGLE_PKG.at_get_env_parameter('code')
);
l_token := GOOGLE_PKG.get_token(l_code);
htp.p('token=' || l_token);
htp.p('scope=');
htp.p(utl_url.unescape(GOOGLE_PKG.at_get_env_parameter('scope'))
);
end;

Goal: Call a modal page from Javascript code (Dynamic Action or other context) and pass javascript values as parameters.

If the parameter value is stored in a JS variable, no need to call an Ajax process.

Just write this kid of statement:
(assuming the modal page is 50)

var pid = '123456';
var purl = "f?p=&APP_ID.:50:&APP_SESSION.:::50:P50_ID:P_ID";   
purl = purl.replace('P_ID', pid);    
apex.navigation.redirect (purl);

It’s important to do the replacement of the parameter P_ID after declaring the purl variable, because APEX will parse the purl variable before the JS code be evaluated. (otherwise, the pid parameter value is put a the very end of the generated JS code (cf below)

Dont’ enclose the P50-ID with # (ie: #P50_ID#) because that doesn’t work.

The JS code generated (before variable substitution) looks like that:

javascript:apex.navigation.dialog('/ords/r/demo/xxxxx/change-owner?p50_id=P_ID&clear=50&session=109433551444631&dialogCs=xxxxxxxxxxxxxxxxxxxxxxxxxx',{title:'Change Owner',height:'auto',width:'720',maxWidth:'960',modal:true,dialog:null},'t-Dialog-page--standard '+'',this);

Lors de la rédaction d’un article Facebook, l’ajout d’un lien vers une application Oracle APEX peut entrainer l’affichage d’un raccourci défectueux. Un examen avec le débuggeur de Facebook indique alors qu’il y a trop de redirections et que les metadata Open Graph n’ont pas pu être récupérées et ont donc été fixées par défaut.

Une solution de contournement consiste à créer un proxy dont le rôle est, soit de fournir les metadata attendues par Facebook, soit de rediriger vers l’application APEX.

On peut réaliser ce proxy sous forme de module REST sous ORDS tel que ci-dessous:

select 'text/html', '
<html><head>
<meta property="og:locale" content="fr_fr" />
<meta property="og:site_name" content="MySitename" />
<meta property="og:title" content="mytitle" />
<meta property="og:description" content="myDescription" />
<meta property="og:url" content="https://xx.oraclecloudapps.com/ords/r/APP_APEX/" />
<meta property="og:image" content="https://xxx/icon-256x256.png" />
<meta property="og:type" content="website" />' ||
decode(substr(:agent,1,19),
'facebookexternalhit',
'',
'<meta http-equiv="refresh" content="0; URL=https://xx.oraclecloudapps.com/ords/r/APP_APEX/" />'
)
||
'</head>
<body>
</body>
</html>'
from dual

L’astuce consiste à analyser le user-agent envoyé par Facebook qui est:

facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)

Si ce n’est pas Facebook, on effectue une redirection vers l’application APEX.

Lors de l’ajout du lien dans l’article FB, on précisera le endpoint de la méthode GET qu’on vient décrire à la place de l’url de l’application APEX.

 

Cette variante concerne les régions où le couvre-feu est en application.

https://gotocity.eu/deplacement-covid-19/index.html

C’est une variante du site officiel qui présente l’avantage de mémoriser les infos de profil et de déclencher automatiquement l’affichage de l’attestation sur l’appui d’un seul bouton (en supplément du téléchargement standard)
L’heure est renseignée par défaut. L’attestation est téléchargée comme dans l’application officielle. Bien vérifier le pdf, on ne sait jamais !

Ci-dessous des questions/Réponses faisant suite au web Séminaire du mardi 30 juin 2020 organisé par Oracle.


Bonjour, Je suis intéressé par la précision que Patrick voulais faire sur l’affichage des liste sur mobile.
Le composant « Interactive Report » est très riche et il est bien adapté pour un écran de type Desktop. Cependant il est plus commun de proposer, sur un mobile, une liste simplifiée évitant le recours à du scrolling latéral. Il vaut ainsi mieux utiliser un autre type de liste qui s’appelle « List view » qui n’affiche la valeur que de quelques colonnes.

Au niveau implémentation, on peut :

  1. Soit installer les deux composants sur la même page et le rendu de l’un ou de l’autre sera sous le contrôle d’une simple classe de style.
    cf https://apex.oracle.com/pls/apex/apex_pm/r/ut/responsive-utilities
    classes : hidden-xxs-down et hidden-xs-up.
    C’est la « magie » du framework Bootstrap qui permet cet affichage conditionnel.
  1. Soit créer deux pages différentes avec dans chacune d’elles le composant adapté, installer un code javascript de détection de type de périphérique et router la demande de liste vers l’une ou l’autre des deux pages.

De façon plus générale, voici quelques liens utiles pour le développement destiné à des mobiles:
cf les patterns APEX pour les mobiles
Cf deux demos de Shakeeb Rahman, Product Manager APEX, autour d’APEX et des mobiles

Bonjour, quel fonctionnement en mode déconnecté ?
Ce mode n’est pas prévu en standard dans le produit APEX, mais cela est possible.
Il faut avoir recours à l’emploi du framework PWA qui permet de mettre en place un fonctionnement en mode déconnecté … au prix, il est vrai d’un peu (!) de programmation en Javascript.

Cf le très bon post de Vincent Morneau (Insum) sur le sujet: http://vmorneau.me/apex-pwa/

Comment dois-je faire pour développer des applications présentes dans une base de données autres que Oracle?
La société www.troiso.fr a évalué et documenté l’emploi d’un passerelle ODBC (Heterogeneous Services inclus dans le SGBD Oracle) pour se connecter à des données présentes dans une base PostgreSQL, ainsi que d’autres.
Sinon, il faut songer à exposer les données via des Web Services (REST ou SOAP) et les consommer dans APEX.

Est il possible de travailler avec des workflows d’approbation (du style BPM) ?
Oui, on peut déclencher des Workflows en effectuant un appel via un WebService (REST ou SOAP).
Si c’est Oracle

On peut également, depuis un Workflow externe, rentrer dans une application APEX dans une page spécifique avec le pre-positionnement d’un contexte. (deep linking).

Et il est bien sur possible d’appeler un service REST manipulant des données gérées avec une application APEX depuis un outil BPMN. Voir cet exemple avec Oracle PCS. Dans ce cas, il faudra developper un module REST soit dans l’interface d’Oracle APEX, soit via Sql Developer.

Par ailleurs, même s’il n’existe pas de capacité de workflow dans APEX, il existe des expérimentations intéressantes de couplage avec un framework open source de type BPMN. cf https://apex.mt-ag.com/apex/f?p=SHOWCASE:11:0&p_lang=en (basé sur bpmn-js qui est un sous-produit open source de Camunda)

Est-ce qu’on peut créer une application qui utiliseraient des données de différentes bases de données (Plusieurs moteur, un moteur oracle, aller chercher des données dans une base SQL Serveur, d’autres dans une base My SQL) ?
oui.

La société www.troiso.fr a évalué l’emploi d’un passerelle ODBC (Heterogeneous Services inclus dans le SGBD Oracle) pour se connecter à des données présentes dans une base PostgreSQL.
Sinon, il faut songer à exposer les données via des Web Services (REST ou SOAP) et les consommer dans APEX.
Tant qu’on est en lecture, tout va bien. Si on doit coordonner une transaction sur plusieurs systèmes, le problème se corse car il faut que les systèmes candidats supportent le « two-phase commit. »

Est-ce qu’on remplacer l’url par notre nom de domaine ?
Oui. S’il s’agit d’une instance Autonomous Database (appelée aussi ATP), il faut installer un custom ORDS (uniquement à partir de la version 19.4) sur une VM de type compute afin de se substituer au module ORDS utilisé par défaut. (ce dernier n’est absolument pas modifiable. C’est une sorte de boite noire)
En général, on installe un simple tomcat avec un Apache ou un Nginx en Reverse proxy, puis on installe un certificat afin de travailler en SSL. Un Load Balancer est également disponible sur la plateforme Free Tier.
Enfin, on redirige son nom de domaine (Record de type A) vers la VM.
https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/19.4/aelig/installing-and-configuring-customer-managed-ords-autonomous-database.html#GUID-24F4D51F-0BAF-4D3B-A714-492ED02D1212

On dispose de deux VM de type Compute (micro-shape) dans l’environnement Free Tier. Donc tout va bien pour tester le concept !.

cf l’excellent blog de Dimitri Giellis

Même une base My SQL ou SQL Server, en gros autre que Oracle ?
oui pour la consommation des données.
Rappel: Oracle APEX DOIT être installé dans une base Oracle !

La société www.troiso.fr a évalué l’emploi d’un passerelle ODBC (Heterogeneous Services inclus dans le SGBD Oracle) pour se connecter à des données présentes dans une base PostgreSQL.
Sinon, il faut songer à exposer les données via des Web Services (REST ou SOAP) et les consommer dans APEX.
Tant qu’on est en lecture, tout va bien. Si on doit coordonner une transaction sur plusieurs systèmes, le problème se corse car il faut que les systèmes participants supportent le « two-phase commit. »

Patrick, c’est quoi le nom du plugin ? PWA, et le plugin carte ?
Le nom du plugin est: JK64 Report Map

Il est disponible depuis le site apex.world:

https://apex.world/ords/f?p=100:710:8140164595770::::P710_PLG_ID:COM.JK64.REPORT_GOOGLE_MAP_R1

Cf le très bon post de Vincent Morneau (Insum) sur le sujet: http://vmorneau.me/apex-pwa/

Peut on partir d’une modélisation pour faire notre appli ? Ou modéliser dans APEX ?
Dans APEX, on travaille au niveau du modèle relationnel. Pour modéliser à un niveau conceptuel, il faut utiliser des outils tiers. On pense, par exemple, à l’outil Oracle Data Modeler qui est basé sur une approche Entité/Association avec un formalisme de type Barker. (https://en.wikipedia.org/wiki/Barker%27s_notation)
Sinon, ou peut utiliser tout autre type de modélisation (objet par exemple) sachant qu’au final, il faut que cela se concrétise par un modèle relationnel sous forme d’un script SQL/DDL.

Peut-on intégrer de l’APEX dans du code PHP ou dans un CMS (ex: WordPress ou Drupal) ?
Oui en utilisant les deux approches suivantes:

Soit on consomme (depuis WordPress, Drupal …) des données gérées par une application APEX via des appels de services REST

Soit on embarque une page complète APEX (avec sa UI) dans le CMS en utilisant une iframe. Dans ce cas, il ne faut pas oublier d’autoriser le « deep linking » dans les propriétés de l’application Apex.

Possibilité de générer une application Native iOS ou Android ?
Non. Oracle APEX ne génère que des application en mode connecté ou semi-connecté (cf approche PWA), mais pas d’applications mobiles natives.

pour la création de compte free on ne trouve pas la region pour la France, il propose suisse, germany, uk ? quel region utiliser ?
Il faut utiliser la région de Francfort.

support apex free sur www.troiso.fr
Info donnée par Fred Brunet

Utilisable avec une base Mysql ?
Oracle APEX DOIT être installé dans une base Oracle, mais peut consommer des données depuis d’autres systèmes de base de données.

Voici un catalogue des produits developpés avec APEX https://www.builtwithapex.com/
Info donnée par Souleman Dembele

Y a t-il aussi un gestionnaire de code source pour intégré ainsi qu’un outil de build ?
Non. Il s’agit des deux points importants sur lesquels travaillent les équipes de développement d’Oracle APEX.

Pour le moment, il faut exporter régulièrement son application et l’enregistrer dans un CVS (Subversion,, Github…) Le format d’export est granulaire jusqu’au niveau Page.
La société Insum propose un outil qui va plus loin pour la granularité des objets: APEXCl
https://apexcl.dev/
Pour le build, il existe des guides de bonnes pratiques et aussi un plugin pour Maven, par exemple.(réalisé en 2014)

Y’a t-il une gestion des profiles d’utilisateurs sous APEX ?
Oui. On peut gérer des profils d’utilisateurs avec des préférences et chaque utilisateur a la possibilité de modifier celles qu’on aura exposées lors de la conception.
Les règles de complexité des mots de passe sont paramétrable.

En parallèle, il est possible aussi de créer des groupes d’utilisateur et mettre en place une gestion d’ACLs.
La méthode la plus sophistiquée pour élaborer une gestion de rôles complète consiste à utiliser l’option Oracle RAS (Real Application Security). Oracle APEX est nativement intégrée avec Oracle RAS.

cf http://gpmfactory.com/index.php/2019/12/14/oracle-apex-et-ras/

J’ai fait un rapide test sur apex.oracle.com pour vérifier la nouvelle fonctionnalité de production de rapport PDF (Report Printing) à partir d’un Interactive Grid.

Voici deux échantillons de rapport à partir d’un Interactive Grid. L’un est en orientation paysage, l’autre en portrait.

On remarque que les règles d’affichage ainsi que les ruptures sur valeur de colonne sont respectées. Il n’existe pas de possibilité d’influencer le modèle PDF. Il s’agit donc d’une fonctionnalité pratique mais qui ne peut pas se substituer à un outil d’édition sophistiqué comme BI Publisher, AOP ou FOP.

Il faut constater qu’un Interactive Report ne bénéficie pas (ou pas encore ?) de cette fonctionnalité

Objet

Tout est prévu dans Oracle APEX pour produire une application multilingues. Dans cet article, on verra comment utiliser un service en ligne de traduction pour accélérer le processus. Nous avons testé le service crowdin. Il s’agit d’un service en ligne payant permettant de traduire des entités textuelles de façon coopérative en permettant d’organiser une équipe virtuelle de traducteurs.

Principes de traduction avec Oracle APEX

Il existe un live, Expert Oracle Application Express dans lequel Francis Mignault décrit, dans un chapitre consacrée à la globalisation avec APEX, les étapes pour traduire une application en plusieurs langues.

Le principe général est :

  • Choisir une application dans sa langue de base
  • Extraire les chaines de caractères
  • Les enregistrer dans un référentiel
  • Les exporter au format XLIFF
  • Les traduire (à l’aide de crowdin dans notre cas)
  • Les importer dans le référentiel
  • Produire, sous un autre ID, une variante de l’application originelle dans la langue cible

Au final, on obtient autant d’applications que de langue cibles mais les taches de développement continuent de n’avoir lieu que sur la version principale. Les applications en langues supplémentaires existent dans le référentiel APEX avec un numéro spécifique mais ne sont pas visibles depuis la console de développement.
Remarque importante: Apres chaque modification de l’application, il faut re-publier toutes les variantes cibles.

Processus de traduction

Ci-dessous sont rassemblées des captures d’écran qui illustrent les différentes étapes. Pour des raisons de simplifications, tous les détails n’ont pas été mentionnés.
Pour mémoire, il faut garder à l’esprit qu’un travail de traduction des donnée dans la database reste à faire (listes de valeurs etc.).

Nous avons utilisé le service Crowdin pour charger et traduire automatiquement les chaines textuelles.

Ces chaines sont obtenues au format XLIFF, qui est un format standard pour le partage de données avec des outils de traduction.

Echantillons de l’application traduite

Ci-dessous quelques échantillons de l’application Customer Tracker traduite en Français, Allemand et Arabe

Conclusion

On peut très rapidement obtenir un prototype d’application APEX traduite dans une langue quelconque avec le support d’un service de traduction automatisée comme celui de Crowdin. Il existe, bien sur, d’autres services du même genre et on peut également envisager l’emploi des APIs de Google Translation pour réaliser un service « Maison » de localisation.

Oracle APEX is a very good starting point for evaluating Oracle Forms migration workload.
From the Builder home page, a very discreet menu option leads to the following page:

From there, it’s possible to create a Forms migration projet then upload successively the different FMX files. The drawback is that it can be a cumbersome task, especially when thare are hundreds of forms.

For this reason, I inspected the code in the internal flow 4400 then put all the pieces of code together and add a loop.
The FMX files will be loaded in one shot as a zip files in the static files Section of Shared Components.
In this version of tool, only FMX are taken into account.

Download form Github.

IMPORTANT: You must have SYS access privilege in order to install the package !! (so, forget it if you’re using ATP)

Once the FMX files are loaded into the APEX repository, its easy to spread the analysis tasks amoung multiple developers as we discuss in an another post.