Oracle APEX popup menu przy pomocy Pretius APEX Context Menu

13 sierpnia 2019, Bartosz Ostrowski

Wprowadzenie

Kiedy pracujemy nad aplikacjami dla naszych klientów skupiamy się przede wszystkim na możliwościach i ograniczeniach Oracle Application Express. Przez cały czas trwania developmentu staramy się spełnić oczekiwania klienta, niejednokrotnie podpowiadając mu najlepsze możliwe rozwiązania.

W przypadku gdy tworzymy aplikację całkowicie od zera, zadanie jest stosunkowo proste. Razem z pracownikami klienta ustalamy granice, omawiamy oczekiwania użytkowników, a finalnie sugerujemy najlepsze z możliwych rozwiązań. Gdy nasz klient skupia się na czymś nie do końca optymalnym, bądź kosztownym do utrzymania w przyszłości to staramy się go przekonać do alternatywnego rozwiązania, które spełni jego potrzeby, a które będzie łatwe w utrzymaniu po wdrożeniu.

W przypadku gdy aplikacja ma powstać w wyniku migracji z innej technologi (np. Oracle Forms, OBIEE, Oracle Discoverer) jest nieco trudniej. Migracja aplikacji z Oracle Forms do Oracle APEX w większości przypadków oznacza przepisanie części aplikacji praktycznie od zera, co paradoksalnie jest dobrą wiadomością. Możliwość przeanalizowania jak wygląda stara aplikacja i w jaki sposób z niej korzystają użytkownicy to bardzo dobry punkt startowy do tego aby wyznaczyć nowe standardy i zaproponować nowe funkcjonalności. Niestety, aktualni użytkownicy niekoniecznie są chętni do tego aby porzucić swoje stare przyzwyczajenia i z tego powodu przepisując aplikację staramy się trzymać tak blisko pierwowzoru jak to tylko możliwe. Takie podejście niestety potrafi nastręczać wielu problemów, ze względu na różnice wynikające z np. tego, że Oracle Forms jest zorientowane na funkcjonalności typu desktop, a aplikacje APEX’owe są aplikacjami uruchamianymi w przeglądarce.

Pewien przypadek biznesowy

Żeby nieco lepiej przybliżyć istotę problemu, wyobraź sobie aplikację, która powstaje dla firmy spedycyjnej (bądź logistycznej). W ramach codziennych obowiązków, użytkownicy planują fracht, transport ładunków, zarządzają flotą pojazdów, przydzielają dostępnych kierowców do pojazdów oraz inwentaryzują samochody firmy. Jeśli wyobrazisz sobie raport, który służy za punkt startowy do rozpoczęcia pracy to miałby on bez wątpienia wiele kolumn. Rozważmy dla przykładu raport przedstawiający planowane trasy przewozu ładunku. W takim raporcie znalazłyby się kolumny takie jak:

  • informacje o pojeździe (nr rejestracyjny, aktualny status, ładowność, lokalizacja GPS),
  • informacje o aktualnie przypisanym kierowcy (imię, nazwisko, numer telefonu komórkowego),
  • punkt początkowy transportu (kraj, miasto, dokładny adres),
  • punkt końcowy transportu (kraj, miasto, dokładny adres),
  • notatki,
  • kto jest odpowiedzialny za dane zlecenie transportu.

Gdyby zwizualizować taki raport, otrzymalibyśmy bardzo dużo informacji, które dla pracownika firmy spedycyjnej są niezbędne w codziennej pracy. Wyobraź sobie teraz liczbę możliwych akcji, które może wykonać użytkownik z poziomu takiego raportu:

  • edycja, kopiowanie, usuwanie zlecenia spedycji,
  • zmiana kierowcy, aktualizacja informacji o bieżącym kierowcy,
  • przeniesienie zlecenia do zewnętrznego systemu spedycyjnego,
  • akceptowanie, odrzucanie zleceń,
  • dodawanie załączników.

