FAQ
- 1 Ako zmeniť názov tlačidla "Ďalej"?
- 2 Ako automaticky importovať dáta (model, user, csv, ...) pri štarte aplikácie?
- 3 Ako zabránim vykonaniu akcie a vytvorím chybový snackbar na frontende?
- 4 Ako pridám nový view?
- 5 Ako vytvorím filter pre nový view?
- 6 Podľa čoho viem vyhľadávať v task view?
- 7 Podľa čoho viem vyhľadávať v case view?
- 8 Ako zoradiť tasky jedného case-u podľa priority?
- 9 Ako pridám novú JS knižnicu?
- 10 Ako zistím odkiaľ sa načítavajú dáta?
- 11 Ako pomenovať Reddis namespace?
Ako zmeniť názov tlačidla "Ďalej"?
Pomocou tagu <event> je nielen možné definovať ktoré akcie sa majú pri vykonať pri výskyte daného eventu, ale aj aký nápis sa má zobrazovať na tlačidle pre daný event na frontende:
<event type="finish">
...
<title>Ďalej</title>
...
</event>
Ako automaticky importovať dáta (model, user, csv, ...) pri štarte aplikácie?
Pri štarte aplikácie sa vykonávajú Runner komponenty. Každý Runner dedí od AbstractOrderedCommandLineRunner ktorý zabezpečuje, že sa metóda run() vykoná pri štarte aplikácie (implementácia CommandLineRunner) a zároveň zabezpečuje vykonanie v správnom poradí (implementácia Ordered). Poradie vykonávania je definované v komponente RunnerController. Pokiaľ nie je Runner komponent zaregistrovaný v zozname v RunnerController aplikácia pri štarte spadne.
Vytvorím nový Runner komponent, do metódy run() vložím kód, ktorý chcem aby sa pri štarte vykonal:
@Component @Profile("dev") // spusti sa iba pri aktivovaní profilu "dev" class ExampleRunner extends AbstractOrderedCommandLineRunner { @Override void run(String... strings) throws Exception { ... } }
Komponent zaregistrujem v RunnerController:
@Component class RunnerController { private List order = [ ... ExampleRunner, ... ] ... }
Ako zabránim vykonaniu akcie a vytvorím chybový snackbar na frontende?
TODO: IllegalArgumentException
Ako pridám nový view?
vo views/app/ si vytvorím nový view ExampleView.html a skopírujem doň obsah už esixtujúceho viewu (tasks.html alebo cases.html podľa toho či sa má jednať o task view alebo case view)
v scripts/app.js pridám Angular routovanie:
$routeSegmentProvider .when('/', 'app') ... .when('/example', 'app.example') // zadefinovanie route segmentu ... .segment('app', { templateUrl: "views/app/main.html", controller: 'MainController', controllerAs: 'mainCtrl' }) .within() ... .segment('example', { templateUrl: "views/app/example.html", // cesta k viewu controller: 'ExampleController', // názov controlleru controllerAs: 'exampleCtrl' // pomenovanie premennej controlleru v jeho html }) ...
vo views/app/sidenav/main_sidenav.html vytvorím nový md-button pre daný view:
... <md-button href="/example" layout="row" layout-align="start center" ng-class="{active: ('example' | routeSegmentContains)}" ng-click="mainCtrl.closeSidenav('left-nav');mainCtrl.navigationClick('example')"> <i class="material-icons">developer_board</i>{{::$i18n.page.example.this}} </md-button> ...
Pomocou tagu <i> vieme zadefinovať ikonu položky menu z preddefinovaných material icons.
Názov položky v menu sa doťahuje z i18n.js.Do scripts/nls/i18n.js (a všetkých jazykových mutácií) doplním prvok page.example.this s názvom položky v menu:
define({ 'root': { ... page: { ... example: { this: "Examples", ... } ... } } });
Do scripts/config.js doplníme konfiguráciu pre nový view:
define([], function () { return { ... show: { ... example: { viewId: "example", countBadge: true, // zobrazenie počtu caseov/taskov v menu transactions: true, // zobrazenie transakcií taskSearch: false, // zobrazenie vyhľadávania taskPriority: true, // (?) taskCaseTitle: true // (?) }, ... }, enable: { ... cases: { caseDelete: true, // povolenie zmazania case-u allowHighlight: false, // povolenie zvýraznenia nových taskov v case-e autoOpenUnfinished: false, // povolenie automatického rozbalenia nového tasku fullReload: false // povolenie načítania celého zobrazenia case-u po zmene (?) }, ... } }; });
v scripts/controllers/ si vytvorím nový Controller pre daný view ExampleController.js a skopírujeme obsah už existujúceho controlleru:
define(['angular', '../classes/CaseTab', '../classes/TaskTab', '../classes/Filter', '../modules/Cases', '../modules/Main', 'angularMaterialExpansionPanels'], function (angular, CaseTab, TaskTab, Filter) { angular.module('ngCases').controller('ExampleController', // definovať meno controlleru ['$log', '$scope', '$http', '$dialog', '$snackbar', '$user', '$fileUpload', '$timeout', '$mdExpansionPanelGroup', '$cache', '$i18n', '$rootScope', '$process', '$config', '$filterRepository', function ($log, $scope, $http, $dialog, $snackbar, $user, $fileUpload, $timeout, $mdExpansionPanelGroup, $cache, $i18n, $rootScope, $process, $config, $filterRepository) { ... self.viewId = $config.show.example.viewId; // ... // definovanie tabov a otvarania novych tabov ... }]); });
pridať referenciu na controller do scripts/controllers/ControllersLoader.js
var path = 'scripts/controllers/'; define(['MainController', ..., 'ExampleController'] .map(ctrl => path + ctrl), function () { });
Ako vytvorím filter pre nový view?
Všetky filtre sa vytvárajú v scripts/services/FilterRepository.js v metóde createDefaults().
createDefaults: function () {
repository.put("openTasks", new Filter("openTasks", Filter.CASE_TYPE,
`{
"data": {
"suspended": false
},
"petriNet": {
"identifier": "union_sprnp"
},
"transition": "${$process.get("union_sprnp").transition("Nová úloha").id}", "role": [${$user.getGeneralReferentRoles($process.get("union_sprnp")).map(role => `"${role}"`).join(",")}]}`,
"{}"
));
repository.put(
...
);
}
Podľa čoho viem vyhľadávať v task view?
Vyhľadávanie sa realizuje na backende v triede TaskSearchService. Hlavnou metódou je buildQuery, ktorá vytvára QueryDSL query. Vstupom je Map<String,Object> requestQuery, ktorá predstavuje vyskladanú query z frontendu, pričom kľúčmi a hodnotami môžu byť:
role
reťazec identifikátoru roly ktorá je referencovaná v hľadanom tasku,
pole reťazcov identifikátoru rolí ktoré sú referencované v hľadanom tasku,
case
reťazec identifkátoru case-u hľadaného tasku,
dvojica atribút_caseu-hodnota, atribútom môže byť:
title,
id,
pole dvojíc atribút_caseu-hodnota, atribútom môže byť:
title,
id,
title
reťazec s názvom tasku,
pole reťazcov s názvami hľadaných taskov,
user
číselné id používateľa, ktorému je priradený task,
reťazec s emailom používateľa, ktorému je priradený task,
pole číselných id používateľov,
transition
reťazec transition import id,
pole reťazcov transition import id,
process
reťazec identifikátoru procesu tasku,
pole reťazcov identifikátorov procesov,
fullText
TODO
Podľa čoho viem vyhľadávať v case view?
Vyhľadávanie sa realizuje na backende v triede CaseSearchService. Hlavnou metódou je buildQuery, ktorá vytvára QueryDSL query. Vstupom je Map<String,Object> requestQuery, ktorá predstavuje vyskladanú query z frontendu, pričom kľúčmi a hodnotami môžu byť:
petriNet
dvojica atribút-hodnota, atribútmi podľa ktorých môžeme vyhľadávať sú:
identifier
pole dvojíc atribút-hodnota,
author
dvojica atribút-hodnota, atribútmi podľa ktorých môžeme vyhľadávať sú:
email,
name,
id,
pole dvojíc atribút hodnota,
transition
reťazec reprezentujúci id prechodu,
pole reťazcov reprezentujúcich id prechodov,
role
pole identifikátorov (string id) povolených rolí hľadaných case-ov
data In progress
mapa dvojíc dátový typ-hodnota
fullText
vyhľadávaný reťazec
Príklad:
new Filter(
"openTasks",
Filter.CASE_TYPE,
`{
"data": {
"suspended": false // vyhľadaj case v ktorom má "suspended" hodnotu false
},
"petriNet": {
"identifier": "example_net" // vyhľadaj case ktorý je vytvorený zo siete s identifikátorom "example_net"
},
"transition": "${$process.get("union_sprnp").transition("Nová úloha").id}", // vyhľadaj case v ktorom existuje task vytvorený z
"role": [
${$user.getRoles($process.get("union_sprnp")).map(role => `"${role}"`).join(",")} // vyhľadaj case v ktorom sú povolené roly, ktoré vráti funkcia getRoles aktuálne prihláseného používateľa
]
}`,
"{}"
)
Ako zoradiť tasky jedného case-u podľa priority?
TODO
Ako pridám novú JS knižnicu?
nainštalujem požadovanú knižnicu cez
bower
bower install angular-currency-format
do main.js pridám do mapovanie cesty k danej knižnici:
paths: { ... 'nazovKniznice':"bower_components/angular-currency-format/dist/currency-format.min", ... }, shim: { ... 'nazovKniznice': ['angular'], ... }
do app.js pridám závislosť:
Do angular.module je potrebné zadať správny názov požadovaného modulu. Ten sa dá nájsť v zdrojovom súbore prípadne vo vzorovom kóde: angular.module('currencyFormat', ...
define('app', [..., 'nazovKniznice', ...
...
let app = angular.module('app', [..., 'currencyFormat', ...
...
)
Ako zistím odkiaľ sa načítavajú dáta?
Problém
Na frontende sa zobrazujú dáta, ktoré by tam nemali byť, alebo sa tam nezobrazujú dáta, ktoré by tam mali byť.
Riešenie
V DevTools si nájdem request, ktorý načítáva dáta z backendu.
V tabe Headers v sekcii General nájdem atribút Request URL
V Intellij IDEA dám vyhľadať (Ctrl+Shift+F) časť hodnoty Request URL za api (napr. "/api/task")
Podľa výsledku vyhľadávania zistím, ktorý controller sa volá (napr. TaskController.java) a v ňom dám vyhľadať zvyšok Request URL (napr. "/search") ktorý bude v anotácii metódy
V nájdenej metóde si nájdem volanie príslušnej service (napr. taskService.search(...)), rozkliknem (Ctrl + LMB) a v interface prejdem na implementáciu
V implementácii danej metódy si nájdem volanie repozitáru, ktorý načítava dáta z databázy:
Ako pomenovať Reddis namespace?
Reddis namespace je potrebné definovať v application.properties
, názov property je spring.session.redis.namespace
, hodnotu treba zadať v tvare <zakaznik>:<projekt>
Príklad: spring.session.redis.namespace=union:pzs