diff --git a/backend/admin.py b/backend/admin.py index ed235961c..f4492b833 100644 --- a/backend/admin.py +++ b/backend/admin.py @@ -330,7 +330,7 @@ def get(self): 'address': address_key, 'actuation_area': 'GOVERNMENT_AGENCIES', 'description': 'Ministério da Saúde', - 'photo_url': 'https://i1.wp.com/notta.news/wp-content/uploads/2017/08/tbg_20170713080909_62787.jpg?w=1024', + 'photo_url': 'https://firebasestorage.googleapis.com/v0/b/development-cis.appspot.com/o/images%2Fministerio_da_saude_logo-1551970633722?alt=media&token=a658e366-a3b6-4699-aa98-95dc79eff3b5', 'email': 'deciis@saude.gov.br', 'phone_number': '61 3315-2425', 'state': 'active', diff --git a/backend/handlers/__init__.py b/backend/handlers/__init__.py index 34e4f1810..4269bdbf1 100644 --- a/backend/handlers/__init__.py +++ b/backend/handlers/__init__.py @@ -44,6 +44,7 @@ from .institution_children_handler import * from .event_followers_handler import * from .feature_toggle_handler import * +from .current_state_email_request_handler import * handlers = [ base_handler, erro_handler, event_collection_handler, event_handler, @@ -63,7 +64,8 @@ user_request_collection_handler, user_timeline_handler, vote_handler, invite_hierarchy_collection_handler, invite_user_collection_handler, invite_institution_handler, invite_user_handler, institution_parent_handler, - institution_children_handler, event_followers_handler, feature_toggle_handler + institution_children_handler, event_followers_handler, feature_toggle_handler, + current_state_email_request_handler ] __all__ = [prop for handler in handlers for prop in handler.__all__] diff --git a/backend/handlers/current_state_email_request_handler.py b/backend/handlers/current_state_email_request_handler.py new file mode 100644 index 000000000..ce27e18fb --- /dev/null +++ b/backend/handlers/current_state_email_request_handler.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +"""Current state link request email handler.""" + +import json + +from util import login_required +from utils import json_response +from . import BaseHandler +from send_email_hierarchy import RequestStateEmailSender + +__all__ = ['CurrentStateEmailRequestHandler'] + + +class CurrentStateEmailRequestHandler(BaseHandler): + """Current state email request handler.""" + + @login_required + @json_response + def post(self, user): + body = json.loads(self.request.body) + + subject = "Link para preenchimento de formulario" + + email_sender = RequestStateEmailSender(**{ + 'receiver': user.email, + 'subject': subject, + 'body': body + }) + email_sender.send_email() diff --git a/backend/handlers/event_collection_handler.py b/backend/handlers/event_collection_handler.py index 125ee8da4..491483b3b 100644 --- a/backend/handlers/event_collection_handler.py +++ b/backend/handlers/event_collection_handler.py @@ -56,8 +56,8 @@ def get_filtered_events(filters, user): december = month == 12 begin_selected_month_utc = datetime(year, month, 1, 3) end_selected_month_utc = datetime(year if not december else year+1, month+1 if not december else 1, 1, 3) - query = ndb.gql("SELECT __key__ FROM Event WHERE institution_key IN :1 AND state =:2 AND start_time < DATETIME(:3)", - user.follows, 'published', end_selected_month_utc.strftime("%Y-%m-%d %H:%M:%S")) + query = ndb.gql("SELECT __key__ FROM Event WHERE institution_key IN :1 AND start_time < DATETIME(:2)", + user.follows, end_selected_month_utc.strftime("%Y-%m-%d %H:%M:%S")) if query.count() > 0: return ndb.gql("SELECT * FROM Event WHERE __key__ IN :1 AND end_time >= DATETIME(:2)", query.fetch(), begin_selected_month_utc.strftime("%Y-%m-%d %H:%M:%S")).order(Event.end_time, Event.key) diff --git a/backend/main.py b/backend/main.py index d135f30d8..aad167f7a 100644 --- a/backend/main.py +++ b/backend/main.py @@ -47,6 +47,7 @@ from handlers import InstitutionChildrenHandler from handlers import EventFollowersHandler from handlers import FeatureToggleHandler +from handlers import CurrentStateEmailRequestHandler methods = set(webapp2.WSGIApplication.allowed_methods) methods.add('PATCH') @@ -100,6 +101,7 @@ ("/api/user/timeline.*", UserTimelineHandler), ("/api/search/institution", SearchHandler), ("/api/feature-toggle.*", FeatureToggleHandler), + ("/api/email/current-state", CurrentStateEmailRequestHandler), ("/login", LoginHandler), ("/logout", LogoutHandler), ("/api/.*", ErroHandler) diff --git a/backend/send_email_hierarchy/__init__.py b/backend/send_email_hierarchy/__init__.py index 910a0cd11..3a2a4db30 100644 --- a/backend/send_email_hierarchy/__init__.py +++ b/backend/send_email_hierarchy/__init__.py @@ -10,13 +10,14 @@ from .request_link_email_sender import * from .request_user_email_sender import * from .transfer_admin_email_sender import * - +from .request_state_email_sender import * email_modules = [ email_sender, request_institution_email_sender, invite_institution_email_sender, invite_user_email_sender, leave_institution_email_sender, remove_institution_email_sender, remove_member_email_sender, - request_link_email_sender, request_user_email_sender, transfer_admin_email_sender + request_link_email_sender, request_user_email_sender, transfer_admin_email_sender, + request_state_email_sender ] __all__ = [prop for email_module in email_modules for prop in email_module.__all__] \ No newline at end of file diff --git a/backend/send_email_hierarchy/request_state_email_sender.py b/backend/send_email_hierarchy/request_state_email_sender.py new file mode 100644 index 000000000..e2cd6f858 --- /dev/null +++ b/backend/send_email_hierarchy/request_state_email_sender.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +"""Request state email sender.""" + +from . import EmailSender + +__all__ = ['RequestStateEmailSender'] + + +class RequestStateEmailSender(EmailSender): + """Entity responsible to send state link email.""" + + def __init__(self, **kwargs): + """The class constructor. + + It initializes the object with its html and its specific properties. + """ + super(RequestStateEmailSender, self).__init__(**kwargs) + self.subject = "Link para preenchimento de formulario" + self.html = "request_state_email.html" + + def send_email(self): + """It enqueue a sending email task with the json that will fill the entity's html. + + For that, it call its super with email_json property. + """ + email_json = { + 'state_link': self.__get_state_link() + } + super(RequestStateEmailSender, self).send_email(email_json) + + def __get_state_link(self): + return self.__get_data()['state-link'] + + def __get_data(self): + return self.body['data'] diff --git a/backend/templates/request_state_email.html b/backend/templates/request_state_email.html new file mode 100644 index 000000000..a580a362b --- /dev/null +++ b/backend/templates/request_state_email.html @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + +
+ + + + + +
+ + +
+ + + + + +
+
+
+
+
+
+ +
+
+
+ AQUI ESTÁ O LINK QUE VOCÊ SOLICITOU +
+
+
+ + VOCÊ SOLICITOU O LINK DE UM FORMULARIO DA PLATAFORMA PARA PREENCHE-LO DEPOIS E AQUI ESTÁ ELE. CLIQUE NO BOTÃO ABAIXO PARA ACESSA-LO. + +
+ +
+
+
+
+
+
+ + + + + +
+ + +
+ + + + + +
+
+
+
+ + +
+
+ +
+
+ +
+
+ + Copyright © 2017 Plataforma CIS - Ministério da Saúde. + +
+
+ + Todos os direitos reservados. + +
+
+
+
+
+
+
+ + + diff --git a/frontend/email/EmailService.js b/frontend/email/EmailService.js new file mode 100644 index 000000000..e6d677733 --- /dev/null +++ b/frontend/email/EmailService.js @@ -0,0 +1,24 @@ +(function () { + 'use strict'; + + angular.module("app").service('EmailService', ["HttpService", function emailService(HttpService) { + const emailService = this; + + emailService.STATE_LINK_EMAIL_API_URI = "/api/email/current-state"; + + /** + * Make a post request to the backend to send a state link by email. + * It receives the state link that will be sent. + * + * @param stateLink the state link that will be sent. + * @returns The post request to the backend. + */ + emailService.sendStateLink = (stateLink) => { + return HttpService.post(emailService.STATE_LINK_EMAIL_API_URI, { + "data": { + "state-link": Config.FRONTEND_URL + stateLink + } + }); + }; + }]); +})(); \ No newline at end of file diff --git a/frontend/email/stateLinkRequest/StateLinkRequestService.js b/frontend/email/stateLinkRequest/StateLinkRequestService.js new file mode 100644 index 000000000..0e97f8682 --- /dev/null +++ b/frontend/email/stateLinkRequest/StateLinkRequestService.js @@ -0,0 +1,43 @@ +(function () { + 'use strict'; + + angular.module("app").service('StateLinkRequestService', ['$mdDialog', function StateLinkRequestService($mdDialog) { + const StateLinkRequestService = this; + + /** + * It shows a dialog that will ask the user if it wants to receive the link of the state + * by email. It is used in pages that has big forms to be filled. + * + * @param stateLink the state link that will be sent by email. + * @param previousState the state that the user will comeback if it accepts to receive + * the email. + */ + StateLinkRequestService.showLinkRequestDialog = (stateLink, previousState) => { + $mdDialog.show({ + templateUrl: "app/email/stateLinkRequest/stateLinkRequestDialog.html", + clickOutsideToClose:true, + locals: { + stateLink: stateLink, + previousState: previousState, + }, + controller: [ + 'EmailService', + '$state', + 'stateLink', + 'previousState', + StateLinkRequestController, + ], + controllerAs: 'ctrl' + }); + }; + + function StateLinkRequestController(EmailService, $state, stateLink, previousState) { + const ctrl = this; + + ctrl.sendStateLink = () => { + EmailService.sendStateLink(stateLink); + $state.go(previousState); + }; + } + }]); +})(); \ No newline at end of file diff --git a/frontend/email/stateLinkRequest/stateLinkConstants.js b/frontend/email/stateLinkRequest/stateLinkConstants.js new file mode 100644 index 000000000..0a0cf085b --- /dev/null +++ b/frontend/email/stateLinkRequest/stateLinkConstants.js @@ -0,0 +1,9 @@ +(function () { + 'use strict'; + + angular.module("app").constant('STATE_LINKS', { + 'CREATE_EVENT': '/events', + 'MANAGE_INSTITUTION': '/institution/INSTITUTION_KEY/edit', + 'INVITE_INSTITUTION': '/inviteInstitution' + }); +})(); \ No newline at end of file diff --git a/frontend/email/stateLinkRequest/stateLinkRequestDialog.html b/frontend/email/stateLinkRequest/stateLinkRequestDialog.html new file mode 100644 index 000000000..b87ae0cde --- /dev/null +++ b/frontend/email/stateLinkRequest/stateLinkRequestDialog.html @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/frontend/event/canceledEventHeader.component.js b/frontend/event/canceledEventHeader.component.js new file mode 100644 index 000000000..8ae316bc6 --- /dev/null +++ b/frontend/event/canceledEventHeader.component.js @@ -0,0 +1,27 @@ +"use strict"; + +(function() { + + function CanceledEventController() { + const canceledEventCtrl = this; + + /** + * Get the first name of who modified the event by last + */ + canceledEventCtrl.getNameOfLastModified = () => { + return _.first(canceledEventCtrl.event.last_modified_by.split(" ")); + }; + + }; + + angular + .module("app") + .component("canceledEventHeader", { + templateUrl: 'app/event/canceled_event_header.html', + controller: [CanceledEventController], + controllerAs: 'canceledEventCtrl', + bindings: { + event: '<', + } + }); +})(); \ No newline at end of file diff --git a/frontend/event/canceled_event_header.html b/frontend/event/canceled_event_header.html new file mode 100644 index 000000000..3dbb824cc --- /dev/null +++ b/frontend/event/canceled_event_header.html @@ -0,0 +1,8 @@ + + highlight_off +
+
ESTE EVENTO FOI CANCELADO
+
por {{canceledEventCtrl.getNameOfLastModified()}} • + {{canceledEventCtrl.event.last_modified_date | amUtc | amLocal | amCalendar:referenceTime:formats}}
+
+
\ No newline at end of file diff --git a/frontend/event/event.css b/frontend/event/event.css index 3b4d2fb18..1da876404 100644 --- a/frontend/event/event.css +++ b/frontend/event/event.css @@ -210,7 +210,7 @@ .events-grid { display: grid; grid-template-columns: 20% 78% auto; - grid-template-rows: 9em auto; + grid-template-rows: auto; align-items: initial; margin: 0; } @@ -250,7 +250,7 @@ grid-column-end: 3; } - .event-preview-image { + .event-preview-image, .event-preview-without-image { max-height: 8em; height: 8em; max-width: 100%; @@ -260,6 +260,10 @@ background-color: #009688; } + .event-preview-without-image { + max-height: 3.5em; + } + .event-preview-border { border-left: 0.55em solid; } @@ -519,6 +523,60 @@ color:#009688; } + .event-canceled-tag, .event-canceled-icon { + color: white; + } + + .event-canceled-icon { + width: 1.5em; + height: 2em; + font-size: 2.5em; + margin-top: 0.4em; + margin-left: 0.3em; + } + + .event-canceled-tag { + margin-right: 2em; + margin-left: -1em; + margin-top: 1.4em; + font-size: 0.9em; + } + + .event-canceled-subtitle { + font-size: 0.65em; + margin-top: -1.9em; + margin-left: -1.25em; + } + + @media screen and (max-width: 400px) { + .event-canceled-tag { + font-size: 0.8em; + } + } + + @media screen and (max-width: 360px) { + .event-canceled-tag { + margin-top: 1.7em; + font-size: 0.75em; + } + } + + @media screen and (max-width: 330px) { + .event-canceled-tag { + margin-right: 1em; + margin-top: 2.1em; + font-size: 0.69em; + } + + .event-canceled-subtitle { + font-size: 0.55em; + } + + .event-canceled-icon { + margin-left: 0.2em; + } + } + @media screen and (min-height: 600px) { .event-links-fields { max-height: 13em; diff --git a/frontend/event/eventCard.component.js b/frontend/event/eventCard.component.js new file mode 100644 index 000000000..a7f5669c5 --- /dev/null +++ b/frontend/event/eventCard.component.js @@ -0,0 +1,31 @@ +"use strict"; + +(function() { + + function EventCardController(AuthService) { + const eventCardCtrl = this; + + eventCardCtrl.user = AuthService.getCurrentUser(); + + /** + * Get the color of institutional profile of the user + */ + eventCardCtrl.getProfileColor = () => { + const profile = _.filter(eventCardCtrl.user.institution_profiles, function(prof) { + return prof.institution_key === eventCardCtrl.event.institution_key; + }); + return _.get(_.first(profile), 'color', 'teal'); + }; + }; + + angular + .module("app") + .component("eventCard", { + templateUrl: 'app/event/event_card.html', + controller: ['AuthService', EventCardController], + controllerAs: 'eventCardCtrl', + bindings: { + event: '<', + } + }); +})(); \ No newline at end of file diff --git a/frontend/event/eventController.js b/frontend/event/eventController.js index 5665516d7..2c81fd45d 100644 --- a/frontend/event/eventController.js +++ b/frontend/event/eventController.js @@ -17,6 +17,8 @@ eventCtrl.selectedYear = null; eventCtrl.user = AuthService.getCurrentUser(); eventCtrl.isLoadingEvents = true; + eventCtrl.isFiltering = false; + eventCtrl.institutionsFilter = []; eventCtrl.loadMoreEvents = function loadMoreEvents() { @@ -53,14 +55,22 @@ eventCtrl.events.push(event); }); } + + if (Utils.isMobileScreen(SCREEN_SIZES.SMARTPHONE) && !eventCtrl.institutionKey) { + eventCtrl.events = eventCtrl.events.filter(event => { + const institution = _.find(eventCtrl.institutionsFilter, institution => institution.name === event.institution_name); + return institution && institution.enable; + }); + } else { + eventCtrl.events = $filter('filter')(eventCtrl.events, eventCtrl.institutionKey); + } - eventCtrl.events = $filter('filter')(eventCtrl.events, eventCtrl.institutionKey); eventCtrl.isLoadingEvents = false; eventCtrl._getEventsByDay(); }, function error() { $state.go(STATES.HOME); }); - } + }; eventCtrl.newEvent = function newEvent(event) { if(Utils.isMobileScreen(SCREEN_SIZES.SMARTPHONE)) { @@ -107,18 +117,7 @@ * @param {object} event - The current event */ eventCtrl.goToEvent = (event) => { - $state.go(STATES.EVENT_DETAILS, { eventKey: event.key }); - }; - - /** - * Get the color of institutional profile of the user - * @param {object} event - The current event - */ - eventCtrl.getProfileColor = (event) => { - const profile = _.filter(eventCtrl.user.institution_profiles, function(prof) { - return prof.institution_key === event.institution_key; - }); - return _.get(_.first(profile), 'color', 'teal'); + event.state !== 'deleted' && $state.go(STATES.EVENT_DETAILS, { eventKey: event.key }); }; /** @@ -172,8 +171,8 @@ * @private */ eventCtrl._getEventsByDay = () => { + eventCtrl.eventsByDay = []; if(eventCtrl.events.length > 0 && eventCtrl.selectedMonth) { - eventCtrl.eventsByDay = []; let eventsByDay = {}; _.forEach(eventCtrl.events, function(event) { eventCtrl._distributeEvents(event, eventsByDay); @@ -214,7 +213,7 @@ eventCtrl.loadMoreEvents(); }); }; - + /** * Generate the menuItems that will live in the middle of the toolbar. */ @@ -252,10 +251,13 @@ title: 'Atualizar', action: () => { eventCtrl._moreEvents = true; eventCtrl._actualPage = 0; eventCtrl.events = []; eventCtrl.loadMoreEvents()} }, - { - title: 'Filtrar por instituição', action: () => {} - } - ] + ]; + + if (!eventCtrl.institutionKey) { + toolbarMenuGeneralOptions.options.push({ + title: 'Filtrar por instituição', action: () => {eventCtrl.isFiltering = true;} + }); + } return toolbarMenuGeneralOptions; }; @@ -268,6 +270,27 @@ eventCtrl.toolbarItems = eventCtrl._getToolbarMobileMenuItems(); }; + /** + * This function applies the modifications made + * to the event filter by institution, + * reloading events and filtering. + */ + eventCtrl.confirmFilter = function confirmFilter() { + eventCtrl.events = []; + eventCtrl._actualPage = 0; + eventCtrl._moreEvents = true; + eventCtrl.isLoadingEvents = true; + eventCtrl.cancelFilter(); + return eventCtrl.loadMoreEvents(); + }; + + /** + * This function cancels the filter run. + */ + eventCtrl.cancelFilter = function cancelFilter() { + eventCtrl.isFiltering = false; + }; + eventCtrl.$onInit = () => { eventCtrl.institutionKey = $state.params.institutionKey; getCurrentInstitution(); @@ -276,6 +299,13 @@ eventCtrl._getMonths().then(() => { eventCtrl.setupToolbarFields(); }); + + eventCtrl.institutionsFilter = eventCtrl.user.follows.map(institution => { + return { + name: institution.name, + enable: true + }; + }); } else { eventCtrl.loadMoreEvents(); } diff --git a/frontend/event/eventDialogController.js b/frontend/event/eventDialogController.js index 50c8e6f51..0d63e015d 100644 --- a/frontend/event/eventDialogController.js +++ b/frontend/event/eventDialogController.js @@ -4,7 +4,7 @@ const app = angular.module("app"); app.controller('EventDialogController', function EventDialogController(MessageService, brCidadesEstados, - ImageService, AuthService, EventService, $mdMenu, $state, $rootScope, $mdDialog, $http, STATES, SCREEN_SIZES, ObserverRecorderService) { + ImageService, AuthService, EventService, $mdMenu, $state, $rootScope, $mdDialog, $http, STATES, SCREEN_SIZES, ObserverRecorderService, StateLinkRequestService, STATE_LINKS) { var dialogCtrl = this; dialogCtrl.loading = false; @@ -365,7 +365,8 @@ dialogCtrl.startHour = new Date(dialogCtrl.event.start_time); dialogCtrl.startHour.setHours(8, 0, 0); dialogCtrl.addStartHour(); - dialogCtrl.event.end_time = new Date(dialogCtrl.event.start_time); + dialogCtrl.event.end_time = _.isNil(dialogCtrl.event.end_time) ? + new Date(dialogCtrl.event.start_time) : dialogCtrl.event.end_time; dialogCtrl.endHour = new Date(dialogCtrl.event.start_time); dialogCtrl.endHour.setHours(18, 0, 0); dialogCtrl.addEndHour(); @@ -518,6 +519,9 @@ } else { dialogCtrl.event = { address: address }; } + if (Utils.isMobileScreen()) { + StateLinkRequestService.showLinkRequestDialog(STATE_LINKS.CREATE_EVENT, STATES.EVENTS); + } }; }); })(); \ No newline at end of file diff --git a/frontend/event/event_card.html b/frontend/event/event_card.html new file mode 100644 index 000000000..21b1bbe7e --- /dev/null +++ b/frontend/event/event_card.html @@ -0,0 +1,23 @@ + +
+ +
+ +
+
+
+ {{ eventCardCtrl.event.title | uppercase}} +
+
+ {{ eventCardCtrl.event.start_time | amUtc | amLocal | amDateFormat:'HH:mm' }} + {{ eventCardCtrl.event.address.city ? ' | ' + eventCardCtrl.event.address.city : ''}} +

+ {{eventCardCtrl.event.institution_name || uppercase}} +

+
+
+
+
\ No newline at end of file diff --git a/frontend/event/events_mobile.html b/frontend/event/events_mobile.html index 349519ec8..550add828 100644 --- a/frontend/event/events_mobile.html +++ b/frontend/event/events_mobile.html @@ -1,6 +1,6 @@ -
+
@@ -11,7 +11,7 @@ title="eventCtrl.institution.name" subtitle="eventCtrl.institution.address.city"> -
@@ -27,31 +27,15 @@
- -
- -
-
- {{ event.title | uppercase}} -
-
- {{ event.start_time | amUtc | amLocal | amDateFormat:'HH:mm' }} - {{ event.address.city ? ' | ' + event.address.city : ''}} -

- {{event.institution_name || uppercase}} -

-
-
-
-
+
- add - \ No newline at end of file + + + + diff --git a/frontend/event/filterEvents/filterEventByInstitution.component.js b/frontend/event/filterEvents/filterEventByInstitution.component.js new file mode 100644 index 000000000..c208702b5 --- /dev/null +++ b/frontend/event/filterEvents/filterEventByInstitution.component.js @@ -0,0 +1,62 @@ +(function() { + 'use strict'; + + const app = angular.module('app'); + + app.controller('FilterEventsByInstitutionController', function() { + const filterCtrl = this; + filterCtrl.originalList = []; + filterCtrl.enableAll = true; + + + /** + * This function checks if all filters are enabled + * and changes the enableAll variable to true, + * if there is at least one disabled, switch to false. + */ + filterCtrl.checkChange = function checkChange() { + filterCtrl.enableAll = (_.find(filterCtrl.filterList, institution => !institution.enable)) ? false : true; + }; + + /** + * This function enables or disables all filters, + * according to the enableAll variable + */ + filterCtrl.enableOrDisableAll = function enableOrDisableAll() { + filterCtrl.filterList.map(institution => institution.enable = filterCtrl.enableAll); + }; + + /** + * This function cancels the filter modification + * and returns it to the original state. + */ + filterCtrl.cancel = function cancel() { + filterCtrl.filterList.map((institution, index) => { + institution.enable = filterCtrl.originalList[index].enable; + }); + filterCtrl.cancelAction(); + }; + + filterCtrl.$onInit = function() { + filterCtrl.originalList = _.cloneDeep(filterCtrl.filterList); + filterCtrl.checkChange(); + }; + }); + + /** + * Filter events by institution component + * @example + * + * + */ + app.component("filterEventsByInstitution", { + templateUrl: 'app/event/filterEvents/filter_events_by_institution.html', + controller: 'FilterEventsByInstitutionController', + controllerAs: 'filterCtrl', + bindings: { + filterList: '<', + confirmAction: '<', + cancelAction: '<' + } + }); +})(); \ No newline at end of file diff --git a/frontend/event/filterEvents/filter_events_by_institution.css b/frontend/event/filterEvents/filter_events_by_institution.css new file mode 100644 index 000000000..dfb062a6f --- /dev/null +++ b/frontend/event/filterEvents/filter_events_by_institution.css @@ -0,0 +1,46 @@ +.filter-container { + display: grid; + grid-template-rows: 1fr min-content; + height: 100%; + max-height: 100%; +} + +.filter-items-container { + max-height: 100%; + overflow-y: scroll; +} + +.filter-items-container > h3 { + text-align: center; +} + +.filter-items-container > div { + display: grid; + grid-auto-rows: 1fr; +} + +.filter-item { + display: grid; + grid-template-columns: 20px auto; + grid-column-gap: 10px; + padding: 0 16px; + margin: 8px 0; + align-items: center; +} + +.filter-item > md-checkbox { + margin: 0; + text-align: center; +} + +.filter-buttons-container { + display: grid; + grid-template-columns: auto auto; + justify-content: end; + margin-bottom: 10px; +} + +.filter-cancel-button { + color: white; + background-color: #7F7F7F; +} \ No newline at end of file diff --git a/frontend/event/filterEvents/filter_events_by_institution.html b/frontend/event/filterEvents/filter_events_by_institution.html new file mode 100644 index 000000000..8a5986c49 --- /dev/null +++ b/frontend/event/filterEvents/filter_events_by_institution.html @@ -0,0 +1,20 @@ +
+
+

Filtrar por institutição

+
+
+ + {{institution.name}} +
+
+ + Todos os eventos +
+
+
+ +
+ CANCELAR + FILTRAR +
+
\ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html index 5c31459a4..b3f9bdb3b 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -73,6 +73,7 @@ + @@ -81,6 +82,7 @@ + @@ -233,6 +235,9 @@ + + + @@ -317,6 +322,13 @@ + + + + + + + diff --git a/frontend/institution/configInstitution/configInstDirective.js b/frontend/institution/configInstitution/configInstDirective.js index 6938ece5c..86c6ae813 100644 --- a/frontend/institution/configInstitution/configInstDirective.js +++ b/frontend/institution/configInstitution/configInstDirective.js @@ -3,7 +3,7 @@ var app = angular.module("app"); app.controller("ConfigInstController", function ConfigInstController(AuthService, InstitutionService, CropImageService,$state, $mdDialog, $http, STATES, ImageService, $rootScope, MessageService, PdfService, $q, $window, - RequestInvitationService, brCidadesEstados, ObserverRecorderService) { + RequestInvitationService, brCidadesEstados, ObserverRecorderService, StateLinkRequestService, STATE_LINKS) { var configInstCtrl = this; var institutionKey = $state.params.institutionKey; @@ -468,8 +468,15 @@ } else { $state.go(STATES.SIGNIN); } + if (Utils.isMobileScreen()) { + StateLinkRequestService.showLinkRequestDialog(getInstEditLink(), STATES.MANAGE_INST); + } }; + function getInstEditLink () { + return STATE_LINKS.MANAGE_INSTITUTION.replace("INSTITUTION_KEY", configInstCtrl.institutionKey); + } + (function main(){ configInstCtrl.institutionKey = institutionKey; configInstCtrl.initController(); diff --git a/frontend/institution/manageMembers/managementMembersController.js b/frontend/institution/manageMembers/managementMembersController.js index d5bca1b8e..a4392aa55 100644 --- a/frontend/institution/manageMembers/managementMembersController.js +++ b/frontend/institution/manageMembers/managementMembersController.js @@ -260,9 +260,9 @@ .clickOutsideToClose(false) .title('Reenviar convite') .textContent('Você deseja reenviar o convite?') - .ariaLabel('Reenviar convite') + .ariaLabel('Reenviar') .targetEvent(event) - .ok('Reenviar convite') + .ok('Reenviar') .cancel('Cancelar'); var promise = $mdDialog.show(confirm); promise.then(function () { diff --git a/frontend/institution/manageMembers/management_members_mobile.css b/frontend/institution/manageMembers/management_members_mobile.css index 4b9079d2b..c339c3075 100644 --- a/frontend/institution/manageMembers/management_members_mobile.css +++ b/frontend/institution/manageMembers/management_members_mobile.css @@ -61,4 +61,25 @@ display: grid; grid-row-gap: 0.5em; max-height: 18em; +} + + +@media screen and (max-width: 361px) { + .remove-member-title{ + font-size: 15px; + } + + .remove-member-name-user{ + font-size: 13px; + } +} + +@media screen and (min-width: 361px) and (max-width: 460px) { + .remove-member-title{ + font-size: 16px; + } + + .remove-member-name-user{ + font-size: 14px; + } } \ No newline at end of file diff --git a/frontend/institution/removeMemberDialog.html b/frontend/institution/removeMemberDialog.html index 575537358..ed597e17f 100644 --- a/frontend/institution/removeMemberDialog.html +++ b/frontend/institution/removeMemberDialog.html @@ -1,20 +1,17 @@
- Deseja remover este membro de sua instituição? + Deseja remover este membro de sua instituição? close
- - -
-

{{ removeMemberCtrl.member.name | uppercase }}

-

{{ removeMemberCtrl.member.email[0]}}

-
-
+ +
Motivo da remoção (Opcional) diff --git a/frontend/institution/transferAdminController.js b/frontend/institution/transferAdminController.js index 4da2d8e97..72400b49a 100644 --- a/frontend/institution/transferAdminController.js +++ b/frontend/institution/transferAdminController.js @@ -20,6 +20,13 @@ return false; }; + /** Get class of element HTML that show member entity. + * The class is defined according if member is selected. + */ + transferAdminCtrl.getClass = function getClass(member){ + return (member === transferAdminCtrl.selectedMember) ? "small-avatar": "small-avatar white-background"; + } + transferAdminCtrl.selectMember = function selectMember(member) { transferAdminCtrl.selectedMember = member; transferAdminCtrl.member = member.email[0]; diff --git a/frontend/institution/transfer_admin_dialog.html b/frontend/institution/transfer_admin_dialog.html index 46dde6143..1961a9735 100644 --- a/frontend/institution/transfer_admin_dialog.html +++ b/frontend/institution/transfer_admin_dialog.html @@ -1,24 +1,18 @@ - - + +

Transferir administração

Cada institutição precisa ter um administrador na plataforma CIS. Escolha abaixo um novo administrador para sua instituição:

- - - search - + - - -
- {{ member.name }} - {{ member.email[0]}} -
-
+

Nenhum membro foi encontrado com esse nome ou email.

@@ -28,10 +22,10 @@

Transferir administração

- + CANCELAR - + CONFIRMAR diff --git a/frontend/invites/inviteInstitutionController.js b/frontend/invites/inviteInstitutionController.js index c4c8a7b79..c0f27ca19 100644 --- a/frontend/invites/inviteInstitutionController.js +++ b/frontend/invites/inviteInstitutionController.js @@ -4,7 +4,7 @@ app.controller("InviteInstitutionController", function InviteInstitutionController( InviteService, $state, AuthService, InstitutionService, RequestInvitationService, - STATES, $mdDialog, MessageService) { + STATES, $mdDialog, MessageService, StateLinkRequestService, STATE_LINKS) { var inviteInstCtrl = this; inviteInstCtrl.invite = {}; @@ -127,9 +127,9 @@ .clickOutsideToClose(false) .title('Reenviar convite') .textContent('Você deseja reenviar o convite?') - .ariaLabel('Reenviar convite') + .ariaLabel('Reenviar') .targetEvent(event) - .ok('Reenviar convite') + .ok('Reenviar') .cancel('Cancelar'); var promise = $mdDialog.show(confirm); promise.then(function () { @@ -189,6 +189,12 @@ } } + inviteInstCtrl.$onInit = () => { + if (Utils.isMobileScreen()) { + StateLinkRequestService.showLinkRequestDialog(STATE_LINKS.INVITE_INSTITUTION, STATES.HOME); + } + }; + (function main() { loadSentInvitations(); loadSentRequests(); diff --git a/frontend/invites/new_invite.css b/frontend/invites/new_invite.css index 6c9fe887d..d0805fac8 100644 --- a/frontend/invites/new_invite.css +++ b/frontend/invites/new_invite.css @@ -10,10 +10,6 @@ margin-left: -4.3em; } -.no-margin{ - margin: 0px; -} - @media screen and (min-width: 600px) and (max-width:800px) { .new-invite-page-card { max-width: 30em; diff --git a/frontend/invites/new_invite_page.html b/frontend/invites/new_invite_page.html index 4247951ba..f83ef19be 100644 --- a/frontend/invites/new_invite_page.html +++ b/frontend/invites/new_invite_page.html @@ -46,26 +46,26 @@

{{ newInviteCtrl.invite.suggestion_institution_name }}

- + - + - +
- + - + @@ -73,7 +73,7 @@

{{ newInviteCtrl.invite.suggestion_institution_name }}

- + Rejeitar @@ -88,7 +88,7 @@

{{ newInviteCtrl.invite.suggestion_institution_name }}

- +
diff --git a/frontend/requests/requestProcessingController.js b/frontend/requests/requestProcessingController.js index fa8e6cc5d..5ef0e3fee 100644 --- a/frontend/requests/requestProcessingController.js +++ b/frontend/requests/requestProcessingController.js @@ -79,16 +79,13 @@ }; requestController.getChildrenInstName = function getChildrenInstName(size) { - const returnValue = requestController.children ? - Utils.limitString(requestController.children.name || - requestController.children.sender_name, size) : ""; - return returnValue; + return requestController.children ? + (requestController.children.name || requestController.children.sender_name) : ""; }; requestController.getChildrenInstEmail = function getChildrenInstEmail(size) { - const returnValue = requestController.children ? - Utils.limitString(requestController.children.institutional_email, size) : ""; - return returnValue; + return requestController.children ? + (requestController.children.institutional_email) : ""; }; requestController.isAnotherCountry = function isAnotherCountry() { diff --git a/frontend/requests/request_user_dialog.css b/frontend/requests/request_user_dialog.css new file mode 100644 index 000000000..ccc1f23a3 --- /dev/null +++ b/frontend/requests/request_user_dialog.css @@ -0,0 +1,46 @@ +.request-user__avatar{ + grid-area: avatar; + height: 3em; + width: 3em; + border-radius: 50%; +} + +.request-user__description-dialog{ + margin: 0; + color: #707070; +} + +.request-user__margin-user{ + margin: 0 0 8px 0; +} + +.request-user__requester-entity{ + display: grid; + grid-template-columns: max-content auto; + grid-template-rows: max-content max-content max-content; + grid-template-areas: + 'avatar title' + 'avatar subtitle' + 'avatar sub'; + grid-gap: 0 0.6rem; + padding: 0.6rem; + align-items: center; + background-color: #E0E0E0; +} + +.request-user__title { + grid-area: title; + line-height: 1rem; +} + +.request-user__subtitle { + grid-area: subtitle; + font-size: 0.8em; + line-height: 1rem; +} + +.request-user__sub{ + grid-area: sub; + font-size: 0.8em; + line-height: 1rem; +} \ No newline at end of file diff --git a/frontend/requests/request_user_dialog.html b/frontend/requests/request_user_dialog.html index 2aed9e4f7..e0d177176 100644 --- a/frontend/requests/request_user_dialog.html +++ b/frontend/requests/request_user_dialog.html @@ -1,37 +1,29 @@ - + -

Confirmar Vínculo

-

+

Confirmar Vínculo

+

{{requestCtrl.isRequestUser() ? "Um usuário da plataforma" : "Uma instituição"}} solicitou vincular-se a uma das instituições que você administra. Clique em confirmar para aceitar ou rejeitar para recusar vinculo.

-
-
- {{requestCtrl.parent.name}} -
-
- {{ requestCtrl.parent.name }} - {{ requestCtrl.parent.email }} -
-
+ +
-
-
- {{ requestCtrl.children.name }} -
-
- {{ requestCtrl.getChildrenInstName(25)}} - {{ requestCtrl.getChildrenInstName(60)}} - {{ requestCtrl.getChildrenInstEmail(20) }} - {{ requestCtrl.getChildrenInstEmail(50) }} - {{ requestCtrl.children.office }} -
+
+ + {{requestCtrl.getChildrenInstName()}} + + {{requestCtrl.getChildrenInstEmail()}} + + + Cargo: {{ requestCtrl.children.office }} +
diff --git a/frontend/styles/custom.css b/frontend/styles/custom.css index 3a72edea3..a9901f4ae 100644 --- a/frontend/styles/custom.css +++ b/frontend/styles/custom.css @@ -1131,6 +1131,10 @@ md-input-container:not(.md-input-invalid).md-input-focused .green-input, font-weight: 500; } +.zero-margin{ + margin: 0px; +} + /* Smartphones */ @media screen and (max-width: 420px) { .custom-card { diff --git a/frontend/test/specs/event/canceledEventHeaderComponentSpec.js b/frontend/test/specs/event/canceledEventHeaderComponentSpec.js new file mode 100644 index 000000000..16a17fb83 --- /dev/null +++ b/frontend/test/specs/event/canceledEventHeaderComponentSpec.js @@ -0,0 +1,29 @@ +"use strict"; + +(describe("CanceledEventHeaderComponent", () => { + + let componentController, rootScope, + scope, event, canceledEventCtrl; + + event = { + last_modified_by: 'User Test', + }; + + beforeEach(module('app')); + + beforeEach(inject(($componentController, $rootScope) => { + + componentController = $componentController; + rootScope = $rootScope; + scope = rootScope.$new(); + canceledEventCtrl = componentController("canceledEventHeader", scope, + {event: event}); + })); + + describe('getNameOfLastModified()', () => { + it('Should return the first name of who modified the event by last', () => { + expect(canceledEventCtrl.event.last_modified_by).toEqual('User Test'); + expect(canceledEventCtrl.getNameOfLastModified()).toEqual('User'); + }); + }); +})); \ No newline at end of file diff --git a/frontend/test/specs/event/eventCardComponentSpec.js b/frontend/test/specs/event/eventCardComponentSpec.js new file mode 100644 index 000000000..df24f8417 --- /dev/null +++ b/frontend/test/specs/event/eventCardComponentSpec.js @@ -0,0 +1,51 @@ +"use strict"; + +(describe("EventCardComponent", () => { + + let componentController, authService, rootScope, + scope, institution, user, event, eventCardCtrl; + + institution = { + key: 'inst-key', + }; + + user = { + institution_profiles: [ + { + institution_key: institution.key, + color: 'pink' + } + ] + }; + + event = { + 'institution_key': institution.key, + }; + + beforeEach(module('app')); + + beforeEach(inject(($componentController, AuthService, $rootScope) => { + + componentController = $componentController; + authService = AuthService; + rootScope = $rootScope; + scope = rootScope.$new(); + authService.login(user); + eventCardCtrl = componentController("eventCard", scope, + {event: event, user: user}); + eventCardCtrl.user = user; + eventCardCtrl.event = event; + })); + + describe('getProfileColor()', () => { + + it('Should return the color if user is member of institution of event', () => { + expect(eventCardCtrl.getProfileColor()).toEqual(_.first(user.institution_profiles).color); + }); + + it('Should return a default color "teal" if user is not a member of institution of event', () => { + eventCardCtrl.user = {institution_profiles: []}; + expect(eventCardCtrl.getProfileColor()).toEqual('teal'); + }); + }); +})); \ No newline at end of file diff --git a/frontend/test/specs/event/eventControllerSpec.js b/frontend/test/specs/event/eventControllerSpec.js index ec8f6c0f2..aa934625f 100644 --- a/frontend/test/specs/event/eventControllerSpec.js +++ b/frontend/test/specs/event/eventControllerSpec.js @@ -39,6 +39,8 @@ 'start_time': startDate, 'end_time': endDate, 'institution_key': institution.key, + 'institution_name': institution.name, + 'last_modified_by': 'User Test', 'key': '12345' }, other_event = { @@ -49,6 +51,7 @@ 'start_time': startDate, 'end_time': endDate, 'institution_key': other_institution.key, + 'institution_name': institution.name, 'key': '54321' }, requestEvent = { @@ -268,19 +271,6 @@ }); }); - describe('getProfileColor()', () => { - - it('Should return the color if user is member of institution of event', () => { - eventCtrl.user = user; - expect(eventCtrl.getProfileColor(event)).toEqual(_.first(user.institution_profiles).color); - }); - - it('Should return a default color "teal" if user is not a member of institution of event', () => { - eventCtrl.user = {institution_profiles: []}; - expect(eventCtrl.getProfileColor(event)).toEqual('teal'); - }); - }); - describe('loadFilteredEvents()', () => { it('Should reset moreEvents, actualPage and isAnotherMonth', () => { @@ -367,19 +357,27 @@ }); it('Should to increase the events of controller if not is another month', () => { - eventCtrl._isAnotherMonth = false; - eventCtrl.events = requestEvent.events; - expect(eventCtrl.events.length).toEqual(2); - eventCtrl._loadEvents(eventService.getEvents, december, testYear); - expect(eventCtrl.events.length).toEqual(4); + spyOn(Utils, 'isMobileScreen').and.callFake(() => true); + const ctrl = createCtrl(); + ctrl.showImage = true; + ctrl.$onInit(); + ctrl._isAnotherMonth = false; + ctrl.events = requestEvent.events; + expect(ctrl.events.length).toEqual(2); + ctrl._loadEvents(eventService.getEvents, december, testYear); + expect(ctrl.events.length).toEqual(4); }); it('Should update the events of controller if is another month', () => { - eventCtrl._isAnotherMonth = true; - eventCtrl.events = []; - eventCtrl._loadEvents(eventService.getEvents, december, testYear); - expect(eventCtrl.events).toEqual(requestEvent.events); - expect(eventCtrl._isAnotherMonth).toBeFalsy(); + spyOn(Utils, 'isMobileScreen').and.callFake(() => true); + const ctrl = createCtrl(); + ctrl.showImage = true; + ctrl.$onInit(); + ctrl._isAnotherMonth = true; + ctrl.events = []; + ctrl._loadEvents(eventService.getEvents, december, testYear); + expect(ctrl.events).toEqual(requestEvent.events); + expect(ctrl._isAnotherMonth).toBeFalsy(); }); }); diff --git a/frontend/test/specs/event/eventDialogCtrlSpec.js b/frontend/test/specs/event/eventDialogCtrlSpec.js index 72d8678af..c757b4c2d 100644 --- a/frontend/test/specs/event/eventDialogCtrlSpec.js +++ b/frontend/test/specs/event/eventDialogCtrlSpec.js @@ -3,7 +3,7 @@ (describe('Test EventDialogController', function() { let controller, scope, httpBackend, rootScope, imageService, eventService, - messageService, newCtrl, state, mdDialog, states, deferred; + messageService, newCtrl, state, mdDialog, states, deferred, stateLinkRequestService, stateLinks; const splab = {name: 'Splab', key: '098745'}, @@ -48,7 +48,8 @@ beforeEach(module('app')); beforeEach(inject(function($controller, $httpBackend, AuthService, - $rootScope, ImageService, EventService, MessageService, $state, $mdDialog, STATES, $q) { + $rootScope, ImageService, EventService, MessageService, $state, $mdDialog, STATES, $q, + StateLinkRequestService, STATE_LINKS) { imageService = ImageService; scope = $rootScope.$new(); httpBackend = $httpBackend; @@ -60,6 +61,8 @@ mdDialog = $mdDialog; states = STATES; deferred = $q.defer(); + stateLinkRequestService = StateLinkRequestService; + stateLinks = STATE_LINKS; AuthService.login(user); controller = newCtrl('EventDialogController', { scope: scope, @@ -73,6 +76,7 @@ controller.events = []; controller.$onInit(); httpBackend.when('GET', 'app/institution/countries.json').respond(200); + httpBackend.when('GET', 'app/email/stateLinkRequest/stateLinkRequestDialog.html').respond(200); httpBackend.flush(); })); @@ -627,6 +631,11 @@ country: "Brasil" }}); }); + it('should call showLinkRequestDialog', function () { + spyOn(stateLinkRequestService, 'showLinkRequestDialog'); + controller.$onInit(); + expect(stateLinkRequestService.showLinkRequestDialog).toHaveBeenCalledWith(stateLinks.CREATE_EVENT, states.EVENTS); + }); }); }); })); \ No newline at end of file diff --git a/frontend/test/specs/event/filterEvents/filterEventsByInstitutionControllerSpec.js b/frontend/test/specs/event/filterEvents/filterEventsByInstitutionControllerSpec.js new file mode 100644 index 000000000..e832decf7 --- /dev/null +++ b/frontend/test/specs/event/filterEvents/filterEventsByInstitutionControllerSpec.js @@ -0,0 +1,131 @@ +'use strict'; + +(describe('Test FilterEventsByInstitutionController', function() { + beforeEach(module('app')); + + let filterCtrl, inst, other_inst, filterList; + + beforeEach(inject(function($controller) { + inst = { + name: 'institution', + enable: true + }; + + other_inst = { + name: 'institution', + enable: true + }; + + filterList = [inst, other_inst]; + + filterCtrl = $controller('FilterEventsByInstitutionController'); + filterCtrl.filterList = filterList; + filterCtrl.$onInit(); + })); + + + describe('test checkChange()', function() { + it('Should be change filterCtrl.enableAll to false', function() { + inst.enable = false; + other_inst.enable = true; + filterCtrl.checkChange(); + expect(filterCtrl.enableAll).toBeFalsy(); + + inst.enable = true; + other_inst.enable = false; + filterCtrl.checkChange(); + expect(filterCtrl.enableAll).toBeFalsy(); + + inst.enable = false; + other_inst.enable = false; + filterCtrl.checkChange(); + expect(filterCtrl.enableAll).toBeFalsy(); + }); + + it('Should be change filterCtrl.enableAll to true', function() { + inst.enable = true; + other_inst.enable = true; + filterCtrl.checkChange(); + expect(filterCtrl.enableAll).toBeTruthy(); + }); + }); + + describe('test enableOrDisableAll', function() { + it('Should be enable all filters', function() { + inst.enable = false; + other_inst.enable = false; + filterCtrl.enableAll = true; + + filterCtrl.enableOrDisableAll(); + expect(inst.enable).toBeTruthy(); + expect(other_inst.enable).toBeTruthy(); + + inst.enable = false; + other_inst.enable = true; + filterCtrl.enableAll = true; + + filterCtrl.enableOrDisableAll(); + expect(inst.enable).toBeTruthy(); + expect(other_inst.enable).toBeTruthy(); + }); + + it('Should be disable all filters', function() { + inst.enable = true; + other_inst.enable = true; + filterCtrl.enableAll = false; + + filterCtrl.enableOrDisableAll(); + expect(inst.enable).toBeFalsy(); + expect(other_inst.enable).toBeFalsy(); + + inst.enable = true; + other_inst.enable = false; + filterCtrl.enableAll = false; + + filterCtrl.enableOrDisableAll(); + expect(inst.enable).toBeFalsy(); + expect(other_inst.enable).toBeFalsy(); + }); + }); + + describe('test cancel()', function() { + it('Should be return to original configs', function() { + filterCtrl.cancelAction = () => {}; + spyOn(filterCtrl, 'cancelAction'); + + const originalList = [ + { + name: 'institution', + enable: true + }, + { + name: 'institution', + enable: true + } + ]; + + inst.enable = false; + other_inst.enable = false; + + expect(originalList).toEqual(filterCtrl.originalList); + expect(originalList).not.toEqual(filterCtrl.filterList); + + filterCtrl.cancel(); + + expect(originalList).toEqual(filterCtrl.filterList); + expect(filterCtrl.cancelAction).toHaveBeenCalled(); + }); + }); + + describe('test $onInit', function() { + it('Should be clone the original filterList', function() { + spyOn(filterCtrl, 'checkChange'); + + filterCtrl.originalList = []; + filterCtrl.$onInit(); + + expect(filterCtrl.originalList).toEqual(filterList); + expect(filterCtrl.checkChange).toHaveBeenCalled(); + }); + }); +})); \ No newline at end of file diff --git a/frontend/test/specs/institution/configInstDirectiveSpec.js b/frontend/test/specs/institution/configInstDirectiveSpec.js index d19e7467f..2a04be49b 100644 --- a/frontend/test/specs/institution/configInstDirectiveSpec.js +++ b/frontend/test/specs/institution/configInstDirectiveSpec.js @@ -3,7 +3,7 @@ describe('Test ConfigInstDirective', function() { var editInstCtrl, scope, institutionService, state, deferred; var mdToast, mdDialog, http, inviteService, httpBackend, imageService; - let authService, createCtrl, pdfService, messageService, states; + let authService, createCtrl, pdfService, messageService, states, stateLinkRequestService; var address = { cep: "11111-000", @@ -84,7 +84,8 @@ describe('Test ConfigInstDirective', function() { beforeEach(module('app')); beforeEach(inject(function($controller, $httpBackend, $q, $state, $mdToast, STATES, - $rootScope, $mdDialog, $http, InstitutionService, InviteService, AuthService, PdfService, ImageService, MessageService) { + $rootScope, $mdDialog, $http, InstitutionService, InviteService, AuthService, PdfService, ImageService, MessageService, + StateLinkRequestService) { httpBackend = $httpBackend; httpBackend.expectGET('app/institution/legal_nature.json').respond(legal_nature); httpBackend.expectGET('app/institution/actuation_area.json').respond(actuation_area); @@ -93,6 +94,8 @@ describe('Test ConfigInstDirective', function() { httpBackend.when('GET', 'main/main.html').respond(200); httpBackend.when('GET', 'home/home.html').respond(200); httpBackend.when('GET', 'auth/login.html').respond(200); + httpBackend.when('GET', 'app/email/stateLinkRequest/stateLinkRequestDialog.html').respond(200); + httpBackend.when('GET', '/api/institutions/inst-key').respond(institution); scope = $rootScope.$new(); state = $state; deferred = $q.defer(); @@ -106,6 +109,7 @@ describe('Test ConfigInstDirective', function() { pdfService = PdfService; http = $http; states = STATES; + stateLinkRequestService = StateLinkRequestService; authService.login(userData); state.params.institutionKey = institution.key; @@ -160,6 +164,13 @@ describe('Test ConfigInstDirective', function() { expect(state.go).toHaveBeenCalledWith(states.SIGNIN); }); + it('should call showLinkRequestDialog', function () { + spyOn(stateLinkRequestService, 'showLinkRequestDialog'); + editInstCtrl.initController(); + expect(stateLinkRequestService.showLinkRequestDialog).toHaveBeenCalled(); + httpBackend.flush(); + }); + afterEach(function() { editInstCtrl.institutionKey = institution.key; editInstCtrl.user.state = 'active'; diff --git a/frontend/test/specs/invites/inviteInstitutionControllerSpec.js b/frontend/test/specs/invites/inviteInstitutionControllerSpec.js index 9c9c2a73e..bcfe692eb 100644 --- a/frontend/test/specs/invites/inviteInstitutionControllerSpec.js +++ b/frontend/test/specs/invites/inviteInstitutionControllerSpec.js @@ -3,6 +3,7 @@ (describe('Test InviteInstitutionController', function() { var inviteinstitutionCtrl, httpBackend, scope, inviteService, createCtrl, state, instService, mdDialog, requestInvitationService; + let stateLinkRequestService, states, stateLinks; var institution = { name: 'institution', @@ -39,7 +40,7 @@ beforeEach(module('app')); beforeEach(inject(function($controller, $httpBackend, $rootScope, $state, $mdDialog, - InviteService, AuthService, InstitutionService, RequestInvitationService) { + InviteService, AuthService, InstitutionService, RequestInvitationService, StateLinkRequestService, STATE_LINKS, STATES) { httpBackend = $httpBackend; scope = $rootScope.$new(); state = $state; @@ -47,6 +48,9 @@ inviteService = InviteService; instService = InstitutionService; requestInvitationService = RequestInvitationService; + stateLinkRequestService = StateLinkRequestService; + stateLinks = STATE_LINKS; + states = STATES; AuthService.login(user); @@ -56,6 +60,7 @@ httpBackend.when('GET', "main/main.html").respond(200); httpBackend.when('GET', "home/home.html").respond(200); httpBackend.when('GET', "auth/login.html").respond(200); + httpBackend.when('GET', 'app/email/stateLinkRequest/stateLinkRequestDialog.html').respond(200); createCtrl = function() { return $controller('InviteInstitutionController', @@ -210,4 +215,12 @@ }); }); }); + + describe('$onInit', function () { + it('should call showLinkRequestDialog if in mobile screen', function () { + spyOn(stateLinkRequestService, 'showLinkRequestDialog'); + inviteinstitutionCtrl.$onInit(); + expect(stateLinkRequestService.showLinkRequestDialog).toHaveBeenCalledWith(stateLinks.INVITE_INSTITUTION, states.HOME); + }); + }); })); \ No newline at end of file diff --git a/frontend/utils/entityShowcase/entityShowcase.css b/frontend/utils/entityShowcase/entityShowcase.css index bcdf08127..9ca749f58 100644 --- a/frontend/utils/entityShowcase/entityShowcase.css +++ b/frontend/utils/entityShowcase/entityShowcase.css @@ -43,4 +43,15 @@ .entity-showcase__right-icon-buttons { grid-area: right-icon-buttons; -} \ No newline at end of file +} + +.white-background .entity-showcase{ + background-color: white; +} + +@media screen and (max-width: 320px) { + .small-avatar .entity-showcase__avatar{ + height: 2.5em; + width: 2.5em; + } +}