Wyobraź sobie teraz, że takich akcji do wykonania jest dużo więcej, bo dana firma spedycyjna ma swoje własne unikalne procesy biznesowe. Tylko poprzez dodanie wyżej wymienionych akcji, raport zostałby rozszerzony o 9 dodatkowych kolumn. W każdej kolumnie przycisk z odpowiednią ikoną, uruchamiający odpowiednią procedurę w bazie danych. Oczywiście, moglibyśmy dodać wszystkie 9 akcji do raportu, ale czy w taki sposób pomagamy naszemu klientowi usprawnić jego aplikację?

Przekonanie użytkowników do tego, że dodanie 9 dodatkowych kolumn nie jest najlepszym pomysłem jest nie lada wyzwaniem. Zwłaszcza jeśli użytkownicy przyzwyczajeni do funkcjonalności desktopowych nie będą chętni do zmiany swoich nawyków. Żeby nieco ułatwić sobie zadanie staramy się pokazać klientowi i jego użytkownikom aplikacje web, które są znane wszystkim – Google Gmail, Facebook czy Twitter. Aplikacje przygotowane przez te firmy są używane przez miliony ludzi na całym świecie, przez co są zorientowane na wygodę użytkownika. W Pretius, staramy się aby najlepsze praktyki, dobry UX oraz UI stały zawsze na pierwszym miejscu. Z tego właśnie względu pokazujemy, że funkcjonalności dostępne w np. Gmail mogą być dostępne również nowej aplikacji stworzonej w Oracle APEX.

Spójrz proszę na obrazki poniżej przedstawiające moją prywatną skrzynkę Gmail.

test

Menu agregujące akcje dla raportu e-maili

Kontekstowe menu dostępne z poziomu pojedyńczego listu e-mail

Kontekstowe menu dostępne z poziomu pojedynczego e-maila

Na pierwszym obrazku zaprezentowany jest przycisk grupujący akcje możliwe do wykonania na zbiorze e-maili. Na drugim obrazku natomiast jest zaprezentowane kontekstowe menu możliwe do wywołania z poziomu każdego wiersza e-mail. Zdecydowanie są to funkcjonalności, które zna każdy i korzysta z nich bardzo naturalnie.

Natywne rozwiązanie

Oracle Application Express posiada możliwość zbudowania takiego rozwijanego menu za pomocą dwóch natywnych komponentów: przycisku oraz zdefiniowanej listy wartości. Na oficjalnej stronie demo dedykowanej Universal Theme znajduje się prosta instrukcja jak połączyć te dwa komponenty ze sobą aby stworzyć proste rozwijane menu wywoływane z poziomu przycisku.

Instrukcja jak zaimplementować natywne popup menu w Oracle APEX

Instrukcja jak zaimplementować natywne popup menu w Oracle APEX

Niestety, takie rozwiązanie nie pokrywa wszystkich oczekiwań użytkowników, a mianowicie:

Tak, chcemy agregować akcję w postaci menu, ale czy możemy je również mieć z poziomu wiersza w raporcie?

John Snyders, jeden z głównych developerów tworzących Oracle APEX, opisał takie menu już w 2015 roku na swoim blogu. W tamtym okresie nie było jeszcze dostępnej dokumentacji dla widget menu odpowiedzialnego za funkcjonalności natywnego popup menu, ale John opisał dokładnie jak za jego pomocą stworzyć menu korzystając z JavaScript i przypisać je do przycisków w wierszach raportu. Niestety, tworząc menu jedynie w oparciu o menu widget tracimy automatycznie możliwość sterowania dostępnością pozycji menu w zależności od uprawnień użytkownika. Wymagania dla każdego popup menu, niezależnie czy wywoływane z poziomu wiersza czy przycisku są następujące:

  • pozycja menu jest wyświetlana w zależności od uprawnień użytkownika,
  • pozycja menu jest wyświetlana w zależności od stanu sesji użytkownika,
  • przypisana akcja powinna uwzględniać dane w wierszu na którym dana akcja została wykonana (np. przekazywanie ID wiersza do okna modalnego),
  • możliwość tworzenia dynamicznych pozycji submenu.

