Showing posts with label UI. Show all posts
Showing posts with label UI. Show all posts

Monday, June 15, 2026

Sparrow 0.6.0: New Production-Ready UI for Local Document AI

Sparrow just got a complete UI overhaul — rebuilt from the ground up with Next.js and shadcn for a production-grade experience.

What's new in this release:

- Faster document upload and extraction workflow
- Real-time analytics dashboard with usage metrics, model distribution, and geographical reach
- Built-in feedback collection
- Dark mode support Fully responsive mobile layout 

Sparrow remains fully local — your documents are processed on-device with Vision LLMs, with nothing stored on disk and no cloud dependencies.

Tuesday, February 4, 2025

Building Web UI Apps with Python Gradio – A Java Developer’s Perspective

I explain building Web UI apps with Python Gradio framework. I used to work with Java in the past and was building enterprise Web UI apps with JSF. Based on this experience I can tell, Gradio is awesome framework for server side generated UI - it is easy to define UI components and control UI flow with event triggers.

 

Sunday, July 24, 2022

Oracle JavaScript (JET) UI rendered in single HTML file

Oracle JavaScript Extension Toolkit (JET) comes with a strong set of UI components for enterprise. You can reuse these components in other UI toolkits/frameworks. In this video I show how you can run JET table components in a single HTML file, without any additional configuration in separate files.

 

Monday, July 4, 2022

MLUI: Webpack, Django, JavaScript

This quick video explains how to run Webpack inside Django project to package JavaScript files into a single bundle.

 

Sunday, June 5, 2022

MLUI: Django App Setup

UI plays an essential part for ML apps, it helps build access to ML model API. With friendly and usable UI there are more chances for ML project to be successful. I'm building UI for our ML product Sparrow (data extraction from the documents). I will be explaining in the series of videos, how to build UI (including security, data model, etc.) for ML project. Stay tuned, it will be fun and lots to learn.

 

Tuesday, April 26, 2022

UI for ML - Django, React or Streamlit?

UI is an important part for ML app to be successful. In this video I discuss multiple UI options I was looking into to build UI for our ML product. While deciding on which UI framework or library to use, you should point your attention to multiple things - such as ease of data transfer, UI flexibility, and ability to build user-friendly functionality.

 

Sunday, January 2, 2022

Hugging Face Gradio Python UI and CSV Processing

Explaining how to process CSV file uploaded through Gradio UI in Python. Gradio is part of Hugging Face. You will also learn how to define inputs and outputs for Gradio, to render UI components out of the box. Towards the end of the video, I will share a tip on how to read an error message, if the error happens during app development.

 

Sunday, December 26, 2021

Hugging Face Gradio Python UI for ML

I dive into Gradio UI with Python, which is now part of Hugging Face. This is a very cool and simple to use library, it helps to build UI for ML models quickly. This is useful to share ML models with the community and run quick demos to showcase your ML model capabilities. I explain app code structure and how you can map ML model inputs and outputs with Gradio.

 

Monday, March 9, 2020

Building Dynamic UI Form with Oracle JET

Dynamic form is a common requirement when building more advanced UIs. With Oracle JET you have all the tools available to build dynamic form. One of the examples of dynamic form requirements - report parameter capture screens. Building fixed forms to capture parameters for each report would be an overkill. A smarter approach is to build one dynamic form, which would handle a set of different UI components and render based on metadata received from the service.

Dynamic form example:


When values are changed, we can capture all changes while submitting the form - value printed in the log:


In the heart of dynamic form logic, we are using JET bind for each tag, it renders form elements from metadata:


Each element is checked and based on the type - UI field is rendered through JET if tag. Input field properties are fetched from metadata.

Example of metadata structure - array. It is important to use Knockout observable for value property. This will allow capturing user input. When we submit the form, we can iterate through the array and read value property:


Sample code available on GitHub.

Thursday, October 24, 2019

SEO for Single Page Oracle (SPA) JET Application

This is a quick tip post related to Oracle JET.

SEO (search engine optimization) is a must for a public website or public-facing app. Search engines do indexing well for static HTML pages. Oracle JET on contrary follows SPA (single page application) approach with dynamic UI. This makes it harder for the search engines to build an index for such an app. The same applies to any other SPA implementations with Angular, React, Vue.js, etc.

If you want to build SEO support for Oracle JET, similar solutions as for Angular, React or Vue.js SPAs apps can be applied.

One of the simpler and reliable solutions - generate static HTML pages for Oracle JET SPA app. You can follow this article, it explains how the same can be done for Angular - SEO for Single Page Applications.

Tuesday, August 6, 2019

Oracle JET Model ID Attribute

When building Oracle JET Model/Collection structure to render table, you should be careful defining ID attribute. This attribute must have unique values only, if there will be duplicates in ID, then table rows will be rendered incorrectly.

