= Реализација на случаите на употреба = ---- === Корисник === ||= **ИД:** =|| 1 || ||= **Случај на употреба:** =|| Пребарува податоци за лекови || 1. Се пристапува до почетната страна на апликацијата (Пребарај лек) - При load на страницата, рутерот ја поставува home компонентата на својот outlet во app компонентата. Home компонентата при вчитување го повикува сервисниот метод getMedicines() од дата сервисот и се „претплатува“ на Observable со wrapped низа од лекови, која се враќа по добивањето на одговор од HTTP GET повикот до backend REST контролерот. Бројот на лекови што се добиваат е лимитиран на 5, па штом се утврди од страна на template директивата *ngIf дека низата на лекови не е веќе празна, тие се популираат во табелата. 2. Во полето за внес „Пребарај лек“ се внесува име на лекот - При секоја промена во полето за внес за пребарување на лекови се испраќа по еден HTTP GET searchMedicines(searchString) сличен како тој од претходниот чекор, со додатен searchString како влезен параметар за пребарување, кој се препраќа на backend REST контролерот во вид на path варијабла. 3. Во табелата се популирани пребараните лекови - Штом се вратени пребараните лекови, односно најдобрите 5 совпаѓања со испратениот пребарувачки string, се поставуваат во посебна низа на филтрирани лекови и следствено се популираат во табелата автоматски по настанување на промената со помош на Angular template engine-от. 4. Со клик на одреден лек во табелата, се отвара прозорец со повеќе информации за лекот заедно со имињата на компаниите во кои се продава лекот - Со клик на некој лек од табелата, се повикува функцијата openMedicineDialog() која отвара посебна дијалог компонента во која се праќаат податоците за лекот кој е кликнат. Тука може да се видат детални информации за лекот, заедно со имињата на компаниите кои го продаваат кои се наоѓаат во низа во рамки на Medicine објектот. \\ ||= **ИД:** =|| 2 || ||= **Случај на употреба:** =|| Отвара мапа на аптеки и здравствени установи || 1. Прелистувачот го прашува корисникот за пристап до неговата локација - При иницијализација на home компонентата со помош на HTML Geolocation API-то, се наоѓа локацијата на корисникот, кој претходно доделува дозвола на апликацијата за користење на неговите координати. Тоа се прави со помош на функцијата getCurrentPosition(), каде се креира и маркер за означување на локацијата на мапата. 2. По успешното враќање на податоците за аптеки/установи, се наоѓаат нивните координати и се означуваат на мапата - Штом заврши успешниот retrieval на податоците за аптеки/установи, се повикува функцијата appendPharmacyMarkers() на кој се испраќа низата од објекти кои ги содржат информациите за градовите и адресите, кој пак се користат како параметри за испраќање на HTTP GET повик до OpenStreetMap API-то, кое служи за пребарување на локации, кое пак ни ги враќа координатите (латитуда и лонгитуда) за секоја аптека/установа. Овие координати се користат за поставување на маркерите за означување на секој објект на мапата. - При секој нареден извршен повик за пребарување, одново се повикува фунцкијата appendPharmacyMarkers(), со цел да бидат најдени адресите на новите пребарани аптеки/установи, а потоа мапата да биде ререндерирана за истите да бидат прикажани. 3. Со клик на копчето „Активирај“ се прикажува мапата - Со клик на копчето „Активирај“ се повикува функцијата toggleMap(), со што се прикажува мапата заедно со претходно испроцесираните и додадените слоеви од маркери и пинови. - Постои и копче „Освежи“ со цел да биде овозможено и ререндерирање на мапата. 4. При клик на индивидуална аптека/установа од табелата, се отвара прозорец со повеќе информации за аптеката/установата и маркирана локација на мапа - Со клик на некој ред од табелата, се повикува функцијата openPharmacyDialog()/openFacilityDialog() која отвара посебна дијалог компонента во која се праќаат податоците за објектот од редот во табелата кој е кликнат. Тука може да се видат детални информации за аптеката/установата, а кај аптеките може да се види и компанијата сопственик од која ја поседува. - При иницијализација на оваа дијалог компонента, се повикува функцијата addMarkers() која наоѓајќи ја адресата на истиот принцип преку наоѓање на координатите преку OpenStreetMap API-то, го додава маркерот и го поставува соодветниот зум за приказ на мапата за индивидуалната аптека/установа во дијалогот. \\ ||= **ИД:** =|| 3 || ||= **Случај на употреба:** =|| Разлистува тековни информации за пандемии || 1. Во темплејтот се популираат бројките - При вчитување на компонентата се повикува сервисниот метод getPandemic() од дата сервисот и се претплатува на Observable со wrapped Pandemic објект, кој се враќа со добивање на одговорот од HTTP GET повикот до backend REST контролерот, до соодветната API патека. Штом се утврди од страна на template директивата *ngIf дека објектот не е веќе празен, податоците/бројките се прикажуваат во темплејтот. \\ === Аптека === ||= **ИД:** =|| 4 || ||= **Случај на употреба:** =|| Ажурира состојба на лекови во продажба, и ажурира аптеки || 1. Агентот ажурира состојба на лекови во продажба - Со клик на копчето „Додај нов лек“ се повикува функцијата addMedicine() со што се отвара дијалог со форма за внес на сите потребни информации за додавање на нов лек. По успешно затворање на овој дијалог, се додава лекот на листата. - Со клик на копчето „Додај постоечки лекови“ постои можноста да се додаваат лековите кои веќе се наоѓаат во базата, се повикува функцијата addMedicinesFromList() која отвара нова дијалог компонента со опции за штиклирање и додавање нови лекови во сопствената листа на продажба. - Со вклучување на слајдер копчето "Edit mode", се повикува функцијата switchEditMedicineMode() при што на сите полиња од табелата со лекови се дозволува менување на вредностите. Исто така се додава копче за бришење на секој лек поединечно, во последната колона од табелата. При клик на ова копче се повикува функцијата deleteMedicine() при што листата се филтрира и лекот се брише од листата. - Сите овие промени се прават во рамки на самиот прелистувач, па се до моментот на кликање на копчето „Зачувај ги промените“, промените врз лековите нема да бидат извршени во самата база. Со клик се повикува сервисната метода updatePharmacyHead() од дата сервисот, при што се праќаат сите ажурирани податоци до backend-от и соодветно се зачувуваат во база. 2. Агентот ажурира аптека - Агентот ги гледа сите свои аптеки во табелата од табот „Мои аптеки“, па со клик на копчето "Edit" до секоја аптека посебно во рамки на табелата се повикува функцијата openEditPharmacyDialog() која отвара дијалог со форма за ажурирање на податоците за соодветната аптека. По кликање на копчето "Save", ажурираните резултати се предаваат на сервисната метода updatePharmacyHead() од дата сервисот и се праќаат до backend-от. \\ ||= **ИД:** =|| 4.1 || ||= **Случај на употреба:** =|| Одвивање на регистрација и автентикација || 1. Агентот навигира до патеката за најава - Копче за најава води до рутата со форма за најава - "/login", на која е мапирана Login компонентата, при нејзина иницијализација се врши проверка за тоа дали некој корисник веќе е логиран и дали постојат токени во localStorage објектот. Во случаи кога веќе постои, го враќа на претходната патека, во спротивно корисникот останува на патеката за најава. 2. Агентот ја пополнува формата и го испраќа барањето за најава - По пополнување на формата, со клик на копчето „Најави се“ се повикува функцијата loginPharmacyHead() која ја повикува сервисната метода login од автентикацискиот сервис, со внесената е-пошта и лозинка како влезни параметри. Потоа се праќа HTTP POST повик до backend-от за валидација на корисникот. По успешната валидација, се рутира агентот до соодветната патека, инаку се прикажува порака за грешка веднаш под формата. - Податоците за корисникот, како и неговите токени за авторизиран пристап се чуваат локално во localStorage објектот, и мора да бидат достапни во текот на неговата интеракција со деловите на апликацијата кои побаруваат автентициран корисник за пристап. - Секое испратено барање мора да го содржи "Authorization" делот во заглавјето на барањето, па за таа цел имплементацијата на JWT interceptor го зема токенот за пристап од localStorage и го „лепи“ за секое заглавие на барање. - Секоe барање исто така се пресретнува од Unauthorized interceptor-от, каде се врши проверка доколку кодот на одговорот од серверот е 401 (Unauthorized), што може да значи невалиден токен за пристап, истечен токен или пак настанала некоја грешка, за во тој случај да ги пребрише податоците запишани локално во localStorage објектот и да го врати корисникот на Login компонентата. \\ ||= **ИД:** =|| 4.2 || ||= **Случај на употреба:** =|| Администрирачки панели и реализација на побарувања || 1. Администраторот менаџира и креира корисници - Во табот "Manage accounts" од администрирачкиот панел се излистани сите кориснички профили, заедно со опциите за бришење и уредување. При клик на "Delete" се повикува функцијата deletePharmacyHead() која ја повикува сервисната метода од дата сервисот за бришење на корисник. Додека пак при клик на "Edit" се повикува функцијата openEditPharmacyHeadDialog() при што се отвара дијалог компонента со полиња за уредување на податоци за корисникот. По затворање се повикува сервисната метода updatePharmacyHead() од дата сервисот и се праќа уредениот корисник на backend па соодветно се уредува во базата. - Табот "Create new account" содржи форма за креација на нов корисник - Агент. По пополнување, со клик на копчето "Create" се повикува функцијата createHead() која ја повикува сервисната метода insertPharmacyHead() од дата сервисот, со што се испраќа HTTP POST барање до backend-от и новиот корисник се креира во база. 2. Агентот испраќа барање за аптека - Во табот „Сите аптеки“ се достапни сите аптеки во табела, и до нив се наоѓа "Claim" функционалноста што служи за испраќање на барање за добивање на привилегии за уредување на аптеката. При клик се повикува функцијата claimPharmacy(), со што сервисната метода од дата сервисот испраќа HTTP POST барање до backend-от, со објект кој ги содржи аптеката и корисникот. 3. Администраторот прифаќа или отфрла барања - Во табот "Claiming requests" во администрирачкиот панел во табела се излистани сите барања испратени од корисниците и аптеките, со контроли за прифаќање и одбивање на барањата. "Approve" ја повикува функцијата approveRequest(), а "Reject" ја повикува rejectRequest(), кои потоа се проследуваат до соодветните сервисни методи од дата сервисот кои испраќаат барања до backend-от.