Jak obsłużyć hierarchię słowników ze środkowym poziomem liczącym tysiące dynamicznie zmieniających się pozycji

Wprowadzenie: Kiedy prosta hierarchia to za mało

W codziennej pracy z systemem AMODIT często spotykamy się z potrzebą tworzenia zależności między polami. Najprostszym i najczęstszym rozwiązaniem są słowniki hierarchiczne, gdzie wybór w jednym polu filtruje dostępne opcje w kolejnym. To idealne narzędzie do odwzorowania struktur takich jak Kategoria -> Podkategoria czy Województwo -> Powiat.

Jednak co w sytuacji, gdy stajemy przed znacznie bardziej złożonym wyzwaniem biznesowym? Co zrobić, gdy w środku naszej hierarchii musimy dać użytkownikowi możliwość wyboru jednego elementu z listy liczącej tysiące pozycji – na przykład konkretnego zlecenia produkcyjnego, numeru umowy, środka trwałego, polisy ubezpieczeniowej czy dowolnego innego obiektu liczącego wiele pozycji i do tego, który może zmieniać się w czasie?

Standardowa hierarchia zawiedzie, prowadząc do „eksplozji danych” i problemów z wydajnością. Rozwiązaniem tego problemu jest mechanizm potocznie nazywany „słownikiem zagnieżdżonym”. Jest to unikalne połączenie prostej konfiguracji słownika hierarchicznego ze specjalnym, dynamicznym zachowaniem interfejsu użytkownika. Ten artykuł wyjaśni krok po kroku, jak to działa i kiedy warto z niego korzystać.

Część 1: Fundament – Jak skonfigurowany jest „Słownik hierarchiczny”?

Zanim przejdziemy do „magii”, spójrzmy na fundament. Jak widać na zrzutach z konfiguracji, u podstaw leży wykorzystanie połączonych słowników czyli tzw słownik hierarchiczny.

  • Mamy pole poz1 i poz2.
  • W definicji formularza, pole poz2 jest zdefiniowane jako podrzędne względem poz1 (Słownik nadrzędny: poz1).
  • W zawartości słownika dla poz2, każda pozycja ma przypisaną kategorię, która odpowiada wartości z poz1.

Gdy w poz1 wybierzemy Pozycja 1, pole poz2 automatycznie pokaże tylko te rekordy, których kategoria odpowiada temu wyborowi.

Część 2: Przełom – Czym jest i jak działa „Słownik zagnieżdżony”?

„Słownik zagnieżdżony” to nie jest inny typ słownika w bazie danych. To specjalne zachowanie interfejsu użytkownika, które jest uruchamiane, gdy w polu nadrzędnym (poz1) zostanie wybrana wartość o specjalnym formacie – rozpoczynająca się od znaku # (hash).

Mechanizm działania krok po kroku:

  1. Wybór „Znacznika” w poz1: Użytkownik na formularzu klika w pole poz1. Oprócz zwykłych pozycji (Pozycja 1), widzi specjalne „znaczniki”, np. #Zlecenia czy #Umowy. Użytkownik wybiera jeden z nich, np. #Zlecenia.

  2. Dynamiczne Wstawienie Pola: System AMODIT wykrywa znak # w wybranej wartości i wykonuje następujące kroki:

    • Sprawdza czy istnieje w AMODIT słownik zewnętrzny o tej nazwie, oczywiście bez znaku #, czyli np. słownik o nazwie Zlecenia
    • Jeśli istnieje to, pokazuje drugie pole bezpośrednio pod polem słownika.
  3. Wybór konkretnej Instancji: To nowo wstawione pole jest automatycznie wypełniane zawartością słownika o nazwie odpowiadającej znacznikowi (w tym przypadku słownika „Zlecenia”). Użytkownik widzi teraz długą, płaską listę konkretnych zleceń i może wybrać z niej poszukiwaną pozycję.

  4. Kontynuacja hierarchii w poz2: , System aktywuje pole poz2. Zostaje ono przefiltrowane na podstawie wartości wybranej w poz1, czyli #Zlecenia. Użytkownik widzi więc podkategorie zdefiniowane dla zleceń (np. Koszty osobowe zlecenia, Koszty dodatkowe zlecenia).