Take as example below structure for Employees REST endpoint. EmployeId attribute provides unique values and it should be defined as ID for JET model:


Let's try and see what happens when non-unique DepartmentId attribute is set for a key in JET model:


In this case, during data fetch and UI table rendering (specifically when navigating to the next page of the table) - JET runtime for the table will get confused and will fetch all of the records from the backend (definitely, not what we want):


Ok, change it to the proper one - use EmployeeId for the ID in JET model:


The table works as expected:


Lesson learned - make sure to use an attribute with unique values for JET model ID. If there is no single attribute with unique values, the concatenate multiple attributes on the backend to construct a single attribute with unique value.

Source code is available from my GitHub repo.

Wednesday, June 26, 2019

Oracle Developer Tools - Do They Still Exist?

People are frustrated about @OracleADF @JDeveloper on social media - "ADF boat has no captain", etc. I agree @Oracle is to blame big time for such lame handling of its own Developer Tools stack. @Oracle please wake up and spend some budget on @OracleADF. Read more:

Oracle VBCS - right now this tool gets the most of Oracle focus. Supposed to offer declarative #JavaScript development experience in the Cloud. Not well received by the community. Are there any VBCS customers, please respond if yes?

Oracle APEX - comes with a very strong community (mostly backed by DB folks). But is not strategic for Oracle. More likely will be used by PL/SQL guys then by Java or Web developers. 

Oracle JET - highly promoted by Oracle. Set of opensource #JavaScript libs, glued by Oracle layer. Nice, but can't be used as a direct replacement for @OracleADF, JET is UI layer only. Oracle folks often confuse community by saying - Oracle JET is a great option to replace ADF

Oracle Forms - still alive, but obviously can't be strategic Oracle platform. A few years ago, Oracle was promoting Forms modernization to @OracleADF

Summary - Oracle Developer tools offering is weak. Lack of Oracle investment into development tools - makes Oracle developers community shrink.

Friday, June 7, 2019

Running Oracle JET on Heroku with Node.js (JET Showcase)

I have implemented JET (more about Oracle JET) showcase app with data visualization components usage. This app shows historical weather data in Boston city, the dataset is taken from Kaggle. Switching years makes data visualization to change and show new data - I love how polar chat is updated. Calendar displays temperature for each day during the year using JET picto chart component:


App is deployed on Heroku and available by this URL. Heroku provides $7 per month account with analytics and better resources, but there is a free option too (it comes with sleep after 30 minutes of inactivity) - free option is good for experimentation, as for this case.

Heroku dashboard for the deployed JET app:


Free deployment comes without analytics option:


App comes with two options - Dashboard and Histogram. The dashboard allows switching between years and shows a polar chart along with daily temperature calendar:


The histogram displays the same data in a different view:


This app comes with Web Component implementation, yes Web Components are a standard feature in JET. Toolbar, where you can switch years, is implemented as Web Component:


Web Component is being used in both UIs - dashboard and histogram:


Visualization components are getting data through Knockout.JS observable variables:


Variables are initialized in JS functions:


Resources:

1. Heroku deployment guide for Node.js
2. Node.js app which is deployed on Heroku - GitHub. JET content is inside the public folder. JET content is copied from JET app web folder, after running ojet build --release
3. Oracle JET app - GitHub

Monday, February 4, 2019

Cross Field Form Validation in Oracle JET

JET keeps evolving and in the latest versions  - toolkit provides improved support for form cross-field validation. It is much easier to implement validation than it was before. I will show it in this example.

Example of the data entry form. Validation logic:

- Invoice Date before Payment Due Date and Payment Date
- Payment Due Date before Payment Date


Example when two fields fail validation:


JET provides component called validation group. Form can be wrapped by this component to identify if any validation errors are reported there. For example, when calling JS function, before proceeding with the function code - we can check if validation group contains errors:


Input field can be assigned with custom validator function:


Example of validation function code where cross-field validation logic is implemented - we compare field value with other fields. If validation rule condition is false - validation error is thrown:


Example of function code, where validation group is checked for errors. If there are errors in the current validation group - errors are displayed and the first field with error is focused:


Download sample code from my GitHub repo.

Wednesday, November 28, 2018

Notification Messages in Oracle JET

Let's take a look into cool component available in Oracle JET - notification messages (it is possible to display messages in different ways - inline or overlay. Check more about messages functionality in JET Cookbook example).

This is how notifications messages are showing up, very cool way to send information to the user:


Messages are implemented with oj-messages components. This component accepts observable array of messages to be displayed. We can specify how message is displayed (notification in this case), position information and close listener (where we can remove message info entry from messages array):