Niektóre z tych wymagań możemy spełnić za pomocą listy wbudowanej w APEX, niektóre tylko za pomocą menu stworzonego w oparciu o menu widget –  niestety te wymagania wykluczają się wzajemnie. Dla przykładu, jeśli stworzymy menu tylko za pomocą menu widget to utracimy możliwość sterowania dostępnością pozycji menu z uwzględnieniem uprawnień użytkownika. Aby wspierać to kluczowe wymaganie musielibyśmy sprawdzać uprawnienia przy pomocy procesu/stanu sesji w APEX Item, a następnie mapować wyniki na dynamicznie tworzone pozycje menu. Jest to oczywiście możliwe, ale utrzymanie tak rozproszonej konfiguracji (JavaScript, dynamiczne akcje, procesy) dla każdego raportu w całej aplikacji byłoby obarczone wielkim kosztem. Co więcej tracimy w ten sposób zalety korzystania z platformy low-code, m.in. domyślnie dostępnych elementów APEX i zasady, że tworzymy aplikację z gotowych komponentów.

Rozwiązanie Pretius

Wyżej opisane kwestie zainspirowały mnie do tego, żeby połączyć widget menu z listami APEX w jeden komponent, który gwarantowałby spójność w implementacji (zasada low-code). W wyniku mojej pracy powstał nowy plugin dla Oracle APEX – Pretius APEX Context Menu, który można wykorzystać w Oracle APEX, zaczynając od wersji 5.1.

Pretius APEX Context Menu is dynamic action plugin implementing APEX popup menu based on defined APEX list. The plugin can be attached to any HTML element and renders entries according to authorisation scheme result. Menu entries can be extended by overriding behaviour, dynamically adding submenu and by adding new entries.

Jeśli chcesz zobaczyć jak plugin prezentuje się na żywo to koniecznie odwiedź przygotowane demo. W demo przedstawiłem kilka wariantów użycia:

  • menu sterujące stanem checkbox’ów w raporcie, z uwzględnieniem logiki danych,
  • menu akcji dla wiersza wywoływane z wiersza,
  • dynamiczne menu dla 3 kolumn,
  • menu kontekstowe, ale tylko w graniach wybranego regionu.
Checkbox menu pozwalające zaznaczyć wiersze wg. filtru (dynamiczne submenu)

Checkbox menu pozwalające zaznaczyć wiersze wg. filtru (dynamiczne submenu)

Menu wiersza dostępne poprzez link w kolumnie

Menu wiersza dostępne poprzez link w kolumnie

Kontekstowe menu dostępne dla komórki w kolumnie

Kontekstowe menu dostępne dla komórki w kolumnie

Kontekstowe menu dostępne tylko w granicach wybranego regionu

Kontekstowe menu dostępne tylko w granicach wybranego regionu

Menu podpięte do przycisku w region breadcrumb

Menu podpięte do przycisku w regionie breadcrumb

Jeśli chciałbyś się dowiedzieć więcej o moim najnowszym pluginie, przejdź do aplikacji demo, a dokładnie do zakładki „Description” gdzie opisałem każdy przypadek użycia bardziej szczegółowo. Dodatkowo, możesz przeczytać przygotowaną dokumentację plug-inu w repozytorium GitHub.

A jeśli chcesz wykorzystać plug-in w swojej aplikacji, to możesz go ściągnąć bezpośrednio z apex.world (nie zapomnij tylko dać mu „like”, jeśli przypadnie Ci do gustu).

Zapraszamy do kontaktu!

Pretius jest firmą tworząca oprogramowanie wspierające biznes.
Tworzymy aplikacje webowe wykorzystując: Java, Oracle DB, Oracle Apex, AngularJS.
Skontaktuj się z nami, aby porozmawiać o tym jak możemy pomóc w realizacji Twojego projektu!