Ważne wymaganie techniczne: Słowniki używane jako „słowniki obiektów” (np. Zlecenia, Umowy, Maszyny) MUSZĄ być skonfigurowane jako słowniki zewnętrzne. To wymaganie systemu dla prawidłowego funkcjonowania mechanizmu dynamicznego ładowania.

Przykład praktyczny z dekretacji kosztów

Scenariusz: Firma ma obieg do dekretacji kosztów, gdzie każdy koszt musi być przypisany do obiektu (zlecenie/projekt/maszyna) i następnie skategoryzowany.

  1. Pole Rodzaj kosztu: Użytkownik wybiera #Zlecenia
  2. Dynamicznie pojawia się pole „Wybór zlecenia” z listą wszystkich aktywnych zleceń produkcyjnych
  3. Użytkownik wybiera „Zlecenie 2024/001 – Produkcja okien PVC”
  4. Pole Kategoria kosztu pokazuje opcje: „Materiały”, „Robocizna”, „Narzędzia” (te same dla wszystkich zleceń)

Dlaczego to podejście jest tak skuteczne?

Ten mechanizm w elegancki sposób rozwiązuje problem, rozdzielając proces wyboru na dwa etapy:

  • Wybór typu/kontekstu obiektu: Użytkownik najpierw decyduje, czy chce przypisać koszt do zlecenia, umowy czy maszyny (wybór w poz1).
  • Wybór konkretnej instancji obiektu: Następnie, w dedykowanym do tego, dodatkowym polu, wybiera konkretny numer zlecenia z tysięcy dostępnych.

Dzięki temu interfejs użytkownika pozostaje czysty i wydajny, a konfiguracja w backendzie jest prosta i opiera się na standardowym mechanizmie hierarchii.

Ograniczenia i wymagania techniczne

  • Słowniki zagnieżdżone: Muszą być skonfigurowane jako słowniki zewnętrzne
  • Struktura: Mechanizm obsługuje tylko 2-poziomową strukturę ( pole słownika → dynamiczne pole do wyboru obiektu), ale jednocześnie nie ogranicza poziomów hierarchii słowników
  • Wydajność: Słowniki z tysiącami pozycji ładują się asynchronicznie, co może powodować krótkie opóźnienia

Kiedy powinieneś użyć słownika zagnieżdżonego? (Checklista dla wdrożeniowca)

Pomyśl o tym rozwiązaniu, gdy w analizie problemu klienta pojawiają się następujące sygnały:

  • W jednym miejscu procesu użytkownik musi najpierw określić typ obiektu (zlecenie, projekt, umowa), a następnie wybrać konkretny egzemplarz z bardzo długiej, płaskiej listy.
  • Chcesz uniknąć sytuacji, w której jedno pole wyboru zawiera jednocześnie kategorie hierarchiczne i tysiące konkretnych pozycji, co byłoby koszmarem z punktu widzenia UX.
  • Potrzebujesz, aby po wyborze konkretnego obiektu z dużej listy, dalsze kroki w formularzu następowały według standardowej ścieżki (np. kategorie kosztów są takie same dla wszystkich zleceń).
  • Zależy Ci na prostocie konfiguracji (wykorzystanie standardowej hierarchii) przy jednoczesnym uzyskaniu zaawansowanego, dynamicznego zachowania na formularzu.

Podsumowanie

„Słownik zagnieżdżony” to sprytny hack UI który na bazie standardowej hierarchii tworzy wrażenie inteligentnego „wstrzykiwania” pól. W rzeczywistości to elegancka kombinacja dwóch mechanizmów: wykrywania wzorca #nazwa oraz dynamicznego ładowania zawartości drugiego pola wyboru.

Ten mechanizm to doskonały przykład jak właściwy projekt UX może rozwiązać problem skalowalności bez komplikowania architektury systemu. Dla wdrożeniowca to potężne narzędzie pozwalające zbudować intuicyjny interfejs dla najbardziej wymagających scenariuszy biznesowych.