In sample processAction function I'm pushing new entries into messages array. To simulate delay for second message, pushing second entry with 1 second delay. Once message is closed after standard delay time - function closeMessageHandler is invoked, where we are removing entry from array:


Sample application code is available on my GitHub repo.

Sunday, June 17, 2018

CDN Support in Oracle JET

With the recent releases of Oracle JET - CDN support in your app can be enabled easily. By default JET app is set to download all JET toolkit related scripts and static files from the same host, where application is hosted. You can track it easily through network monitor, you should see such files as ojknockout.js, etc. fetched from same host:


CDN can be enabled by changing use property from local to cdn in path_mapping.json and restarting the app:


After this change, you should see all JET toolkit content to be downloaded from static.oracle.com host:


Benefit - you reduce load on your host, from where only application specific files will be downloaded, with JET toolkit code downloaded from external Oracle host. Same achievable on your own host, but JET toolkit content downloaded from Oracle host - is compressed out of the box (another benefit):

Saturday, December 16, 2017

Machine Learning with Oracle JET and TensorFlow

Oracle JET works with any kind of REST service, such service could be the one coming from TensorFlow (read more in my previous post - TensorFlow Linear Regression Model Access with Custom REST API using Flask). I have implemented linear regression model with gradient descent optimizer in TensorFlow (will describe this in more detail in my next post - machine learning is all about mathematics) and consuming it in JET UI:


There is option to define training steps (or data points) and learning rate. As outcome we get W and b values for linear equation y = Wx + b. After training is executed (so called machine learning process) - W and b parameters are identified, this allows to predict y value for any x. More about this in my next post, today will focus on JET.

To execute training, we call TensorFlow REST API endpoint and pass number of training steps/points and learning rate. I'm have create JET helper module to perform actual REST call, to separate logic from REST call invocation. Useful technique of custom callback is used to call method located in main module from helper module. We pass callback method name REST call helper function:


REST call is executed through JQuery and success callback is assigned with our method name (instead of processing results in REST call helper method, we can do processing in main module):


This is where results processing happens - in custom callback method. We prepare x/y training dataset to be displayed in chart. We get back estimated W and b parameters, this allows to calculate estimated y based on equation y = Wx + b for all x values used in training set (to compare how well model was trained):


One more nice component of Oracle JET - Form Layout. It makes very easy to create simple forms, specify number of max columns and you will get responsive UI for form components out of the box:


Make sure to add ojformlayout module:


To debug data returned by TensorFlow REST service, check Network history in browser developer tools:


By the way - it is completely up to you to decide about REST JSON data shape. With Python jsonify from Flask you can construct JSON from arrays of data and publish your own REST end point anywhere in Python script (you code in Python for TensorFlow):


Download sample JET application (make sure to use ojet restore, before ojet serve) from GitHub. TensorFlow linear regression model used for this sample is available as GitHubGist.

Monday, November 27, 2017

JET 4.1.0 Composite - List Item Action and Defferred Loading

I was reviewing JET 4.1.0 features and decided to build simple composite component. Would like to share some of the items I learned.

Composite component comes with collapsible UI and action link, it implements list item, which can be rendered in any kind of parent UI container:


When item is expanded, more info is displayed:


Once user clicks on Open link, JS call is made and key from current item is printed in the background:


Let's take a look into component metadata. I'm using several properties and one event. Through event we can call JS method outside of composite component, this can be very useful:


How this event is used? Take a look into composite HTML implementation, click is handled by JS method, inside that function event will be initialized:


One more interesting thing - I'm using JET Defer functionality, to render HTML expandable content, when item is expanded. This allows to minimize client side load by lazy loading, renders content when it is displayed:


JS method, which handles click - creates event. This will allow to execute event implementation method outside composite component. Syntax looks pretty similar to ADF Server listener call:


Naming of the event is important. If event name is openDetails, then make sure to use on-open-details as property name for the event handler in composite component interface. Here I define external method to be invoked when event is fired:


Here is the code for event listener JS method in main view module:


Let's see how JET Defer works on runtime. This is source from JET running app, when list item is rendered initially, there is no content for expanded block - it only contains JET Defer block:


After we expand it:


Content is rendered in source. This is called lazy loading and this concept allows to improve performance, especially for large lists (or tabs, etc.), when a lot of content is rendered:


Now few hints how to create JET Composite with OJET tooling. Run similar command (if you run this command outside JET app context, it will create new shell JET app with this component. if you run command in context of JET app, it will create component inside the app):

ojet create component list-itemrs

This will create JET Composite with given name. To be able to run JET Composite from index page, add applyBindings to main.js require block:


Don't forget to add JET composite module and actual composite loader:


Finally add your own JET Composite tag to index.html:


Sample code can be accessed in GitHub repository (run ojet restore) - list-itemrs.